【问题标题】:Create an OpenCL Context using all CPU and GPU Devices使用所有 CPU 和 GPU 设备创建 OpenCL 上下文
【发布时间】:2015-03-26 00:02:14
【问题描述】:

我正在使用 OpenCL 1.1。我将在我所有的 gpus 和我的所有 cpus 上运行我的代码。因此,由于很难在两个不同的上下文上进行同步,因此我想创建一个包含所有 CPU 和 GPU 作为设备的上下文。因此,首先我将获取所有平台,然后是与每个平台相关的设备,然后获取 CPU 和 GPU 设备并将它们存储在单独的向量中。然后,为了创建上下文,我将创建一个由所有 CPU 和 GPU 设备创建的向量。然后,我会打电话给clCreateContext。它会正常工作,但之后,当我想为每个设备分别创建命令队列时,它总是给我:

OpenCL call falls with error -34.

代码如下:

  cl_int error = CL_SUCCESS;
  cl_uint num_platforms;
  clGetPlatformIDs(0, nullptr, &num_platforms);
  if (num_platforms == 0){
    std::cout << "Cannot find any platform.\n";
    return;
  }
  platform.resize(num_platforms);
  error = clGetPlatformIDs(num_platforms, platform.data(), nullptr);
  checkError(error);

  for (cl_uint i = 0; i < num_platforms; i++){
    std::string platform_name;
    size_t platform_name_len;
    clGetPlatformInfo(platform[i], CL_PLATFORM_NAME, 0, nullptr, &platform_name_len);
    platform_name.resize(platform_name_len);
    clGetPlatformInfo(platform[i], CL_PLATFORM_NAME, platform_name_len, const_cast<char*>(platform_name.data()), nullptr);
    std::cout << "[" << i << "]\t" << platform_name << std::endl;

    std::vector<cl_device_id> devices(0);
    cl_uint num_cpus = 0, num_gpus = 0;
    error = clGetDeviceIDs(platform[i], CL_DEVICE_TYPE_CPU, 0, nullptr, &num_cpus);
    error = clGetDeviceIDs(platform[i], CL_DEVICE_TYPE_GPU, 0, nullptr, &num_gpus);
    devices.resize(num_cpus);

    std::cout << "\tCPUS: \n";
    error = clGetDeviceIDs(platform[i], CL_DEVICE_TYPE_CPU, num_cpus, devices.data(), nullptr);
    for (cl_uint d = 0; d < num_cpus; d++){
      std::string device_name;
      size_t device_name_len;
      clGetDeviceInfo(devices[d], CL_DEVICE_NAME, 0, nullptr, &device_name_len);
      device_name.resize(device_name_len);
      clGetDeviceInfo(devices[d], CL_DEVICE_NAME, device_name_len, const_cast<char*>(device_name.data()), nullptr);
      std::cout << "\t\t[" << d << "]\t" << device_name << std::endl;

      cpu_devices.push_back(devices[d]);
    }

    std::cout << "\tGPUS: \n";
    devices.resize(num_gpus);
    error = clGetDeviceIDs(platform[i], CL_DEVICE_TYPE_GPU, num_gpus, devices.data(), nullptr);
    for (cl_uint d = 0; d < num_gpus; d++){
      std::string device_name;
      size_t device_name_len;
      clGetDeviceInfo(devices[d], CL_DEVICE_NAME, 0, nullptr, &device_name_len);
      device_name.resize(device_name_len);
      clGetDeviceInfo(devices[d], CL_DEVICE_NAME, device_name_len, const_cast<char*>(device_name.data()), nullptr);
      std::cout << "\t\t[" << d << "]\t" << device_name << std::endl;

      gpu_devices.push_back(devices[d]);
    }
  }

  std::vector<cl_device_id> devices;
  for (size_t i = 0; i < cpu_devices.size(); i++)
    devices.push_back(cpu_devices[i]);
  for (size_t i = 0; i < gpu_devices.size(); i++)
    devices.push_back(gpu_devices[i]);

  ctx = clCreateContext(NULL, static_cast<cl_uint>(devices.size()), devices.data(), nullptr, nullptr, nullptr);

  cpu_devices_queue.resize(cpu_devices.size());
  for (size_t i = 0; i < cpu_devices.size(); i++){
    cpu_devices_queue[i] = clCreateCommandQueue(ctx, cpu_devices[i], 0, &error);
    checkError(error);
  }

  gpu_devices_queue.resize(gpu_devices.size());
  for (size_t i = 0; i < gpu_devices.size(); i++){
    gpu_devices_queue[i] = clCreateCommandQueue(ctx, gpu_devices[i], 0, &error);
    checkError(error);
  }

【问题讨论】:

    标签: opencl


    【解决方案1】:

    OpenCL 上下文只能封装来自单个平台的设备,不能使用来自两个或多个不同平台的设备创建。

    您实际上并没有检查您对clCreateContext 的调用是否成功。如果您检查返回值或错误代码,您可能会发现它实际上是失败的。这就是为什么当您稍后在调用 clCreateCommandQueue 时使用该上下文时,您会收到错误 -34 (CL_INVALID_CONTEXT)。

    【讨论】:

    • 因此,不可能在同一个上下文中使用计算机的所有 cpus 和 gpus,我应该创建与平台一样多的上下文。然后,使用 clFlush() 进行同步?
    • @mmostajab 正确,如果您希望在同一程序中使用来自多个平台的设备,则需要创建多个上下文对象,并且您需要通过主机手动同步并在设备之间手动复制内存。
    • 这是我们必须在 opencl 1.1 中做的事情,还是我们必须在 opencl 2.0 中做的事情?因为那样在 cpu 和 gpu 之间共享虚拟内存是不可能的。
    • 您当然可以在 OpenCL 2.0 中的主机 (CPU) 和 GPU 设备之间使用 SVM - 尽管这不会将 CPU 视为 OpenCL 设备。如果您有 AMD 或 Intel GPU,则可以在 CPU 和 GPU 上使用相同的 OpenCL 平台。
    • 那么,如果我们使用CPU作为opencl设备,它不会使用在CPU上运行的SIMD指令吗?我在想,与仅使用多核或多线程解决方案相比,它会变得非常快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多