Program to check CUDA presence needs CUDA? - c++

I wrote a simple application that checks if NVIDIA CUDA is available on the computer. It simply displays true if a CUDA-capable device is found.
I send the app to a second PC, and the application didn't run - a dialog box showed up that cudart.dll was not found. I want to check if CUDA is present and it requires CUDA to do that :)
I am using CUDA 5.0, VS2012, VC++11, Windows 7.
Can I compile the application in a way, that all CUDA libraries are inside the executable?
So the scenario is:
My app is compiled & sent to a computer
The computer can:
be running windows, linux (my app is compatible with the system)
have a gpu or not
have an nvidia gpu or not
have CUDA installed or not
My app should return true only if 2.3 and 2.4 are positive (GPU with CUDA)

As an opening comment, I think the order and number of steps in your edit is incorrect. It should be:
Programs starts and attempts to load the runtime API library
If the runtime library is present, attempt to use it to enumerate devices.
If step 1 fails, you do not have the necessary runtime support, and CUDA cannot be used. If 2 fails, there is not a compatible driver and GPU present in the system and CUDA cannot be used. If they both pass, you are good to go.
In step 1 you want to use something like dlopen on Linux and handle the return status. On Windows, you probably want to use the DLL delay loading mechanism (Sorry, not a Windows programmer, can't tell you more than that).
In both cases, if the library loads, then fetch the address of cudaGetDeviceCount via the appropriate host OS API and call it. That tells you whether there are compatible GPUs which can be enumerated. What you do after you find an apparently usable GPU is up to you. I would check for compute status and try establishing a context on it. That will ensure that a fully functional runtime/driver combination is present and everything works.

Linking to a different post on stackoverflow: detecting-nvidia-gpus-without-cuda
This shows the whole sequence to check if the cuda api is available and accessible.

I think that using only the software there is no reliable way to ensure that a GPU is Cuda-capable or not, especially if we consider that Cuda is a driver-based technology and for the OS Cuda doesn't exist if the driver says that Cuda doesn't exist.
I think that the best way to do this is the old fashion way, consider checking this simple web page and you will get a much more reliable answer.

create a plugin for your application that dynamically links to the relevant CUDA-libraries and performs the check.
then try loading the plugin and run it's check.
if the plugin fails to load, then you don't have the CUDA-libraries installed, so you can assume False
if the plugin succeeds to load, then you have CUDA-libs installed and can perform the check, whether the hardware supports CUDA as well.

As a late andditional answer:
I am struggling with the same problem (detecting cuda installation without using it) and my solution so far is
ensuring LoadLibraryA("nvcuda.dll") != nullptr (tells you pretty much only if there is an nvidia card installed, though)
checking for environment variable CUDA_PATH (or in my case, CUDA_PATH_V8_0), since that seems to be set by the cuda installation: const char * szCuda8Path = std::getenv("CUDA_PATH_V8_0"); (must be != nullptr)

Use cudaGetDeviceCount() to know if the computer is CUDA-capable.
According to this thread, you cannot statically link cudart.dll.
There are workarounds: embed the CUDA runtime as a resource in your executable, then extract it when your program runs, then dynamically link.
You can also use nvidia-smi to see if CUDA is installed on a machine.

Related

Find out the active graphics driver using SetupAPI

I try to find out the version of the currently active graphics driver on Windows using C++ and SetupAPI. The solution roughly looks like
Call SetupDiGetClassDevs for GUID_DEVCLASS_DISPLAY.
Call SetupDiBuildDriverInfoList for the result set.
Call SetupDiEnumDriverInfo for the device set with SPDIT_COMPATDRIVER, which gives me all known drivers compatible with the GPU.
The result includes the fallback driver from Microsoft, which I can easily exclute, but it also includes all driver versions (from NVIDIA) that have been installed on the system.
The question is: How do I find out which of the drivers is actually running?
I know from the SP_DEVINFO_DATA returned in step 1 how the driver service is called and I also get some kind of registry key, but I do not see how I could relate this to the SP_DRVINFO_DATA. I also know that NVAPI provides driver management capabilities, but I would prefer a solution that works with GPUs of all kinds of vendors.
Just FYI, you can also query the SPDRP_DRIVER via SetupDiGetDeviceRegistryProperty and then lookup that registry value under Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\. That key contains all the driver info. Here is some sample code from WebKit that actually retrieves GPU info this way.
I found the solution in the meantime at Why does SetupDiEnumDriverInfo give two version numbers for my driver: You need to update the install parameters of the device information set with the DI_FLAGSEX_INSTALLEDDRIVER flag before step 3.

DirectX11 Desktop duplication not working with NVIDIA

I'm trying too use DirectX desktop duplication API.
I tried running exmaples from
http://www.codeproject.com/Tips/1116253/Desktop-Screen-Capture-on-Windows-via-Windows-Desk
And from
https://code.msdn.microsoft.com/windowsdesktop/Desktop-Duplication-Sample-da4c696a
Both of these are examples of screen capture using DXGI.
I have NVIDIA GeForce GTX 1060 with Windows 10 Pro on the machine. It has Intel™ Core i7-6700HQ processor.
These examples work perfectly fine when NVIDIA Control Panel > 3D Settings is selected to Auto select processor.
However if I set the setting manually to NVIDIA Graphics Card the samples stop working.
Error occurs at the following line.
//IDXGIOutput1* DxgiOutput1
hr = DxgiOutput1->DuplicateOutput(m_Device, &m_DeskDupl);
Error in hr(HRESULT) is DXGI_ERROR_UNSUPPORTED 0x887A0004
I'm new to DirectX and I don't know the issue here, is DirectX desktop duplication not supported on NVIDIA ?
If that's the case then is there a way to select a particular processor at the start of program so that program can run with any settings ?
#Edit
After looking around I asked the developer (Evgeny Pereguda) of the second sample project on codeproject.com
Here's a link to the discussion
https://www.codeproject.com/Tips/1116253/Desktop-Screen-Capture-on-Windows-via-Windows-Desk?msg=5319978#xx5319978xx
Posting the screenshot of the discussion on codeproject.com in case original link goes down
I also found an answer on stackoverflow which unequivocally suggested that it could not be done with the desktop duplication API referring to support ticket at microsoft's support site https://support.microsoft.com/en-us/help/3019314/error-generated-when-desktop-duplication-api-capable-application-is-ru
Quote from the ticket
This issue occurs because the DDA does not support being run against
the discrete GPU on a Microsoft Hybrid system. By design, the call
fails together with error code DXGI_ERROR_UNSUPPORTED in such a
scenario.
However there are some applications which are efficiently duplicating desktop on windows in both modes (integrated graphics and discrete) on my machine. (https://www.youtube.com/watch?v=bjE6qXd6Itw)
I have looked into the installation folder of the Virtual Desktop on my machine and can see following DLLs of interest
SharpDX.D3DCompiler.dll
SharpDX.Direct2D1.dll
SharpDX.Direct3D10.dll
SharpDX.Direct3D11.dll
SharpDX.Direct3D9.dll
SharpDX.dll
SharpDX.DXGI.dll
SharpDX.Mathematics.dll
Its probably an indication that this application is using DXGI to duplicate desktop, or may be the application is capable of selecting a specific processor before it starts.
Anyway the question remains, is there any other efficient method of duplicating desktop in both modes?
The likely cause is certain internal limitation for Desktop Duplication API, described in Error generated when Desktop Duplication API-capable application is run against discrete GPU:
... when the application tries to duplicate the desktop image against the discrete GPU on a Microsoft Hybrid system, the application may not run correctly, or it may generate one of the following errors:
Failed to create windows swapchain with 0x80070005
CDesktopCaptureDWM: IDXGIOutput1::DuplicateOutput failed: 0x887a0004
The article does not suggest any other workaround except use of a different GPU (without more specific detail as for whether it is at all achievable programmatically):
To work around this issue, run the application on the integrated GPU instead of on the discrete GPU on a Microsoft Hybrid system.
Microsoft introduced a registry value that can be set programmatically to control which GPU an application runs on. Full answer here.

(linux) How can I know inside a c++ program if Opengl 4 is supported?

I would like to detect inside my C++ program if opengl 4 is supported on the running computer.
I don't know if I search on google and stackoverflow with wrong/bad terms (my english skill...), but surprisingly I didn't found any example... I would not be suprise if you tell me this question is a duplicate...
It would eventually useful for me to know how to get more usefull datas from the video card and the drivers used by it on the running computer. I didn't take time to look around to know how to do that, but if you have some usefull link, feel free to share it with me.
Step 1: Create an OpenGL Context; first try by the "attrib" method requesting the minium OpenGL version you want to have. If that succeeds you're done.
Step 2: If that didn't work and you can gracefully downgrade create a no-frills context
and call glGetString(GL_VERSION) to get the actual context version supported. Note that on MacOS X this limits you to 2.1 and earlier.
Step 3: If you want some context, portable and reliably between 2.1 and your optimimal version, try with the attribs method in a loop, decrementing your needs until it succeeds.
Note that there is no way to determine in advance which version is supported in OpenGL. The main reason for this is, that operating systems and the graphics layer may decide on demand which locally available OpenGL version to use, depending on the request and the resources available at the moment (graphics cards in theory can be hotplugged).

Is there a PoC empty OS?

For fun i'd like to write code that runs on OSless hardware. I think writing code that will run in a VM (like VMware or virtualbox) would be good. However i don't want to start from scratch. I'd like the C++ runtime to be available. Something that allows me to read/write (maybe FAT32 filesystem code). Graphics for text and if i can graphics for drawing on screen (pixel by pixel. sdl support would be a bonus but not essential).
I'll write my own threads if i want them. I'll write everything else (that i want to use) needed for an OS. I just want a basic filesystem, gfx and keyboard/mouse support.
Take a look at the list of projects on osdev.org - (http://wiki.osdev.org/Projects) - most of these are hobbyist, open-source and range from just-a-bootsector through to proper threads/graphics/terminal support.
Minix3 targets your desires pretty well.
You should definitely take a look at OSKit (links to source code on this site are dead but there is a mirror here). Unfortunately, OSKit has no support for C++ but using this information you may be able to use GCC libraries.

Can cuda be used combining with activeX technology?

every one. i am a newbie to cuda. i am wondering that can cuda be used combining with ActiveX technology,
the presented ocx or dll file can be used in webpage,
for example, using cuda can we simulate a fluid particle easily.
if combine cuda and activeX technology ,
we can see fluid particle in a webpage, am i right?
what's more, if there are problems when i simulate lots of particles?
Thank you very much.
I think that if ActiveX could access your GPU on such low level as running your arbitrary CUDA code, it would be a big security risk. If on the other hand, ActiveX could perform some of its computations on the GPU though some higher-level interface, that would be safer, but it is Microsoft who would have to implement it, not you.
A trusted ActiveX control can do anything. So, yes, you could theoretically spin up the CUDA runtime and go to town with the GPU. You would need to distribute the CUDA runtime with the ActiveX control, but everything else you need would already be installed assuming they're using an nVidia GPU. FWIW, distributing cudart.dll is permissable per the EULA on the CUDA Developer Toolkit.
Since, last I read, you cannot statically link against cudart.dll, you would need to distribute that dependency along with your ActiveX control by using a CAB file. Details on creating CAB files can be found here on MSDN. Then again that forum post is from 2008, so maybe newer versions of cudart.dll can be statically linked now... you might want to give it a try.
First and foremost, it runs on the client machine. What means that the client needs to have a CUDA enabled graphics card (nVidia only).