2013-02-04 27 views
0

有沒有簡單的方法讓float4或任何其他向量參數傳遞給OpenCL內核? 對於標量參數(int,float),可以在調用內核時直接傳遞它。對於數組參數,您必須先使用cl.Buffer()將其複製到GPU並傳遞指針。當然,可能可以像傳遞數組一樣傳遞float4。但我問是否有更簡單更清晰的方法。 (特別是使用Python,numpy,pyOpenCL)向OpenCL傳遞vector(float4)kernell參數(Python)

我嘗試通過numpy數組大小爲4 * float32作爲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 

其他possibiliy是把它當作標量整數或浮點數的集合 - 像:

__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。

我認爲在OpenCL中傳遞int和float的向量(2,3,4)必須非常普遍 - 例如3D數據網格的大小。所以我想知道是否真的有必要使用cl.Buffer()作爲指針來傳遞它。

我想這常變量個float4也快於*浮子

+0

您定義myFloat4作爲numpy的陣列。如果這被視爲一個實際的數組,那麼你不能像float4那樣將它作爲參數傳遞,因爲它實際上是float vec [4]。在C/C++中,你可以將它轉換爲float4,但我不知道它在Python中是如何工作的。 –

回答

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 
0

對我來說(因爲它可以作爲一個常數由所有工作項被共享),創建形狀的numpy的陣列(SIZE,4)和D型FLOAT32當我運行opencl內核時工作得很好。確保第二個維度匹配你想要的floatN類型,如果它們不匹配,它不會拋出任何錯誤,但在我的情況下,它會使圖形卡驅動程序崩潰。

我inited我數組的方式:np.zeros((SIZE,4), dtype=np.float32)

希望這有助於人誰是想知道同樣的。

+0

我仍然在想這個問題,但它是第二個參數應該是N爲一個floatN數組,或者/最後/參數應該是N? np.random.rand(SIZEx,SIZEy,4)似乎工作在np.random.rand(SIZEx,4,SIZEy)沒有。 – Omegaman

0

我不知道Python中的OpenCl,但我確實通過double,int,double8或OpenCl類型的內核。
假設N是一個整數,alpha是一個double,並且是一個double8。
我做的是

clSetKernelArg(kernel, 0, sizeof(int), &N); 
clSetKernelArg(kernel, 18, sizeof(double), &alpha); 
clSetKernelArg(kernel, 11, sizeof(cl_double8), &vect); 

希望它能幫助。 Éric。

1

問題是在這裏:

myFloat4 = numpy.array ([1.0 ,2.0 ,3.0], dtype=numpy.float32) 

但myFloat4。大小等於3

只需鍵入:

myFloat4 = numpy.array ([1.0 ,2.0 ,3.0, 4.0], dtype=numpy.float32) 

的代碼的其餘部分是被罰款

1

我注意到了三兩件事:

  1. 望着錯誤消息,似乎有與第二內核參數的問題,即myFloat。如果在內核簽名中聲明const參數,會發生什麼情況?如果你這樣做

    myFloat = myFloat.astype(np.float32) 
    kernelArgs = (..., myFloat, ...) 
    prg.myKernel(...) 
    
  2. 你要定義一個四元向量myFloat4但你給三個值[1.0, 2.0, 3.0]僅會發生什麼。也可以在內核簽名中嘗試設置const float4 myFloat4

  3. 你並不需要額外的括號中的實際內核調用的kernelargs元組:

    prg.myKernel(queue, cl_myArray.shape() , None, *kernelargs)