在 ArrayFire 中将向量分量与数组相乘
Multiplying a vector component with an array in ArrayFire
尝试将向量分量与数组相乘(逐元素乘法或广播)时出现错误。文档显示 * 的这种重载情况应该没问题:
AFAPI array operator* (const float &lhs, const array &rhs)
Multiplies two arrays or an array and a value. (const array&, const
array&)
但根据下面的错误信息,也许 vect(0)
需要进一步展平或缩小以使尺寸一致?
错误表述清楚:
Invalid dimension for argument 1 Expected: 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
matrix
[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: terminating with uncaught exception of type
af::exception: ArrayFire Exception (Invalid input size:203): In
function getOutDims In file src/backend/ArrayInfo.cpp:173
Invalid dimension for argument 1 Expected: ldims == rides
In function af::array af::operator*(const af::array &, const af::array
&)
添加一个用例来阐明:
在实践中,我通过对 coeff(k) *(3 维数组 Z 的 2 维切片)求和来构建最终数组:
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, ...}
并且元素不一定按顺序排列;这允许选择特定术语。
ArrayFire 不会隐式执行 vector array
-scalar array
元素操作(你说的情况是失败的)。仅 vector array
-value
隐式支持。
要完成您正在做的事情,您将需要使用 tile() 函数,如下所示。
af_print(tile(vect(0), matrix.dims()) * matrix);
由于要平铺的维度为 1,因此平铺将用作 JIT 函数。这里没有使用额外的内存。整个计算在单个内核中完成。因此也没有性能受到影响。
自从上次回答以来 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);
尝试将向量分量与数组相乘(逐元素乘法或广播)时出现错误。文档显示 * 的这种重载情况应该没问题:
AFAPI array operator* (const float &lhs, const array &rhs)
Multiplies two arrays or an array and a value. (const array&, const array&)
但根据下面的错误信息,也许 vect(0)
需要进一步展平或缩小以使尺寸一致?
错误表述清楚:
Invalid dimension for argument 1 Expected: 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 6750Mmatrix
[3 3 1 1]
0.0000 0.0000 0.0000
0.0000 0.0000 0.0000
0.0000 0.0000 0.0000vect
[5 1 1 1]
1.0000
2.0000
3.0000
4.0000
5.0000vect(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: terminating with uncaught exception of type af::exception: ArrayFire Exception (Invalid input size:203): In function getOutDims In file src/backend/ArrayInfo.cpp:173
Invalid dimension for argument 1 Expected: ldims == rides
In function af::array af::operator*(const af::array &, const af::array &)
添加一个用例来阐明: 在实践中,我通过对 coeff(k) *(3 维数组 Z 的 2 维切片)求和来构建最终数组:
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, ...}
并且元素不一定按顺序排列;这允许选择特定术语。
ArrayFire 不会隐式执行 vector array
-scalar array
元素操作(你说的情况是失败的)。仅 vector array
-value
隐式支持。
要完成您正在做的事情,您将需要使用 tile() 函数,如下所示。
af_print(tile(vect(0), matrix.dims()) * matrix);
由于要平铺的维度为 1,因此平铺将用作 JIT 函数。这里没有使用额外的内存。整个计算在单个内核中完成。因此也没有性能受到影响。
自从上次回答以来 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);