有没有简单的方法如何将float4或任何其他vector参数传递给OpenCL内核? 对于标量参数(int,float),您可以在调用内核时直接传递它。对于数组参数,您必须首先使用cl.Buffer()将其复制到GPU,然后再传递指针。当然可能以与数组相同的方式传递float4。但我问是否有更简单,更明确的方式。 (特别是使用Python,numpy,pyOpenCL)
我尝试将大小为4 * float32的numpy数组作为float4传递,但它不起作用。是否有可能以其他方式做到这一点?
例如: 的 kernnel:
__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快(因为它可以被所有工作项共享为常量)
答案 0 :(得分:2)
我觉得这是在python中创建float4的好方法:
import numpy as np
import pyopencl as cl
import pyopencl.array as cl_array
data= np.zeros(N, dtype=cl_array.vec.float4)
编辑:还要提供MWE:
import numpy as np
import pyopencl as cl
import pyopencl.array as cl_array
deviceID = 0
platformID = 0
workGroup=(1,1)
N = 10
testData = np.zeros(N, dtype=cl_array.vec.float4)
dev = cl.get_platforms()[platformID].get_devices()[deviceID]
ctx = cl.Context([dev])
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
Data_In = cl.Buffer(ctx, mf.READ_WRITE, testData.nbytes)
prg = cl.Program(ctx, """
__kernel void Pack_Cmplx( __global float4* Data_In, int N)
{
int gid = get_global_id(0);
Data_In[gid] = 1;
}
""").build()
prg.Pack_Cmplx(queue, (N,1), workGroup, Data_In, np.int32(N))
cl.enqueue_copy(queue, testData, Data_In)
print testData
答案 1 :(得分:1)
问题出在这里:
myFloat4 = numpy.array ( [1.0 ,2.0 ,3.0], dtype=numpy.float32 )
但myFloat4.size等于3
只需输入:
myFloat4 = numpy.array ( [1.0 ,2.0 ,3.0, 4.0], dtype=numpy.float32 )
剩下的代码很好
答案 2 :(得分:1)
我发现了三件事:
查看错误消息,第二个内核参数似乎存在问题,即myFloat
。如果在内核签名中将其声明为const
参数,会发生什么?如果你这样做会发生什么
myFloat = myFloat.astype(np.float32)
kernelArgs = (..., myFloat, ...)
prg.myKernel(...)
您想要定义一个四元素向量myFloat4
,但只提供三个值[1.0, 2.0, 3.0]
。还可以尝试在内核签名中设置const float4 myFloat4
。
在实际内核调用中,kernelargs
元组不需要额外的括号:
prg.myKernel(queue, cl_myArray.shape() , None, *kernelargs)
答案 3 :(得分:0)
对我来说,当我运行opencl内核时,创建一个numpy数组(SIZE,4)和dtype float32工作正常。确保第二个维度与您想要的floatN相匹配,如果它们不匹配则不会抛出任何错误,但在我的情况下它会崩溃显卡驱动程序。
我参与数组的方式:np.zeros((SIZE,4), dtype=np.float32)
希望这可以帮助任何想知道相同的人。
答案 4 :(得分:0)
我不知道Python中的OpenCl,但我确实将double
,int
,double8
或任何OpenCl类型传递给了内核。
假设N是一个整数,alpha是double,而vect是double8
我的工作是
clSetKernelArg(kernel, 0, sizeof(int), &N);
clSetKernelArg(kernel, 18, sizeof(double), &alpha);
clSetKernelArg(kernel, 11, sizeof(cl_double8), &vect);
希望它有所帮助。 埃里克。