OpenCl clEnqueueMapBuffer无法正常工作?

时间:2016-09-13 14:05:44

标签: opencl

据我所知,您可以使用clEnqueueMapBuffer来访问内存对象。您可以将设备上的内存对象映射到主机上的内存区域,而不是使用读/写操作。 我写了一个非常简单的代码来测试它。这段代码将章程'X'发送给GPU,内核加1,所以我们应该得到'Y',但我没有。 似乎clEnqueueUnmapMemObject不会将存储在GPU内存中的结果复制到主机上的缓冲区! 这是我的代码:

#include <iostream>
#include <CL\cl.h>
using namespace std;
#pragma warning(disable : 4996)
#define PROGRAM "__kernel void hello(__global char* string )\
{\
string[0] = string[0] + 1;\
}"

int main() {
cl_platform_id platform; cl_device_id device; cl_context context;
cl_program program; cl_int error; cl_build_status status;

char *programBuffer = PROGRAM;   

// make contex
clGetPlatformIDs(1, &platform, NULL);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);

//built program
program = clCreateProgramWithSource(context, 1, (const char**)&programBuffer, nullptr, NULL);
const char options[] = "-cl-std=CL1.1 -cl-mad-enable -Werror";
error = clBuildProgram(program, 1, &device, options, NULL, NULL);

// create kernel 
cl_command_queue   command_queue;
command_queue = clCreateCommandQueue(context, device, NULL, nullptr);
cl_kernel kernels, found_kernel;
cl_uint num_kernels;

error = clCreateKernelsInProgram(program, 0, nullptr, &num_kernels);
kernels = clCreateKernel(program, "hello", nullptr);
//make buffers
cl_mem memobj = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR| CL_MEM_READ_WRITE, 2 * sizeof(char), nullptr, &error);//if nulptr nazarim then itt will retun null pointer
error = clSetKernelArg(kernels, 0, sizeof(cl_mem), (void *)&memobj);
// I am goign to send this data to GPU
char *CPU_2_GPU_Data = new char[2]{ "X" };
void* mapbuffer =clEnqueueMapBuffer(command_queue, memobj, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, 2 * sizeof(char), 0, nullptr, nullptr, &error);
memccpy(mapbuffer, CPU_2_GPU_Data, 0, 2 * sizeof(char));
cout<<"I am sending this dat to GPU:"<<(char*)(mapbuffer)<<endl;
error = clEnqueueTask(command_queue, kernels, 0, nullptr, nullptr);
clEnqueueUnmapMemObject(command_queue, memobj, mapbuffer, 1, nullptr, nullptr);
cout << "I am getiing this data from GPU:" << (char*)(mapbuffer) << endl;
clReleaseContext(context);
return 0;

}

实际上我可以使用Mapping内存对象将数据发送到GPU,但我无法读取结果。为了使代码工作,我必须明确要求GPU将数据发送给我:

char* newbuffer = new char[2];
clEnqueueReadBuffer(command_queue, memobj, CL_TRUE, 0, 2 * sizeof(char), newbuffer, 0, nullptr, nullptr);
cout << "the result is :" << newbuffer << endl;

为什么会这样?为什么我可以使用Mapping内存对象将数据发送到GPU,但我无法得到结果?

1 个答案:

答案 0 :(得分:2)

意图是: 1)您映射以在主机上读取它。 2)然后取消映射,以便GPU可以再次使用它。 3)然后再次映射它以从主机读取它。 4)然后取消映射以清理。

您似乎正在映射,启动任务然后取消映射。因此,当您尝试读取数据时,主机实际上无法读取它,因为您刚刚取消映射它!

相关问题