2013-07-01 5 views
2

У меня есть 2D массив C, который я создаю экземпляр так:Как вы читаете многомерный массив из clEnqueueReadBuffer?

const int wA = 16; 
float * C[wA]; 
for(int i = 0; i < hA; i++) 
{ 
C[i] = new float[hA]; 
for(int i2 = 0; i2 < hA; i2++) 
    C[i][i2] = 0; 
} 

/* looks like this: 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
*/ 

я создаю ядро, которое работает на C:

__kernel void simpleMultiply(__global float* outputC, 
          int widthA, 
          int heightA, 
          int widthB, 
          int heightB, 
          __global float * inputA, 
          __global float * inputB) 
{ 
    int row = get_global_id(1); 
    int col = get_global_id(0); 
    float sum = 0.0f; 
    for(int i = 0; i < widthA; i++) 
    { 
     sum += inputA[row*widthA+i] * inputB[i*widthB+col]; 
    } 
    outputC[row*widthB+col] = sum; 
} 

и все идет хорошо. Я получаю CL_SUCCESS для статуса на всем пути от создания контекста к созданию буферов, создания ядра, программы, clEnqueueNDRangeKernel, clEnqueueReadBuffer и т. Д.

Но когда я иду читать данные, он выходит из строя.

status = clEnqueueNDRangeKernel(cmdQueue, kernel, 2, NULL, globalws, localws, 0, NULL, NULL); 
cout << "\nclEnqueueNDRangeKernel: " << (status == CL_SUCCESS ? "SUCCESS" : "FAIL"); // prints SUCCESS 
status = clEnqueueReadBuffer(cmdQueue, bufferC, CL_TRUE, 0, wC*hC*sizeof(float), (void*)C, 0, NULL, NULL); 
cout << "\nclEnqueueReadBuffer: " << (status == CL_SUCCESS ? "SUCCESS" : "FAIL"); // prints SUCCESS 
cout << "\nC[0][0]: " << C[0][0]; // <--crash 

enter image description here

Я так же, как новичок в C++, как я OpenCL, так что это может быть из-за слабое понимание массивов и указателей в C++.

Весь код here

+1

Вы уверены, что линия 67 является блокировка чтения? Возможно, вы закончили линию 69, прежде чем закончите чтение. Также ваш C - массив указателей, поэтому размер каждого элемента может быть неизвестен? Можете ли вы попробовать с чистым 2D-массивом и чистым двойным указателем? –

+0

Третий аргумент в строке 67 говорит, что он блокирует. Так что это блокирование наверняка. Мне понадобится день или около того, пока я не получу время для повторного набора массивов (im new для C++). – user1873073

ответ

4

Массив

float * C[wA]; 

Является 1D массив float * указателей. Таким образом, вы не создали в памяти 2D-массив со смежными строками и столбцами. Но вы создали массив указателей на строки.

Таким образом, вы должны сгладить массив хоста C и проиндексировать его так же, как и на ядре.

float * C; 

c = new float[ha * ha]; // Create a contiguous memory area to be addressed in a 2D pattern 

memset(C, 0, ha * ha * sizeof(float)); // Set all bytes to zero 


... 

Теперь вы можете обратиться массив C после запуска ядра

cout << C[ icolumn + irow * ha ]; // icolumn and irow are your row and columns indices 
Смежные вопросы