2015-12-25 4 views
1

Когда я пытаюсь записать обратно на хосте буфера вывода кода OpenCL я всегда получаю массив нулей/нулейOpenCL Ответьте на буфере

Вот ядро:

void kernel convolution(global const int* A, global const int* B, 
     global int* C, const int size_1, const int size_2) { 
    float prob_1[256]; 
    float prob_2[256]; 
    float cum_prob_1[256]; 
    float cum_prob_2[256]; 
    prob_1[get_global_id(0)] = (A[get_global_id(0)]/size_1); 
    prob_2[get_global_id(0)] = (B[get_global_id(0)]/size_2); 
    cum_prob_1[0] = prob_1[0]; 
    cum_prob_1[get_global_id(0)+1] = cum_prob_1[get_global_id(0)] + prob_1[get_global_id(0)+1]; 
    cum_prob_2[0] = prob_2[0]; 
    cum_prob_2[get_global_id(0)+1] = cum_prob_2[get_global_id(0)] + prob_2[get_global_id(0)+1]; 
    int j = 0; 
    for (int i = 0; i < 256; i++) { 
     if (cum_prob_1[i] <= cum_prob_2[j]) { 
      C[i] = j; 
     } 
     else { 
      while (cum_prob_1[i] > cum_prob_2[j]) 
       j++; 
      if (cum_prob_2[j] - cum_prob_1[i] > cum_prob_1[i] - cum_prob_2[j - 1]) { 
       C[i] = j - 1; 
      } 
      else { 
       C[i] = j; 
      } 
     } 
    } 
} 

а вот остальная часть кода:

// create buffers on the device 
cl::Buffer buffer_A(context, CL_MEM_READ_WRITE, sizeof(int) * 256); 
cl::Buffer buffer_B(context, CL_MEM_READ_WRITE, sizeof(int) * 256); 
cl::Buffer buffer_C(context, CL_MEM_READ_WRITE, sizeof(int) * 256); 

//create queue to which we will push commands for the device. 
cl::CommandQueue queue(context, default_device); 

//write arrays A and B to the device 
queue.enqueueWriteBuffer(buffer_A, CL_TRUE, 0, sizeof(int) * 256, pixls_1); 
queue.enqueueWriteBuffer(buffer_B, CL_TRUE, 0, sizeof(int) * 256, pixls_2); 

//alternative way to run the kernel 
cl::Kernel kernel_add = cl::Kernel(program, "convolution"); 
kernel_add.setArg(0, buffer_A); 
kernel_add.setArg(1, buffer_B); 
kernel_add.setArg(2, buffer_C); 
kernel_add.setArg(3, size_1); 
kernel_add.setArg(4, size_2); 

queue.enqueueNDRangeKernel(kernel_add, cl::NullRange, cl::NDRange(sizeof(cl_mem)), cl::NullRange); 
queue.finish(); 

int lookup_table[256]; 
for (size_t i = 0; i < 256; i++) { 
    lookup_table[i] = 10; 
} 
//read result C from the device to array C 
queue.enqueueReadBuffer(buffer_C, CL_TRUE, 0, sizeof(int) * 256, lookup_table); 

//map the new pixel values from the lookup table 
for (int i = 0; i < inp_image.total(); i++) { 
    myData[i]= lookup_table[myData[i]]; 
} 

system("pause"); 
return 0; 

lookup_table является тот, который дает мне нули/аннулирует, но он должен дать мне 5 во всех клетках ...

ответ

1

Я вижу две вещи очень сильно подозрительной мне в вашем коде:

  1. Вызов enqueueNDRangeKernel() и, в частности использование cl::NDRange(sizeof(cl_mem)) для определения массива глобальных размеров рабочих элементов ... AFAICT, это просто Безразлично Не имеет никакого смысла, но я мог бы очень что-то пропустить.

  2. Использование временных массивов в самом ядре: это очень похоже на то, как вы забыли объявить их local. Так будет? И если это так, вам нужно будет добавить barrier(CLK_LOCAL_MEM_FENCE) после части инициализации.

Во всяком случае, мне кажется, что ваш код предназначен для использования с рабочими группами размеров 256, с local памяти для временных массивов. Возможно, я ошибаюсь, но в любом случае есть проблемы в том, как запускается ядро ​​и в его логике тоже.

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