Search code examples
gpgpusycl

SyCL ComputeCpp: how to support both SPIR and PTX bitcode at runtime


I recently did some experiments with the SyCL ComputeCpp library, we good results. However, in the application I'd like to achieve, I should support both nVidia and AMD/Intel cards on runtime. At the time of this writing, it seems to me nVidia is not giving any support to spir64/spirv64 bitcode, forcing the developer to create 2 different projects for each of them. This is manifest using the current cmake use done by the Cpp, which creates gently a UNIQUE .sycl file for each cpp containing any SyCL kernel. This .sycl will be compiled targeting either spir XOR PTX, but not altogether. May be, we could try to hack the cmakelists.txt to generate both -sycl, with slightly different names (I'm not a cmake expert, but I guess this is doable, hopefully).

However, the real problem is then how to tell the SyCL ComputeCpp runtime to feed the graphic card driver choosing among those 2 .sycl. The aim would be to detect which GPU is installed, i.e. nVidia or AMD (or Intel) and decide from that which .sycl to be used when feeding the kernel.

From your experience, is that eventually already doable and so in case I missed something about how to achieve that?

I mean, I guess this is "common" problem among people trying to target different GPUs, so there's must be an "easy" solution already present in ComputeCpp.

However, since the .sycl are embedded as resources in the exe, as dirty trick could be to hot patch the .sycl image in the resource of the exe during the runtime.

Thanks for your support in advance.


Solution

  • This is very possible and implemented in multiple SYCL implementations including ComputeCpp and DPC++.

    In ComputeCpp you need to have the Professional Edition to use the mult-target feature, the documentation is here.

    Essentially something like this would work:

    compute++ -sycl-target spir32 -sycl-target spir64 -sycl-target spirv64 hello-world.cpp

    It is also possible to do this using another SYCL implementation called DPC++ that provides support for Intel, Nvidia and AMD targets.

    e.g.

    clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda,spir64 myfile.cpp

    You then need to specify the target during execution by either passing this when running the binary, or ensuring you use the correct device through the device selector.

    e.g.

    SYCL_DEVICE_FILTER=spir64 ./simple

    or you can use a device selector if you want to achieve this in code.