将结构传递给内核本地内存

| 我在将结构传递到内核本地内存时遇到问题。这是内核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, 1, &device_id, NULL, NULL, &ret);

    /* Create command queue with measurment of preformance */
    commandQueue = clCreateCommandQueue(context, device_id, 0, &ret);

    /* Create memory object */
    cmPinnedBufOut = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, group_size * sizeof(DATA), NULL, &ret);
    cDataOut = (DATA *)malloc(group_size * sizeof(DATA));

    /* Create kernel program from source file */
    program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);
    assert(ret == CL_SUCCESS);
    ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
    if (ret != CL_SUCCESS) {   
        printf(\"\\nFail to build the program\\n\");
        char buffer[10240];
        clGetProgramBuildInfo(program, device_id, 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, 0, sizeof(cl_mem), (void *)&cmPinnedBufOut);
    assert(ret == CL_SUCCESS);

    DATA tmp;
    tmp.wId = 66;
    ret = clSetKernelArg(kernel, 1, 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, 1, NULL, &global_item_size, &local_item_size, 0, NULL, 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, 0, group_size * sizeof(DATA), cDataOut, 0, NULL, 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。您无法从主机初始化本地内存。     

要回复问题请先登录注册