0

我是 C、C++ 和 OpenCL 的新手。我有两个问题。

(1) 如果我有许多主机输入数据变量,例如长数组和双数组,有没有办法避免将每个变量复制到设备(以传统的 OpenCL 方式,即 createBuffer 等),而是简单地从设备映射一些内存进入主机并将主机指针写入设备内存,然后在内核中访问?有人告诉我有,但我无法弄清楚执行此操作的代码。

下面我有一个示例输入数据数组。目标是以某种方式将指向它的指针中继到设备而不以任何方式复制它,因为各种输入数据变量可能非常大。我分配了一个缓冲区,将一个映射缓冲区排入队列,取回一个设备指针,但是我不确定如何将输入传递给该设备指针。我为设备指针使用了一种 cl_long 类型,这可能是错误的。

cl_long inputData[2] = {1,2};

cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, 
        sizeof(cl_long) * 2, NULL, NULL);

cl long* inputMap = (cl_long*) clEnqueueMapBuffer(
        queue, inputBuffer, TRUE, CL_MAP_WRITE, 0, 
        sizeof(cl_long) * 2, 0, NULL, NULL, NULL);

// what to do here?

clEnqueueUnmapMemObject(queue, inputBuffer, inputMap, 0, NULL, NULL);

我已经为上面的两个 cl_long 使用了空间,但实际上,如果我将指针传递给主机数据,我会在这里分配什么?

(2) 将指向多个输入变量的指针打包到 clEnqueueMapBuffer 返回的同一内存空间中会怎样?假设我有一个长数组和一个双精度数组,我可以将指向它们的指针传递到同一块映射设备内存中吗?

我真的很感激一些示例源代码,其中特别详细说明了主机和设备内存以及它们如何保持同步以及指针,因为我对它们有点陌生。

PS我已经看到另一个将主机数据写入设备映射内存的示例(http://stackoverflow.com/questions/5673794/opencl-mapped-memory-doesnt-work),但它再次使用手动将数据写入相当于复制的内存。

更新:为了回应 Raj 的评论(如果我的评论太长,请在此处回复)我已经开始使用该标志,但我的指针代码可能在某处有错误。

double a[2] = { 3.0, 6.0 } ;
size_t pointerSize = sizeof(double*);

cl_mem bufA = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, pointerSize, NULL, NULL);
clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufA);

double* pA = (double*) clEnqueueMapBuffer(queue, bufA, CL_TRUE, CL_MAP_WRITE, 0, pointerSize, 0, NULL, NULL, &err);
*pA = *a;

此时,如果我在内核本身中打印 a[0] 和 a[1],我会得到:

a[0]=3.000000
a[1]=-0.000000

a[1] 显然是错误的。任何想法我做错了什么?

4

1 回答 1

2

所以答案是使用clCreateBuffer并传递这个参数来创建一个缓冲区CL_MEM_ALLOC_HOST_PTR

查看此描述OpenCL create Buffer API

在 CUDA 架构上,它类似于cudaHostAlloc. cudaHostAlloc将在主机上分配内存,GPU 设备也可以访问该内存。有关相同的更多信息可以在此网页上找到

于 2012-09-17T13:14:54.147 回答