CUDA和C++混合编程及CMakeLists.txt

2023-11-06

1. 概要

首先认识一个问题,单从CMakeLists.txt的角度来看,无法同时使用两种编译器编译两种语言。不过直接编写Makefile是可以的,通过设置不同的任务,可以实现一个Makefile编译两个语言。但这不是这里要讨论的重点。
使用CUDA和C++进行混合编程的意思是:在cpp文件中调用CUDA函数,实现加速。
所以混合编程有两种方法:
1.1 直接编译
1.2 将CUDA工程编译成库,然后在我们的cpp工程中使用target_link_libraries()来链接到我们刚编译好的CUDA库。

2. 注意点

我们要做的事情是将CUDA工程编译成库,然后在我们的cpp工程中使用target_link_libraries()来链接到我们刚编译好的CUDA库。
有几个需要注意的地方,下面这些都是在cpp的CMakeLists.txt中:

  1. The project() command will initialize many CMake variables concerning your system and compiler. As such, it sets the languages that your CMake project will be using. Without specifying any language in the project() command, the defaults (C and CXX) are enabled:

    # Initialize for C and C++ languages.
    project(cmake_and_cuda)
    

    啥意思?意思是说,CMakeLists.txt中的 project() 作用是根据你的系统和编译器初始化CMake变量,所以,projects()的作用是设置你CMake项目的语言,如果没有特别指出,默认使用C和CXX

  2. project() 应该紧跟在cmake_minimum_required()后面,这里因为我们需要引用cuda库,所以需要设置语言的时候加上cuda,有两种方式:

    project(cmake_and_cuda CUDA CXX)
    # 或者如下:
    project(cmake_and_cuda CUDA CXX)
    enable_language(CUDA)
    
  3. 设置CUDA架构
    后面的数值需要根据显卡来确定,查阅 https://developer.nvidia.com/cuda-gpus,比如我的是8.6这里就设置86

    set(CMAKE_CUDA_ARCHITECTURES 86)
    
  4. 给cuda库进行编译,并且链接到cpp程序中去【直接编译的方法跳过】

    add_subdirectory(kernels)
    target_link_libraries(main kernels)
    

3. 实现

main.cpp

#include "kernels/test.cuh"

int main() {
  wrap_test_print();

  return 0;
}

版本一:
直接编译:

cmake_minimum_required(VERSION 3.8 FATAL_ERROR)

project(cmake_and_cuda)
set(CMAKE_CUDA_ARCHITECTURES 86)
enable_language(CUDA)
# 把cu当成普通cpp来用
add_executable(main main.cpp kernels/test.cu)

版本二:
编译CUDA成库再链接方式的CMakeLists.txt

cmake_minimum_required(VERSION 3.8 FATAL_ERROR)

project(cmake_and_cuda)

set(CMAKE_CUDA_ARCHITECTURES 86)
#set(CMAKE_CUDA_COMPILER /usr/local/cuda-11.1/bin/nvcc)
#set(CUDACXX /usr/local/cuda-11.1/bin/nvcc)

enable_language(CUDA)

add_executable(main main.cpp)
add_subdirectory(kernels)

# set_property(TARGET main 
#              PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_libraries(main kernels)

test.cuh:cuda的头文件

#ifndef TEST_CUH__
#define TEST_CUH__

#include <stdio.h>

void wrap_test_print();

#endif

test.cu

#include "test.cuh"
__global__ void test_print(){
  printf("Hello World!\n");
}

void wrap_test_print() {
  test_print<<<1, 1>>>();
  cudaDeviceSynchronize();
  return;
}

cuda的CMakeLists.txt【直接编译的方法不要这个CMakeLists.txt】

enable_language(CUDA)
add_library(kernels
test.cu
test.cuh
)
target_compile_features(kernels PUBLIC cxx_std_11)
set_target_properties(kernels
                       PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
target_link_libraries(kernels)

最终目录结构:

├── CMakeLists.txt
├── kernels
│   ├── CMakeLists.txt
│   ├── test.cu
│   └── test.cuh
└── main.cpp

编译运行,输出Hello World!

4. CLion注意点

如果你用的是clion来编写cpp和cuda的混合,很有可能你直接使用界面上的运行按钮会报错,找不到文件blabla…,比如fatal error: cuda_runtime.h: 没有那个文件或目录,但是其实你从终端里面cmake make是能通过也是正常执行的,只要你在终端编过一次,IDE中即使一堆报错波浪线也可以run,很莫名其妙。

解决办法,在CMakeLists中加上一句include_directories(/usr/local/cuda-11.1/targets/x86_64-linux/include),这里的路径可以通过在命令行执行locate cuda_runtime.h来获得,这样所有clion中所有和cuda相关的报红色波浪线的地方都可以加上#include <cuda_runtime.h>,这样就可以愉快的CLion来运行和调试代码啦!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CUDA和C++混合编程及CMakeLists.txt 的相关文章

随机推荐

  • ARGB色彩空间模型:ARGB_8888、ARGB_4444、RGB_565、ALPHA_8、ARGB1555

    ARGB是一种色彩空间模式 由RGB色彩空间和Alpha通道组成 RGB即红 Red 绿 Green 蓝 Blue Alpha为透明度参数 数值为0 完全透明 无法被看见 数值为100 表示像素完全不透明 ARGB后跟的数字一般为字面意思
  • uni-app 2.2发布,大幅优化H5端性能体验

    背景 uni app发布以来 已经服务了几十万开发者 让我们意外 或者说惊喜的是 有大量开发者用uni app只编写H5版 并没有多端发布 可参考案例 这其实也符合uni app的初衷 uni app的定位并不是需要多端发布时才用uni a
  • uniapp上拉加载更多功能的简单实现

    https www cnblogs com huihuihero p 13206958 html
  • esp32-s2 wifi

    ESP32 S2 wifi 1 AP 无线接入点 网络的中心节点 无心路由器 这个路由器的特点是不能插入网络 没有接入Internet 只能等待其他设备的连接 只能智能接入 类似于点对点的连接 2 STA站点 每一个连接到无线网络的终端设备
  • 一个域名最多能对应几个IP地址?,一个IP地址可以绑定几个域名?

    一个域名最多能对应几个IP地址 一个IP地址可以绑定几个域名 谢谢 1 也就是说通常情况下一个域名同一时刻只能对应一个IP地址 但是在域名服务商那里 你可以把服务器群里面的多个提供相同服务的服务器IP设置一个域名可以轮询 但是同一时刻 一个
  • 微信小程序页面栈超出导致页面卡死

    微信小程序页面栈不能超出10个 超出10个之后无法进行点击选择跳转 解决方法 跳转的时候 判断之前页面栈里是否存在要跳转的页面 如果存在之前页面 就navigateBack返回之前页面 如果不存在之前页面 判断当前页面栈里是否到10个 如果
  • 软件和硬件数据交互接口的的演进

    编者按AMD Kria SOM及KV260视觉入门套件介绍 电子发烧友在线研讨会 软件和硬件 既相互依存又需要某种程度上的相互独立 通过软件和硬件之间的接口把两者连接在一起 软硬件接口 有很多含义 比如指令集是CPU软件和硬件之间的接口 比
  • PTA 4-1 计算分段函数[1]

    本题目要求计算下列分段函数f x 的值 输入格式 输入在一行中给出实数x 输出格式 在一行中按 f x result 的格式输出 其中x与result都保留一位小数 输入样例1 10 输出样例1 f 10 0 0 1 输入样例2 0 输出样
  • React import 配置路径别名‘@’,简化import Component的方式

    摘要 在react中 大多数业务逻辑都组件化 极大的减轻了代码的冗余度 如果组件的层次比较深的话 组件的import就比较费劲 在import时使用 components test 的方式 组件的import就会稍显混乱 组件代码不容易维护
  • 全国哀悼日,网站变黑白完美兼容IE,亲测有效

    首先在你的页面头部 里面加入如下代码 不加的话IE11就嗝屁了 然后在css文件里加入如下代码 body webkit filter grayscale 100 html webkit filter grayscale 100 moz fi
  • c++给出一个百分制成绩,输出等级‘A‘,‘B‘,‘C‘,‘D‘,‘E‘

    include
  • 利用Maven把项目生成jar包供其他项目使用

    每当搭建框架时 第一步就是为系统整理一个接一个的jar包 用多了就开始深思 如何把自己的项目也整成jar包 供他人使用呢 近期一直在看徐晓斌所著 Maven实战 因自己学识不够 只是简单理解了一些 但也受益颇深 下面介绍如何利用Maven把
  • 对区块链技术的一些新思考

    作者 朱金灿 来源 clever101的专栏 为什么大多数人学不会人工智能编程 gt gt gt 缘起 上周写了一篇 对区块链技术的一些思考 之后和一些朋友进行了交流 纠正了我之前的一些关于区块链的错误认识 重新认识区块链 在之前的文章中我
  • AngularJS的增删改查、state嵌套案例,不涉及服务端

    本篇实践一个案例 大致是 左边有导航菜单 右边显示列表 并可对列表项编辑或删除 也可添加新的列表项 借此 可体会到 如何组织可扩展的AngualrJS文件结构 如何点击左侧菜单项右侧显示相应内容 angular ui router的使用以及
  • zgrep查看前后几行日志

    zgrep C 10 a 关键字 error log 2021 09 02 tar gz C注意大写 标识前后10行的意思
  • 如何利用AJAX技术提高网站搜索引擎排名(4)

    四 使用XmlHttpRequest 如果你的用户主要使用Internet Explorer的较新版本或基于Gecko的浏览器 Mozilla Firefox Netscape 7 那么你可以决定使用XmlHttpRequest对象来把其它
  • 阴影LightMode = ShadowCaster

    阴影 实现原理 使用Shadow Map技术 把摄像机与光源位置重合 光源的阴影部分就是摄像机看不到的地方 前向渲染路径中 最重要的平行光如果开启了阴影 Unity就会为光源计算阴影映射纹理 shadowmap 本质就是深度图 记录光源出发
  • Android Studio出现:Your project path contains non-ASCII characters.

    公司设备需要自己开发安卓软件 我这就想自己研究下 开始想用IDEA 因为本身搞Java 后一番蒸腾没成功 在同事建议下装了Android Studio 4 X 一路跟着视频配置挺顺 没想到在创建项目上那里翻车了 如下图 自己没截图 用的别人
  • BitLocker自动解锁的密钥保存在哪里?

    当使用BitLocker加密Windows操作系统的系统分区时 可以选择让操作系统自动解锁系统盘 这通常需要将加密密钥保存在计算机上 以便系统能够自动解密系统盘并启动操作系统 在这种情况下 BitLocker会将密钥存储在计算机的TPM芯片
  • CUDA和C++混合编程及CMakeLists.txt

    1 概要 首先认识一个问题 单从CMakeLists txt的角度来看 无法同时使用两种编译器编译两种语言 不过直接编写Makefile是可以的 通过设置不同的任务 可以实现一个Makefile编译两个语言 但这不是这里要讨论的重点 使用C