0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用CMake工具套件构建CUDA应用程序

星星科技指导员 来源:NVIDIA 作者:wnger 2022-04-01 17:42 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

跨平台软件开发对应用程序的构建过程提出了许多挑战。如何针对多个平台而不维护多个平台特定的构建脚本、项目或生成文件?如果您需要构建 CUDA 代码作为过程的一部分呢? CMake 是一个开源、跨平台的工具系列,旨在跨不同平台构建、测试和打包软件。许多开发人员使用 CMake 来使用简单的独立于平台和编译器的配置文件来控制他们的软件编译过程。 CMake 生成可在您选择的编译器环境中使用的本机 makefile 和工作区。 CMake 工具套件是由 Kitware 创建的,是为了响应对 ITK 和 VTK 等开源项目的强大、跨平台构建环境的需求。

图 1 。 CGED 将 CUDA C ++添加到支持的编程语言的长列表中。

在这篇文章中,我想向您展示使用 cmake3 . 8 +( 3 . 9 支持 MSVC )的特性来构建 CUDA 应用程序是多么容易。从 2009 年起, CMake (从 2 . 8 . 0 开始)就提供了通过 Find CUDA 包提供的cuda_add_executablecuda_add_library等自定义命令编译 CUDA 代码的能力。 CGEASE 3 . 8 使 CUDA C ++成为一种本质上支持的语言。 CUDA 现在加入了 CMake 支持的各种语言、平台、编译器和 ide ,如图 1 所示。

CMake 中的一个 CUDA 示例

让我们从一个用 CMake 构建 CUDA 的例子开始。清单 1 显示了名为“ particles ”的 CUDA 示例的 CMake 文件。我已经在 Github 上提供了此示例的完整代码

cmake_minimum_required(VERSION 3.8 FATAL_ERROR)

project(cmake_and_cuda LANGUAGES CXX CUDA)



include(CTest)



add_library(particles STATIC

  randomize.cpp

  randomize.h

  particle.cu

  particle.h

  v3.cu

  v3.h

  )



# Request that particles be built with -std=c++11

# As this is a public compile feature anything that links to

# particles will also build with -std=c++11

target_compile_features(particles PUBLIC cxx_std_11)



# We need to explicitly state that we need all CUDA files in the

# particle library to be built with -dc as the member functions

# could be called by other libraries and executables

set_target_properties( particles

                       PROPERTIES CUDA_SEPARABLE_COMPILATION ON)



add_executable(particle_test test.cu)



set_property(TARGET particle_test

             PROPERTY CUDA_SEPARABLE_COMPILATION ON)

target_link_libraries(particle_test PRIVATE particles)



if(APPLE)

  # We need to add the path to the driver (libcuda.dylib) as an rpath,

  # so that the static cuda runtime can find it at runtime.

  set_property(TARGET particle_test

               PROPERTY

               BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})

endif()

在我完成清单 1 所示的所有逻辑和特性之前,让我们先跳过构建。如果您使用 VisualStudio ,则需要使用 CGuess 3 . 9 和 VisualStudio CUDA 构建扩展(包含在 CUDA 工具包中),否则您可以使用生成文件生成器(或忍者生成器)nvcc( NVIDIA CUDA 编译器)和 C ++编译器在您的路径中使用 CMASE 3 . 8 或更高。(或者,您可以将CUDACXXCXX环境变量分别设置为nvcc和 C ++编译器的路径)。

minus.png
Y您可以使用CUDAHOSTCXX环境变量显式指定与NVCC一起使用的主机编译器。(这将控制NVCC-ccbin选项。)

Figure 2. Building a static library and executable which uses CUDA and C++ with CMake and the Makefile generator.

图 2 。构建一个静态库和可执行文件,它使用 CUDA 和 C ++与 CMake 和 Mag 文件生成器。

为了配置 CMake 项目并生成一个 makefile ,我使用了以下命令

cmake -DCMAKE_CUDA_FLAGS=”-arch=sm_30” .

图 1 显示了输出。 CMADE 自动发现并验证 C ++和 CUDA 编译器并生成一个 MaMaFrimeProject 。注意,参数-DCMAKE_CUDA_FLAGS="-arch=sm_30"-arch=sm_30传递给nvcc,告诉它以我计算机中的开普勒体系结构( SM _ 30 或 ComputeCapability 3 . 0 ) GPU 为目标。

接下来,图 1 显示了我如何使用命令make -j4调用构建。这运行了make多个线程,因此它并行编译 C ++和 CUDA 源文件。有关 CMake 如何确定在项目中的何处查找并行性的更多信息,请阅读““用你所有的核心来建设”。 CMake 还可以自动管理将多种语言构建和链接到可执行文件或共享库中。

启用 CUDA

让我们深入研究 CMake 代码并研究不同的组件。和往常一样,根 CMake 文件中的第一个命令应该是cmake_minimum_required,它断言 CMake 版本足够新,并确保 CMake 可以确定当用户运行的 CMake 版本比需要的版本更新时,它需要保留哪些向后兼容性。

minus.png
通过将– CUDA rt { none |共享|静态}设置为– CUDA rt { none |共享|静态},可以指定所有 CUDA 目标将在项目内部使用的运行时。例如,要使用静态 CUDA 运行时库,请将其设置为– CUDA rt 静态

接下来,第 2 行是 Project 命令,它设置项目名称(cmake_and_cuda)并定义所需语言( C ++和 CUDA )。这使 CMake 能够识别和验证所需的编译器,并缓存结果。这将生成图 3 所示的公共缓存语言标志。

图 3 。当启用 CUDA 时, CMake 为每个配置提供默认标志(调试、发布、 RelWithDebInfo 和 MinSizeRel)

既然 CMake 已经确定了项目需要什么语言,并且配置了它的内部基础设施,我们就可以继续编写一些真正的 CMake 代码了。

用 CMake 建立图书馆

学习 CMake 时,每个人做的第一件事就是编写一个生成单个可执行文件的玩具示例就像这个。让我们更大胆一点,并生成一个可执行文件使用的静态库。

使用要求是现代 CMake 的核心。 include 目录、编译器定义和编译器选项等信息可以与目标相关联,这样这些信息就可以通过target_link_libraries自动传播给使用者。在 CMake 的早期版本中,构建 CUDA 代码需要命令,比如cuda_add_library。不幸的是,这些命令无法参与使用需求,因此无法使用传播的编译器标志或定义。 CMake 中现在对 CUDA 的内在支持使使用 CUDA 的目标能够充分利用现代 CMake 使用需求,并为所有语言提供统一的 CMake 语法。

C ++语言层

在一个项目中,首先要配置的事情之一是 C ++语言级别( 98 , 11 , 14 , 17 …)。 CGuSE 3 . 1 介绍了为整个项目或基于每个目标的基础来设置 C ++语言级别的能力。还可以控制 CUDA 编译的 C ++语言级别。

您可以通过CMAKE_CUDA_STANDARDtarget_compile_features命令轻松地要求特定版本的 CUDA 编译器。为了使target_compile_features更容易与 CUDA 一起使用, CMake 使用了 CUDA C ++的同一组 C ++特征关键字。下面的代码展示了如何请求 C ++ 11 对particles目标的支持,这意味着粒子目标所使用的任何 CUDA 文件都会被 CUDA C ++ 11 启用(--std=c++11参数]nvcc]编译。

# Request that particles be built with --std=c++11

# As this is a public compile feature anything that links to particles

# will also build with -std=c++11

target_compile_features(particles PUBLIC cxx_std_11)

启用位置无关代码

在处理大型项目时,通常会生成一个或多个共享库。作为共享库一部分的每个对象文件通常都需要在启用位置独立代码的情况下进行编译,这是通过设置fPIC编译器标志来完成的。不幸的是,并非所有编译器都支持fPIC,因此 CMake 在构建共享库时自动启用位置无关的代码,从而避免了这个问题。对于将链接到共享库的静态库,需要通过如下设置POSITION_INDEPENDENT_CODEtarget 属性显式地启用位置无关的代码。

set_target_properties(particles PROPERTIES POSITION_INDEPENDENT_CODE ON)

CMake 3 . 8 支持 CUDA 编译的POSITION_INDEPENDENT_CODE属性,并在请求时构建所有可重新定位的主机端代码。对于那些希望在跨平台项目或内部共享库中使用 CUDA 的项目,或者希望支持深奥的 C ++编译器的项目,这是一个好消息。

可分离汇编

默认情况下, CUDA 编译器使用整个程序编译。实际上,这意味着所有设备函数和变量都需要位于单个文件或编译单元中。单独编译和链接是在 CUDA 5 . 0 中引入的,它允许将 CUDA 程序的组件编译成单独的对象。为了使其正常工作,任何使用可分离编译的库或可执行文件都有两个链接阶段。首先它必须为包含 CUDA 设备代码的所有对象执行设备链接,然后必须执行主机端链接,包括上一个链接阶段的结果。

可分离编译不仅允许项目维护一个代码结构,其中独立的函数被保存在不同的位置,它还有助于提高增量构建性能(所有基于 CMake 的项目的一个特性)。增量构建只允许重新编译和链接已修改的单元,这减少了构建时间。可分离编译的主要缺点是,对于驻留在不同编译位中的函数的调用,某些函数调用优化被禁用,因为编译器不知道被调用函数的详细信息。

CMake 现在基本上理解了独立编译和设备链接的概念。隐式地, CMake 会尽可能长时间地延迟 CUDA 代码的设备链接,因此,如果您使用可重定位的 CUDA 代码生成静态库,则设备链接将被推迟,直到静态库链接到共享库或可执行文件。这是一个显著的改进,因为现在可以将 CUDA 代码组合到多个静态库中,这在 CMake 中以前是不可能的。要控制 CMake 中的可分离编译,请按如下方式打开目标的CUDA_SEPARABLE_COMPILATION属性。

set_target_properties(particles PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

info.png 高级提示
minus.png
如果需要在共享库或可执行文件使用之前发生可分离编译设备链接,则可以通过设置 target 属性CUDA_RESOLVE_DEVICE_SYMBOLS显式请求 CMake 调用设备链接。

PTX 生成

如果要将 PTX 文件打包用于加载时 JIT 编译,而不是将 CUDA 代码编译到库或可执行文件的集合中,则可以启用CUDA_PTX_COMPILATION属性,如下例所示。本例将一些.cu文件编译为 PTX ,然后指定安装位置。

add_library(CudaPTX OBJECT kernelA.cu kernelB.cu)

set_property(TARGET CudaPTX PROPERTY CUDA_PTX_COMPILATION ON)



install(TARGETS CudaPTX

   OBJECTS DESTINATION bin/ptx

)

为了使 PTX 生成成为可能,对 CMake 进行了扩展,以便所有对象库都能够在生成器表达式中安装、导出、导入和引用。这也使得 PTX 文件能够被 bin2c 等工具转换或处理,然后作为 C 字符串嵌入到库或可执行文件中。这是一个基本的例子

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73151
  • 应用程序
    +关注

    关注

    38

    文章

    3342

    浏览量

    59926
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    使用vscode和cmake工具开发极海G32R501 MCU

    目前极海官方提供的 IDE 开发环境有 Keil/IAR/Eclipse。都能很好的完成开发,但是 VS Code 配合 CMake 工具是更加“现代”的C/C++开发环境,本文提供了在 VS Code 环境下的开发经验,以供参考。
    的头像 发表于 11-25 14:45 2664次阅读
    使用vscode和<b class='flag-5'>cmake</b><b class='flag-5'>工具</b>开发极海G32R501 MCU

    PYQT 应用程序框架及开发工具

    大家好,本团队此次分享的内容为开发过程中使用到的PYQT 应用程序框架及开发工具。 pYqt 是一个多平台的 python 图形用户界面应用程序框架,由于其面向对象、 易扩展(可实现组件编程等
    发表于 10-29 07:15

    【CPKCOR-RA8D1】1、VSCODE+CMAKE开发环境搭建

    Smart Configurator是一款自动生成微控制器初始配置程序工具。通过本工具提供的基础管脚配置功能和GUI,用户可以轻松添加和配 置驱动程序和中间件,为正在开发的
    发表于 10-09 16:17

    学生适合使用的SOLIDWORKS 云应用程序

    SOLIDWORKS云应用程序如何满足学生的需求,并介绍其关键功能和优势。 SOLIDWORKS云应用程序是SOLIDWORKS软件与3DEXPERIENCE平台云端设计应用程序和人工智能设计辅助
    的头像 发表于 09-15 10:39 528次阅读
    学生适合使用的SOLIDWORKS 云<b class='flag-5'>应用程序</b>

    SEGGER工具链集成到CMake和VS Code了

    SEGGER公司已将其嵌入式开发工具链集成到了广泛使用的CMake构建配置工具中,这意味着基于Visual Studio Code(VS Code)代码编辑器的应用开发可以方便的使用S
    的头像 发表于 07-23 15:06 775次阅读

    使用英特尔® NPU 插件C++运行应用程序时出现错误:“std::Runtime_error at memory location”怎么解决?

    使用OpenVINO™工具套件版本 2024.4.0 构建C++应用程序 使用英特尔® NPU 插件运行了 C++ 应用程序 遇到的错
    发表于 06-25 08:01

    请问是否可以在通用Windows平台中构建OpenVINO™ GenAI C++ 应用程序

    无法在通用 Windows 平台中构建OpenVINO™ GenAI C++ 应用程序
    发表于 06-24 07:35

    如何在 Raspberry Pi AI Camera 上构建为开发人员提供实时的智能应用程序

    在这篇特邀文章中,我们的合作伙伴索尼公司的雷蒙娜-雷纳(RamonaRayner)将向您展示如何快速探索不同的模型和人工智能功能,以及如何在RaspberryPi人工智能相机的基础上轻松构建应用程序
    的头像 发表于 03-25 09:37 614次阅读
    如何在 Raspberry Pi AI Camera 上<b class='flag-5'>构建</b>为开发人员提供实时的智能<b class='flag-5'>应用程序</b>!

    如何部署OpenVINO™工具套件应用程序

    编写代码并测试 OpenVINO™ 工具套件应用程序后,必须将应用程序安装或部署到生产环境中的目标设备。 OpenVINO™部署管理器指南包含有关如何轻松使用部署管理器将
    发表于 03-06 08:23

    构建开源OpenVINO™工具套件后,模型优化器位于何处呢?

    构建开源OpenVINO™工具套件后,模型优化器位于何处?
    发表于 03-06 08:18

    请问OpenVINO™工具套件中的验证应用程序是什么?

    OpenVINO™工具套件中的验证应用程序是什么?
    发表于 03-06 06:54

    安装OpenVINO™适用于Raspberry Pi64位操作系统的工具套件2022.3.1,配置英特尔®NCS2时出错怎么解决?

    安装OpenVINO™适用于 Raspberry Pi* 64 位操作系统的工具套件 2022.3.1。 配置英特尔® NCS2时出错: CMake Error at CMakeLists.txt
    发表于 03-05 07:27

    应用程序工具套件集成到Unity 3D OpenVINO™过程中遇到\"DLLNotFound异常\"错误怎么解决?

    在将 OpenVINO™工具套件与 Unity 3D* 集成期间,Unity 3D 编辑器无法找到 OpenVINO 工具套件的依赖性,并引发 DLLNotFoundException
    发表于 03-05 06:22

    使用Ozone调试基于nRF9160 Zephyr应用程序

    Ozone是SEGGER免费的嵌入式软件调试器。它是一个强大的工具,可以让你深入了解嵌入式系统中发生的事情。它在调试nRF9160 Zephyr应用程序时特别有用。整理多个线程和多映像构建可能很困难,但这就是你想要的
    的头像 发表于 02-25 17:07 1425次阅读
    使用Ozone调试基于nRF9160 Zephyr<b class='flag-5'>应用程序</b>

    基于HPM_SDK_ENV开发应用程序的升级处理

    基于HPM_SDK_ENV开发应用程序的方式HPM_SDK_ENV是先楫半导体MCU的Windows集成开发环境,其包含HPM_SDK,工具链,依赖工具(cmake,ninja,ope
    的头像 发表于 02-08 13:38 1439次阅读
    基于HPM_SDK_ENV开发<b class='flag-5'>应用程序</b>的升级处理