2013-03-20 24 views
0

出於好奇找到調用OpenCL內核時可以傳遞的最大參數大小,我發現我可以傳遞一個大於最大大小的數組。這裏是正在發生的事情: (靠了靠,我使用pyopencl)OpenCL:如何傳遞大於max_parameter_size的參數?

>>> plat = cl.get_platforms() 
>>> dev = plat[0].get_devices(cl.device_type.ALL) 
>>> dev[0] 
<pyopencl.Device 'Juniper' on 'AMD Accelerated Parallel Processing' at 0x58fde60> 
>>> dev[0].max_parameter_size 
1024 

在谷歌搜索,我瞭解到,1024是以字節爲單位。(我忘了,其中說,我認爲Nvidia的論壇。)現在

,我跑這個腳本:

import pyopencl as cl 
import numpy as np 

plat = cl.get_platforms() 
dev = plat[0].get_devices(cl.device_type.ALL) 
ctx = ctx = cl.Context([ dev[0] ]) 
cq = cl.CommandQueue(ctx) 

kernel = """ 
__kernel void test(__global int* A, __global int* B){ 
const int id = get_global_id(0); 
B[ id ] = A[ id ]; 
barrier(CLK_GLOBAL_MEM_FENCE); 
} 
""" 

prg = cl.Program(ctx, kernel).build() 

A = np.ones((2**18,), dtype = np.int32) 
B = np.zeros_like(A) 

A_buf = cl.Buffer(ctx, cl.mem_flags.READ_ONLY|cl.mem_flags.COPY_HOST_PTR, hostbuf = A) 
B_buf = cl.Buffer(ctx, cl.mem_flags.WRITE_ONLY, B.nbytes) 

調用內核之前,我做了以下內容:

>>> A.nonzero()[0].shape 
(262144,) 
>>> B.nonzero()[0].shape 
(0,) 

然後我調用內核並檢查B中的非零元素:

>>> prg.test(cq, A.shape, A_buf, B_buf).wait() 
>>> cl.enqueue_copy(cq, B, B_buf) 
>>> B.nonzero()[0].shape 
(262144,) 

因此,cl早期,我可以發送並讀回大小大於cl.max_parameter_size的數組。 這怎麼可能?我哪裏錯了?

回答

3

CL_DEVICE_MAX_PARAMETER_SIZE指傳遞給clSetKernelArg的內核參數的最大大小。請參閱clGetDeviceInfo中的CL_DEVICE_MAX_MEM_ALLOC_SIZE和CL_DEVICE_GLOBAL_MEM_SIZE。

+0

dev [0] .max_parameter_size給出1024,其中dev [0]是GPU,dev [2] .max_parameter_size給出4096,其中dev [2]是我的comp上的CPU,它們有1GB和4GB的RAM分別。所以我想'dev [i] .max_parameter_size'返回可用於計算設備的內存大小.....因此,我假設它們在Bytes中是錯誤的,它們實際上以MB爲單位。謝謝您的幫助。 – Yash 2013-03-21 08:53:35

+3

你應該放棄猜測並假設,而是接受標準所說的話。正如答案中給出的那樣,'CL_DEVICE_MAX_MEM_ALLOC_SIZE'告訴你可以一次分配多少。 – matthias 2013-03-21 11:02:17

+0

@matthias,你是對的,我不應該猜到。但是我沒有找到通過向OpenCL設備發送這些查詢返回的值的單位(即比特/字節/ KB/MB),並且我已經在Google上花費了幾個小時的時間。現在,我知道他們是什麼。謝謝您的幫助。 – Yash 2013-03-22 06:28:16