CMake混合编译CUDA&&使用VS调试

CMake编译CUDA

  1. FindCUDA:在CMake 3.10版本已弃用。
  2. FindCUDAToolkit:在CMake 3.17版本更新。

使用CMake编译纯 .cu 文件

  • 旧版本使用FindCUDA的CMake编写会比较麻烦,需要使用特定的cuda的函数,例如:cuda_add_executable(test test.cu)

  • 高版本使用FindCUDAToolkit的CMake编写极其简单,只需要指定语言:enable_language(CUDA),其余一切与编译cpp相同。

  • 例如,文件目录结构如下:

    /project_root_path
    ----/build
    ----CMakeLists.txt
    ----main.cu
    
  • CMakeLists.txt内容如下:

    cmake_minimum_required(VERSION 3.17)
    
    project(test)
    enable_language(CUDA)
    
    aux_source_directory(. SRC)
    add_executable(test ${SRC})
    
    ## cd build
    ## cmake ..
    ## cmake --build .
    
  • 可直接生成.exe文件

CMake混合编译

  • 如果项目目录下既有.cu文件又有.cpp文件,先将.cu编译为动态库,再由.cpp调用

  • 目录结构:

    /project_root_path
    ----/build
    ----/cuda
    --------CMakeLists.txt
    --------deploy.cu
    --------deploy.h
    ----CMakeLists.txt
    ----main.cpp
    
  • 最外层CMakeLists.txt

    cmake_minimum_required(VERSION 3.17)
    
    project(test)
    enable_language(CXX)
    add_subdirectory(./cuda)
    
    aux_source_directory(. SRC)
    add_executable(test ${SRC})
    target_link_libraries(test gpu) 
    ## 链接 gpu.lib 文件,不需要写绝对路径 
    
  • cuda/CMakeLists.txt

    cmake_minimum_required(VERSION 3.17)
    project(gpu_lib)
    enable_language(CUDA)
    
    aux_source_directory(. SRC_CUDA)
    add_library(gpu SHARED ${SRC_CUDA})
    ## 在Windows下,最后会编译出 gpu.dll 与 gpu.lib
    
  • 编译一次即可同时生成.exe.dll.lib文件:

    cd build 
    cmake ..
    cmake --build .
    

    将编译出的.dll.lib移入.exe的目录下即可调用

  • 完整代码:

    /** deploy.cu **/
    #include <stdio.h>
    #include "deploy.h"
    
    __global__ void square(float* d_out, float* d_in){
        int idx = threadIdx.x;
        float f = d_in[idx];
        d_out[idx] = f * f;
    }
    
    int deploy(){
        const int ARRAY_SIZE = 8;
        const int ARRAY_BYTES = ARRAY_SIZE * sizeof(float);
    
        float h_in[ARRAY_SIZE];
        float h_out[ARRAY_SIZE];
        for(int i = 0; i < ARRAY_SIZE; i++){
            h_in[i] = float(i);
        }
    
        float* d_in;
        float* d_out;
    
        cudaMalloc((void**) &d_in, ARRAY_BYTES);
        cudaMalloc((void**) &d_out, ARRAY_BYTES);
    
        cudaMemcpy(d_in, h_in, ARRAY_BYTES, cudaMemcpyHostToDevice);
        square<<<1, ARRAY_SIZE>>>(d_out, d_in);
        cudaMemcpy(h_out, d_out, ARRAY_BYTES, cudaMemcpyDeviceToHost);
    
        for(int i = 0; i < ARRAY_SIZE; i++){
            printf("%f", h_out[i]);
            if( i % 4 != 3 )
                printf("\t");
            else
                printf("\n");
        }
    
        cudaFree(d_in);
        cudaFree(d_out);
    
        return 0;
    }
    
    /* deploy.h */
    #ifndef gpu_api
    #define gpu_api __declspec(dllexport)
    
    extern "C"
    gpu_api int deploy();
    
    #endif
    
    /* source.cpp */
    #include "cuda/deploy.h"
    #include <iostream>
    using namespace std;
    #pragma comment(lib, "gpu.lib")
    
    int main(){
        deploy();
        return 0;
    }
    

    NVCC的编译平台报错

  • 使用MSVC时,默认的编译平台是WIN 32

  • CMake使用默认编译平台nvcc可能会报错:

    nvcc fatal: 32 bit compilation is only supported for Microsoft Visual Studio 2013 and earlier
    
  • 可以通过以下命令改变:

    cmake .. -G "Visual Studio 15 2017 Win64"
    
  • 在指定编译平台后,就可以正常使用MSVC编译cuda代码了。

  • 如果不想输入命令,可以直接新建环境变量,命名为:CMAKE_GENERATOR,值为Visual Studio 15 2017 Win64

  • 也有其他方法,比如在CMakeLists.txt中添加set(CMAKE_GENERATOR "Visual Studio 15 2017 Win64")。但是经过个人实践,在只有一个CMakeLists.txt时,该方法无效,因为在读取到这一条语句之前就已经选定编译平台了。

使用VS启动项目

  • 因为使用MSVC编译的,所以会生成VS的解决方案(.sln文件),直接用VS运行即可。
  • 可能会出现:无法启动.../ALL_BUILD,拒绝访问的问题,这是因为CMake编译出的项目太多了,设置一个启动项即可解决。(右键项目 – 属性 – 设置为启动项)

使用VS调试CUDA

  1. 需要给nvcc添加-G选项,在旧版本的FindCUDA中可以使用set(CUDA_NVCC_FLAGS -G;-g)添加调试选项,但是在新版的FindCUDAToolkit中CUDA_NVCC_FLAGS被弃用了,这样写是无效的,更换为了更通用的add_definitions("-g -G")
  • 在CMakeLists.txt中添加add_definitions:

    cmake_minimum_required(VERSION 3.17)
    project(test)
    enable_language(CUDA)
    
    aux_source_directory(. SRC)
    add_definitions("-g -G")
    
    add_executable(test ${SRC})
    
  • 可以观察到编译选项中增添了-G选项:
    在这里插入图片描述

  1. 启动Nsight Monitor:开始菜单中或者直接搜索可以找到该程序。
  • 右下角会有Nsight Monitor的图标,右键,选择Options进行简单配置。

    • GeneralEnable Secure Connection设置为True
    • CUDA(Legacy)Use This Monitor For CUDA Attach设置为True
      在这里插入图片描述
      在这里插入图片描述
  1. 使用.sln文件启动VS,并设置项目为启动选项。

  2. 资源管理器中右键项目,选择Nsight User Properties
    在这里插入图片描述

  3. Launch中的Launch external program设置为生成的exe文件
    在这里插入图片描述

  4. 打断点,选择VS菜单中的Nsight,选择Start CUDA Debugging,至于是选用legacy还是Next-Gen需要看你的GPU架构,我的架构不支持Next-Gen,只能选用LegacyLegacy只支持调试GPU代码Kernel函数,Next-Gen两者都能调试。
    在这里插入图片描述

  5. 然后就可以调试了。

参考文献

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用CMake编译CUDA代码,你需要按照以下步骤进行操作: 1. 确保你已经安装了CUDA工具包,并且CUDA的bin目录已经添加到了系统的环境变量中。 2. 创建一个CMakeLists.txt文件,用于描述你的项目的构建过程。在该文件中,你需要指定CUDA的相关设置。 以下是一个示例的CMakeLists.txt文件: ``` cmake_minimum_required(VERSION 3.17) project(your_project_name CUDA) # 设置CUDA的相关设置 find_package(CUDA REQUIRED) include_directories(${CUDA_INCLUDE_DIRS}) set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};-O3 -arch=sm_35) # 添加你的源文件 add_executable(your_executable_name your_source_files.cu) ``` 在上述示例中,通过`find_package(CUDA REQUIRED)`来查找CUDA,并使用`include_directories`添加CUDA的头文件目录。 通过`set(CUDA_NVCC_FLAGS ...)`设置NVCC编译选项,例如指定优化级别和计算能力。 通过`add_executable`添加你的CUDA源文件。 3. 在项目的根目录下创建一个build目录,然后进入该目录。 4. 运行CMake来生成构建文件。可以使用下面的命令: ``` cmake .. ``` 这将根据CMakeLists.txt文件生成适用于你的操作系统的构建文件。 5. 运行构建命令来编译你的项目。可以使用下面的命令: ``` cmake --build . ``` 这将根据生成的构建文件进行编译。 完成上述步骤后,你的CUDA项目应该成功编译。请注意,以上仅提供了一个基本示例,你可能需要根据你的项目的实际情况进行适当的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值