检测没有CUDA的NVIDIA GPU

psz*_*ard 6 c cuda

我想提取一组有关NVIDIA GPU的信息,而不需要链接到CUDA库.唯一需要的信息是计算能力和GPU的名称,这可能比这更有用但不是必需的.代码应该用C(或C++)编写.这些信息将在配置时(当CUDA工具包不可用时)和运行时(当执行的二进制文件未使用CUDA支持编译时)使用,以向用户建议系统中存在受支持的GPU.

据我所知,这可以通过驱动程序API实现,但我不太熟悉这需要的技术细节.所以我的问题是:

  • 至少满足最低要求的具体步骤是什么(见上文);

  • 有没有这样的开源代码?

请注意,我的第一步是为Linux提供一些代码,但最终我需要与平台无关的代码.考虑到CUDA的平台可用性,对于完整的解决方案,这将涉及适用于Linux,Mac OS和Windows的x86/AMD64代码(至少目前,该列表很快就可以通过ARM扩展).

编辑

我所说的"通过驱动程序API可以"是一个应该能够动态加载libcuda.so并通过驱动程序API查询设备属性.不过,我不确定细节.

Prz*_*ych 7

不幸的是,NVML不提供有关设备计算能力的信息.

你需要做的是:

  1. 手动加载CUDA库(应用程序未链接到libcuda)
    • 如果库不存在,则不安装CUDA驱动程序
  2. 查找库中必要函数的指针
  3. 使用驱动程序API查询有关可用GPU的信息

我希望这段代码会有所帮助.我已经在Linux下进行了测试,但只需稍作修改,它也应该在Windows下编译.

#include <cuda.h>
#include <stdio.h>

#ifdef WINDOWS
#include <Windows.h>
#else
#include <dlfcn.h>
#endif


void * loadCudaLibrary() {
#ifdef WINDOWS
    return LoadLibraryA("nvcuda.dll");
#else
    return dlopen ("libcuda.so", RTLD_NOW);
#endif
}

void (*getProcAddress(void * lib, const char *name))(void){
#ifdef WINDOWS
    return (void (*)(void)) GetProcAddress(lib, name);
#else
    return (void (*)(void)) dlsym(lib,(const char *)name);
#endif
}

int freeLibrary(void *lib)
{
#ifdef WINDOWS
    return FreeLibrary(lib);
#else
    return dlclose(lib);
#endif
}

typedef CUresult CUDAAPI (*cuInit_pt)(unsigned int Flags);
typedef CUresult CUDAAPI (*cuDeviceGetCount_pt)(int *count);
typedef CUresult CUDAAPI (*cuDeviceComputeCapability_pt)(int *major, int *minor, CUdevice dev);

int main() {
    void * cuLib;
    cuInit_pt my_cuInit = NULL;
    cuDeviceGetCount_pt my_cuDeviceGetCount = NULL;
    cuDeviceComputeCapability_pt my_cuDeviceComputeCapability = NULL;

    if ((cuLib = loadCudaLibrary()) == NULL)
        return 1; // cuda library is not present in the system

    if ((my_cuInit = (cuInit_pt) getProcAddress(cuLib, "cuInit")) == NULL)
        return 1; // sth is wrong with the library
    if ((my_cuDeviceGetCount = (cuDeviceGetCount_pt) getProcAddress(cuLib, "cuDeviceGetCount")) == NULL)
        return 1; // sth is wrong with the library
    if ((my_cuDeviceComputeCapability = (cuDeviceComputeCapability_pt) getProcAddress(cuLib, "cuDeviceComputeCapability")) == NULL)
        return 1; // sth is wrong with the library

    {
        int count, i;
        if (CUDA_SUCCESS != my_cuInit(0))
            return 1; // failed to initialize
        if (CUDA_SUCCESS != my_cuDeviceGetCount(&count))
            return 1; // failed

        for (i = 0; i < count; i++)
        {
            int major, minor;
            if (CUDA_SUCCESS != my_cuDeviceComputeCapability(&major, &minor, i))
                return 1; // failed

            printf("dev %d CUDA compute capability major %d minor %d\n", i, major, minor);
        }
    }
    freeLibrary(cuLib);
    return 0; 
}
Run Code Online (Sandbox Code Playgroud)

在Linux上测试:

$ gcc -ldl main.c
$ ./a.out
dev 0 CUDA compute capability major 2 minor 0
dev 1 CUDA compute capability major 2 minor 0
Run Code Online (Sandbox Code Playgroud)

在没有CUDA驱动程序的情况下测试linux

$ ./a.out
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

干杯


eLR*_*uLL 1

这些人肯定知道答案:

http://www.ozone3d.net/gpu_caps_viewer

但我只能知道我可以通过安装 CUDA 或 OpenCL 来完成。

我认为一种方法是直接使用 OpenGL,也许这就是您所讨论的驱动程序 API,但我只能给您这些示例(需要 CUDA):

http://www.naic.edu/~phil/hardware/nvidia/doc/src/deviceQuery/deviceQuery.cpp