不,不保证地址空间匹配。对于基本类型(float,int,...),您有对齐要求(标准的第 6.1.5 节),并且您必须使用 OpenCL 实现的 cl_type 名称(在 C 中编程时,pyopencl 完成了我的工作会说)。
对于指针,由于这种不匹配,它甚至更简单。标准 v 1.2 的第 6.9 节的开头(1.1 版的第 6.8 节)指出:
在程序中声明为指针的内核函数的参数必须使用 __global、__constant 或 __local 限定符声明。
在第 p 点:
声明为结构或联合的内核函数的参数不允许将 OpenCL 对象作为结构或联合的元素传递。
还要注意第 d 点:
不支持可变长度数组和具有灵活(或未调整大小)数组的结构。
所以,没有办法让你的内核按照你的问题中的描述运行,这就是为什么你找不到一些 OpenCl 结构的例子有指针作为成员。
我仍然可以提出一个解决方法,利用内核在 JIT 中编译的事实。它仍然要求您正确打包数据并注意对齐,最后在程序执行期间大小不会改变。老实说,我会选择一个以 3 个缓冲区作为参数的内核,但无论如何,它就在那里。
这个想法是使用预处理器选项 -D,如以下 python 示例中所示:
核心:
typedef struct {
uint a[SIZE];
uint b[SIZE];
uint c[SIZE];
} SumParameters;
kernel void foo(global SumParameters *params){
int idx = get_global_id(0);
params->c[idx] = params->a[idx] + params->b[idx];
}
主机代码:
import numpy as np
import pyopencl as cl
def bar():
mf = cl.mem_flags
ctx = cl.create_some_context()
queue = cl.CommandQueue(self.ctx)
prog_f = open('kernels.cl', 'r')
#a = (1, 2, 3), b = (4, 5, 6)
ary = np.array([(1, 2, 3), (4, 5, 6), (0, 0, 0)], dtype='uint32, uint32, uint32')
cl_ary = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=ary)
#Here should compute the size, but hardcoded for the example
size = 3
#The important part follows using -D option
prog = cl.Program(ctx, prog_f.read()).build(options="-D SIZE={0}".format(size))
prog.foo(queue, (size,), None, cl_ary)
result = np.zeros_like(ary)
cl.enqueue_copy(queue, result, cl_ary).wait()
print result
结果:
[(1L, 2L, 3L) (4L, 5L, 6L) (5L, 7L, 9L)]