问题和基本细节
我正在试验 Aparapi,我想编写一个实用程序类来处理常见操作;例如
public final class GPUUtils {
public static void add(final double[] sum, final double[] a, final double[] b, final int i) {
sum[i] = a[i] + b[i];
}
}
我不确定这是否可行,因为网站的文档说它不会,但我发现该网站的文档已经过时了;例如,Aparapi 现在确实支持 2D 和 3D 数组,但文档中另有说明。
为了测试这一点,我编写了以下测试:
@Test
void testAdd() {
final double[] sum = new double[8];
final double[] a = new double[] { 1, 2, 3, 4, 5, 6, 7, 8};
final double[] b = new double[] { 1, 2, 3, 4, 5, 6, 7, 8};
final Kernel kernel = new Kernel() {
@Override
public void run() {
GPUUtils.add(sum, a, b, this.getGlobalId());
}
};
kernel.execute(Range.create(8));
final double[] expected = new double[] { 2, 4, 6, 8, 10, 12, 14, 16 };
assertArrayEquals(expected, sum);
kernel.dispose();
}
除了测试失败之外,它运行得非常好,因为sum
从未修改过(它只是 [0, 0, 0, 0, 0, 0, 0, 0])
所以,我的问题是:Aparapi 是否意味着支持静态方法调用/对添加的实例方法的调用(有关添加的实例方法的详细信息,请参见下文)?或者这并没有因异常而失败的事实是一个错误?
如果它不支持静态方法调用,我希望在我们尝试创建 OpenCL 时会引发异常。
我试过的东西:
我将 VM arg 设置为打印生成的 OpenCL (-Dcom.aparapi.enableShowGeneratedOpenCL=true),我得到以下信息:
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
typedef struct This_s{
__global double *val$sum;
__global double *val$a;
__global double *val$b;
int passid;
}This;
int get_pass_id(This *this){
return this->passid;
}
void the_canonical_classname_GPUUtils__add( __global double* sum, __global double* a, __global double* b, int i){
sum[i] = a[i] + b[i];
return;
}
__kernel void run(
__global double *val$sum,
__global double *val$a,
__global double *val$b,
int passid
){
This thisStruct;
This* this=&thisStruct;
this->val$sum = val$sum;
this->val$a = val$a;
this->val$b = val$b;
this->passid = passid;
{
the_canonical_classname_GPUUtils__add(this->val$sum, this->val$a, this->val$b, get_global_id(0));
return;
}
}
现在,我不知道C
,OpenCL
但对于未经训练的人来说,这看起来不错
我尝试的另一件事是扩展Kernel
到不同的abstract class
本地并在那里添加实用程序方法作为实例方法。
例子:
public abstract class AparapiUtility extends Kernel {
void add(final double[] sum, final double[] a, final double[] b, final int i) {
sum[i] = a[i] + b[i];
}
}
AparapiUtility
使用匿名内部类而不是 a稍作修改的相同测试Kernel
仍然失败,我收到以下 OpenCL:
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
typedef struct This_s{
__global double *val$sum;
__global double *val$a;
__global double *val$b;
int passid;
}This;
int get_pass_id(This *this){
return this->passid;
}
void the_canonical_classname_AparapiUtility__add(This *this, __global double* sum, __global double* a, __global double* b, int i){
sum[i] = a[i] + b[i];
return;
}
__kernel void run(
__global double *val$sum,
__global double *val$a,
__global double *val$b,
int passid
){
This thisStruct;
This* this=&thisStruct;
this->val$sum = val$sum;
this->val$a = val$a;
this->val$b = val$b;
this->passid = passid;
{
the_canonical_classname_AparapiUtility__add(this, this->val$sum, this->val$a, this->val$b, get_global_id(0));
return;
}
}
再一次,看起来不错。