本文主要是介绍英特尔oneAPI—DPCT 移植 CUDA 程序方法、示例及注意事项,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
oneAPI 提供了 DPCT 工具来移植 CUDA 程序,官方称可以移植 95 %的 CUDA 程序。实际体验下来,在自动生成的代码有一些小的语法上错误,需要做一些修正才可正常使用。暂时感觉 AMD 的 hipify 转出来的程序需要修改的内容更少。毕竟 C 语言转 C++ 难度挺大的。可以通过以下途径获取和安装 DPCT:
- 安装 Intel OneAPI Base Toolkit 。
- 单独安装 DPCT。
DPCT 的使用方式
移植单个 CUDA 文件
单个文件时,对 CUDA 程序进行迁移十分的简单,只需要输入下面的命令行即可完成迁移:
dpct --in-root=. src/<cuda_source_code>.cu --cuda-include-path=<path>/cuda/include
其中cuda_source_code
文件为需要转换的 CUDA 程序。--cuda-include-path
后加 CUDA 头文件的路径。
移植 CUDA 工程
在实际的 CUDA 项目开发中,一般都是通过 Makefile 或者 CMake 来管理工程。DPCT 同样也支持直接对上述方式管理的 CUDA 工程进行移植。不用用户一个一个的将 CUDA 程序进行迁移。
Makefile工程
第一步:intercept
使用 DPCT 内置的 intercept-build 指令,可以自动的生成 DPCT 所能支持 compile_commands.json
文件,方便 DPCT 进行转化。
make clean
intercept-build make
在当前文件假下会生成 compile_commands.json
文件。
倘若当前项目已经构建完成了,需要先执行make clean,否则会无法移植。
第二步:使用 DPCT 进行移植
使用DPCT的-p
选项和第一步生成的compile_commands.json
文件来将 CUDA 程序转为 DPC++ 程序。
dpct --in-root=. -p compile_commands.json --cuda-include-path=<path>/cuda/include
示例
以 cuda 经典入门程序 VectorAdd 为例。
首先使用intercept-build make
来生成compile_commands.json
,再用dpct
生成相对应的 oneAPI 代码。在我的环境下输入如下指令即可:
intercept-build make
dpct --in-root=. -p compile_commands.json --cuda-include-path=/opt/cuda/include
需要根据自己环境配置路径
CMake工程
先使用 cmake 指令生成相应的 Makefile 文件,其余步骤与上一章节相同。
其他重要的 Options
- –assume-nd-range-dim=,值为1、3,默认的情况下dpct是将程序转为三维 nd-range,对于一些简单的 CUDA 程序,我们指定为 1,更加方便理解。
- –optimize-migration,调用后会尽可能优化程序。
- –out-root,指定输出文件夹的路径。
- –usm-level,指定是否 usm,oneAPI 中的 usm 相当于 CUDA 的 Unified Memory,若为 Restricted 则使用 usm,若为 none 则不使用。
CUDA 与 oneAPI 对应概念
编程模型
CUDA | thread | wrap | block | grid |
---|---|---|---|---|
DPC++(oneAPI) | work item | sub group | work group | nd range |
OpenCL | work item | sub group | work group | nd range |
数据管理模型
CUDA | shared | Unified Memory | _syncthreads |
---|---|---|---|
DPC++(oneAPI) | local | Unified Shared Memory | barrier |
OpenCL | local | Unified Shared Memory | barrier |
onoAPI 在 CPU 上的映射
注意事项
oneAPI 暂不支持的内容
头文件
所有 CUDA helper头文件,oneAPI 暂时不支持,当然,也可以直接将相应的 helper 代码复制到工程中来,从而使得 DPCT 将其转化为 DPC++代码。
#include <helper_functions.h>
#include <helper_strings.h>
#include <helper_cuda.h>
...
API
因为 CUDA 和 DPC++ 的编程模型和风格的不同,导致了 DPC++ 缺失一部分的 API。但是,总体都有相应的替换方法。
//CUDA
checkCudaError(...);
//cublas
cublasCreate(...);
cublasDestory(...);
此处关于第一个API,有一个很好的移植方法,就是使用
try{...} catch(...){exit(-1)}
的方法对要检测的内容进行包裹。
参考资料和扩展阅读
- Migrate Your Existing CUDA Code to Data Parallel C++ (intel.com)
- 官方诊断信息以及修改建议
这篇关于英特尔oneAPI—DPCT 移植 CUDA 程序方法、示例及注意事项的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!