2017-10-05 7 views
-1

J'essaie d'implémenter un code précédemment écrit en CUDA en utilisant OpenCL pour l'exécuter sur FPGA Altera. J'ai du mal à lire les données qui sont censées être dans le tampon. J'utilise la même structure que la version CUDA, seule chose différente est que cudaMalloc peut allouer de la mémoire pour tous les types de pointeurs alors que pour clCreateBuffer je dois utiliser cl_mem. Mon code ressemble à ceci:OpenCL, gérer le pointeur de tampon de périphérique de l'hôte?

cl_mem d_buffer=clCreateBuffer(...); 
//CUDA version: 
//float* d_buffer; 
//cudaMalloc((void **)&d_buffer, MemSz); 

clEnqueueWriteBuffer(queue, d_buffer, ..., h_data,); 
//cudaMemcpy(d_buffer, h_Data, MemSz, cudaMemcpyHostToDevice); 

#define d_buffer(index1, index2, index3) &d_buffer + index1/index2*index3 
//#define d_buffer(index1, index2, index3) d_buffer + index1/index2*index3 

cl_mem* d_data=d_buffer(1,2,3); 

clEnqueueReadBuffer(queue, *d_data,...)// Error reading d_data 

J'ai essayé clEnqueueMapBuffer ou CL_MEM_ALLOC_HOST_PTR pour le clCreateBuffer, cela ne fonctionne pas non plus.

Répondre

1

cl_mem est un objet opaque. Vous ne devez pas exécuter l'arithmétique du pointeur dessus; tenter de le faire se traduira par des bogues très méchant.

Je ne suis pas familier avec la façon dont CUDA gère l'allocation de tampon, mais l'implication de votre code commenté est que les tampons CUDA sont toujours Host-Visible. Ce n'est pas du tout le cas dans OpenCL. OpenCL vous permet de "mapper" un tampon vers la mémoire visible par l'hôte, mais il ne sera pas implicitement visible par l'hôte. Si vous avez l'intention de lire un index arbitraire du tampon, vous devez le mapper en premier ou le copier vers les données de l'hôte.

float * h_data = new float[1000]; 
cl_mem d_buffer=clCreateBuffer(...); 

clEnqueueWriteBuffer(queue, d_buffer, true, 0, 1000 * sizeof(float), h_data, 0, nullptr, nullptr); 
//======OR====== 
//float * d_data = static_cast<float*>(clEnqueueMapBuffer(queue, d_buffer, true, CL_MAP_WRITE, 0, 1000 * sizeof(float), 0, nullptr, nullptr, nullptr)); 
//std::copy(h_data, h_data + 1000, d_data); 
//clEnqueueUnmapMemObject(queue, d_buffer, d_data, 0, nullptr, nullptr); 
//clEnqueueBarrier(queue); 

//Do work with buffer, probably in OpenCL Kernel... 

float result; 
size_t index = 1/2 * 3; //This is what you wrote in the original post 
clEnqueueReadBuffer(queue, d_buffer, true, index * sizeof(float), 1 * sizeof(float), &result, 0, nullptr, nullptr); 
//======OR====== 
//float * result_ptr = static_cast<float*>(clEnqueueMapBuffer(queue, d_buffer, true, CL_MAP_READ, index * sizeof(float), 1 * sizeof(float), 0, nullptr, nullptr, nullptr)); 
//result = *result_ptr; 
//clEnqueueUnmapMemObject(queue, d_buffer, result_ptr, 0, nullptr, nullptr); 
//clEnqueueBarrier(queue); 

std::cout << "Result was " << result << std::endl;