【问题标题】:OpenCL, manage device buffer pointer from host?OpenCL,从主机管理设备缓冲区指针?
【发布时间】:2017-10-05 18:14:58
【问题描述】:

我正在尝试使用 OpenCL 实现以前在 CUDA 中编写的代码,以便在 Altera FPGA 上运行。我在读回应该在缓冲区中的数据时遇到问题。我使用与 CUDA 版本相同的结构,唯一不同的是 cudaMalloc 可以为所有类型的指针分配内存,而对于 clCreateBuffer 我必须使用 cl_mem。我的代码如下所示:

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

我为 clCreateBuffer 尝试了 clEnqueueMapBuffer 或 CL_MEM_ALLOC_HOST_PTR,它也不起作用。

【问题讨论】:

    标签: c++ opencl


    【解决方案1】:

    cl_mem 是一个不透明的对象。您不应该对其执行指针运算;尝试这样做会导致非常讨厌的错误。

    我不熟悉 CUDA 如何处理缓冲区分配,但您注释掉的代码的含义是 CUDA 缓冲区始终是主机可见的。这在 OpenCL 中是非常严格的。 OpenCL 允许您将缓冲区“映射”到主机可见内存,但它不会对主机隐式可见。如果您打算读取缓冲区的任意索引,则需要先对其进行映射或将其复制到主机数据。

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 2012-05-12
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      相关资源
      最近更新 更多