【发布时间】:2013-01-18 23:48:30
【问题描述】:
是否有任何简单的方法可以将 float4 或任何其他向量参数传递给 OpenCL 内核? 对于标量参数(int,float),您可以在调用内核时直接传递它。对于数组参数,您必须先使用 cl.Buffer() 将其复制到 GPU,然后再传递指针。当然有可能以与数组相同的方式传递 float4。但我问是否有任何更简单,更清晰的方法。 (尤其是使用 Python、numpy、pyOpenCL)
我尝试将大小为 4*float32 的 numpy 数组作为 float4 传递,但它不起作用。是否有可能以其他方式做到这一点?
例如: 内核:
__kernel void myKernel( __global float * myArray, float myFloat, float4 myFloat4 )
Python:
myFloat4 = numpy.array ( [1.0 ,2.0 ,3.0], dtype=np.float32 )
myArray = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=myArray_host)
kernelargs = ( myArray , numpy.float32(myFloat) , myFloat4)
prg.myKernel(queue, cl_myArray.shape() , None, *(kernelargs) )
我遇到了错误:
pyopencl.LogicError: when processing argument #2 (1-based): clSetKernelArg failed: invalid arg size
另一种可能性是将它作为标量 int 或 float 的集合传递 - 像:
__kernel void myKernel( __global float * myArray, float myFloat, float myFloat4_x, float myFloat4_y, float myFloat4_z )
kernelargs = ( myArray , numpy.float32(myFloat) ,numpy.float32(myFloat4_x),numpy.float32(myFloat4_y),numpy.float32(myFloat4_z))
但这也不是很方便 - 如果你想将 4x float4 和 5x int3 传递给 kernell,你很容易迷失在许多变量名中。
我认为传递 int 和 float 的向量 (2,3,4) 在 OpenCL 中一定很常见 - 例如 3D 数据网格的大小。所以我想知道是否真的有必要使用 cl.Buffer() 作为指针来传递它。
我猜常量参数 float4 也比 *float 快(因为它可以被所有工作项共享为常量)
【问题讨论】:
-
您将 myFloat4 定义为一个 numpy 数组。如果将其视为实际数组,则不能将其作为 float4 之类的参数传递,因为它实际上是 float vec[4]。在 C/C++ 中,您可以将其转换为 float4,但我不知道它在 Python 中是如何工作的。
标签: python numpy parameter-passing opencl pyopencl