[英]How to pass a C struct with arrays and variables to OpenCL kernel using PyOpenCL
因此,我必須使用PyOpenCL將一些數據傳遞給OpenCL內核,或者使用Python將一些解決方法傳遞給OpenCL。 數據在內核端作為結構讀取,我無法更改內核cuz,它工作正常,並且是我的代碼必須使用的更大項目的一部分。
內核看起來像這樣:
typedef struct VglClStrEl{
float data[VGL_ARR_CLSTREL_SIZE];
int ndim;
int shape[VGL_ARR_SHAPE_SIZE];
int offset[VGL_ARR_SHAPE_SIZE];
int size;
} VglClStrEl;
typedef struct VglClShape{
int ndim;
int shape[VGL_ARR_SHAPE_SIZE];
int offset[VGL_ARR_SHAPE_SIZE];
int size;
} VglClShape;
__kernel void kernel(__global unsigned char* img_input,
__global unsigned char* img_output,
__constant VglClShape* img_shape,
__constant VglClStrEl* window)
{
// do what is needed
}
因此,如您所見,VglClShape和VglClStrElEl結構具有不同的類型數組和靜態位大小變量。
[1]解決方法僅支持一種類型數組的結構(或者我悲慘地無法獲得一種處理多種數組類型的方法)。
[2]解決方法是PyOpenCL文檔參考,有關如何將Python數據傳遞到OpenCL內核結構。 這種方法根本不支持數組。
那么,如何傳遞OpenCL內核可以讀取的python數據? 我已經在Python端擁有了所有數據,我只需要知道如何將其從Python傳遞到內核。
在您詢問之前:我正在使用Python 3,並且無法更改內核 。
是的,數組大小是靜態的。 您可以假設這樣:
VGL_ARR_CLSTREL_SIZE=256;
VGL_ARR_SHAPE_SIZE=20;
[1] 使用PyOpenCL將帶有指針成員的結構傳遞給OpenCL內核
[2] https://documen.tician.de/pyopencl/howto.html#how-to-use-struct-types-with-pyopencl
有一種駭人聽聞的方法來執行此操作,這需要一些乏味的字節爭用。 大概您可以部署小型OpenCL探測內核了嗎? (在任何情況下,PyOpenCL都會在某些操作下進行此操作)
基本思想是:
以下內核可以完成這項工作:
__kernel void get_struct_sizes( __global uint *struct_sizes )
{
const uint global_id = get_global_id(0u)+get_global_id(1u)*get_global_size(0u);
VglClStrEl vgclstrel;
VglClShape vgclshape;
uint offset;
printf("In GPU (probing):\n Kernel instance = %d\n", global_id);
if (global_id==0) {
offset = (uint)&(vgclstrel.data);
struct_sizes[0] = (uint)sizeof(vgclstrel);
struct_sizes[1] = (uint)&(vgclstrel.ndim)-offset;
struct_sizes[2] = (uint)&(vgclstrel.shape)-offset;
struct_sizes[3] = (uint)&(vgclstrel.offset)-offset;
struct_sizes[4] = (uint)&(vgclstrel.size)-offset;
offset = (uint)&(vgclshape.ndim);
struct_sizes[5] = (uint)sizeof(vgclshape);
struct_sizes[6] = (uint)&(vgclshape.shape)-offset;
struct_sizes[7] = (uint)&(vgclshape.offset)-offset;
struct_sizes[8] = (uint)&(vgclshape.size)-offset;
}
return;
}
執行此內核並將struct_sizes
返回到vgclshape_sizes
,創建以下數組:
img_shape = np.zeros((vgclshape_sizes[0]), dtype=np.uint8)
並復制到其中:
def copy_into_byte_array(value, byte_array, offset):
for i,b in enumerate(np.ndarray.tobytes(value)):
byte_array[i+offset] = b
copy_into_byte_array(ndim, img_shape, 0)
copy_into_byte_array(shape, img_shape, vgclshape_sizes[1])
copy_into_byte_array(offset, img_shape, vgclshape_sizes[2])
copy_into_byte_array(size, img_shape, vgclshape_sizes[3])
我在這里跳過了一些步驟; 填寫它們,您會發現此方法有效。 我能夠將演示結構傳遞給違規內核的虛擬副本。
我想聽聽是否有更優雅的方法來完成所有這些步驟。 我還希望字節序等方面存在問題,否則這些問題將是透明的。 幸運的話,您可以在他們周圍工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.