我使用下面的测试代码来利用ArrayFire库。
void test_seq(const array& input, array& output, const int N)
{
array test = seq(0,N-1);
output = input;
}
(for the moment `array test` has no role)
double2* test_CPU; test_CPU=(double2*)malloc(10*sizeof(double2));
for (int k=0; k<10; k++) { test_CPU[k].x=2.; test_CPU[k].y=1.; }
array test_GPU(10, test_CPU);
array test_GPU_output = constant(0.,10, c64);
test_seq(test_GPU,test_GPU_output,10);
print(test_GPU_output);
try {
double2 *CPU_test = test_GPU_output.host<double2>();
printf("%f %fn",CPU_test[0].x,CPU_test[0].y);
} catch (af::exception& e) {
fprintf(stderr, "%sn", e.what());
}
和所有东西都编译并正确运行。
但是,然后我将上面的函数更改为
void test_seq(const array& input, array& output, const int N)
{
array test = seq(0,N-1);
output = input * test;
}
我收到以下运行时错误消息
src/gena/gtypes.cpp:112:错误:从cuComplex类型的数组请求cuDoubleComplex
如果在另一边,我改变了
一行double2 *CPU_test = test_GPU_output.host<double2>();
float2 *CPU_test = test_GPU_output.host<float2>();
一切又正常了。似乎有一个降级到float2与使用seq
。如果我使用像seq(0,N-1,f64)
这样的东西(我甚至不知道它是否被ArrayFire允许),上述问题不会消失。
如何保持double2
处理,避免降级为float2
?
当将seq转换为数组时,它被存储为单精度(float)。
目前在arrayfire中,涉及两个精度不同的数组的操作规则是选择精度较低的数组。这就是input * test
从双精度转换为单精度的原因(也就是float2
)。
现在的解决方案是在生成test的下面添加一行。
test = test.as(f64);
它只会增加很少的开销,因为数组只有在需要的时候才会生成。