使用的服务器上每个节点有4个dcu,导师要求使用openmp启动4个线程,每个线程在一个dcu上启动一个kernel。写出来的程序一直报段错误,通过不断注释的方法确认是clCreateBuffer的问题,但是我不知道如何解决,部分代码如下,上下文和编译程序是在omp之前完成的,在omp中创建了命令队列和buffer
omp_set_num_threads(4);
#pragma omp parallel
{
resmat res[10];
tid = omp_get_thread_num();
CommandQueue = clCreateCommandQueue(Context, deviceIds[tid], CL_QUEUE_PROFILING_ENABLE, &err);
if (err != CL_SUCCESS)
{
cout << "Error: Can not create CommandQueue" << endl;
}
//-------------------------7. 创建输入输出内核内存对象--------------------------------
// 创建内存对象
r = clCreateBuffer(
Context,
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, // 输入内存为只读,并可以从宿主机内存复制到设备内存
10 * sizeof(resmat), // 输入内存空间大小
res,
&err);
if (err != CL_SUCCESS)
{
cout << err << endl;
cout << "Error creating memory objects" << endl;
}
你好,我对这个问题也十分感兴趣。请问你解决了吗?
个人认为因为多个设备的缘故,但是会话context始终是一个,而一个context生成的时候需要关联设备。你这里有多个opencl设备,直接生成CL_MEM_COPY_HOST_PTR的cl_mem应该会让opencl不知道往哪个设备上拷贝吧。个人认为应该去掉CL_MEM_COPY_HOST_PTR这个标志,然后后序使用clEnqueueWriteBuffer绑定对应的命令队列来进行初始化各自的cl_mem吧。
我在一个拥有三张nvidia的显卡的环境中,改写了你上述代码,发现是能够正常运行的。现在的代码如下所示:
// 进行omp ocl的组合问题实践
/*
进行操作之后
*/
void omp_ocl(cl_platform_id platform)
{
cl_int err;
cl_device_id* devices;
cl_uint num_devices;
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
devices = (cl_device_id*)malloc(sizeof(cl_device_id) * num_devices);
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
cl_int errcode;
cl_context Context = clCreateContext(NULL, num_devices, devices, NULL, NULL, &errcode);
if(errcode != CL_SUCCESS || Context == NULL)
{
printf("create context failed(errcode=%d)\n", errcode);
}
omp_set_num_threads(num_devices);
#pragma omp parallel
{
int tid = omp_get_thread_num();
int res[10];
for(size_t j = 0; j < 10; j++)
res[j] = tid;
cl_command_queue CommandQueue = clCreateCommandQueue(Context, devices[tid], CL_QUEUE_PROFILING_ENABLE, &errcode);
if (errcode != CL_SUCCESS)
{
std::cout << "Error: Can not create CommandQueue" << std::endl;
}
//-------------------------7. 创建输入输出内核内存对象--------------------------------
// 创建内存对象
cl_mem r = clCreateBuffer(
Context,
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, // 输入内存为只读,并可以从宿主机内存复制到设备内存
10 * sizeof(int), // 输入内存空间大小
res,
&errcode);
if (errcode != CL_SUCCESS)
{
std::cout << errcode << std::endl;
std::cout << "Error creating memory objects" << std::endl;
}
printf("tid-----%d\n", tid);
clReleaseMemObject(r);
clReleaseCommandQueue(CommandQueue);
}
clReleaseContext(Context);
for(size_t i = 0; i < num_devices; i++)
clReleaseDevice(devices[i]);
free(devices);
}