1

尝试将向量分量与数组相乘(逐元素乘法或广播)时出现错误。文档显示 * 的这种重载情况应该没问题:

AFAPI 数组 运算符* (const float &lhs, const array &rhs)
将两个数组或一个数组与一个值相乘。(常量数组&,常量数组&)

但是根据下面的错误信息,也许vect(0)需要进一步展平或缩小以使尺寸一致?

错误声明很明确:

参数 1 的尺寸无效预期:ldims == 游乐设施


下面是代码:

#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 异常(输入大小无效:203):在函数 getOutDims 中在文件 src/backend/ArrayInfo.cpp:173
参数 1 的尺寸无效预期:ldims ==
在函数 af::array af::operator*(const af::array &, const af::array &)


添加一个用例来澄清: 在实践中,我通过 coeff(k) * (3-d 数组 Z 的 2-d 切片)的总和来构造最终数组:

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

我会考虑使用 agfor但最初只是想获得正确的数字输出。还要注意向量:index是预定义的,例如,index = {1, 2, 4, 7, ...}元素不一定按顺序排列;这允许选择特定的术语。

4

2 回答 2

2

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

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

由于被平铺的维度为 1,因此 tile 将用作 JIT 函数。这里没有使用额外的内存。整个计算在单个内核中完成。因此也没有性能受到影响。

于 2016-09-30T17:02:08.420 回答
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);
于 2016-09-30T20:00:31.370 回答