问题描述
|
我在将结构传递到内核本地内存时遇到问题。这是内核kode:
typedef struct data {
unsigned long wId; // group_id
unsigned long iId[1]; // global_item_id
} DATA;
__kernel void tKernel(__global DATA *x,__local DATA tmp) {
int wd = get_work_dim();
// x dimension
int xGrId = get_group_id(0);
int xLId = get_local_id(0);
int xGlId = get_global_id(0);
x += xGrId;
x->wId = tmp.wId;
x->iId[xLId] = ++tmp.wId;
}
这是主机代码:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#define GLOBAL_ITEM_SIZE (1)
#define LOCAL_ITEM_SIZE (1)
#define MAX_SOURCE_SIZE (0x100000)
typedef struct data {
unsigned long wId;
unsigned long iId[LOCAL_ITEM_SIZE];
} DATA;
int main() {
cl_platform_id platform_id = NULL;
cl_device_id device_id = NULL;
cl_context context = NULL;
cl_command_queue commandQueue = NULL;
cl_mem cmPinnedBufOut = NULL;
DATA *cDataOut = NULL;
cl_program program = NULL;
cl_kernel kernel = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret;
size_t group_size = GLOBAL_ITEM_SIZE / LOCAL_ITEM_SIZE;
FILE *fp;
const char fileName[] = \"./kernel.cl\";
size_t source_size;
char *source_str;
/* Load kernel source file */
fp = fopen(fileName,\"r\");
if (!fp) {
fprintf(stderr,\"Failed to load kernel.\\n\");
exit(EXIT_FAILURE);
}
source_str = (char *)malloc(MAX_SOURCE_SIZE);
source_size = fread(source_str,1,MAX_SOURCE_SIZE,fp);
fclose(fp);
/* Create OpenCL Context */
context = clCreateContext( NULL,&device_id,NULL,&ret);
/* Create command queue with measurment of preformance */
commandQueue = clCreateCommandQueue(context,device_id,&ret);
/* Create memory object */
cmPinnedBufOut = clCreateBuffer(context,CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,group_size * sizeof(DATA),&ret);
cDataOut = (DATA *)malloc(group_size * sizeof(DATA));
/* Create kernel program from source file */
program = clCreateProgramWithSource(context,(const char **)&source_str,(const size_t *)&source_size,&ret);
assert(ret == CL_SUCCESS);
ret = clBuildProgram(program,NULL);
if (ret != CL_SUCCESS) {
printf(\"\\nFail to build the program\\n\");
char buffer[10240];
clGetProgramBuildInfo(program,CL_PROGRAM_BUILD_LOG,sizeof(buffer),buffer,NULL);
printf(\"%s\\n\",buffer);
exit(EXIT_FAILURE);
}
/* Create data parallel OpenCL kernel */
kernel = clCreateKernel(program,\"tKernel\",&ret);
assert(ret == CL_SUCCESS);
/* Set OpenCL kernel arguments */
ret = clSetKernelArg(kernel,sizeof(cl_mem),(void *)&cmPinnedBufOut);
assert(ret == CL_SUCCESS);
DATA tmp;
tmp.wId = 66;
ret = clSetKernelArg(kernel,sizeof(DATA),&tmp);
assert(ret == CL_SUCCESS);
size_t global_item_size = GLOBAL_ITEM_SIZE;
size_t local_item_size = LOCAL_ITEM_SIZE;
/* Execute OpenCL kernel as data parallel */
ret = clEnqueueNDRangeKernel(commandQueue,kernel,&global_item_size,&local_item_size,NULL);
if (ret == CL_INVALID_WORK_GROUP_SIZE) {
printf(\"Invalid work group size: error when compute group size: %lu/%lu\",global_item_size,local_item_size);
exit(EXIT_FAILURE);
}
assert(ret == CL_SUCCESS);
/* Transfer result to host */
ret = clEnqueueReadBuffer(commandQueue,cmPinnedBufOut,CL_TRUE,cDataOut,NULL);
assert(ret == CL_SUCCESS);
/* display Results */
for (int i = 0; i < group_size; i++) {
printf(\"%d: -> group_id %lu ~> work_item_ids: \",i,cDataOut[i].wId);
for (int j = 0; j < LOCAL_ITEM_SIZE; j++)
printf(\"%2lu,\",cDataOut[i].iId[j]);
printf(\"\\n\");
}
printf(\"\\n\");
/* Finalization */
ret = clFlush(commandQueue);
ret = clFinish(commandQueue); // blockink function,wait until all queue cmd are finished
ret = clReleaseKernel(kernel);
ret = clReleaseProgram(program);
ret = clReleaseCommandQueue(commandQueue);
ret = clReleaseContext(context);
free(source_str);
return 0;
}
所以我期望结果为0:-> group_id 66〜> work_item_ids:67,
但是我得到0:-> group_id 0〜> work_item_ids:1,
由此我得出结论,数字为66的hh结构无法正确读取
由内核。我尝试将同样的方法放在整数上,并且效果很好。
所以我的问题是,我是在做错什么,还是没有方法将数据结构从主机复制到设备本地内存,还是有另一种方法?
解决方法
“ 3”缓冲区的“ 2”仅指定大小,并且指针必须为0。请参见OpenCL规范5.7.2。您无法从主机初始化本地内存。