如何传递一些参数,这些参数将在 .cl 文件中被视为使用 pyopencl 定义的预处理器?
意义:
foo.cl
# define LIMIT 12
typedef struct {
uint i[LIMIT];
} foomatic;
转向
foo_nodefs.cl
typedef struct {
uint i[LIMIT]; // python script passing LIMIT to set it
} foomatic;
谢谢,
约翰
编辑:扩展答案,使其尽可能详细。
有两种方法可以做到这一点:
(元编程)将您的预处理器指令直接添加到带有源代码的字符串中,或者甚至使用一些模板引擎运行您自己的预处理器。
import pyopencl as cl
import numpy
import numpy.linalg as la
a = numpy.random.rand(50000).astype(numpy.float32)
b = numpy.random.rand(50000).astype(numpy.float32)
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
a_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a)
b_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=b)
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, b.nbytes)
defines = """
#define AXIS 0
#define COEFF 1
"""
prg = cl.Program(ctx,
defines +
"""
__kernel void sum(__global const float *a,
__global const float *b, __global float *c)
{
int gid = get_global_id(AXIS);
c[gid] = a[gid] + b[gid] + COEFF;
}
""").build()
prg.sum(queue, a.shape, None, a_buf, b_buf, dest_buf)
a_plus_b = numpy.empty_like(a)
cl.enqueue_copy(queue, a_plus_b, dest_buf)
print(la.norm(a_plus_b - (a+b+1)), la.norm(a_plus_b))
(C 方式)使用options关键字 ofProgram.build将构建选项直接传递给clBuildProgram():
import pyopencl as cl
import numpy
import numpy.linalg as la
a = numpy.random.rand(50000).astype(numpy.float32)
b = numpy.random.rand(50000).astype(numpy.float32)
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
a_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a)
b_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=b)
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, b.nbytes)
prg = cl.Program(ctx, """
__kernel void sum(__global const float *a,
__global const float *b, __global float *c)
{
int gid = get_global_id(AXIS);
c[gid] = a[gid] + b[gid] + COEFF;
}
""").build(options=['-D', 'AXIS=0', '-D', 'COEFF=1'])
prg.sum(queue, a.shape, None, a_buf, b_buf, dest_buf)
a_plus_b = numpy.empty_like(a)
cl.enqueue_copy(queue, a_plus_b, dest_buf)
print(la.norm(a_plus_b - (a+b+1)), la.norm(a_plus_b))
(我使用了 PyOpenCL 文档主页上修改后的源代码。在 pyopencl 2013.1 上测试)。