jrprice / Oclgrind

An OpenCL device simulator and debugger
Other
346 stars 63 forks source link

Cannot configure device type #198

Open Aerijo opened 3 years ago

Aerijo commented 3 years ago

Currently, the device type is exposed as a union of all the possible device types. This has two drawbacks that come to mind:

  1. Code that conditionally picks a kernel based on the device type may not run the other kernels. E.g., if it's implemented like

    if (device_is_cpu()) {
    run_cpu_kernel();
    } else if (device_is_gpu()) {
    run_gpu_kernel();
    }

    Then with Oclgrind it will never run the GPU kernel. This case can be helped if the above code allows some kind of override, but it would be easier if Oclgrind itself could change what device it shows as.

  2. SYCL appears to treat device type as a plain enum, not a bitfield, so it cannot represent multi-type devices in the first place. E.g., this DPC++ issue. DPC++ uses equality checks for the device type, and so does not recognise the value returned by Oclgrind as anything. The SYCL spec itself defines device_type as

    enum class device_type : unsigned int {
    cpu,         // Maps to OpenCL CL_DEVICE_TYPE_CPU
    gpu,         // Maps to OpenCL CL_DEVICE_TYPE_GPU
    accelerator, // Maps to OpenCL CL_DEVICE_TYPE_ACCELERATOR
    custom,      // Maps to OpenCL CL_DEVICE_TYPE_CUSTOM
    automatic,   // Maps to OpenCL CL_DEVICE_TYPE_DEFAULT
    host,
    all          // Maps to OpenCL CL_DEVICE_TYPE_ALL
    };

    which seems kind of vague (does "maps to" mean it is equal to, or just corresponds to?).

I've been using Oclgrind with SYCL recently, so to get around this I patched it to configure the device type with environment variables. Does this approach seem worth making a PR for? I considered making the device fully configurable (e.g., using some kind of config file), but that seems overkill for my needs. All I've done is add a check for an OCLGRIND_DEVICE_TYPE environment variable, and pick it if defined (else default to the original device type). Something like

cl_device_type get_device_type() {
  cl_device_type device_type = DEVICE_TYPE;

  const char* device = std::getenv("OCLGRIND_DEVICE_TYPE");
  if (device != nullptr) {
    std::string kind = device;
    if (kind == "ACCELERATOR") {
      device_type = CL_DEVICE_TYPE_ACCELERATOR;
    } else if (kind == "CPU") {
      device_type = CL_DEVICE_TYPE_CPU;
    } else if (kind =="DEFAULT") {
      device_type = CL_DEVICE_TYPE_DEFAULT;
    } else if (kind == "GPU") {
      device_type = CL_DEVICE_TYPE_GPU;
    }
  }

  return device_type;
}