使用musify对代码进行平台迁移

  更多内容请访问摩尔线程博客中心

1. 引言

近些年,NVIDIA及其CUDA生态占据着GPGUP的领先地位,国产厂商也在奋力追赶。基于现实的考量,追赶者们需要尊重业界现存大量CUDA代码的事实,因此我们推出了musify这一工具,旨在尽量将原有的CUDA代码便捷无痛地转化,迁移至MUSA平台上编译运行,从而达到间接兼容的效果。

2. 如何使用musify

2.1. 安装依赖

musify使用python编写,要运行musify首先需要系统中安装有python3,然后假设用户使用ubuntu为例,执行以下命令

# 使得python默认指向python3
sudo apt install python-is-python3 -y
# 安装python依赖管理工具
sudo apt install pip -y              
# 如果最后一行依赖库安装存在网络问题可以按需配置更新源,取消下一行的注释是一种可行的选择
# pip config set global.index-url https://pypi.mirrors.ustc.edu.cn/simple/
# 安装musify的依赖库
pip install ahocorapy

2.2. 帮助信息

和一般的命令行程序一样,musify通过-h/--help提供了帮助信息,有经验的用户可以直接参考帮助信息进行使用

$ musify-text -h
usage: musify-text [-h] [-t | -c | -i] [-d {c2m,m2c}] [-m [MAPPING ...]] [--clear-mapping] [-l {DEBUG,INFO,WARNING}] [srcs ...]
 
positional arguments:
  srcs                  source files to be transformed
 
options:
  -h, --help            show this help message and exit
  -t, --terminal        print code to stdout
  -c, --create          write code to newly created file, default action
  -i, --inplace         modify code inplace
  -d {c2m,m2c}, --direction {c2m,m2c}
                        convert direction
  -m [MAPPING ...], --mapping [MAPPING ...]
                        api mapping
  --clear-mapping       clear default and previous mapping
  -l {DEBUG,INFO,WARNING}, --log-level {DEBUG,INFO,WARNING}
                        lowest log level to display

如上信息,本工具的使用方式是先设置一系列的选项,最后跟着需要转化的代码文件列表

以下是对选项的详细解释:

  • -t-c-i是输出方式,使用时三选其一;分别为输出到屏幕,另外新建文件,直接修改原来的代码文件;默认行为是新建文件输出(但是如果代码有版本管理等保护,使用-i/--inplace直接原地修改比较方便)
  • -d设置方向c2m是cuda至musa,m2c是musa至cuda;默认为cuda至musa
  • -m指定替换使用的映射表,是映射表是json文件,内容为单层无嵌套的json object,其中每个name,value对分别表示相应的cuda和musa命名;一般不用指定使用默认即可,如果有特殊需求可自己生成映射表并指定,如果有多个映射表,使用如下格式-m a.json m b.json,即每个映射表前都有一个前置的-m
  • -m会添加新的映射表,不会覆盖原有的默认映射表,如果不想要默认映射表,需要使用--clear-mapping,然后在这个选项右边使用-m指定自己想要的映射表
  • -l指定日志等级,高于设置等级的日志都会被打印出来,默认为INFO

前面的选项顺序可以随意调整,如果使用默认值也可以不写,但是需要转化的代码文件必须跟在最后;同时为了防止存在以-开头的文件路径被识别为选项,在所有选项之后,文件路径之前,加上--

2.3. 使用示例

经过了如上的解释后,我们可以来到一个最简单的例子,使用默认映射表,默认转化方向(cuda至musa),只有输出方式改为了原地修改

如下命令修改了当前目录下的a.cpp和b.cpp两个文件

musify-text --inplace -- a.cpp b.cpp

但是一般而言,我们并不想手动列举需要转化的文件,一般一个项目有大量的代码文件需要转化,此时我们可以借助shell的``语法和一些第三方的文件搜索工具,比如

# 递归查找目录${DIR}下所有后缀名为cu,cuh,cpp或h的文件并转化
musify-text --inplace -- `find ${DIR} -name '*.cu' -name '*.cuh' -name '*.cpp' -name '*.h'`

同时我们可以推荐一些更加现代化的工具

# 安装此处使用的工具
sudo apt install ripgrep -y
# 如果没有自己编写kernel,cuda程序可以是纯C/C++代码,ripgrep对于cpp的后缀名自带预设,-tcpp就可以调用,rg --files则递归搜索指定目录下所有符合要求的文件
musify-text --inplace -- `rg --files -tcpp ${DIR}`
# ripgrep没有内置cuda的后缀模式,但是我们可以通过--type-add指定,然后再当场调用
musify-text --inplace -- `rg --files --type-add 'cuda:*.cu' --type-add 'cuda:*.cuh' -tcuda -tcpp ${DIR}`
# 如果嫌上面两种复杂,也可以使用-g选项直接指定后缀名,和前面的find作用基本一致
musify-text --inplace -- `rg --files -g '*.cu' -g '*.cuh' -g '*.cpp' -g '*.h' ${DIR}`

2.4. 排除标记

可能有不少读者注意到了musify的命令名称为musify-text,其实这是因为它的算法是单纯的文本匹配。

这种实现方案的原因主要是发现语法分析会引入过重的依赖(尤其对C++这种上下文相关文法),给用户的使用带来不便,纯粹文本匹配的工具更加小巧灵活。

当然这样带来了一定的转化可能不够智能的问题,于是我们加入了类似于lcov行覆盖率工具的排除标记功能,可以标记一定范围的代码不受转化影响,保持原样。

使用排除标记需要一定程度上修改原有代码,加入排除标记。

MUSIFY_EXCL_LINE
包含本标记的行会被排除
MUSIFY_EXCL_START
从包含本标记的行开始,直到MUSIFY_EXCL_STOP之间的行会被排除;当前行也会被排除
MUSIFY_EXCL_STOP
结束由MUSIFY_EXCL_START开启的排除;当前行不会被排除

其中START和STOP成对使用

// MUSIFY_EXCL_START
char *str_array[] = {
    "cuInit",
    "cuMalloc"
};
// MUSIFY_EXCL_STOP

LINE单独使用

char str[] = "cuInit"; // MUSIFY_EXCL_LINE

3. 总结与展望

本文介绍了musify的设计意图,使用方法和当前的缺陷。可能有不少读者也意识到如果没有其他不同版本需要加以区分,单纯因为使用了文本匹配就将工具叫做musify-text是不充分的;事实上,介于语法分析过重,文本匹配不够智能,目前存在一个后续计划是引入词法分析进行一定的代码分析识别,准备使用musify-lexer作为命令名称。

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值