2017-10-05 3 views
-1

Ich versuche, einen Code zu implementieren, der zuvor in CUDA mit OpenCL geschrieben wurde, um auf Altera FPGA zu laufen. Ich habe Probleme beim Zurücklesen von Daten, die sich im Puffer befinden sollen. Ich benutze die gleiche Struktur wie CUDA Version, nur etwas anderes ist cudaMalloc kann Speicher für alle Arten von Zeiger zuweisen, während für clCreateBuffer ich cl_mem verwenden muss. Mein Code sieht wie folgt aus:OpenCL, Gerätepufferzeiger vom Host verwalten?

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 

Ich versuchte clEnqueueMapBuffer oder CL_MEM_ALLOC_HOST_PTR für die clCreateBuffer, es funktioniert auch nicht.

Antwort

1

cl_mem ist ein undurchsichtiges Objekt. Sie sollten keine Zeigerarithmetik ausführen; Der Versuch, dies zu tun, wird zu sehr unangenehmen Fehlern führen.

Ich bin nicht vertraut mit, wie CUDA behandelt Pufferzuweisung, aber die Implikation Ihrer kommentierte heraus Code ist, dass CUDA Puffer sind immer Host sichtbar. Dies ist in OpenCL sehr streng nicht der Fall. OpenCL ermöglicht es Ihnen, einen Puffer in den Host-sichtbaren Speicher zu "mappen", aber er ist nicht implizit für den Host sichtbar. Wenn Sie einen beliebigen Index des Puffers lesen möchten, müssen Sie ihn entweder zuerst zuordnen oder in Hostdaten kopieren.

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; 
Verwandte Themen