canoe开发从入门到精通_xmake从入门到精通7:开发和构建Cuda程序
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验。
本文我们会详细介绍下如何通过xmake来构建cuda程序以及与c/c++程序混合编译。
- 项目源码
- 官方文档
准备环境
首先,我们需要安装NVIDIA提供的Cuda Toolkit SDK工具,其相关说明以及安装文档,可参考官方文档:CUDA Toolkit Documentation。
下载安装好Cuda SDK后,在macosx上会默认安装到/Developer/NVIDIA/CUDA-x.x目录下,Windows上可以通过CUDA_PATH的环境变量找到对应的SDK目录,而 Linux下默认会安装到/usr/local/cuda目录下。
通常,xmake都能自动检测到默认的cuda安装环境,并不需要做任何操作,只需要执行xmake命令就可以自动完成编译,当然如果找不到SDK,我们也可以手动指定Cuda SDK环境目录:
$ xmake f --cuda=/usr/local/cuda-9.1/
或者通过xmake g/global命令切到全局设置,避免每次切换编译模式都要重新配置一遍。
$ xmake g --cuda=/usr/local/cuda-9.1/
如果想要测试xmake对当前cuda环境的探测支持,可以直接运行:
$ xmake l detect.sdks.find_cuda{ linkdirs = { "/Developer/NVIDIA/CUDA-10.2/lib/stubs", "/Developer/NVIDIA/CUDA-10.2/lib" }, bindir = "/Developer/NVIDIA/CUDA-10.2/bin", sdkdir = "/Developer/NVIDIA/CUDA-10.2", includedirs = { "/Developer/NVIDIA/CUDA-10.2/include" } }
大家也可以帮忙贡献相关检测代码find_cuda.lua来改进xmake的检测机制。
创建工程
接下来,我们就可以创建一个空工程来快速体验下了,xmake自带了cuda的工程模板,只需要指定对应的语言即可创建cuda项目:
$ xmake create -l cuda testcreate test ... [+]: xmake.lua [+]: src/main.cu [+]: .gitignorecreate ok!
默认创建的cuda工程,就是一个最简单的基于Cuda的hello world工程,其源码结构如下:
├── src│ └── main.cu└── xmake.lua
而xmake.lua里面的内容我们也可以简单看下:
-- define targettarget("test") set_kind("binary") add_files("src/*.cu") -- generate SASS code for SM architecture of current host add_cugencodes("native") -- generate PTX code for the virtual architecture to guarantee compatibility add_cugencodes("compute_30")
可以看到,除了最基本的.cu源文件添加,跟其他c/c++项目唯一的区别就是多了个add_cugencodes()用来设置cuda需要的gencodes,关于这块,下面会详细讲解。
编译项目
工程创建好后,只需要简单的执行xmake即可完成编译。
$ xmake[00%]: ccache compiling.release src/main.cu[99%]: devlinking.release test_gpucode.cu.o[100%]: linking.release test
需要注意的是:从v2.2.7版本开始,xmake默认构建会启用device-link的构建行为,也就是说,现在编译过程中,会额外增加一步device-link过程:
[100%]: devlinking.release test_gpucode.cu.o
按照官方的说法,启用device-link设备代码链接的主要优点是可以为您的应用程序提供更传统的代码结构,尤其是在C++中,在现有项目结构不变的前提下,控制每个构建和链接步骤,方便快速的启用GPU代码,实现混合编译。
关于这块可参看NVIDIA的官方描述:Separate Compilation and Linking of CUDA C++ Device Code) 如果要禁用device-link的构建逻辑,可以通过add_values("cuda.devlink", false) 来设置禁用它。
当然,我们也可以尝试直接运行这个cuda程序:
$ xmake run
项目设置
并且如果设置了里面值为native,那么xmake会自动探测当前主机的cuda设备对应的gencode。
add_cuflags
这个接口主要用于添加cu代码相关的编译选项,我们如果还需要一些更加定制化的设置flags,那么就可以调用add_cuflags来直接设置更加原始的编译选项,就好比c/c++中的add_cxflags。
例如:
add_cuflags("-gencode arch=compute_30,code=sm_30")
add_culdflags
这个接口主要用于添加cuda设备链接选项,由于上文所说,2.2.7之后,xmake对于cuda程序的默认构建行为会使用device-link,这个阶段如果要设置一些链接flags,则可以通过这个接口来设置。 因为最终的程序链接,会使用ldflags,不会调用nvcc,直接通过gcc/clang等c/c++链接器来链接,所以device-link这个独立的链接阶段的flags设置,通过这个接口来完成。
add_culdflags("-gencode arch=compute_30,code=sm_30")
add_cugencodes
add_cugencodes()接口其实就是对add_cuflags("-gencode arch=compute_xx,code=compute_xx")编译flags设置的简化封装,其内部参数值对应的实际flags映射关系如下:
- compute_xx --> `-gencode arch=compute_xx,code=compute_xx`- sm_xx --> `-gencode arch=compute_xx,code=sm_xx`- sm_xx,sm_yy --> `-gencode arch=compute_xx,code=[sm_xx,sm_yy]`- compute_xx,sm_yy --> `-gencode arch=compute_xx,code=sm_yy`- compute_xx,sm_yy,sm_zz --> `-gencode arch=compute_xx,code=[sm_yy,sm_zz]`- native --> match the fastest cuda device on current host, eg. for a Tesla P100, `-gencode arch=compute_60,code=sm_60` will be added, if no available device is found, no `-gencode` flags will be added
例如:
add_cugencodes("sm_30")
就等价为
add_cuflags("-gencode arch=compute_30,code=sm_30")add_culdflags("-gencode arch=compute_30,code=sm_30")
是不是上面的更加精简些,这其实就是个用于简化设置的辅助接口。
而如果我们设置了native值,那么xmake会自动探测当前主机的cuda设备,然后快速匹配到它对应的gencode设置,自动追加到整个构建过程中。
例如,如果我们主机目前的GPU是Tesla P100,并且能够被xmake自动检测到,那么下面的设置:
add_cugencodes("native")
等价于:
add_cugencodes("sm_60")
Cuda/C/C++的混合编译
对于混合编译,我们只需要通过add_files接口继续加上对应的c/c++代码文件就行了,是不是很简单?
target("test") set_kind("binary") add_files("src/*.cu") add_files("src/*.c", "src/*.cpp") add_cugencodes("native")
编译设置
nvcc在编译内部的c/c++代码时候,其实会调用主机环境的c/c++编译器来编译,比如linux下会默认使用gcc/g++,macos下默认使用clang/clang++,windows上默认使用cl.exe。 如果想要让nvcc采用其他的编译器,比如在linux下改用clang作为默认的c/c++编译器,则需要指定--ccbin=参数设置,这块可以看下:compiler-ccbin
而在xmake中,也对其进行了支持,只需要设置xmake f --cu-ccbin=clang 就可以切换到其他编译器。
还有两个跟cuda相关的编译参数,我就简单介绍下:
xmake f --cu=nvcc --cu-ld=nvcc
其中--cu用来设置.cu代码的编译器,默认就是nvcc,不过clang现在也支持对.cu代码的编译,可以切换设置来尝试,--cu-ld是设置device-link的链接器,而最终的整体程序link过程,还是用的--ld来链接的。
canoe开发从入门到精通_xmake从入门到精通7:开发和构建Cuda程序相关推荐
- Elasticsearch7从入门到精通(简介、部署、原理、开发、ELK)
Elasticsearch7从入门到精通(简介.部署.原理.开发.ELK) 第1章.Elasticsearch简介 1-1.Elasticsearch介绍 Elasticsearch官方网站:http ...
- 【作废】Inventor 二次开发学习指南入门到精通(含Inventor最新二次开发教程下载)
(由于AU中国已关闭,很多链接失效,而且有些内容需要更新.特作废此文,另外撰写一篇新的) 年初我曾撰写了一篇文章,登载到我同事的博客,以及AU中国.我想这篇作为本博客的第一篇正式技术文章,应该是最合适 ...
- 大数据开发是做什么的?怎样入门?
其实现在有很多小伙伴看中了大数据的发展前景,但是其实不知道大数据开发具体是做什么的,又该怎么学习?学习了之后又该做什么? 下面具体给你分析下大数据开发是做什么的,又需要学习和掌握哪些技能~ 大数据开发 ...
- python适合开发区块链吗_区块链入门开发语言选择 python适合开发区块链吗
区块链用什么需要开发?在哪可以了解? 从现在各个公有链的使用情况来看,来一代的都是参考Bitcoin,使用C 开发,而新一代的区块链技术使用的语言则是Go,Python,C#和JavaScript.以 ...
- Java如何快速入门?Java初学者从入门到精通必看!
作为刚刚接触Java的小白来说,最担心的应该就是Java怎么学,都需要掌握哪些内容?今天这篇文章希望能帮助大家快速入门Java,少走弯路! 如何快速入门Java? 一.作为刚接触Jav ...
- Struts 2创始人Patrick Lightbody看《精通Struts 2:Web 2.0开发实战 》
<精通Struts 2:Web 2.0开发实战 > Apache Struts是目前最成功开源项目之一.除了一些基础性项目如Linux.MySQL以及若干编程语言外,很少有开源框架能像St ...
- PHP入门《PHP程序设计案例教程》——PHP网站开发
PHP入门<PHP程序设计案例教程>--PHP网站开发 web表单设计 表单数据获取和提交 1.GET方法 2.POST方法 超链接数据的获取 SESSION管理 SESSION原理 使用 ...
- C#语言入门、xamarin基础、.NET MAUI全栈开发技术综合笔记
文章目录 前言: 一.C#语言入门 1.类 类的三大成员 属性(Property) 方法(Method) 事件(Event) 2.静态成员与实例成员 3.类型.变量和方法 3.1类型(Type) 3. ...
- 5G时代来临,前端开发工程师必须了解的音视频入门基础知识
1. 音视频基础 本文将给大家进行音视频基础的常规知识点的梳理.当然,短短的一篇文章并不能让大家立即变成音视频领域的专家,但这些知识点已经基本涵盖了音视频的入门知识.我们将按照下面的内容给大家 音视频 ...
最新文章
- jvm调优工具_JVM性能调优监控工具jps、jstack、jmap、jhat、hprof使用详解
- 数据蒋堂 | 迭代聚合语法
- phpMyAdmin安装部署
- jQuery Mobile 1.1八大新特性介绍
- 没有主清单属性_原神:晴知的主C诺艾尔大型进阶攻略初版
- 把enum绑定到ComboBox
- Mysql不能远程连接的解决方法
- 95-872-050-源码-CEP-CEP之模式流与运算符
- OpenShift 4 - 为Gogs构建一个Operator
- AutoFac IoC DI 依赖注入
- git push 出现 you are not allowed to upload merges 错误提示
- C# 实现打开和关闭可执行文件
- AS解决在导入library之后lable/icon/theme合并出现bug
- 2020-8-6 Codeforces摸鱼报告
- 大白话式粗浅地聊聊NLP语言模型
- Python 从函数 def 到类 Class
- 索引算法原理解析(B-tree以及磁盘存储原理)
- axis.jar的应用
- 解决debian xmms乱码
- 算法导论-上课笔记11:单源最短路径