How do you make SYCL "default_selector" select an Intel GPU rather than an NVIDIA GPU? - gpu

I am currently working on a project using SYCL to apply an unsharp mask to an image. My machine has an NVIDIA and an Intel GPU inside it. I am starting with the following code:
default_selector deviceSelector;
queue myQueue(deviceSelector);
The issue is that the line of code "default_selector deviceSelector;" automatically grabs the NVIDIA GPU inside my machine, this breaks all the code that follows as SYCL does not work with NVIDIA.
Therefore my question is - how can I force "default_selector deviceSelector;" to get my Intel GPU and not the NVIDIA GPU? Perhaps I can say something like:
if (device.has_extension(cl::sycl::string_class("Intel")))
if (device.get_info<info::device::device_type>() == info::device_type::gpu)
then select this GPU;//pseudo code
Thus making the code skip over the NVIDIA GPU and guaranteeing the selecting of my Intel GPU.

You are checking the extensions contain an entry called "Intel" which it would not. Extensions are things the device supports, such as SPIR-V You can see the supported extensions by calling clinfo at the command line. To choose the Intel GPU you need to check the manufacturer of the device to select the correct one.
So in the sample code for custom device selection https://github.com/codeplaysoftware/computecpp-sdk/blob/master/samples/custom-device-selector.cpp#L46
You would need to just have something like
if (device.get_info<info::device::name>() == "Name of device") {
return 100;
}
You could print out the value of
device.get_info<info::device::name>
to get the value to check against.

Related

How can I determine the generation/codename of AMD gpu in Linux?

I want to detect the AMD gpu deneration in python code. My case is that to run specific application (davinci resolve), it is required to use amdgpu pro drivers for gpu cards before Vega. And amdgpu pro drivers are not required when AMD gpu is Vega or newer generation. See the list of amd gpus in wikipedia. I am writing a script (davinci-resolve-checker) that tells user if he/she need to use that driver.
The question is, how do I differentiate between gpu generations/chip codenames of a gpu? I am using pylspci to get information of the presented gpus. Is there a list of generations that I can check with?
There is a pci id list published here: https://pci-ids.ucw.cz/v2.2/pci.ids
In that list for Advanced Micro Devices, Inc. [AMD/ATI] (1002 vendor id) you can see their devices. For example, for AMD Radeon PRO W6600 GPU there is 73e3 Navi 23 WKS-XL [Radeon PRO W6600] line.
There you can see if the device name contains the codename substring. In this case it is Navi.
For the specified question, the codenames that currently describes vega and above are: Vega, Navi. So if the device name does not contain that substring, I consider it as "older than vega".
For programming that, you do not actually need the list, as you can just take the device name from VerboseParser device.device.name. But just in case, this list is located in /usr/share/hwdata/pci.ids in the system.
Probably, it is not a very reliable way. But I did not yet found a better way. Any suggestions are welcome.

Is it safer to use OpenCL rather than SYCL when the objective is to have the most hardware-compatible program?

My objective is to obtain the ability of parallelizing a code in order to be able to run it on GPU, and the Graal would be to have a software that can run in parallel on any GPU or even CPU (Intel, NVIDIA, AMD, and so...).
From what I understood, the best solution would be to use OpenCL. But shortly after that, I also read about SYCL, that is supposed to simplify the codes that run on GPU.
But is it just that ? Isn't better to use a lower level language in order to be sure that it will be possible to be used in the most hardware possible ?
I know that all the compatibilities are listed on The Khronos Group website, but I am reading everything and its opposite on the Internet (like if a NVIDIA card supports CUDA, then it supports OpenCL, or NVIDIA cards will never work with OpenCL, even though OpenCL is supposed to work with everything)...
This is a new topic to me and there are lots of informations on the Internet... It would be great if someone could give me a simple answer to this question.
Probably yes.
OpenCL is supported on all AMD/Nvidia/Intel GPUs and on all Intel CPUs since around 2009. For best compatibility with almost any device, use OpenCL 1.2. The nice thing is that the OpenCL Runtime is included in the graphics drivers, so you don't have to install anything extra to work with it or to get it working on another machine.
SYCL on the other hand is newer and not yet established that well. For example, it is not officially supported (yet) on Nvidia GPUs: https://forums.developer.nvidia.com/t/is-sycl-available-on-cuda/37717/7
But there are already SYCL implememtations that are compatible with Nvidia/AMD GPUs, essentially built on top of CUDA or OpenCL 1.2, see here: https://stackoverflow.com/a/63468372/9178992

Why can the environment variable TF_CUDA_COMPUTE_CAPABILITIES be set with multi values?

The environment variable TF_CUDA_COMPUTE_CAPABILITIES can be set as:
TF_CUDA_COMPUTE_CAPABILITIES=3.0,3.5,5.2,7.0,7.5, why can it be set with multi values?
TF_CUDA_COMPUTE_CAPABILITIES is a build time parameter for TensorFlow, it has no effect if you set it at runtime.
Setting it to multiple values allows you to build a TensorFlow install image that supports multiple types of GPUs with the cuda libraries to leverage the abilities of the graphic card's hardware.
The more TF_CUDA_COMPUTE_CAPABILITIES values you include, the longer the build will take and the larger the final wheel size will be.
Using this web page: https://developer.nvidia.com/cuda-gpus#compute, you can find the cuda compute capabilities value for each graphic card you wish to use. If your using a P100 for example the compute capability would be 6.0.
Continuing the example if you built TensorFlow with only compute capability 6.0, and then installed in on a system with a V100 (compute capability 7.0), it would work, but it would not run as fast as if it was built including compute capability 7.0.
To fit different CUDA verisons while compiling, I suppose.

Force display from APU and have discrete GPU for OpenCL?

I need a system for OpenCL programming with the following restrictions:
The discrete GPU must not run as a display card --> I can do that
from BIOS
The internal GPU of the AMD's APU must be used as display GPU --> I can do that
from BIOS
OpenCL must not recognize the internal APU's GPU and must always
default to the discrete GPU
Why do I need this?
It is because I am working on a GPU code that demands the GPU's BIOS
to be flashed and a custom BIOS to be installed, which makes the GPU
unusable for display.
AMD boards can't boot without VGA card so I am getting an APU that
has internal GPU.
The code base I am working on can't deal with conflicting GPUs so I
need to disable that (APU's GPU) from OpenCL seeing it.
How can I approach it?
According to the AMD OpenCL Programming Guide, AMD's drivers support the GPU_DEVICE_ORDINAL environment variable to configure which devices are used (Section 2.3.3):
In some cases, the user might want to mask the visibility of the GPUs seen by
the OpenCL application. One example is to dedicate one GPU for regular graphics operations and the other three (in a four-GPU system) for Compute. To
do that, set the GPU_DEVICE_ORDINAL environment parameter, which is a comma-separated
list variable:
Under Windows: set GPU_DEVICE_ORDINAL=1,2,3
Under Linux: export GPU_DEVICE_ORDINAL=1,2,3
You'll first need to determine the ordinal for the devices you want to include. For this, I would recommend using clinfo with the -l switch, which will give you a basic tree of the available OpenCL platforms and devices. If the devices are listed with the APU first and then the dedicated GPU, you would want to only enable device 1 (the GPU), and would set the environment variable to GPU_DEVICE_ORDINAL=1.

D3D11CreateDevice with non-default adapter

I'm not sure if this is the right place to ask ... please tell me if there are better places for this question.
When writing Direct3d 11 programs, I observed the following problem:
I have two GPUs on my laptop: intel and nvidia (GT640M). Usually the nvidia card is not default (i.e. not the first one enumerated by IDXGIFactory::EnumAdapters).
In that case, I can still creat a D3D11Device using D3D11CreateDevice or D3D11CreateDeviceAndSwapChain, and set the pAdapter to the adapter of the nvidia card. The program runs correctly.
However, when the program terminates, the nvidia card is still doing SOMETHING... I have no idea what it is doing, but it obviously is: the icon is colorful, and the temperature of my laptop raises quickly.
If I set nvidia card as the default for this particular program (which I did in the control panel of nvidia), the problem disappears.
After many experiments, I have drawn the conclusion that the problem occurs if and only if I want to create device with a non-default adapter.
Is this an issue of the nvidia card, or of Direct3D? Is there a solution to it?