musify 一键代码迁移
什么是 musify?
musify 是摩尔线程推出的一款 CUDA 到 MUSA 一键代码迁移工具,属于 MUSA Toolkits 的一部分。musify 通过命令行工具 musify-text 提供服务,采用纯文本匹配的方式进行代码转换,实现:
- 轻量级: 避免语法分析引入过重的依赖
- 易部署: 无需复杂的编译器基础设施
- 灵活快速: 工具小巧灵活
注意
由于仅基于文本匹配,musify 无法理解代码语义,可能会误改不该转换的内容。你可以在代码中添加排除标记(exclude markers),明确告诉工具哪些部分跳过处理。
主要特性
- 自动转换 - 自动将 CUDA API 调用转换为 MUSA API
- 语法兼容 - 支持 CUDA C/C++ 语法转换
- 批量处理 - 支持批量转换多个源文件
- 原地转换 - 支持
--inplace模式直接修改源文件 - 双向转换 - 支持 CUDA→MUSA 和 MUSA→CUDA 双向转换
- 自定义映射 - 支持用户自定义 API 映射表
快速开始
安装
安装 MUSA SDK 后,musify-text 命令即可使用。
tip
如果需要在其他机器上单独使用 musify,或者 SDK 安装有问题,可以手动安装依赖。
(可选)手动安装依赖
musify 使用 Python 编写,需要系统中安装有 Python 3。
# Ubuntu 系统安装依赖
sudo apt install python-is-python3 -y
sudo apt install pip -y
pip install ahocorapy
# 如遇网络问题,可配置国内镜像源
pip config set global.index-url https://pypi.mirrors.ustc.edu.cn/simple/
基本示例
# 转换单个文件(输出到新文件,默认行为)
musify-text source.cu
# 原地转换(直接修改源文件)
musify-text --inplace source.cu
# 输出到标准输出
musify-text --terminal source.cu
# 转换多个文件
musify-text --inplace -- *.cu
转换示例
CUDA 源代码 (source.cu):
#include <cuda_runtime.h>
__global__ void vector_add(float* a, float* b, float* c, int n) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) {
c[idx] = a[idx] + b[idx];
}
}
int main() {
float *d_a, *d_b, *d_c;
cudaMalloc(&d_a, N * sizeof(float));
cudaMalloc(&d_b, N * sizeof(float));
cudaMalloc(&d_c, N * sizeof(float));
vector_add<<<grid, block>>>(d_a, d_b, d_c, N);
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
return 0;
}
转换后 MUSA 代码:
#include <musa_runtime.h>
__global__ void vector_add(float* a, float* b, float* c, int n) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) {
c[idx] = a[idx] + b[idx];
}
}
int main() {
float *d_a, *d_b, *d_c;
musaMalloc((void**)&d_a, N * sizeof(float));
musaMalloc((void**)&d_b, N * sizeof(float));
musaMalloc((void**)&d_c, N * sizeof(float));
vector_add<<<grid, block>>>(d_a, d_b, d_c, N);
musaFree(d_a);
musaFree(d_b);
musaFree(d_c);
return 0;
}
编译转换后的示例
# 转换
musify-text --inplace source.cu
# 重命名为 .mu 后缀
mv source.cu source.mu
# 编译
mcc source.mu -lmusart -L/usr/local/musa/lib -o app
命令行选项
帮助信息
$ 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, --terminal | 输出到标准输出(stdout) |
-c, --create | 写入新文件(默认行为) |
-i, --inplace | 原地修改源文件 |
-d, --direction | 转换方向:c2m(CUDA→MUSA)或 m2c(MUSA→CUDA) |
-m, --mapping | 指定映射表 JSON 文件(可多个) |
--clear-mapping | 清除默认映射表,只用 -m 指定的 |
-l, --log-level | 日志级别(DEBUG/INFO/WARNING) |
重要提示
- 输出方式三选一:
-t、-c、-i必须选择其一 - 文件路径保护:在所有选项之后、文件路径之前,加上
--,防止以-开头的文件路径被识别为选项 - 映射表叠加:
-m会添加新的映射表,不会覆盖默认映射表 - 映射表格式:JSON 文件,内容为单层无嵌套的 JSON Object,每个 name-value 对分别表示相应的 CUDA 和 MUSA 命名
{
"cudaMalloc": "musaMalloc",
"cudaFree": "musaFree",
"cudaMemcpy": "musaMemcpy"
}