2012-05-27 2 views
1

У меня возникла проблема с выполнением ядра, которое не пишет информацию в правильных местах, когда я использую большие массивы (1000 x 10000). Но для небольших массивов проблем нет, я получаю правильные результаты. Для выполнения ядра я использую GPU от ATI Mobility RADEON HD 4300 Series.Неверная информация о больших массивах, обработанных с помощью OpenCL

код C образец:

#include <stdio.h> 
#include <stdlib.h> 

#ifdef __APPLE__ 
#include <OpenCL/opencl.h> 
#else 
#include <CL/cl.h> 
#endif 

#define MAX_SOURCE_SIZE (0x100000) 
#define MAX_SIZE 108 
#define NCOLS 1000 
#define NROWS 10000 

int main(void) { 
    char* source_name = "mykernel.cl"; 
    char* source_code; 
    size_t source_size; 
    cl_platform_id platformId = NULL; 
    cl_uint nbplatforms; 
    cl_device_id deviceId = NULL; 
    cl_uint nbdevices; 
    cl_context context = NULL; 
    cl_int errcode; 
    cl_command_queue commandQueue = NULL; 
    cl_program program; 
    size_t global_work_size[2]; 
    size_t local_work_size[2]; 

    FILE* fh; 

    //Retrieving platform information 
    errcode = clGetPlatformIDs(1, &platformId, &nbplatforms); 

    //Retrieving device (GPU) information 
    errcode = clGetDeviceIDs(platformId, CL_DEVICE_TYPE_GPU, 1, &deviceId, &nbdevices); 

    //Creation of a working context 
    context = clCreateContext(NULL, 1, &deviceId, NULL, NULL, &errcode); 

    commandQueue = clCreateCommandQueue(context, deviceId, 0, &errcode); 

    //Opening and reading the kernel source file 
    if((fh = fopen(source_name, "r")) == NULL){ 
     fprintf(stderr, "Failed to open the file containing the kernel source !\n"); 
     exit(EXIT_FAILURE); 
    } 
    source_code = (char*) malloc (MAX_SOURCE_SIZE * sizeof(char)); 
    source_size = fread(source_code, sizeof(char), MAX_SOURCE_SIZE, fh); 
    fclose(fh); 

    program = clCreateProgramWithSource(context, 1, (const char**) &source_code, (const size_t*) &source_size, &errcode); 

    //Building kernel 
    errcode = clBuildProgram(program, 1, &deviceId, NULL, NULL, NULL); 

    //Creation of the kernel program 
    cl_kernel kernel = clCreateKernel(program, "mykernel", &errcode); 
    unsigned int *op1 = (unsigned int*) malloc (NCOLS * NROWS * sizeof(unsigned int)); 

    cl_mem op1buff = clCreateBuffer(context, CL_MEM_WRITE_ONLY, NCOLS * NROWS * sizeof(unsigned int), NULL, &errcode); 

    clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*) &op1buff); 

    global_work_size[0] = NCOLS; 
    global_work_size[1] = NROWS; 
    local_work_size[0] = NCOLS; 
    local_work_size[1] = 1; 

    clEnqueueNDRangeKernel(commandQueue, kernel, 2, NULL, global_work_size, local_work_size, 0, NULL, NULL); 

    errcode = clEnqueueReadBuffer(commandQueue, op1buff, CL_TRUE, 0, NCOLS * NROWS * sizeof(unsigned int), (void*)op1, 0, NULL, NULL); 

    for(int i = 0; i < NROWS; i++){ 
     for(int j = 0; j < NCOLS; j++) 
      printf("[index:%d - %u] ", i*NCOLS+j, op1[i*NCOLS+j]); 
     printf("\n"); 
    } 

    return EXIT_SUCCESS; 
} 

Исходный код ядра находится на файл с именем mykernel.cl и представлена ​​следующим образом:

__kernel void mykernel(__global unsigned int* op1buf){ 
    unsigned int index = get_group_id(1) * get_global_size(0) + get_local_id(0); 
    op1buf[index] = index; 
} 

Выполнение этой программы возвращает неожиданные значения читать из массивов, когда я использую большие массивы. Например:

[index:0 - 16777215] [index:1 - 16777215] [index:2 - 16777215] [index:3 - 16777215] ... 
[index:1000 - 3438339071] [index:1001 - 3941660159] [index:1002 - 1650092117] [index:1003 - 2529976771] ... 
[index:1000 - 3438339071] [index:1001 - 3941660159] [index:1002 - 1650092117] [index:1003 - 2529976771] ... 
[index:3000 - 16777215] [index:3001 - 16777215] [index:3002 - 16777215] [index:3003 - 16777215] ... 
[index:4000 - 3438339071] [index:4001 - 3941660159] [index:4002 - 1650092117] [index:4003 - 2529976771] ... 
.... 

Что может быть дело в моем коде или есть что-то на использование GPU, который я не принимать во внимание?

Заранее спасибо.

+0

Первое, что я бы посмотрел, это то, возвращаются ли какие-либо коды ошибок из ваших вызовов. Они дают какие-то подсказки? –

+0

После просмотра кодов ошибок, возвращаемых из функций OpenCL, я получил код -55 как код ошибки для clEnqueueNDRange, который соответствует CL_INVALID_WORK_ITEM_SIZE – semteu

ответ

1

1000, очевидно, слишком большой для вашего устройства. Используйте clGetDeviceInfo с CL_DEVICE_MAX_WORK_GROUP_SIZE, чтобы определить наибольшее значение, которое вы можете использовать.

Смежные вопросы