0

问题和基本细节

我正在试验 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;
   }
}

现在,我不知道COpenCL但对于未经训练的人来说,这看起来不错

我尝试的另一件事是扩展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;
   }
}

再一次,看起来不错。

4

0 回答 0