我的电脑配有GeForce 1080Ti。使用11GB的VRAM,我不会期待内存问题,因此我无法解释为什么以下内容会破坏我的代码。
我使用此代码在主机上执行内核。
cl_mem buffer = clCreateBuffer(context.GetContext(), CL_MEM_READ_WRITE, n * n * sizeof(int), NULL, &error);
error = clSetKernelArg(context.GetKernel(myKernel), 1, n * n, m1);
error = clSetKernelArg(context.GetKernel(myKernel), 0, sizeof(cl_mem), &buffer);
error = clEnqueueNDRangeKernel(context.GetCommandQueue(0), context.GetKernel(myKernel), 1, NULL, 10, 10, 0, NULL, NULL);
clFinish(context.GetCommandQueue(0));
error = clEnqueueReadBuffer(context.GetCommandQueue(0), buffer, true, 0, n * n * sizeof(int), results, 0, NULL, NULL);
results
是指向n-by-n int
数组的指针。 m1是指向n×n位数组的指针。变量n可以被8整除,因此我们可以将数组解释为char
数组。
内核将数组的前十个值设置为1025(值不重要):
__kernel void PopCountProduct (__global int *results)
{
results[get_global_id(0)] = 1025;
}
当我在主机上打印出结果时,前10个指数是1025.一切都很好。
当我引入一个额外的论点时突然停止工作:
__kernel void PopCountProduct (__global int *results, __global char *m)
{
results[get_global_id(0)] = 1025;
}
为什么会这样?我错过了一些关于OpenCL的重要内容吗?
答案 0 :(得分:1)
您无法在OpenCL 1.2中托管指向clSetKernelArg
的指针。类似的事情只能通过clSetKernelArgSVMPointer
使用SVM指针在OpenCL 2.0+中完成(如果支持)。但最有可能在GPU上制作缓冲区对象并将主机内存复制到它就是你需要的。