gpt4 book ai didi

build-automation - 从 cmake 测试是否存在支持 cuda 的 GPU 的最简单方法是什么?

转载 作者:行者123 更新时间:2023-12-03 21:11:56 44 4
gpt4 key购买 nike

我们有一些夜间构建机器具有 cuda libraries已安装,但未安装支持 cuda 的 GPU。这些机器能够构建支持 cuda 的程序,但它们不能运行这些程序。

在我们的自动化夜间构建过程中,我们的 cmake 脚本使用 cmake 命令
find_package(CUDA)
判断是否安装了cuda软件。这将设置 cmake 变量 CUDA_FOUND在安装了 cuda 软件的平台上。这很棒,而且效果很好。当CUDA_FOUND设置好了,就可以构建支持cuda的程序了。即使机器没有支持 cuda 的 GPU。

但是使用 cuda 的测试程序在非 GPU 的 cuda 机器上自然会失败,导致我们的夜间仪表板看起来“脏”。所以我希望 cmake 避免在这些机器上运行这些测试。但我仍然想在这些机器上构建 cuda 软件。

得到肯定后CUDA_FOUND结果,我想测试是否存在实际的 GPU,然后设置一个变量,比如 CUDA_GPU_FOUND , 来反射(reflect)这一点。

让 cmake 测试是否存在支持 cuda 的 gpu 的最简单方法是什么?

这需要在三个平台上运行:带有 MSVC 的 Windows、Mac 和 Linux。 (这就是我们首先使用 cmake 的原因)

编辑:关于如何编写程序来测试 GPU 是否存在的答案中有一些好看的建议。仍然缺少的是让 CMake 在配置时编译和运行该程序的方法。我怀疑 TRY_RUN CMake 中的命令在这里很重要,但不幸的是该命令是 nearly undocumented ,我不知道如何使它工作。问题的这个 CMake 部分可能是一个更困难的问题。也许我应该把这个作为两个单独的问题来问......

最佳答案

这个问题的答案包括两部分:

  • 用于检测是否存在支持 cuda 的 GPU 的程序。
  • CMake 代码用于在配置时编译、运行和解释该程序的结果。

  • 对于第 1 部分,gpu 嗅探程序,我从 fabrizioM 提供的答案开始,因为它非常紧凑。我很快发现我需要在未知的答案中找到许多细节才能使其正常工作。我最终得到的是以下 C 源文件,我将其命名为 has_cuda_gpu.c :
    #include <stdio.h>
    #include <cuda_runtime.h>

    int main() {
    int deviceCount, device;
    int gpuDeviceCount = 0;
    struct cudaDeviceProp properties;
    cudaError_t cudaResultCode = cudaGetDeviceCount(&deviceCount);
    if (cudaResultCode != cudaSuccess)
    deviceCount = 0;
    /* machines with no GPUs can still report one emulation device */
    for (device = 0; device < deviceCount; ++device) {
    cudaGetDeviceProperties(&properties, device);
    if (properties.major != 9999) /* 9999 means emulation only */
    ++gpuDeviceCount;
    }
    printf("%d GPU CUDA device(s) found\n", gpuDeviceCount);

    /* don't just return the number of gpus, because other runtime cuda
    errors can also yield non-zero return values */
    if (gpuDeviceCount > 0)
    return 0; /* success */
    else
    return 1; /* failure */
    }

    请注意,在找到启用了 cuda 的 GPU 的情况下,返回码为零。这是因为在我的一台 has-cuda-but-no-GPU 机器上,该程序生成一个运行时错误,退出代码非零。因此,任何非零退出代码都被解释为“cuda 在这台机器上不起作用”。

    你可能会问为什么我不在非 GPU 机器上使用 cuda 仿真模式。这是因为仿真模式是错误的。我只想调试我的代码,并解决 cuda GPU 代码中的错误。我没有时间调试模拟器。

    问题的第二部分是使用这个测试程序的cmake代码。经过一番挣扎,我想通了。以下 block 是较大 CMakeLists.txt 的一部分文件:
    find_package(CUDA)
    if(CUDA_FOUND)
    try_run(RUN_RESULT_VAR COMPILE_RESULT_VAR
    ${CMAKE_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/has_cuda_gpu.c
    CMAKE_FLAGS
    -DINCLUDE_DIRECTORIES:STRING=${CUDA_TOOLKIT_INCLUDE}
    -DLINK_LIBRARIES:STRING=${CUDA_CUDART_LIBRARY}
    COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR
    RUN_OUTPUT_VARIABLE RUN_OUTPUT_VAR)
    message("${RUN_OUTPUT_VAR}") # Display number of GPUs found
    # COMPILE_RESULT_VAR is TRUE when compile succeeds
    # RUN_RESULT_VAR is zero when a GPU is found
    if(COMPILE_RESULT_VAR AND NOT RUN_RESULT_VAR)
    set(CUDA_HAVE_GPU TRUE CACHE BOOL "Whether CUDA-capable GPU is present")
    else()
    set(CUDA_HAVE_GPU FALSE CACHE BOOL "Whether CUDA-capable GPU is present")
    endif()
    endif(CUDA_FOUND)

    这设置了 CUDA_HAVE_GPU cmake 中的 bool 变量,随后可用于触发条件操作。

    我花了很长时间才弄清楚包含和链接参数需要放在 CMAKE_FLAGS 节中,以及语法应该是什么。 try_run documentation很轻,但是 try_compile documentation 里有更多信息,这是一个密切相关的命令。在让它工作之前,我仍然需要在网上搜索 try_compile 和 try_run 的示例。

    另一个棘手但重要的细节是 try_run 的第三个参数。 ,“绑定(bind)目录”。您可能应该始终将其设置为 ${CMAKE_BINARY_DIR} .特别是不要将其设置为 ${CMAKE_CURRENT_BINARY_DIR}如果您在项目的子目录中。 CMake 期望找到子目录 CMakeFiles/CMakeTmp在 bindir 中,如果该目录不存在,则会出现错误。只需使用 ${CMAKE_BINARY_DIR} ,这是这些子目录似乎自然存在的一个位置。

    关于build-automation - 从 cmake 测试是否存在支持 cuda 的 GPU 的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2285185/

    44 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com