将矢量组件与ArrayFire中的数组相乘

时间:2016-09-30 13:49:03

标签: arrayfire

我在尝试将矢量分量与数组相乘(元素乘法或广播)时出错。文档显示这个重载的情况应该没问题:

  

AFAPI数组运算符* (const float& lhs,const array& rhs)
    将两个数组或数组和值相乘。 (const array&,const   阵列&安培;)

但是根据下面的错误消息,可能vect(0)需要进一步展平或缩小,以便大小一致吗?

错误陈述很明确:

  

参数1的维度无效预期:ldims == rides

以下是代码:

#include <arrayfire.h>

int main(int argc, char *argv[])
{
    int device = argc > 1 ? atoi(argv[1]) : 0;
    af::setDevice(device);
    af::info();

    int n = 3;
    int N = 5;

    // Create the arrays:
    af::array matrix = af::constant(0,n,n,f32); // 3 x 3 float array of zeros
    af::array vect = af::seq(1,N); // A col vector of floats: {1.0, ... ,5.0}

    // Show the arrays:
    af_print(matrix);
    af_print(vect);

    // Print a single component of the vector:
    af_print(vect(0));

    // This line produces the error (see below):
    af_print(vect(0) * matrix); // Why doesn't this work?

    // But somthing like this is fine:
    af_print(1.0 * matrix);

    return 0;
}

制作输出:

  

ArrayFire v3.3.2
  ATI Radeon HD 6750M

     

矩阵
[3 3 1 1]
  0.0000 0.0000 0.0000
  0.0000 0.0000 0.0000
  0.0000 0.0000 0.0000

     

vect
[5 1 1 1]
      1.0000
      2.0000
      3.0000
      4.0000
      5.0000

     

vect(0)
[1 1 1 1]
      1.0000

矩阵= [3 3 1 1]和vect(0)= [1 1 1 1]的af_print()的dims()输出让我怀疑,但我不确定如何进一步展平。有人会认为这个例子是使用ArrayFire API的常用方法。

抛出的错误异常是:

  

libc ++ abi.dylib:以未捕获的类型异常终止   af :: exception:ArrayFire Exception(无效输入大小:203):In   function getOutDims在文件src / backend / ArrayInfo.cpp中:173
  参数1的维度无效预期:ldims == rides   
  在函数af :: array af :: operator *(const af :: array&amp;,const af :: array   &安培;)

添加用例以澄清: 在实践中,我通过coeff(k)*(3维阵列Z的2-d切片)的总和构建最终数组:

for (int j = 0; j<indx.dims(0); ++j)
  final += coeff(indx(j)) * Z(af::span,af::span,indx(j));

我将研究使用gfor,但最初只想得到正确的数字输出。另请注意,向量:index是预定义的,例如,说index = {1, 2, 4, 7, ...},元素不一定是顺序的;这允许选择特定术语。

2 个答案:

答案 0 :(得分:2)

ArrayFire不会隐式执行vector array - scalar array元素操作(你说的情况是失败的)。隐式支持仅vector array - value个。 要做你正在做的事情,你需要使用tile()函数,如下所示。

af_print(tile(vect(0), matrix.dims()) * matrix);

由于平铺的维度为1,因此tile将用作JIT函数。这里没有使用额外的内存。整个计算在单个内核中完成。因此也没有表现出色。

答案 1 :(得分:1)

由于自上一个答案以来OP添加了一个用例,这就是你在arrayfire中编写完全矢量化版本的方法。

array coeffs = moddims(coeff(indx), 1, 1, coeff.elements());
array final = sum(Z(span, span, indx) * tile(coeffs, Z.dims(0), Z.dims(1)), 2);