已合并
项目readme大纲结构调整 #719
liu-wei创建于 4月15日
项目readme大纲结构调整 #719
已合并
共 17 个文件变更+915-930
| @@ -10,78 +10,45 @@ | |||
| 10 | 10 | ||
| 11 | ## 🚀概述 | 11 | ## 🚀概述 |
| 12 | 12 | ||
| 13 | -ops-cv是[CANN](https://hiascend.com/software/cann) (Compute Architecture for Neural Networks)算子库中提供图像处理、目标检测等能力的高阶算子库,涵盖常见的图像处理操作,包括image类、objdetect类算子,算子库架构图如下: | 13 | +ops-cv是[CANN](https://hiascend.com/software/cann) (Compute Architecture for Neural Networks)算子库中提供图像处理、目标检测等能力的高阶算子库,包括image类、objdetect类算子,覆盖常见的图像处理操作,子库在架构图中的位置如下。 |
| 14 | 14 | ||
| 15 | <img src="docs/zh/figures/architecture.png" alt="架构图" width="700px" height="326px"> | 15 | <img src="docs/zh/figures/architecture.png" alt="架构图" width="700px" height="326px"> |
| 16 | 16 | ||
| 17 | -## 📝版本配套 | 17 | +## 📌版本配套 |
| 18 | 18 | ||
| 19 | 本项目源码会跟随CANN软件版本发布,关于CANN软件版本与本项目标签的对应关系请参阅[release仓库](https://gitcode.com/cann/release-management)中的相应版本说明。 | 19 | 本项目源码会跟随CANN软件版本发布,关于CANN软件版本与本项目标签的对应关系请参阅[release仓库](https://gitcode.com/cann/release-management)中的相应版本说明。 |
| 20 | 请注意,为确保您的源码定制开发顺利进行,请选择配套的CANN版本与Gitcode标签源码,使用master分支可能存在版本不匹配的风险。 | 20 | 请注意,为确保您的源码定制开发顺利进行,请选择配套的CANN版本与Gitcode标签源码,使用master分支可能存在版本不匹配的风险。 |
| 21 | 21 | ||
| 22 | -## ⚡️快速入门 | 22 | +## 🛠️环境准备 |
| 23 | 23 | ||
| 24 | -若您希望**从零到一快速体验**项目能力,请访问下述简易教程。 | 24 | +[环境部署](docs/zh/install/quick_install.md)是体验本项目能力的前提,请先完成NPU驱动、CANN包安装等,确保环境正常。 |
| 25 | 25 | ||
| 26 | -1. [环境部署](docs/zh/install/quick_install.md):本文是**QuickStart和各类教程的操作前提**,请先完成基础环境搭建和源码下载。 | 26 | +## ⬇️源码下载 |
| 27 | 27 | ||
| 28 | -2. [QuickStart](docs/QUICKSTART.md):针对源码编译、算子调用/开发/调试等关键能力,提供快速上手的简易指南。 | 28 | +环境准备好后,根据环境中CANN版本下载与之配套的分支源码,\$\{tag\_version\}替换为配套的分支标签名。 |
| 29 | + | ||
| 30 | +```bash | ||
| 31 | +git clone -b ${tag_version} https://gitcode.com/cann/ops-cv.git | ||
| 32 | +``` | ||
| 33 | + | ||
| 34 | +说明:对于WebIDE环境,已默认提供最新商发CANN版本配套的源码,如需获取其他版本源码,参考上述命令获取。 | ||
| 29 | 35 | ||
| 30 | ## 📖学习教程 | 36 | ## 📖学习教程 |
| 31 | 37 | ||
| 32 | -若您已学习完**快速入门**章节,对本项目有一定认知,并希望**深入了解和体验项目**,请访问下述详细教程。 | 38 | +- [快速入门](docs/QUICKSTART.md):从零开始快速体验项目核心基础能力,涵盖源码编译、算子调用、开发与调试等操作。 |
| 33 | - | 39 | +- [进阶教程](docs/README.md):如需深入了解项目编译部署、算子调用、开发、调试调优等能力,请查阅文档中心获取详细指引。 |
| 34 | -1. [算子列表](docs/zh/op_list.md):提供全量算子信息,方便您查看算子分类和功能。 | ||
| 35 | -2. [算子调用](docs/zh/invocation/quick_op_invocation.md):提供多种源码编译和执行算子样例(包括执行UT)的方法。 | ||
| 36 | -3. [算子开发](docs/zh/develop/aicore_develop_guide.md):提供算子端到端开发指南,从零学习创建算子工程、实现Tiling和Kernel核心交付件。 | ||
| 37 | -4. [算子调试调优](docs/zh/debug/op_debug_prof.md):提供常见算子调试和调优方法,如DumpTensor、Msprof、Simulator等。 | ||
| 38 | - | ||
| 39 | -除了上述关键教程,还有其他文档介绍,例如算子调用方式、build参数说明、术语概念等,全量文档请访问[docs](docs/README.md)。 | ||
| 40 | - | ||
| 41 | -## 🔍目录结构 | ||
| 42 | - | ||
| 43 | -关键目录如下,详细目录介绍参见[项目目录](./docs/zh/install/dir_structure.md)。 | ||
| 44 | - | ||
| 45 | -```Cpp | ||
| 46 | -├── build.sh # 项目工程编译脚本 | ||
| 47 | -├── cmake # 项目工程编译目录 | ||
| 48 | -├── CMakeLists.txt | ||
| 49 | -├── common # 项目公共头文件和公共源码 | ||
| 50 | -├── docs # 项目文档介绍(目前仅提供中文版本) | ||
| 51 | -├── examples # 端到端算子开发和调用示例 | ||
| 52 | -├── experimental # 用户自定义算子存放目录 | ||
| 53 | -├── objdetect # objdetect类算子 | ||
| 54 | -├── ... | ||
| 55 | -├── image # image类算子 | ||
| 56 | -│ ├── grid_sample # GridSample算子所有交付件,如Kernel、InferShape等 | ||
| 57 | -│ │ ├── CMakeLists.txt # 算子编译配置文件 | ||
| 58 | -│ │ ├── docs # 算子说明文档 | ||
| 59 | -│ │ ├── examples # 算子使用示例 | ||
| 60 | -│ │ ├── op_graph # 算子构图相关目录 | ||
| 61 | -│ │ ├── op_host # 算子信息库、Tiling、InferShape相关实现目录 | ||
| 62 | -│ │ ├── op_api # 可选,算子aclnn接口实现目录,如未提供则表示此算子的aclnn接口会让工程自动生成 | ||
| 63 | -│ │ ├── op_kernel # 算子Kernel目录 | ||
| 64 | -│ │ └── README.md # 算子介绍文档 | ||
| 65 | -│ ├── ... | ||
| 66 | -│ └── CMakeLists.txt # 算子编译配置文件 | ||
| 67 | -├── tests # 测试工程目录 | ||
| 68 | -├── README.md | ||
| 69 | -├── install_deps.sh # 安装依赖包脚本 | ||
| 70 | -├── requirements.txt # 项目需要的第三方依赖包 | ||
| 71 | -└── scripts # 脚本目录,包含自定义算子、Kernel构建相关配置文件 | ||
| 72 | -``` | ||
| 73 | 40 | ||
| 74 | ## 💬相关信息 | 41 | ## 💬相关信息 |
| 75 | 42 | ||
| 43 | +- [目录结构](docs/zh/install/dir_structure.md) | ||
| 76 | - [贡献指南](CONTRIBUTING.md) | 44 | - [贡献指南](CONTRIBUTING.md) |
| 77 | - [安全声明](SECURITY.md) | 45 | - [安全声明](SECURITY.md) |
| 78 | - [许可证](LICENSE) | 46 | - [许可证](LICENSE) |
| 79 | - [所属SIG](https://gitcode.com/cann/community/tree/master/CANN/sigs/ops-basic) | 47 | - [所属SIG](https://gitcode.com/cann/community/tree/master/CANN/sigs/ops-basic) |
| 80 | 48 | ||
| 81 | -## 🤝联系我们 | 49 | +----- |
| 82 | - | 50 | +PS:本项目功能和文档正在持续更新和完善中,欢迎您关注最新版本。 |
| 83 | -本项目功能和文档正在持续更新和完善中,建议您关注最新版本。 | ||
| 84 | 51 | ||
| 85 | - **问题反馈**:通过GitCode[【Issues】](https://gitcode.com/cann/ops-cv/issues)提交问题。 | 52 | - **问题反馈**:通过GitCode[【Issues】](https://gitcode.com/cann/ops-cv/issues)提交问题。 |
| 86 | - **社区互动**:通过GitCode[【讨论】](https://gitcode.com/cann/ops-cv/discussions)参与交流。 | 53 | - **社区互动**:通过GitCode[【讨论】](https://gitcode.com/cann/ops-cv/discussions)参与交流。 |
| 87 | -- **技术专栏**:通过GitCode[【Wiki】](https://gitcode.com/cann/ops-cv/wiki)获取技术文章,如系列化教程、优秀实践等。 | 54 | +- **技术专栏**:通过GitCode[【Wiki】](https://gitcode.com/cann/ops-cv/wiki)获取技术文章。 |
| @@ -409,7 +409,7 @@ usage() { | |||
| 409 | echo " --asan enable asan with pkg on the host side" | 409 | echo " --asan enable asan with pkg on the host side" |
| 410 | echo " --valgrind run ut with valgrind. This option will disable asan, noexec and run utest by valgrind" | 410 | echo " --valgrind run ut with valgrind. This option will disable asan, noexec and run utest by valgrind" |
| 411 | echo "" | 411 | echo "" |
| 412 | - echo " --ops Compile specified operator, use snake name, like: --ops=add,add_lora, use ',' to separate different operator" | 412 | + echo " --ops Compile specified operator, use snake name, like: --ops=grid_sample,iou_v2, use ',' to separate different operator" |
| 413 | echo " --soc Compile binary with specified Ascend SoC, like: --soc=ascend910b" | 413 | echo " --soc Compile binary with specified Ascend SoC, like: --soc=ascend910b" |
| 414 | echo " --vendor_name Specify the custom operator package vendor name, like: --vendor_name=customize, default to customize-cv" | 414 | echo " --vendor_name Specify the custom operator package vendor name, like: --vendor_name=customize, default to customize-cv" |
| 415 | echo " --aicpu build aicpu task" | 415 | echo " --aicpu build aicpu task" |
| @@ -2,12 +2,12 @@ | |||
| 2 | 2 | ||
| 3 | ## 使用须知 | 3 | ## 使用须知 |
| 4 | 4 | ||
| 5 | -本指南旨在帮助您快速上手CANN和`ops-cv`算子仓的使用。为方便快速了解算子开发全流程,将以**AddExample**算子为实践对象,其源文件位于`ops-cv/examples/add_example`,具体操作流程如下: | 5 | +本指南旨在帮助您快速上手CANN和`ops-cv`算子仓的使用。为方便您快速了解算子开发全流程,以**AddExample**算子为实践对象,算子源码位于`ops-cv/examples/add_example`,操作流程如下: |
| 6 | 6 | ||
| 7 | -1. **[环境部署](zh/install/quick_install.md)**:完成软件安装和源码下载,此处不再赘述。快速入门场景下,**推荐WebIDE或Docker环境**,安装操作简单。 | 7 | +1. **[前提条件](../README.md)**:参考项目README完成环境准备和源码下载,此处不再赘述。快速入门场景**推荐WebIDE或Docker部署**,操作简单。 |
| 8 | + | ||
| 9 | + > **说明**:WebIDE或Docker环境默认提供最新商发版CANN包;如需体验master分支最新能力,可手动搭建环境。 | ||
| 8 | 10 | ||
| 9 | - > **说明**:WebIDE或Docker环境默认提供最新商发版CANN包;如需体验master分支最新能力,可手动搭建环境。注意软件包与源码版本是否配套。 | ||
| 10 | - | ||
| 11 | 2. **[编译运行](#一编译运行)**:编译自定义算子包并安装,实现快速调用算子。 | 11 | 2. **[编译运行](#一编译运行)**:编译自定义算子包并安装,实现快速调用算子。 |
| 12 | 12 | ||
| 13 | 3. **[算子开发](#二算子开发)**:通过修改现有算子Kernel,体验开发、编译、验证的完整闭环。 | 13 | 3. **[算子开发](#二算子开发)**:通过修改现有算子Kernel,体验开发、编译、验证的完整闭环。 |
| @@ -20,21 +20,29 @@ | |||
| 20 | 20 | ||
| 21 | 本阶段目的是**快速体验项目标准流程**,验证环境能否成功进行算子源码编译、打包、安装和运行。 | 21 | 本阶段目的是**快速体验项目标准流程**,验证环境能否成功进行算子源码编译、打包、安装和运行。 |
| 22 | 22 | ||
| 23 | -### 1. 进入项目目录 | 23 | +### 1. 进入项目源码 |
| 24 | + | ||
| 25 | +1. 检查源码版本。 | ||
| 26 | + | ||
| 27 | + 根据[release仓库](https://gitcode.com/cann/release-management)CANN版本配套关系检查源码版本是否配套,若不配套请参考下述命令重新下载,\$\{tag\_version\}替换为目标分支标签。 | ||
| 28 | + | ||
| 29 | + > 说明:对于WebIDE环境,**已默认提供最新商发版CANN配套的项目源码**。 | ||
| 24 | 30 | ||
| 25 | -环境准备好后(注意软件与源码版本配套),进入项目目录。 | 31 | + ```bash |
| 32 | + git clone -b ${tag_version} https://gitcode.com/cann/ops-cv.git | ||
| 33 | + ``` | ||
| 34 | + | ||
| 35 | + 若出现提示信息`fatal: destination path 'ops-cv' already exists and is not an empty directory.`,说明项目源码已存在。 | ||
| 26 | 36 | ||
| 27 | -- 对于Docker部署或手动安装场景,项目源码位于 | 37 | +2. 进入源码目录。 |
| 28 | - | 38 | + - Docker或手动安装场景下源码位于: |
| 29 | -```bash | 39 | + ```bash |
| 30 | -cd ops-cv | 40 | + cd ops-cv |
| 31 | -``` | 41 | + ``` |
| 32 | - | 42 | + - WebIDE场景下源码位于: |
| 33 | -- 对于WebIDE场景,项目源码位于 | 43 | + ```bash |
| 34 | - | 44 | + cd /mnt/workspace/ops-cv |
| 35 | -```bash | 45 | + ``` |
| 36 | -cd /mnt/workspace/ops-cv | ||
| 37 | -``` | ||
| 38 | 46 | ||
| 39 | ### 2. 编译AddExample算子 | 47 | ### 2. 编译AddExample算子 |
| 40 | 48 | ||
| @@ -82,7 +90,7 @@ bash build.sh --run_example add_example eager cust --vendor_name=custom | |||
| 82 | 90 | ||
| 83 | 预期输出:打印算子`AddExample`的加法计算结果,表明算子已成功部署并正确执行。 | 91 | 预期输出:打印算子`AddExample`的加法计算结果,表明算子已成功部署并正确执行。 |
| 84 | 92 | ||
| 85 | -```bash | 93 | +``` |
| 86 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 2.000000 | 94 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 2.000000 |
| 87 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 2.000000 | 95 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 2.000000 |
| 88 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 2.000000 | 96 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 2.000000 |
| @@ -143,7 +151,7 @@ __aicore__ inline void AddExample<T>::Compute(int32_t progress) | |||
| 143 | 151 | ||
| 144 | 4. **成功标志**:输出结果变成乘法结果。 | 152 | 4. **成功标志**:输出结果变成乘法结果。 |
| 145 | 153 | ||
| 146 | - ```bash | 154 | + ``` |
| 147 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 1.000000 | 155 | add_example first input[0] is: 1.000000, second input[0] is: 1.000000, result[0] is: 1.000000 |
| 148 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 1.000000 | 156 | add_example first input[1] is: 1.000000, second input[1] is: 1.000000, result[1] is: 1.000000 |
| 149 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 1.000000 | 157 | add_example first input[2] is: 1.000000, second input[2] is: 1.000000, result[2] is: 1.000000 |
| @@ -167,7 +175,7 @@ __aicore__ inline void AddExample<T>::Compute(int32_t progress) | |||
| 167 | 175 | ||
| 168 | * **printf** | 176 | * **printf** |
| 169 | 177 | ||
| 170 | - 该接口支持打印Scalar类型数据,如整数、字符型、布尔型等,详细介绍请参见[《Ascend C API》](https://hiascend.com/document/redirect/CannCommunityAscendCApi)中“算子调测API > printf”。 | 178 | + 该接口支持打印Scalar类型数据,如整数、字符型、布尔型等,详细介绍请参见[《Ascend C API》](https://hiascend.com/document/redirect/CannCommunityAscendCApi)中"算子调测API > printf"。 |
| 171 | 179 | ||
| 172 | ```c++ | 180 | ```c++ |
| 173 | blockLength_ = (tilingData->totalLength + AscendC::GetBlockNum() - 1) / AscendC::GetBlockNum(); | 181 | blockLength_ = (tilingData->totalLength + AscendC::GetBlockNum() - 1) / AscendC::GetBlockNum(); |
| @@ -181,7 +189,7 @@ __aicore__ inline void AddExample<T>::Compute(int32_t progress) | |||
| 181 | * **DumpTensor** | 189 | * **DumpTensor** |
| 182 | 190 | ||
| 183 | 该接口支持Dump指定Tensor的内容,同时支持打印自定义附加信息,比如当前行号等,详细介绍请参见[《Ascend C API》](https://hiascend.com/document/redirect/CannCommunityAscendCApi)中“算子调测API > DumpTensor”。 | 191 | 该接口支持Dump指定Tensor的内容,同时支持打印自定义附加信息,比如当前行号等,详细介绍请参见[《Ascend C API》](https://hiascend.com/document/redirect/CannCommunityAscendCApi)中“算子调测API > DumpTensor”。 |
| 184 | - | 192 | + |
| 185 | ```c++ | 193 | ```c++ |
| 186 | AscendC::LocalTensor<T> zLocal = outputQueueZ.DeQue<T>(); | 194 | AscendC::LocalTensor<T> zLocal = outputQueueZ.DeQue<T>(); |
| 187 | // 打印zLocal Tensor信息 | 195 | // 打印zLocal Tensor信息 |
| @@ -193,22 +201,22 @@ __aicore__ inline void AddExample<T>::Compute(int32_t progress) | |||
| 193 | 当算子功能验证正确后,可通过`msprof`工具采集算子性能数据。 | 201 | 当算子功能验证正确后,可通过`msprof`工具采集算子性能数据。 |
| 194 | 202 | ||
| 195 | - **生成可执行文件** | 203 | - **生成可执行文件** |
| 196 | - | 204 | + |
| 197 | - 调用AddExample算子的example样例,生成可执行文件(test_aclnn_add_example),该文件位于项目`ops-cv/build`目录。 | 205 | + 调用AddExample算子的example样例,生成可执行文件(test_aclnn_add_example),该文件位于项目`ops-cv/build`目录。 |
| 198 | 206 | ||
| 199 | - ```bash | 207 | + ```bash |
| 200 | - bash build.sh --run_example add_example eager cust --vendor_name=custom | 208 | + bash build.sh --run_example add_example eager cust --vendor_name=custom |
| 201 | - ``` | 209 | + ``` |
| 202 | 210 | ||
| 203 | - **采集性能数据** | 211 | - **采集性能数据** |
| 204 | 212 | ||
| 205 | - 进入AddExample算子可执行文件目录`ops-cv/build/`,执行如下命令: | 213 | + 进入AddExample算子可执行文件目录`ops-cv/build/`,执行如下命令: |
| 206 | - | ||
| 207 | - ```bash | ||
| 208 | - msprof --application="./test_aclnn_add_example" | ||
| 209 | - ``` | ||
| 210 | 214 | ||
| 211 | - 采集结果在项目`ops-cv/build/`目录,msprof命令执行完后会自动解析并导出性能数据结果文件,详细内容请参见[msprof](https://www.hiascend.com/document/detail/zh/mindstudio/82RC1/T&ITools/Profiling/atlasprofiling_16_0110.html#ZH-CN_TOPIC_0000002504160251)。 | 215 | + ```bash |
| 216 | + msprof --application="./test_aclnn_add_example" | ||
| 217 | + ``` | ||
| 218 | + | ||
| 219 | +采集结果在项目`ops-cv/build/`目录,msprof命令执行完后会自动解析并导出性能数据结果文件,详细内容请参见[msprof](https://www.hiascend.com/document/detail/zh/mindstudio/82RC1/T&ITools/Profiling/atlasprofiling_16_0110.html#ZH-CN_TOPIC_0000002504160251)。 | ||
| 212 | 220 | ||
| 213 | ## 四、算子验证 | 221 | ## 四、算子验证 |
| 214 | 222 | ||
| @@ -228,7 +236,7 @@ int main() { | |||
| 228 | // 修改前:shape = {32, 4, 4, 4}, 数值全为1 | 236 | // 修改前:shape = {32, 4, 4, 4}, 数值全为1 |
| 229 | // 修改后:将输入shape改为 {8, 8, 8, 8},并填充不同的测试数据 | 237 | // 修改后:将输入shape改为 {8, 8, 8, 8},并填充不同的测试数据 |
| 230 | std::vector<int64_t> selfXShape = {8, 8, 8, 8}; | 238 | std::vector<int64_t> selfXShape = {8, 8, 8, 8}; |
| 231 | - std::vector<float> selfXHostData(4096); // 4096 = 8 * 8 * 8 * 8 | 239 | + std::vector<float> selfXHostData(4096); // 4096 = 8 * 8 * 8 *8 |
| 232 | // 可使用循环填充更有区分度的数据,例如递增序列 | 240 | // 可使用循环填充更有区分度的数据,例如递增序列 |
| 233 | for (int i = 0; i < 4096; ++i) { | 241 | for (int i = 0; i < 4096; ++i) { |
| 234 | selfXHostData[i] = static_cast<float>(i % 10); // 填充0-9的循环值 | 242 | selfXHostData[i] = static_cast<float>(i % 10); // 填充0-9的循环值 |
| @@ -253,4 +261,5 @@ int main() { | |||
| 253 | 261 | ||
| 254 | ## 结语 | 262 | ## 结语 |
| 255 | 263 | ||
| 256 | -体验完上述流程后,您已基本完成一个算子开发,如果您想贡献算子或学习更多高阶技能,请访问本项目README,进一步了解[学习教程](../README.md#学习教程)和[贡献指南](../README.md#相关信息)等。 | 264 | +体验完上述流程,您已基本完成算子开发过程,如果您想进一步贡献新算子或学习更多高阶开发、调试等技能,请访问本项目README学习[进阶教程](../README.md#学习教程)和[贡献指南](../README.md#相关信息)等。 |
| 265 | + | ||
| @@ -1,52 +1,68 @@ | |||
| 1 | -# 项目文档 | 1 | +# 文档中心 |
| 2 | 2 | ||
| 3 | -## 目录说明 | 3 | +## 目录结构 |
| 4 | 4 | ||
| 5 | -关键目录结构如下: | 5 | +Docs目录结构说明如下: |
| 6 | 6 | ||
| 7 | -```Cpp | 7 | +``` |
| 8 | -├── context # 公共文档,如术语、基础概念等 | 8 | +├── zh |
| 9 | -├── debug # 算子调试指导文档 | 9 | + ├── context # 公共文档,如术语、基础概念等 |
| 10 | -│ ├── op_debug_prof.md | 10 | + ├── debug # 算子调试指导文档 |
| 11 | -│ ├── ... | 11 | + │ ├── op_debug_prof.md |
| 12 | -├── develop # 算子开发指导文档 | 12 | + │ ├── ... |
| 13 | -│ ├── aicore_develop_guide.md | 13 | + ├── develop # 算子开发指导文档 |
| 14 | -│ ├── aicpu_develop_guide.md | 14 | + │ ├── aicore_develop_guide.md |
| 15 | -│ ├── ... | 15 | + │ ├── aicpu_develop_guide.md |
| 16 | -├── figures # 图片目录 | 16 | + │ ├── ... |
| 17 | -├── install # 环境安装指导文档 | 17 | + ├── figures # 图片目录 |
| 18 | -│ ├── quick_install.md | 18 | + ├── install # 环境安装和编译指导文档 |
| 19 | -│ ├── build.md | 19 | + │ ├── build.md |
| 20 | -│ └── ... | 20 | + │ ├── compile.md |
| 21 | -├── invocation # 算子调用指导文档(包括aclnn调用、图模式调用等) | 21 | + │ ├── quick_install.md |
| 22 | -│ ├──op_invocation.md | 22 | + │ └── ... |
| 23 | -│ ├── ... | 23 | + ├── invocation # 算子调用指导文档(包括aclnn调用、图模式调用等) |
| 24 | -├── op_api_list.md # 全量算子接口列表(aclnn) | 24 | + │ ├── quick_op_invocation.md |
| 25 | -├── op_list.md # 全量算子列表 | 25 | + │ ├── ... |
| 26 | -├── QUICKSTART.md # 快速入门指南 | 26 | + ├── op_api_list.md # 全量算子接口列表(aclnn) |
| 27 | -├── CONTRIBUTING_DOCS.md # 文档贡献指南 | 27 | + ├── op_list.md # 全量算子列表 |
| 28 | -└── README.md | 28 | +├── CONTRIBUTING_DOCS.md # 文档贡献说明 |
| 29 | +├── QUICKSTART.md # 快速入门 | ||
| 30 | +└── README.md | ||
| 29 | ``` | 31 | ``` |
| 30 | 32 | ||
| 31 | -## 文档说明 | 33 | +## 进阶教程 |
| 34 | +### 指南类文档 | ||
| 32 | 35 | ||
| 33 | -项目全量文档如下,请按需获取对应内容。 | 36 | +| 文档 | 说明 | |
| 37 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | | ||
| 38 | +| [源码构建指南](zh/install/compile.md) | 介绍联网/未联网场景下不同的源码构建方式和验证方法。 | | ||
| 39 | +| [算子调用指南](zh/invocation/quick_op_invocation.md) | 介绍调用算子样例方法和不同算子调用方式(如PyTorch/aclnn/图等)。 | | ||
| 40 | +| [标准算子开发指南](zh/develop/aicore_develop_guide.md) | 介绍如何基于标准工程定义算子原型、实现Tiling和Kernel,此类算子称为“标准算子”。<br>标准算子支持aclnn和图模式调用。 | | ||
| 41 | +| [简易算子开发指南](../examples/fast_kernel_launch_example/README.md) | 介绍如何基于简易工程实现fast_kernel_launch,即`<<<>>>`方式,此类算子称为“简易算子”。<br>简易算子仅支持PyTorch调用。 | | ||
| 42 | +| [算子调试调优](zh/debug/op_debug_prof.md) | 介绍常见的算子功能调试和性能调优方法(如数据采集和仿真流水等)。 | | ||
| 34 | 43 | ||
| 35 | -| 文档 | 说明 | | 44 | +### API类文档 |
| 36 | -| ------------------------------------------------ | ------------------------------------------------------------ | | 45 | + |
| 46 | +| 文档 | 说明 | | ||
| 47 | +| ----------------------- | ---------------------- | | ||
| 37 | | [算子列表](zh/op_list.md) | 介绍项目包含的所有算子清单。 | | 48 | | [算子列表](zh/op_list.md) | 介绍项目包含的所有算子清单。 | |
| 38 | -| [aclnn列表](zh/op_api_list.md) | 介绍项目包含的所有算子API,通过该API可直调算子。 | | 49 | +| [aclnn列表](zh/op_api_list.md) | 介绍项目包含的所有算子aclnn API清单。为方便用户在Host侧调用算子,提供了C语言API,即aclnn前缀的API。 | |
| 39 | -| [环境部署](zh/install/quick_install.md) | 介绍基础环境搭建过程,包括不同场景下软件包和第三方依赖的获取和安装。 | | 50 | + |
| 40 | -| [算子调用](zh/invocation/quick_op_invocation.md) | 介绍如何编译源码并执行算子,包括不同场景下的算子包编译、算子样例执行、UT执行等。 | | 51 | +### 工具类文档 |
| 41 | -| [算子开发](zh/develop/aicore_develop_guide.md) | 介绍如何基于本项目工程开发新算子,包括算子原型定义、Tiling实现、Kernel实现等。 | | 52 | +| 文档 | 说明 | |
| 42 | -| [算子调用方式](zh/invocation/op_invocation.md) | 介绍多种算子调用方式和调用流程,例如aclnn调用、图模式调用等。 | | 53 | +| ----------------------- | ---------------------- | |
| 43 | -| [算子调试调优](zh/debug/op_debug_prof.md) | 介绍常见的算子调试、调优方法。 | | 54 | +| [Simulator仿真工具](zh/debug/cann_sim.md) | 面向算子开发场景的SoC级仿真工具,用于分析运行在AI仿真器上AI任务在各阶段精度和性能数据。 | |
| 44 | -| [快速入门](QUICKSTART.md) | 零基础入门指南,涵盖Docker部署、算子开发和贡献流程。 | | 55 | + |
| 45 | -| [贡献指南](CONTRIBUTING_DOCS.md) | 介绍如何参与文档完善和贡献文档改进。 | | 56 | +### 更多文档 |
| 57 | + | ||
| 58 | +- 样例类文档:可参考[cann-samples](https://gitcode.com/cann/cann-samples)仓算子样例。 | ||
| 59 | +- 实践类文档:**建设中**,请您访问项目wiki进行搜索。 | ||
| 60 | +- FAQ类文档:**建设中**,请您访问项目wiki进行搜索。 | ||
| 46 | 61 | ||
| 47 | ## 附录 | 62 | ## 附录 |
| 48 | 63 | ||
| 49 | | 文档 | 说明 | | 64 | | 文档 | 说明 | |
| 50 | | ----------------------------------- | ------------------------------------------------------------ | | 65 | | ----------------------------------- | ------------------------------------------------------------ | |
| 51 | | [算子基本概念](zh/context/基本概念.md) | 介绍算子领域相关的基础概念和术语,如量化/稀疏、数据类型、数据格式等。 | | 66 | | [算子基本概念](zh/context/基本概念.md) | 介绍算子领域相关的基础概念和术语,如量化/稀疏、数据类型、数据格式等。 | |
| 52 | -| [build参数说明](zh/install/build.md) | 介绍本项目build.sh脚本的功能和参数含义。 | | 67 | +| [build参数说明](zh/install/build.md) | 介绍本项目build.sh参数功能和取值,包括源码编译、算子调用、调试等。 | |
| 68 | + | ||
| @@ -36,14 +36,14 @@ CANN Simulator集成在CANN toolkit包里,参考[环境部署](../install/quic | |||
| 36 | 36 | ||
| 37 | * 参考[算子调用](../invocation/quick_op_invocation.md)完成add_example的算子编译和安装 | 37 | * 参考[算子调用](../invocation/quick_op_invocation.md)完成add_example的算子编译和安装 |
| 38 | 38 | ||
| 39 | -```sh | 39 | +``` |
| 40 | # 说明:进入项目根目录,执行如下编译命令,命令仅供参考,详细可以查看算子调用的说明。 | 40 | # 说明:进入项目根目录,执行如下编译命令,命令仅供参考,详细可以查看算子调用的说明。 |
| 41 | bash build.sh --pkg --soc=Ascend950 --vendor_name=custom --ops=add_example | 41 | bash build.sh --pkg --soc=Ascend950 --vendor_name=custom --ops=add_example |
| 42 | # 安装自定义算子包 | 42 | # 安装自定义算子包 |
| 43 | ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run | 43 | ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run |
| 44 | ``` | 44 | ``` |
| 45 | 45 | ||
| 46 | -* 参考[aclnn调用](../invocation/op_invocation.md#aclnn调用)完成test_aclnn_add_example.cpp的编译,编出可执行文件test_aclnn_add_example | 46 | +* 参考[aclnn调用](../invocation/quick_op_invocation.md#aclnn调用)完成test_aclnn_add_example.cpp的编译,编出可执行文件test_aclnn_add_example |
| 47 | 47 | ||
| 48 | ## 执行仿真命令 | 48 | ## 执行仿真命令 |
| 49 | 49 | ||
| @@ -2,15 +2,22 @@ | |||
| 2 | 2 | ||
| 3 | ## 概述 | 3 | ## 概述 |
| 4 | 4 | ||
| 5 | -> **说明:** | 5 | +### 使用说明 |
| 6 | -> | ||
| 7 | -> 1. 算子开发过程中涉及的基本概念如Tiling、Kernel、硬件架构等请参考[《Ascend C算子开发》](https://hiascend.com/document/redirect/CannCommunityOpdevAscendC),涉及的接口请参考[《Ascend C算子开发接口》](https://hiascend.com/document/redirect/CannCommunityAscendCApi)、[《基础数据结构和接口》](https://hiascend.com/document/redirect/CannCommunitybasicopapi)。 | ||
| 8 | -> 2. AI Core算子是使用Ascend C语言开发,运行在AI Core硬件单元算子;AI CPU算子是使用C++语言开发,运行在AI CPU硬件单元算子。如果您想贡献AI CPU算子,请参考[AI CPU算子开发指南](./aicpu_develop_guide.md)。 | ||
| 9 | -> 3. 针对基于[Ascend/samples](https://gitee.com/ascend/samples/tree/master)仓贡献的算子,请参考[附录 > 算子工程迁移](#算子工程迁移)完成存量算子往本项目工程迁移。 | ||
| 10 | -> 4. build.sh:算子开发过程中涉及的命令可通过`bash build.sh --help`查看,功能参数介绍参考[build参数说明](../install/build.md)。 | ||
| 11 | -> 5. 涉及多平台间算子迁移(如将Atlas A2上已实现算子功能迁移适配至Ascend 950)时,可参考[跨平台迁移指导](./cross_platform_migration_guide.md)。 | ||
| 12 | 6 | ||
| 13 | -开发指南以`AddExample`算子开发为例,介绍新算子开发流程以及涉及的交付件,完整样例代码请访问项目`examples`目录。 | 7 | +算子根据运行的硬件单元不同,可分为AI Core算子和AI CPU算子(少数)。AI Core算子使用Ascend C语言开发,运行在AI Core硬件单元;AI CPU算子使用C++语言开发,运行在AI CPU硬件单元。 |
| 8 | + | ||
| 9 | +本文旨在介绍如何基于标准工程开发AI Core算子,如果您想贡献AI CPU算子,请参考[AI CPU算子开发指南](./aicpu_develop_guide.md)。 | ||
| 10 | + | ||
| 11 | +算子开发前,请先了解如下信息: | ||
| 12 | + | ||
| 13 | +- 基础知识:请先学习Ascend C编程语言,了解基本语法和原理,参考[《Ascend C算子开发》](https://hiascend.com/document/redirect/CannCommunityOpdevAscendC)熟悉硬件架构、算子Tiling/Kernel等概念。 | ||
| 14 | +- 开发API:算子开发过程中使用到的接口请参考[《Ascend C算子开发接口》](https://hiascend.com/document/redirect/CannCommunityAscendCApi)、[《基础数据结构和接口》](https://hiascend.com/document/redirect/CannCommunitybasicopapi)。 | ||
| 15 | +- 算子工程迁移:针对[Ascend/samples](https://gitee.com/ascend/samples/tree/master)仓已贡献的算子,请参考[附录 > 算子工程迁移](#算子工程迁移)完成存量算子往本项目工程迁移。 | ||
| 16 | +- 算子跨平台迁移:针对涉及多平台算子实现迁移的场景,例如将Atlas A2上已实现的算子功能迁移到Ascend 950平台,请参考[附录 > 算子跨平台迁移](#算子跨平台迁移)完成适配。 | ||
| 17 | + | ||
| 18 | +### 开发流程 | ||
| 19 | + | ||
| 20 | +以`AddExample`算子为例,介绍标准AI Core算子开发的全流程和交付件,完整样例请访问项目`examples`目录。 | ||
| 14 | 21 | ||
| 15 | 1. [工程创建](#工程创建):开发算子前,需完成环境部署并创建算子目录,方便后续算子的编译和部署。 | 22 | 1. [工程创建](#工程创建):开发算子前,需完成环境部署并创建算子目录,方便后续算子的编译和部署。 |
| 16 | 23 | ||
| @@ -30,20 +37,14 @@ | |||
| 30 | 37 | ||
| 31 | ## 工程创建 | 38 | ## 工程创建 |
| 32 | 39 | ||
| 33 | -**1. 环境部署** | ||
| 34 | - | ||
| 35 | -开发算子前,请先参考[环境部署](../install/quick_install.md)完成基础环境搭建。 | ||
| 36 | - | ||
| 37 | -**2. 目录创建** | ||
| 38 | - | ||
| 39 | 目录创建是算子开发的重要步骤,为后续代码编写、编译构建和调试提供统一的目录结构和文件组织方式。 | 40 | 目录创建是算子开发的重要步骤,为后续代码编写、编译构建和调试提供统一的目录结构和文件组织方式。 |
| 40 | 41 | ||
| 41 | 本项目`build.sh`,支持快速创建算子目录。进入项目根目录,执行以下命令: | 42 | 本项目`build.sh`,支持快速创建算子目录。进入项目根目录,执行以下命令: |
| 42 | 43 | ||
| 43 | ```bash | 44 | ```bash |
| 44 | -# 创建指定算子目录,如bash build.sh --genop=examples/add_example | 45 | +# 创建指定算子目录,如bash build.sh --genop=examples/example_ops |
| 45 | # ${op_class}表示算子类型,如image类。 | 46 | # ${op_class}表示算子类型,如image类。 |
| 46 | -# ${op_name}表示算子名的小写下划线形式,如`AddExample`算子对应为add_example,新增算子不允许与已有算子重名。 | 47 | +# ${op_name}表示算子名的小写下划线形式,如`ExampleOps`算子对应为example_ops,新增算子不允许与已有算子重名。 |
| 47 | bash build.sh --genop=${op_class}/${op_name} | 48 | bash build.sh --genop=${op_class}/${op_name} |
| 48 | ``` | 49 | ``` |
| 49 | 50 | ||
| @@ -55,10 +56,13 @@ Create the initial directory for ${op_name} under ${op_class} success | |||
| 55 | 56 | ||
| 56 | 创建完成后,目录结构如下所示: | 57 | 创建完成后,目录结构如下所示: |
| 57 | 58 | ||
| 58 | -```cpp | 59 | +``` |
| 59 | ${op_name} # 替换为实际算子名的小写下划线形式 | 60 | ${op_name} # 替换为实际算子名的小写下划线形式 |
| 60 | ├── examples # 算子调用示例 | 61 | ├── examples # 算子调用示例 |
| 61 | -│ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 | 62 | +│ ├── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 |
| 63 | +├── op_graph # 算子图模式 | ||
| 64 | +│ ├── {op_name}_graph_infer.cpp # InferDtepy实现,实现算子dtype推导,在运行时推导输出dtype | ||
| 65 | +│ └── {op_name}_proto.h # 实现算子图模式的原型 | ||
| 62 | ├── op_host # Host侧实现 | 66 | ├── op_host # Host侧实现 |
| 63 | │ ├── ${op_name}_def.cpp # 算子信息库,定义算子基本信息,如名称、输入输出、数据类型等 | 67 | │ ├── ${op_name}_def.cpp # 算子信息库,定义算子基本信息,如名称、输入输出、数据类型等 |
| 64 | │ ├── ${op_name}_infershape.cpp # InferShape实现,实现算子形状推导,在运行时推导输出shape | 68 | │ ├── ${op_name}_infershape.cpp # InferShape实现,实现算子形状推导,在运行时推导输出shape |
| @@ -73,7 +77,7 @@ ${op_name} # 替换为实际算子名的小写下 | |||
| 73 | 77 | ||
| 74 | 若`${op_class}`为全新算子分类需额外在`CMakeLists.txt`中添加`add_subdirectory(${op_class})`,否则无法正常编译。 | 78 | 若`${op_class}`为全新算子分类需额外在`CMakeLists.txt`中添加`add_subdirectory(${op_class})`,否则无法正常编译。 |
| 75 | 79 | ||
| 76 | -```CMake | 80 | +``` |
| 77 | if(ENABLE_EXPERIMENTAL) | 81 | if(ENABLE_EXPERIMENTAL) |
| 78 | # genop新增experimental算子分类 | 82 | # genop新增experimental算子分类 |
| 79 | # add_subdirectory(${op_class}) | 83 | # add_subdirectory(${op_class}) |
| @@ -89,6 +93,8 @@ endif() | |||
| 89 | 93 | ||
| 90 | 算子定义需要完成两个交付件:`README.md` ```${op_name}_def.cpp``` | 94 | 算子定义需要完成两个交付件:`README.md` ```${op_name}_def.cpp``` |
| 91 | 95 | ||
| 96 | +> 💡 **进阶内容**:关于算子原型定义的详细说明,包括输入/输出/属性定义、AI处理器配置、多硬件平台差异化注册等,请参考[《AI Core算子开发进阶指南 - 算子原型定义》](./aicore_develop_advanced_guide.md#算子原型定义)。 | ||
| 97 | + | ||
| 92 | **交付件1:README.md** | 98 | **交付件1:README.md** |
| 93 | 99 | ||
| 94 | 开发算子前需要先确定目标算子的功能和计算逻辑。 | 100 | 开发算子前需要先确定目标算子的功能和计算逻辑。 |
| @@ -103,6 +109,8 @@ endif() | |||
| 103 | 109 | ||
| 104 | ## Tiling实现 | 110 | ## Tiling实现 |
| 105 | 111 | ||
| 112 | +> 💡 **进阶内容**:关于Host侧Tiling实现的详细说明,包括基本流程、Tiling结构体定义、Tiling模板编程等,请参考[《AI Core算子开发进阶指南 - Host侧Tiling实现》](./aicore_develop_advanced_guide.md#host侧tiling实现)。 | ||
| 113 | + | ||
| 106 | ### Tiling简介 | 114 | ### Tiling简介 |
| 107 | 115 | ||
| 108 | 因NPU中AI Core内部存储空间有限,无法一次性将整个张量数据加载到计算单元中处理,因此需要将输入张量切分为多个小块(Tile),逐块进行计算,这一过程称为Tiling。 | 116 | 因NPU中AI Core内部存储空间有限,无法一次性将整个张量数据加载到计算单元中处理,因此需要将输入张量切分为多个小块(Tile),逐块进行计算,这一过程称为Tiling。 |
| @@ -112,9 +120,7 @@ endif() | |||
| 112 | ### 代码实现 | 120 | ### 代码实现 |
| 113 | 121 | ||
| 114 | Tiling一共需要三个交付件:```${op_name}_tiling.cpp``` ```${op_name}_tiling_key.h``` ```${op_name}_tiling_data.h``` | 122 | Tiling一共需要三个交付件:```${op_name}_tiling.cpp``` ```${op_name}_tiling_key.h``` ```${op_name}_tiling_data.h``` |
| 115 | - | ||
| 116 | > 说明: | 123 | > 说明: |
| 117 | -> | ||
| 118 | > 1. `${op_name}_tiling.cpp`放在`${op_name}/op_host`目录下; | 124 | > 1. `${op_name}_tiling.cpp`放在`${op_name}/op_host`目录下; |
| 119 | > 2. `${op_name}_tiling_key.h`和`${op_name}_tiling_data.h`放在`${op_name}/op_kernel`目录下; | 125 | > 2. `${op_name}_tiling_key.h`和`${op_name}_tiling_data.h`放在`${op_name}/op_kernel`目录下; |
| 120 | > 3. 如果`${op_name}_tiling.cpp`中需要引用`${op_name}_tiling_data.h`,请使用相对路径的方式,例如:`#include "../op_kernel/${op_name}_tiling_data.h"`。 | 126 | > 3. 如果`${op_name}_tiling.cpp`中需要引用`${op_name}_tiling_data.h`,请使用相对路径的方式,例如:`#include "../op_kernel/${op_name}_tiling_data.h"`。 |
| @@ -126,7 +132,7 @@ Tiling主要切分逻辑。 | |||
| 126 | 如需查看详细实现,请参考[add_example_tiling.cpp](../../../examples/add_example/op_host/add_example_tiling.cpp)。 | 132 | 如需查看详细实现,请参考[add_example_tiling.cpp](../../../examples/add_example/op_host/add_example_tiling.cpp)。 |
| 127 | 133 | ||
| 128 | > **样例中函数空实现说明:** | 134 | > **样例中函数空实现说明:** |
| 129 | -> | 135 | + |
| 130 | > 1. **TilingParse**:图模式标准交付件,保留函数定义以满足框架调用规范,无实际逻辑时可置空。 | 136 | > 1. **TilingParse**:图模式标准交付件,保留函数定义以满足框架调用规范,无实际逻辑时可置空。 |
| 131 | > 2. **CompileInfo**:图模式标准交付件,保留函数定义以满足框架调用规范,无实际逻辑时可置空。 | 137 | > 2. **CompileInfo**:图模式标准交付件,保留函数定义以满足框架调用规范,无实际逻辑时可置空。 |
| 132 | 138 | ||
| @@ -197,7 +203,6 @@ static ge::graphStatus TilingFunc(gert::TilingContext* context){ | |||
| 197 | // 3.Tiling注册入口 | 203 | // 3.Tiling注册入口 |
| 198 | IMPL_OP_OPTILING(${op_name}).Tiling(TilingFunc).TilingParse<CompileInfo>(TilingParse); | 204 | IMPL_OP_OPTILING(${op_name}).Tiling(TilingFunc).TilingParse<CompileInfo>(TilingParse); |
| 199 | ``` | 205 | ``` |
| 200 | - | ||
| 201 | **交付件2:${op_name}_tiling_key.h** | 206 | **交付件2:${op_name}_tiling_key.h** |
| 202 | 207 | ||
| 203 | TilingKey是一个算子内为了区分不同的实现而将kernel代码进行区分的方法,kernel侧可以通过TilingKey来选择不同的算法逻辑。 | 208 | TilingKey是一个算子内为了区分不同的实现而将kernel代码进行区分的方法,kernel侧可以通过TilingKey来选择不同的算法逻辑。 |
| @@ -214,7 +219,6 @@ ASCENDC_TPL_ARGS_DECL( | |||
| 214 | 219 | ||
| 215 | ASCENDC_TPL_SEL(ASCENDC_TPL_ARGS_SEL( | 220 | ASCENDC_TPL_SEL(ASCENDC_TPL_ARGS_SEL( |
| 216 | ASCENDC_TPL_UINT_SEL(schMode, ASCENDC_TPL_UI_LIST, ELEMENTWISE_TPL_SCH_MODE_0, ELEMENTWISE_TPL_SCH_MODE_1))); | 221 | ASCENDC_TPL_UINT_SEL(schMode, ASCENDC_TPL_UI_LIST, ELEMENTWISE_TPL_SCH_MODE_0, ELEMENTWISE_TPL_SCH_MODE_1))); |
| 217 | - | ||
| 218 | ``` | 222 | ``` |
| 219 | 223 | ||
| 220 | **交付件3:${op_name}_tiling_data.h** | 224 | **交付件3:${op_name}_tiling_data.h** |
| @@ -233,6 +237,8 @@ struct ${op_name}TilingData { | |||
| 233 | 237 | ||
| 234 | ## Kernel实现 | 238 | ## Kernel实现 |
| 235 | 239 | ||
| 240 | +> 💡 **进阶内容**:关于Kernel侧算子实现的详细说明,包括核函数定义、GET_TILING_DATA获取Tiling参数、核函数内推导输入数据类型和格式等,请参考[《AI Core算子开发进阶指南 - Kernel侧算子实现》](./aicore_develop_advanced_guide.md#kernel侧算子实现)。 | ||
| 241 | + | ||
| 236 | ### Kernel简介 | 242 | ### Kernel简介 |
| 237 | 243 | ||
| 238 | Kernel是算子在NPU执行的核心部分,负责张量数据的加载、计算和存储,是算子功能实现的最终载体。Kernel的实现需要与Tiling策略紧密配合,根据Tiling提供的`TilingData`、`TilingKey`信息进行内存分配和计算调度。 | 244 | Kernel是算子在NPU执行的核心部分,负责张量数据的加载、计算和存储,是算子功能实现的最终载体。Kernel的实现需要与Tiling策略紧密配合,根据Tiling提供的`TilingData`、`TilingKey`信息进行内存分配和计算调度。 |
| @@ -241,8 +247,8 @@ Kernel实现包括如下步骤,整个流程通过`Process`函数串联,实 | |||
| 241 | 247 | ||
| 242 | ```mermaid | 248 | ```mermaid |
| 243 | graph LR | 249 | graph LR |
| 244 | - H([核函数定义]) -->A([定义Kernel类]) | 250 | + H([核函数定义]) -->A([定义Kernel类]) |
| 245 | - A -->B([初始化函数<br>Init]) | 251 | + A -->B([初始化函数<br>Init]) |
| 246 | B -->C([主处理函数<br>Process]) | 252 | B -->C([主处理函数<br>Process]) |
| 247 | subgraph C [主处理函数 Process] | 253 | subgraph C [主处理函数 Process] |
| 248 | D([数据搬入<br>CopyIn]) -->E([计算<br>Compute]) -->F([数据搬出<br>CopyOut]) | 254 | D([数据搬入<br>CopyIn]) -->E([计算<br>Compute]) -->F([数据搬出<br>CopyOut]) |
| @@ -253,9 +259,7 @@ graph LR | |||
| 253 | ### 代码实现 | 259 | ### 代码实现 |
| 254 | 260 | ||
| 255 | Kernel一共需要两个交付件:```${op_name}.cpp``` ```${op_name}.h``` | 261 | Kernel一共需要两个交付件:```${op_name}.cpp``` ```${op_name}.h``` |
| 256 | - | ||
| 257 | > 说明: | 262 | > 说明: |
| 258 | -> | ||
| 259 | > 1. `${op_name}.cpp`为kernel的入口函数只能放在`${op_name}/op_kernel`目录下; | 263 | > 1. `${op_name}.cpp`为kernel的入口函数只能放在`${op_name}/op_kernel`目录下; |
| 260 | > 2. `${op_name}.h`文件可以按照不同SoC或模板放在对应目录下,例如:`${op_name}/op_kernel/arch32`、`${op_name}/op_kernel/arch35`或`${op_name}/op_kernel/impl`等目录下; | 264 | > 2. `${op_name}.h`文件可以按照不同SoC或模板放在对应目录下,例如:`${op_name}/op_kernel/arch32`、`${op_name}/op_kernel/arch35`或`${op_name}/op_kernel/impl`等目录下; |
| 261 | 265 | ||
| @@ -373,11 +377,15 @@ __aicore__ inline void AddExample<T>::Process() | |||
| 373 | 377 | ||
| 374 | ## 图模式适配 | 378 | ## 图模式适配 |
| 375 | 379 | ||
| 380 | +> 💡 **进阶内容**:关于GE图模式原型定义的详细说明,包括REG_OP接口、TensorType类等,请参考[《AI Core算子开发进阶指南 - GE图模式原型定义》](./aicore_develop_advanced_guide.md#ge图模式原型定义)。 | ||
| 381 | + | ||
| 376 | 图模式一共需要三个交付件:```${op_name}_graph_infer.cpp``` ```${op_name}_infershape.cpp``` ```${op_name}_proto.h``` | 382 | 图模式一共需要三个交付件:```${op_name}_graph_infer.cpp``` ```${op_name}_infershape.cpp``` ```${op_name}_proto.h``` |
| 377 | 详细说明见图模式适配指南[graph_develop_guide.md](./graph_develop_guide.md)。 | 383 | 详细说明见图模式适配指南[graph_develop_guide.md](./graph_develop_guide.md)。 |
| 378 | 384 | ||
| 379 | ## aclnn适配 | 385 | ## aclnn适配 |
| 380 | 386 | ||
| 387 | +> 💡关于Aclnn接口的详细说明,包括自动生成配置方式、动态库路径等,请参考[《AI Core算子开发进阶指南 - Aclnn指导》](./aicore_develop_advanced_guide.md#aclnn指导)。 | ||
| 388 | + | ||
| 381 | 通常算子开发和编译完成后,会自动生成aclnn接口(一套基于C 的API),可直接在应用程序中调用aclnn接口实现调用算子。 | 389 | 通常算子开发和编译完成后,会自动生成aclnn接口(一套基于C 的API),可直接在应用程序中调用aclnn接口实现调用算子。 |
| 382 | 390 | ||
| 383 | 为实现该调用方式,需提前生成算子对应的二进制包,增加二进制编译json文件,以`AddExample`算子为例: | 391 | 为实现该调用方式,需提前生成算子对应的二进制包,增加二进制编译json文件,以`AddExample`算子为例: |
| @@ -397,31 +405,30 @@ __aicore__ inline void AddExample<T>::Process() | |||
| 397 | 参考[工程创建](#工程创建)完成基础环境搭建,同时检查算子开发交付件是否完备,是否在对应算子分类目录下。 | 405 | 参考[工程创建](#工程创建)完成基础环境搭建,同时检查算子开发交付件是否完备,是否在对应算子分类目录下。 |
| 398 | 406 | ||
| 399 | 2. **配置环境变量。** | 407 | 2. **配置环境变量。** |
| 408 | + | ||
| 409 | + 根据实际场景,选择合适的命令。 | ||
| 400 | 410 | ||
| 401 | - 根据实际场景,选择合适的命令。 | 411 | + ```bash |
| 402 | - | 412 | + # 默认路径安装,以root用户为例(非root用户,将/usr/local替换为${HOME}) |
| 403 | - ```bash | 413 | + source /usr/local/Ascend/cann/set_env.sh |
| 404 | - # 默认路径安装,以root用户为例(非root用户,将/usr/local替换为${HOME}) | 414 | + # 指定路径安装 |
| 405 | - source /usr/local/Ascend/cann/set_env.sh | 415 | + # source ${install_path}/cann/set_env.sh |
| 406 | - # 指定路径安装 | 416 | + ``` |
| 407 | - # source ${install_path}/cann/set_env.sh | ||
| 408 | - ``` | ||
| 409 | 417 | ||
| 410 | 3. **编译自定义算子包。** | 418 | 3. **编译自定义算子包。** |
| 411 | 419 | ||
| 412 | 以`AddExample`算子为例,假设开发交付件在`examples`目录,完整代码参见[add_example](../../../examples/add_example)目录。若编译`experimental`目录下用户自定义算子,编译命令需增加编译参数`--experimental`。 | 420 | 以`AddExample`算子为例,假设开发交付件在`examples`目录,完整代码参见[add_example](../../../examples/add_example)目录。若编译`experimental`目录下用户自定义算子,编译命令需增加编译参数`--experimental`。 |
| 413 | 421 | ||
| 414 | - > 说明:编译过程依赖第三方开源软件,联网场景会自动下载,离线编译场景需要自行安装,具体参考[未联网编译](../invocation/quick_op_invocation.md#未联网编译)。 | 422 | + > 说明:编译过程依赖第三方开源软件,联网场景会自动下载,离线编译场景需要自行安装,具体参考[未联网编译](../install/compile.md#未联网编译)。 |
| 415 | 423 | ||
| 416 | 进入项目根目录,执行如下编译命令。 | 424 | 进入项目根目录,执行如下编译命令。 |
| 417 | 425 | ||
| 418 | ```bash | 426 | ```bash |
| 419 | # 编译指定算子,如bash build.sh --pkg --ops=add_example -j16 | 427 | # 编译指定算子,如bash build.sh --pkg --ops=add_example -j16 |
| 420 | bash build.sh --pkg --soc=${soc_version} --vendor_name=${vendor_name} --ops=${op_list} [-j${n}] | 428 | bash build.sh --pkg --soc=${soc_version} --vendor_name=${vendor_name} --ops=${op_list} [-j${n}] |
| 421 | - | 429 | + |
| 422 | # 编译experimental目录下指定算子 | 430 | # 编译experimental目录下指定算子 |
| 423 | bash build.sh --pkg --soc=${soc_version} --vendor_name=${vendor_name} --ops=${op_list} [--experimental] [-j${n}] | 431 | bash build.sh --pkg --soc=${soc_version} --vendor_name=${vendor_name} --ops=${op_list} [--experimental] [-j${n}] |
| 424 | - | ||
| 425 | ``` | 432 | ``` |
| 426 | 433 | ||
| 427 | - --soc:\$\{soc\_version\}表示NPU型号。Atlas A2系列产品使用"ascend910b"(默认),Atlas A3系列产品使用"ascend910_93",Ascend 950PR/Ascend 950DT产品使用"ascend950"。 | 434 | - --soc:\$\{soc\_version\}表示NPU型号。Atlas A2系列产品使用"ascend910b"(默认),Atlas A3系列产品使用"ascend910_93",Ascend 950PR/Ascend 950DT产品使用"ascend950"。 |
| @@ -439,18 +446,18 @@ __aicore__ inline void AddExample<T>::Process() | |||
| 439 | 4. **安装自定义算子包。** | 446 | 4. **安装自定义算子包。** |
| 440 | 447 | ||
| 441 | 执行以下命令进行安装: | 448 | 执行以下命令进行安装: |
| 442 | - | 449 | + |
| 443 | ```bash | 450 | ```bash |
| 444 | # 安装run包 | 451 | # 安装run包 |
| 445 | ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run | 452 | ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run |
| 446 | ``` | 453 | ``` |
| 447 | 454 | ||
| 448 | - 自定义算子包安装在```${ASCEND_HOME_PATH}/opp/vendors```路径中,```${ASCEND_HOME_PATH}```表示CANN软件安装目录,可提前在环境变量中配置。 | 455 | + 自定义算子包安装在```${ASCEND_HOME_PATH}/opp/vendors```路径中,```${ASCEND_HOME_PATH}```表示CANN软件安装目录,可提前在环境变量中配置。 |
| 449 | 456 | ||
| 450 | 5. **(可选)卸载自定义算子包。** | 457 | 5. **(可选)卸载自定义算子包。** |
| 451 | 458 | ||
| 452 | 自定义算子包安装后在```${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts```目录会生成`uninstall.sh`,通过该脚本可卸载自定义算子包,命令如下: | 459 | 自定义算子包安装后在```${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts```目录会生成`uninstall.sh`,通过该脚本可卸载自定义算子包,命令如下: |
| 453 | - | 460 | + |
| 454 | ```bash | 461 | ```bash |
| 455 | bash ${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts/uninstall.sh | 462 | bash ${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts/uninstall.sh |
| 456 | ``` | 463 | ``` |
| @@ -707,7 +714,6 @@ TEST_F(${OpName}KernelTest, test_case_basic) | |||
| 707 | **3. Tiling数据准备方式** | 714 | **3. Tiling数据准备方式** |
| 708 | 715 | ||
| 709 | - **手动构造**:适合字段少、逻辑简单。 | 716 | - **手动构造**:适合字段少、逻辑简单。 |
| 710 | - | ||
| 711 | - **调用Tiling函数自动生成**:适合字段多、依赖属性/shape复杂。可复用`tests/ut/common/tiling_context_faker.h`与`tiling_case_executor.h`。示例: | 717 | - **调用Tiling函数自动生成**:适合字段多、依赖属性/shape复杂。可复用`tests/ut/common/tiling_context_faker.h`与`tiling_case_executor.h`。示例: |
| 712 | 718 | ||
| 713 | ```CPP | 719 | ```CPP |
| @@ -741,12 +747,16 @@ uint32_t blockDim = tilingInfo.blockNum; | |||
| 741 | export LD_LIBRARY_PATH=${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv/op_api/lib:${LD_LIBRARY_PATH} | 747 | export LD_LIBRARY_PATH=${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv/op_api/lib:${LD_LIBRARY_PATH} |
| 742 | ``` | 748 | ``` |
| 743 | 749 | ||
| 744 | -开发好的算子完成编译部署后,可通过aclnn方式验证功能,方法请参考[算子调用方式](../invocation/op_invocation.md)。 | 750 | +开发好的算子完成编译部署后,可通过aclnn方式验证功能,方法请参考[算子调用方式](../invocation/quick_op_invocation.md)。 |
| 745 | 751 | ||
| 746 | ## 附录 | 752 | ## 附录 |
| 747 | 753 | ||
| 748 | 自定义算子如需运行图模式,不需要aclnn适配,详细内容请参考[图模式开发指南](./graph_develop_guide.md)。 | 754 | 自定义算子如需运行图模式,不需要aclnn适配,详细内容请参考[图模式开发指南](./graph_develop_guide.md)。 |
| 749 | 755 | ||
| 756 | +> 💡 **进阶内容**: | ||
| 757 | +> | ||
| 758 | +> - 关于多芯片代际隔离的详细说明,包括芯片架构映射、隔离位置清单、Kernel入口配置等,请参考[《AI Core算子开发进阶指南 - 代际隔离说明》](./aicore_develop_advanced_guide.md#代际隔离说明)。 | ||
| 759 | + | ||
| 750 | ### 算子工程迁移 | 760 | ### 算子工程迁移 |
| 751 | 761 | ||
| 752 | 由于Ascend/samples工程与本项目工程有差异,在本项目创建工程后(参考[工程创建](#工程创建)),迁移请参考下表中的迁移方法。 | 762 | 由于Ascend/samples工程与本项目工程有差异,在本项目创建工程后(参考[工程创建](#工程创建)),迁移请参考下表中的迁移方法。 |
| @@ -1066,4 +1076,10 @@ template<int D_T_X, int D_T_Y, int D_T_Z, int TILE_NUM, int IS_SPLIT> | |||
| 1066 | <p style="font-size:18px;"><b>op_kernel/{op_name}_tiling_key.h</b></p> | 1076 | <p style="font-size:18px;"><b>op_kernel/{op_name}_tiling_key.h</b></p> |
| 1067 | </div> | 1077 | </div> |
| 1068 | 1078 | ||
| 1069 | -保留原有op_kernel/tiling_key_{op_name}.h中算子的模板参数定义,若不存在op_kernel/tiling_key_{op_name}.h,请参考[add_example_tiling_key.h](../../../examples/add_example/op_kernel/add_example_tiling_key.h)新增定义模板参数和模板参数组合。 | 1079 | +保留原有op\_kernel/tiling\_key\_{op\_name}.h中算子的模板参数定义,若不存在op\_kernel/tiling\_key\_{op\_name}.h,请参考[add_example_tiling_key.h](../../../examples/add_example/op_kernel/add_example_tiling_key.h)新增定义模板参数和模板参数组合。 |
| 1080 | + | ||
| 1081 | +### 算子跨平台迁移 | ||
| 1082 | + | ||
| 1083 | +完成算子代码开发后,如需实现多平台间(如Atlas A2/A3等)的算子代码迁移,需考虑硬件结构差异引发的软件实现变更。 | ||
| 1084 | + | ||
| 1085 | +您可以参考[算子跨平台迁移指导](./cross_platform_migration_guide.md),该文档提供了常见的适配要点与方法论,并提供相关算子的适配样例。 | ||
| @@ -2,34 +2,36 @@ | |||
| 2 | 2 | ||
| 3 | ## 概述 | 3 | ## 概述 |
| 4 | 4 | ||
| 5 | -> 说明: | 5 | +### 使用说明 |
| 6 | -> | ||
| 7 | -> 1. 算子开发过程中涉及的基本概念、AI CPU接口等,详细介绍请参考[《TBE&AI CPU算子开发》](https://hiascend.com/document/redirect/CannCommunityOpdevWizard)。 | ||
| 8 | -> 2. AI CPU算子是使用C++语言开发,运行在AI CPU硬件单元的算子。 | ||
| 9 | -> 3. build.sh:算子开发过程中涉及的命令可通过`bash build.sh --help`查看,功能参数介绍参考[build参数说明](../install/build.md)。 | ||
| 10 | 6 | ||
| 11 | -开发指南以`AddExample`算子开发为例,介绍新算子开发流程以及涉及的交付件,完整样例代码请访问项目`examples`目录。 | 7 | +算子根据运行的硬件单元不同,可分为AI Core算子和AI CPU算子(少数)。前者使用Ascend C语言开发,运行在AI Core硬件单元;后者使用C++语言开发,运行在AI CPU硬件单元。 |
| 12 | 8 | ||
| 13 | -1. [工程创建](#工程创建):开发算子前,需完成环境部署并创建算子目录,方便后续算子编译和部署。 | 9 | +本文重点介绍如何基于标准工程开发AI CPU算子,如果您想贡献AI Core算子,请参考[AI Core算子开发指南](./aicore_develop_guide.md)。 |
| 14 | 10 | ||
| 15 | -2. [算子定义](#算子定义):确定算子功能与原型定义。 | 11 | +算子开发前,请先了解如下信息: |
| 16 | 12 | ||
| 17 | -3. [Kernel实现](#Kernel实现):实现Device侧算子核函数。 | 13 | +- 基础知识:请先学习C++编程语言,了解基本语法和原理,参考[《TBE&AI CPU算子开发》](https://hiascend.com/document/redirect/CannCommunityOpdevWizard)熟悉硬件架构、开发API等。 |
| 18 | 14 | ||
| 19 | -4. [aclnn适配](#aclnn适配):自定义算子推荐aclnn接口调用,需提前完成二进制发布。**如采用图模式调用算子**,请参考[图模式适配指南](./graph_develop_guide.md)。 | 15 | +### 开发流程 |
| 20 | 16 | ||
| 21 | -5. [编译部署](#编译部署):通过工程编译脚本完成自定义算子的编译和安装。 | 17 | +以`AddExample`算子为例,介绍标准AI CPU算子开发的全流程和交付件,完整样例请访问项目`examples`目录。 |
| 22 | 18 | ||
| 23 | -6. [算子验证](#算子验证):通过常见算子调用方式,验证自定义算子功能。 | 19 | +1. [前提条件](../../../README.md):参考项目README完成环境准备和源码下载,此处不再赘述。 |
| 20 | + | ||
| 21 | +2. [工程创建](#工程创建):创建标准算子工程目录,方便后续算子编译和部署。 | ||
| 22 | + | ||
| 23 | +3. [算子定义](#算子定义):确定算子功能与原型定义。 | ||
| 24 | + | ||
| 25 | +4. [Kernel实现](#Kernel实现):实现Device侧算子核函数。 | ||
| 26 | + | ||
| 27 | +5. [aclnn适配](#aclnn适配):自定义算子推荐aclnn接口调用,需提前完成二进制发布。**如采用图模式调用算子**,请参考[图模式适配指南](./graph_develop_guide.md)。 | ||
| 28 | + | ||
| 29 | +6. [编译部署](#编译部署):通过工程编译脚本完成自定义算子的编译和安装。 | ||
| 30 | + | ||
| 31 | +7. [算子验证](#算子验证):通过常见算子调用方式,验证自定义算子功能。 | ||
| 24 | 32 | ||
| 25 | ## 工程创建 | 33 | ## 工程创建 |
| 26 | 34 | ||
| 27 | -**1. 环境部署** | ||
| 28 | - | ||
| 29 | -开发算子前,请先参考[环境部署](../install/quick_install.md)完成基础环境搭建。 | ||
| 30 | - | ||
| 31 | -**2. 目录创建** | ||
| 32 | - | ||
| 33 | 目录创建是算子开发的重要步骤,为后续代码编写、编译构建和调试提供统一的目录结构和文件组织方式。 | 35 | 目录创建是算子开发的重要步骤,为后续代码编写、编译构建和调试提供统一的目录结构和文件组织方式。 |
| 34 | 36 | ||
| 35 | 可通过`build.sh`快速创建算子目录,进入项目根目录,执行如下命令: | 37 | 可通过`build.sh`快速创建算子目录,进入项目根目录,执行如下命令: |
| @@ -49,7 +51,7 @@ Create the AI CPU initial directory for ${op_name} under ${op_class} success | |||
| 49 | 51 | ||
| 50 | 创建完成后,目录结构如下所示: | 52 | 创建完成后,目录结构如下所示: |
| 51 | 53 | ||
| 52 | -```cpp | 54 | +``` |
| 53 | ${op_name} # 替换为实际算子名的小写下划线形式 | 55 | ${op_name} # 替换为实际算子名的小写下划线形式 |
| 54 | ├── examples # 算子调用示例 | 56 | ├── examples # 算子调用示例 |
| 55 | │ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 | 57 | │ └── test_aclnn_${op_name}.cpp # 算子aclnn调用示例 |
| @@ -66,7 +68,7 @@ ${op_name} # 替换为实际算子名的小写下 | |||
| 66 | 68 | ||
| 67 | 若```${op_class}```为全新算子分类需额外在`CMakeLists`中添加`add_subdirectory(${op_class})`,否则无法正常编译。 | 69 | 若```${op_class}```为全新算子分类需额外在`CMakeLists`中添加`add_subdirectory(${op_class})`,否则无法正常编译。 |
| 68 | 70 | ||
| 69 | -```CMake | 71 | +``` |
| 70 | if(ENABLE_EXPERIMENTAL) | 72 | if(ENABLE_EXPERIMENTAL) |
| 71 | # genop新增experimental算子分类 | 73 | # genop新增experimental算子分类 |
| 72 | # add_subdirectory(${op_class}) | 74 | # add_subdirectory(${op_class}) |
| @@ -210,36 +212,36 @@ REGISTER_CPU_KERNEL(kAddExample, AddExampleCpuKernel); | |||
| 210 | 以`AddExample`算子为例,假设开发交付件在`examples`目录,完整代码参见[add_example_aicpu](../../../examples/add_example_aicpu)目录。 | 212 | 以`AddExample`算子为例,假设开发交付件在`examples`目录,完整代码参见[add_example_aicpu](../../../examples/add_example_aicpu)目录。 |
| 211 | 213 | ||
| 212 | ```bash | 214 | ```bash |
| 213 | - # 编译指定算子,如bash build.sh --pkg --ops=add_example | 215 | + # 编译指定算子,如bash build.sh --pkg --ops=add_example -j16 |
| 214 | - bash build.sh --pkg --soc=${soc_version} --vendor_name=${vendor_name} --ops=${op_list} [--experimental] | 216 | + bash build.sh --pkg --soc=${soc_version} --vendor_name=${vendor_name} --ops=${op_list} [--experimental] [-j${n}] |
| 215 | ``` | 217 | ``` |
| 216 | 218 | ||
| 217 | - - --soc:\$\{soc\_version\}表示NPU型号。Atlas A2系列产品使用"ascend910b"(默认),Atlas A3系列产品使用"ascend910_93",Ascend 950PR/Ascend 950DT产品使用"ascend950"。 | 219 | + - --soc:\$\{soc\_version\}表示NPU型号。Atlas A2系列产品使用"ascend910b"(默认),Atlas A3系列产品使用"ascend910_93",Ascend 950PR/Ascend 950DT产品使用"ascend950"。 |
| 218 | - - --vendor_name(可选):\$\{vendor\_name\}表示构建的自定义算子包名,默认名为custom。 | 220 | + - --vendor_name(可选):\$\{vendor\_name\}表示构建的自定义算子包名,默认名为custom。 |
| 219 | - - --ops(可选):\$\{op\_list\}表示待编译算子,不指定时默认编译所有算子。格式形如"--ops=add_example"。 | 221 | + - --ops(可选):\$\{op\_list\}表示待编译算子,不指定时默认编译所有算子。格式形如"--ops=add_example"。 |
| 220 | - - --experimental(可选):若编译的算子为贡献算子,需配置--experimental。 | 222 | + - --experimental(可选):若编译的算子为贡献算子,需配置--experimental。 |
| 221 | - | 223 | + - -j(可选):指定编译线程数,加快编译速度。 |
| 224 | + | ||
| 222 | 若提示如下信息,说明编译成功: | 225 | 若提示如下信息,说明编译成功: |
| 223 | - | 226 | + |
| 224 | ```bash | 227 | ```bash |
| 225 | Self-extractable archive "cann-ops-cv-${vendor_name}_linux-${arch}.run" successfully created. | 228 | Self-extractable archive "cann-ops-cv-${vendor_name}_linux-${arch}.run" successfully created. |
| 226 | ``` | 229 | ``` |
| 227 | - | 230 | + |
| 228 | 3. **安装自定义算子包。** | 231 | 3. **安装自定义算子包。** |
| 229 | 232 | ||
| 230 | ```bash | 233 | ```bash |
| 231 | # 安装run包 | 234 | # 安装run包 |
| 232 | ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run | 235 | ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run |
| 233 | ``` | 236 | ``` |
| 234 | - | ||
| 235 | 自定义算子包安装在```${ASCEND_HOME_PATH}/opp/vendors```路径中,```${ASCEND_HOME_PATH}```表示CANN软件安装目录,可提前在环境变量中配置。 | 237 | 自定义算子包安装在```${ASCEND_HOME_PATH}/opp/vendors```路径中,```${ASCEND_HOME_PATH}```表示CANN软件安装目录,可提前在环境变量中配置。 |
| 238 | + | ||
| 239 | +4. **(可选)卸载自定义算子包。** | ||
| 236 | 240 | ||
| 237 | -4. **(可选)卸载自定义算子包** | 241 | + 自定义算子包安装后在```${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts```目录会生成`uninstall.sh`,通过该脚本可卸载自定义算子包,命令如下: |
| 238 | - | 242 | + |
| 239 | - 自定义算子包安装后在```${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv/scripts```目录下会生成`uninstall.sh`脚本,通过执行该脚本可卸载自定义算子包,具体命令如下: | ||
| 240 | - | ||
| 241 | ```bash | 243 | ```bash |
| 242 | - bash ${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv/scripts/uninstall.sh | 244 | + bash ${ASCEND_HOME_PATH}/opp/vendors/custom_cv/scripts/uninstall.sh |
| 243 | ``` | 245 | ``` |
| 244 | 246 | ||
| 245 | ## 算子验证 | 247 | ## 算子验证 |
| @@ -253,8 +255,8 @@ export ASCEND_CUSTOM_OPP_PATH=${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv | |||
| 253 | 255 | ||
| 254 | - **UT验证** | 256 | - **UT验证** |
| 255 | 257 | ||
| 256 | - 算子开发过程中,可通过UT验证(如Kernel)方式进行快速验证。 | 258 | + 算子开发过程中,可通过UT验证(如Kernel)方式进行快速验证,如需查看详细实现,请参考[Kernel UT](../../../examples/add_example_aicpu/tests/ut/op_kernel_aicpu/test_add_example.cpp)。 |
| 257 | 259 | ||
| 258 | - **aclnn调用验证** | 260 | - **aclnn调用验证** |
| 259 | 261 | ||
| 260 | - 开发好的算子完成编译部署后,可通过aclnn方式验证功能,方法请参考[算子调用方式](../invocation/op_invocation.md)。 | 262 | + 开发好的算子完成编译部署后,可通过aclnn方式验证功能,方法请参考[算子调用方式](../invocation/quick_op_invocation.md)。 |
| @@ -1,4 +1,4 @@ | |||
| 1 | -# 跨平台迁移指导 | 1 | +# 算子跨平台迁移指导 |
| 2 | 2 | ||
| 3 | 本指南介绍算子在多平台间迁移的适配要点与方案。以算子从Atlas A2系列迁移至Ascend 950系列为例,对比硬件架构差异项及所涉适配点,并提供相关算子适配样例。 | 3 | 本指南介绍算子在多平台间迁移的适配要点与方案。以算子从Atlas A2系列迁移至Ascend 950系列为例,对比硬件架构差异项及所涉适配点,并提供相关算子适配样例。 |
| 4 | 4 | ||
| @@ -0,0 +1,298 @@ | |||
| 1 | +# 源码构建 | ||
| 2 | + | ||
| 3 | +源码构建前,请参考本项目README完成环境准备和源码下载,此处不再赘述。 | ||
| 4 | + | ||
| 5 | +## 安装构建工具 | ||
| 6 | + | ||
| 7 | +> **说明**:对于WebIDE或Docker环境,默认已安装源码编译所需的构建工具,无需手动安装,可跳过本章操作。 | ||
| 8 | + | ||
| 9 | +请先确保编译环境的基础库依赖已安装,注意满足版本号要求。 | ||
| 10 | + | ||
| 11 | +- python >= 3.7.0(建议版本 <= 3.10) | ||
| 12 | +- gcc >= 7.3.0 | ||
| 13 | +- cmake >= 3.16.0 | ||
| 14 | +- pigz(可选,安装后可提升打包速度,建议版本 >= 2.4) | ||
| 15 | +- dos2unix | ||
| 16 | +- gawk | ||
| 17 | +- make | ||
| 18 | +- patch | ||
| 19 | +- googletest(仅执行UT时依赖,建议版本 [release-1.11.0](https://github.com/google/googletest/releases/tag/release-1.11.0)) | ||
| 20 | + | ||
| 21 | +上述依赖可通过项目根目录install\_deps.sh一键安装,命令如下,若遇到不支持系统,请参考该文件自行适配。 | ||
| 22 | + | ||
| 23 | +```bash | ||
| 24 | +bash install_deps.sh | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +安装完上述依赖后,可通过项目根目录requirements.txt继续安装python三方库依赖,命令如下。 | ||
| 28 | + | ||
| 29 | +```bash | ||
| 30 | +pip3 install -r requirements.txt | ||
| 31 | +``` | ||
| 32 | + | ||
| 33 | +## 安装第三方依赖 | ||
| 34 | + | ||
| 35 | +> **说明**:对于WebIDE或Docker环境,默认联网,编译过程中会自动下载第三方依赖,无需手动安装,可跳过本章操作。 | ||
| 36 | + | ||
| 37 | +本项目编译过程依赖的第三方开源软件列表如下: | ||
| 38 | + | ||
| 39 | +| 开源软件 | 版本 | 下载地址 | | ||
| 40 | +|---|---|---| | ||
| 41 | +| json | 3.11.3 | [include.zip](https://gitcode.com/cann-src-third-party/json/releases/download/v3.11.3/include.zip) | | ||
| 42 | +| makeself | 2.5.0 | [makeself-release-2.5.0-patch1.tar.gz](https://gitcode.com/cann-src-third-party/makeself/releases/download/release-2.5.0-patch1.0/makeself-release-2.5.0-patch1.tar.gz) | | ||
| 43 | +| eigen | 5.0.0 | [eigen-5.0.0.tar.gz](https://gitcode.com/cann-src-third-party/eigen/releases/download/5.0.0-h0.trunk/eigen-5.0.0.tar.gz) | | ||
| 44 | +| protobuf | 25.1.0 | [protobuf-25.1.tar.gz](https://gitcode.com/cann-src-third-party/protobuf/releases/download/v25.1/protobuf-25.1.tar.gz) | | ||
| 45 | +| abseil-cpp | 20230802.1 | [abseil-cpp-20230802.1.tar.gz](https://gitcode.com/cann-src-third-party/abseil-cpp/releases/download/20230802.1/abseil-cpp-20230802.1.tar.gz) | | ||
| 46 | +| opbase(自CANN 9.0.0及以后版本需要下载) | master | [opbase](https://gitcode.com/cann/opbase) | | ||
| 47 | + | ||
| 48 | +若您的编译环境可以访问网络,请参考[联网编译](#联网编译),编译脚本会自动联网下载第三方软件。否则,请参考[未联网编译](#未联网编译)手动下载第三方软件。 | ||
| 49 | + | ||
| 50 | +准备好开源第三方软件后,可采用如下编译方式,请按需选择: | ||
| 51 | + | ||
| 52 | +- **自定义算子包**: | ||
| 53 | + | ||
| 54 | + 选择部分算子编译生成的包称为自定义算子包,以**挂载**形式作用于CANN包,不改变原始包内容。生成的自定义算子包优先级高于原始CANN包。该包支持aclnn和图模式调用AI Core、AI CPU算子。 | ||
| 55 | + | ||
| 56 | +- **ops-cv包**: | ||
| 57 | + | ||
| 58 | + 选择整个项目编译生成的包称为ops-cv包,可**完整替换**CANN包对应部分。该包支持aclnn和图模式调用AI Core算子。 | ||
| 59 | + | ||
| 60 | +- **ops-cv静态库**: | ||
| 61 | + | ||
| 62 | + > 说明:若您需要**基于本项目进行二次发布**并且对**软件包大小有要求**时,建议采用静态库编译,该库可以链接您的应用开发程序,仅保留业务所需的算子,从而实现软件最小化部署。 | ||
| 63 | + | ||
| 64 | + 表示整个项目编译为一个静态库文件,包含libcann_cv_static.a和aclnn接口头文件。该包仅支持aclnn调用AI Core算子。 | ||
| 65 | + | ||
| 66 | +## 联网编译 | ||
| 67 | + | ||
| 68 | +若在有互联网的环境下编译,编译过程中会自动安装第三方依赖,无需手动安装。不同场景下源码编译和部署命令如下: | ||
| 69 | + | ||
| 70 | +### 自定义算子包 | ||
| 71 | + | ||
| 72 | +1. **编译自定义算子包** | ||
| 73 | + | ||
| 74 | + 进入项目根目录,执行如下编译命令: | ||
| 75 | + | ||
| 76 | + ```bash | ||
| 77 | + bash build.sh --pkg --soc=${soc_version} [--vendor_name=${vendor_name}] [--ops=${op_list}] [-j${n}] | ||
| 78 | + # 以GridSample算子编译为例 | ||
| 79 | + # bash build.sh --pkg --soc=ascend910b --ops=grid_sample -j16 | ||
| 80 | + # 编译experimental贡献目录下的用户算子(以GridSample算子为例,编译时请以实际贡献算子为准) | ||
| 81 | + # bash build.sh --pkg --experimental --soc=ascend910b --ops=grid_sample -j16 | ||
| 82 | + ``` | ||
| 83 | + | ||
| 84 | + - --soc:\$\{soc\_version\}表示NPU型号。Atlas A2 训练系列产品/Atlas A2 推理系列产品使用"ascend910b"(默认),Atlas A3 训练系列产品/Atlas A3 推理系列产品使用"ascend910_93",Ascend 950PR/Ascend 950DT产品使用"ascend950"。 | ||
| 85 | + - --vendor_name(可选):\$\{vendor\_name\}表示构建的自定义算子包名,默认名为custom。 | ||
| 86 | + - --ops(可选):\$\{op\_list\}表示待编译算子,不指定时默认编译所有算子。格式形如"grid_sample,iou_v2,...",多算子之间用英文逗号","分隔。 | ||
| 87 | + - --experimental(可选):表示编译用户保存在experimental贡献目录下的算子。 | ||
| 88 | + - -j(可选):指定编译线程数,加快编译速度。 | ||
| 89 | + | ||
| 90 | + 若\$\{vendor\_name\}和\$\{op\_list\}都不传入编译的是ops-cv包;若编译所有算子的自定义算子包,需传入\$\{vendor\_name\}。当提示如下信息,说明编译成功。 | ||
| 91 | + | ||
| 92 | + ```bash | ||
| 93 | + Self-extractable archive "cann-ops-cv-${vendor_name}_linux-${arch}.run" successfully created. | ||
| 94 | + ``` | ||
| 95 | + | ||
| 96 | + 编译成功后,run包存放于项目根目录的build_out目录下。 | ||
| 97 | + | ||
| 98 | +2. **安装自定义算子包** | ||
| 99 | + | ||
| 100 | + ```bash | ||
| 101 | + ./build_out/cann-ops-cv-${vendor_name}_linux-${arch}.run | ||
| 102 | + ``` | ||
| 103 | + | ||
| 104 | + 自定义算子包默认安装路径为```${ASCEND_HOME_PATH}/opp/vendors```,\$\{ASCEND\_HOME\_PATH\}已通过环境变量配置,表示CANN toolkit包安装路径,一般为\$\{install\_path\}/cann。 | ||
| 105 | + | ||
| 106 | + > 说明:可通过配置--install-path=\$\{install\_path\}参数定义算子包安装目录,在使用自定义算子包前,需执行source \$\{install_path\}/vendors/${vendor_name}/bin/set_env.bash命令,set\_env.bash脚本将自定义算子包安装路径追加到环境变量ASCEND\_CUSTOM\_OPP\_PATH中,使自定义算子包在当前环境中生效。 | ||
| 107 | + | ||
| 108 | +3. **(可选)卸载自定义算子包。** | ||
| 109 | + | ||
| 110 | + 自定义算子包安装后在```${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv/scripts```目录会生成`uninstall.sh`,通过该脚本可卸载自定义算子包,命令如下: | ||
| 111 | + | ||
| 112 | + ```bash | ||
| 113 | + bash ${ASCEND_HOME_PATH}/opp/vendors/${vendor_name}_cv/scripts/uninstall.sh | ||
| 114 | + ``` | ||
| 115 | + | ||
| 116 | +### ops-cv包 | ||
| 117 | + | ||
| 118 | +1. **编译ops-cv包** | ||
| 119 | + | ||
| 120 | + 进入项目根目录,执行如下编译命令: | ||
| 121 | + | ||
| 122 | + ```bash | ||
| 123 | + # 编译除experimental目录外的所有算子 | ||
| 124 | + bash build.sh --pkg --soc=${soc_version} [-j${n}] | ||
| 125 | + # 编译experimental目录下的所有算子 | ||
| 126 | + # bash build.sh --pkg --experimental --soc=${soc_version} [-j${n}] | ||
| 127 | + ``` | ||
| 128 | + | ||
| 129 | + - --soc:\$\{soc\_version\}表示NPU型号。Atlas A2 训练系列产品/Atlas A2 推理系列产品使用"ascend910b"(默认),Atlas A3 训练系列产品/Atlas A3 推理系列产品使用"ascend910_93",Ascend 950PR/Ascend 950DT产品使用"ascend950"。 | ||
| 130 | + - --experimental(可选):表示编译用户保存在experimental目录下的算子。 | ||
| 131 | + - -j(可选):指定编译线程数,加快编译速度。 | ||
| 132 | + | ||
| 133 | + 若提示如下信息,说明编译成功。 | ||
| 134 | + | ||
| 135 | + ```bash | ||
| 136 | + Self-extractable archive "cann-${soc_name}-ops-cv_${cann_version}_linux-${arch}.run" successfully created. | ||
| 137 | + ``` | ||
| 138 | + | ||
| 139 | + \$\{soc\_name\}表示NPU型号名称,即\$\{soc\_version\}删除“ascend”后剩余的内容。编译成功后,run包存放于build_out目录下。 | ||
| 140 | + | ||
| 141 | +2. **安装ops-cv包** | ||
| 142 | + | ||
| 143 | + ```bash | ||
| 144 | + # 安装命令 | ||
| 145 | + ./build_out/cann-${soc_name}-ops-cv_${cann_version}_linux-${arch}.run --full --install-path=${install_path} | ||
| 146 | + ``` | ||
| 147 | + | ||
| 148 | + \$\{install\_path\}:表示指定安装路径,需要与toolkit包安装在相同路径,默认安装在`/usr/local/Ascend`目录。 | ||
| 149 | + | ||
| 150 | +3. **(可选)卸载ops-cv包** | ||
| 151 | + | ||
| 152 | + ```bash | ||
| 153 | + # 卸载命令 | ||
| 154 | + ./${install_path}/cann/share/info/ops_cv/script/uninstall.sh | ||
| 155 | + ``` | ||
| 156 | + | ||
| 157 | +### ops-cv静态库 | ||
| 158 | + | ||
| 159 | +> 说明:静态库仅支持Atlas A2、Atlas A3系列产品、Ascend950PR/Ascend 950DT产品。experimental算子暂不支持使用静态库。 | ||
| 160 | + | ||
| 161 | +1. **编译ops-cv静态库** | ||
| 162 | + | ||
| 163 | + 进入项目根目录,执行如下编译命令: | ||
| 164 | + | ||
| 165 | + ```bash | ||
| 166 | + bash build.sh --pkg --static --soc=${soc_version} [-j${n}] | ||
| 167 | + ``` | ||
| 168 | + | ||
| 169 | + - --soc:\$\{soc\_version\}表示NPU型号。Atlas A2系列产品使用"ascend910b"(默认),Atlas A3系列产品使用"ascend910_93",Ascend950PR/Ascend 950DT产品使用"ascend950"。 | ||
| 170 | + - -j(可选):指定编译线程数,加快编译速度。 | ||
| 171 | + 若提示如下信息,说明编译并压缩成功。 | ||
| 172 | + | ||
| 173 | + ```bash | ||
| 174 | + [SUCCESS] Build static lib success! | ||
| 175 | + Successfully created compressed package: ${repo_path}/build_out/cann-${soc_name}-ops-cv-static_${cann_version}_linux-${arch}.tar.gz | ||
| 176 | + ``` | ||
| 177 | + | ||
| 178 | + \$\{repo\_path\}表示项目根目录,\$\{soc\_name\}表示NPU型号名称,即\$\{soc\_version\}删除“ascend”后剩余的内容。编译成功后,压缩包存放于build_out目录下。 | ||
| 179 | + | ||
| 180 | +2. **解压ops-cv静态库** | ||
| 181 | + | ||
| 182 | + 进入build_out目录执行解压命令: | ||
| 183 | + | ||
| 184 | + ```bash | ||
| 185 | + tar -zxvf ./cann-${soc_name}-ops-cv-static_${cann_version}_linux-${arch}.tar.gz -C ${static_lib_path} | ||
| 186 | + ``` | ||
| 187 | + | ||
| 188 | + \$\{static\_lib\_path\}表示静态库解压路径。解压后目录结构如下: | ||
| 189 | + | ||
| 190 | + ``` | ||
| 191 | + ├── cann-${soc_name}-ops-cv-static_${cann_version}_linux-${arch} | ||
| 192 | + │ ├── lib64 | ||
| 193 | + │ │ ├── libcann_cv_static.a # 静态库文件 | ||
| 194 | + │ └── include | ||
| 195 | + | ├── ... # aclnn接口头文件 | ||
| 196 | + ``` | ||
| 197 | + | ||
| 198 | +## 未联网编译 | ||
| 199 | + | ||
| 200 | +若在没有连接互联网的环境下编译,需要提前准备好依赖的第三方软件,再进行源码编译。具体过程如下: | ||
| 201 | + | ||
| 202 | +2. **下载第三方依赖** | ||
| 203 | + | ||
| 204 | + 在联网环境中提前下载第三方软件,目前有如下方式,请按需选择: | ||
| 205 | + | ||
| 206 | + - 方式1:根据[第三方软件依赖](#第三方软件依赖)提供的表格手动下载,若从其他地址下载,请确保版本号一致。 | ||
| 207 | + | ||
| 208 | + - 方式2:通过[third_lib_download.py](../../../scripts/tools/third_lib_download.py)脚本一键下载,该脚本在本项目`scripts/tools/`目录,下载该脚本并执行如下命令: | ||
| 209 | + | ||
| 210 | + ```bash | ||
| 211 | + python ${scripts_dir}/third_lib_download.py | ||
| 212 | + ``` | ||
| 213 | + | ||
| 214 | + \$\{scripts\_dir\}表示脚本存放路径,下载的第三方软件包默认存放在当前脚本所在目录。 | ||
| 215 | + | ||
| 216 | +3. **编译算子包** | ||
| 217 | + | ||
| 218 | + 将下载好的第三方软件上传至离线环境,可存放在`third_party`目录或自定义目录下。**推荐前者,其编译命令与联网编译场景下的命令一致。** | ||
| 219 | + | ||
| 220 | + - **third\_party目录**(推荐) | ||
| 221 | + | ||
| 222 | + 请在本项目根目录创建`third_party`目录(若有则无需创建),将第三方软件拷贝到该指定目录。此时编译命令与联网编译命令一致,具体参考[联网编译](#联网编译)。 | ||
| 223 | + | ||
| 224 | + - **自定义目录** | ||
| 225 | + | ||
| 226 | + 在离线环境的任意位置新建`${cann_3rd_lib_path}`目录,将第三方软件拷贝到该目录,请确保该目录有权限访问。 | ||
| 227 | + | ||
| 228 | + ```bash | ||
| 229 | + mkdir -p ${cann_3rd_lib_path} | ||
| 230 | + ``` | ||
| 231 | + | ||
| 232 | + 此时编译命令需在联网编译命令基础上额外增加`--cann_3rd_lib_path=${cann_3rd_lib_path}`用于指定第三方软件所在路径。假设存放路径为`/path/cann_3rd_lib_path`,不同编译方式对应的命令如下: | ||
| 233 | + | ||
| 234 | + - 自定义算子包 | ||
| 235 | + | ||
| 236 | + ```bash | ||
| 237 | + bash build.sh --pkg --soc=${soc_version} [--vendor_name=${vendor_name}] [--ops=${op_list}] --cann_3rd_lib_path=${cann_3rd_lib_path} | ||
| 238 | + # 以GridSample算子编译为例 | ||
| 239 | + # bash build.sh --pkg --soc=ascend910b --ops=grid_sample -j16 --cann_3rd_lib_path=/path/cann_3rd_lib_path | ||
| 240 | + ``` | ||
| 241 | + | ||
| 242 | + - ops-cv整包 | ||
| 243 | + | ||
| 244 | + ```bash | ||
| 245 | + bash build.sh --pkg --soc=${soc_version} --cann_3rd_lib_path=${cann_3rd_lib_path} | ||
| 246 | + # bash build.sh --pkg --soc=ascend910b --cann_3rd_lib_path=/path/cann_3rd_lib_path | ||
| 247 | + ``` | ||
| 248 | + | ||
| 249 | + - ops-cv静态库 | ||
| 250 | + | ||
| 251 | + ```bash | ||
| 252 | + bash build.sh --pkg --static --soc=${soc_version} --cann_3rd_lib_path=${cann_3rd_lib_path} | ||
| 253 | + # bash build.sh --pkg --static --soc=ascend910b --cann_3rd_lib_path=/path/cann_3rd_lib_path | ||
| 254 | + ``` | ||
| 255 | + | ||
| 256 | +4. **安装/卸载算子包** | ||
| 257 | + | ||
| 258 | + 未联网和联网场景下编译得到算子包结果一样,默认存放于项目根目录build_out目录下,并且安装和卸载的操作命令也一样,具体参见[联网编译](#联网编译)。 | ||
| 259 | + | ||
| 260 | +## 本地验证 | ||
| 261 | + | ||
| 262 | +源码包部署后,可通过项目根目录build.sh执行UT用例,验证项目功能是否正常。 | ||
| 263 | + | ||
| 264 | +> 说明:执行UT用例依赖googletest单元测试框架,详细介绍参见[googletest官网](https://google.github.io/googletest/advanced.html#running-a-subset-of-the-tests)。 | ||
| 265 | + | ||
| 266 | +```bash | ||
| 267 | +# 安装根目录下test相关requirements.txt依赖 | ||
| 268 | +pip3 install -r tests/requirements.txt | ||
| 269 | +# 方式1: 编译并执行指定算子和对应功能的UT测试用例(选其一) | ||
| 270 | +bash build.sh -u --[opapi|ophost|opkernel] --ops=grid_sample | ||
| 271 | +# 方式2: 编译并执行所有的UT测试用例 | ||
| 272 | +# bash build.sh -u | ||
| 273 | +# 方式3: 编译所有的UT测试用例但不执行 | ||
| 274 | +# bash build.sh -u --noexec | ||
| 275 | +# 方式4: 编译并执行对应功能的UT测试用例(选其一) | ||
| 276 | +# bash build.sh -u --[opapi|ophost|opkernel] | ||
| 277 | +# 方式5: 编译对应功能的UT测试用例但不执行(选其一) | ||
| 278 | +# bash build.sh -u --noexec --[opapi|ophost|opkernel] | ||
| 279 | +# 方式6: 执行UT测试用例时可指定soc编译 | ||
| 280 | +# bash build.sh -u --[opapi|ophost|opkernel] [--soc=${soc_version}] | ||
| 281 | +``` | ||
| 282 | + | ||
| 283 | +以验证ophost功能是否正常为例,执行如下命令: | ||
| 284 | + | ||
| 285 | +```bash | ||
| 286 | +bash build.sh -u --ophost | ||
| 287 | +``` | ||
| 288 | + | ||
| 289 | +执行完成后出现如下内容,表示执行成功。 | ||
| 290 | + | ||
| 291 | +```bash | ||
| 292 | +Global Environment TearDown | ||
| 293 | +[==========] ${n} tests from ${m} test suites ran. (${x} ms total) | ||
| 294 | +[ PASSED ] ${n} tests. | ||
| 295 | +[100%] Built target cv_op_host_ut | ||
| 296 | +``` | ||
| 297 | + | ||
| 298 | +\$\{n\}表示执行了n个用例,\$\{m\}表示m项测试,\$\{x\}表示执行用例消耗的时间,单位为毫秒。 | ||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | 在学习[QuickStart](../../QUICKSTART.md)或各类[学习教程](../../../README.md#学习教程)操作之前,请您先参考下面步骤完成基础环境搭建和源码下载,确保已安装NPU驱动、固件和CANN软件(`Ascend-cann-toolkit`和`Ascend-cann-ops`)等。 | 3 | 在学习[QuickStart](../../QUICKSTART.md)或各类[学习教程](../../../README.md#学习教程)操作之前,请您先参考下面步骤完成基础环境搭建和源码下载,确保已安装NPU驱动、固件和CANN软件(`Ascend-cann-toolkit`和`Ascend-cann-ops`)等。 |
| 4 | 4 | ||
| 5 | -## 环境准备 | 5 | +## 环境安装 |
| 6 | 6 | ||
| 7 | 本项目提供多种搭建昇腾环境的方式,请按需选择。 | 7 | 本项目提供多种搭建昇腾环境的方式,请按需选择。 |
| 8 | 8 | ||
| @@ -84,32 +84,6 @@ docker run --name cann_container --device /dev/davinci0 --device /dev/davinci_ma | |||
| 84 | 84 | ||
| 85 | 对于有昇腾设备的开发者,若您想手动搭建昇腾环境,请参考下述步骤。 | 85 | 对于有昇腾设备的开发者,若您想手动搭建昇腾环境,请参考下述步骤。 |
| 86 | 86 | ||
| 87 | -#### 前置依赖 | ||
| 88 | - | ||
| 89 | -请先确保编译环境的基础库依赖已安装,注意满足版本号要求。 | ||
| 90 | - | ||
| 91 | -- python >= 3.7.0 | ||
| 92 | -- gcc >= 7.3.0 | ||
| 93 | -- cmake >= 3.16.0 | ||
| 94 | -- pigz(可选,安装后可提升打包速度,建议版本 >= 2.4) | ||
| 95 | -- dos2unix | ||
| 96 | -- gawk | ||
| 97 | -- make | ||
| 98 | -- patch | ||
| 99 | -- googletest(仅执行UT时依赖,建议版本 [release-1.11.0](https://github.com/google/googletest/releases/tag/release-1.11.0)) | ||
| 100 | - | ||
| 101 | -上述依赖可通过项目根目录install\_deps.sh一键安装,命令如下,若遇到不支持系统,请参考该文件自行适配。 | ||
| 102 | - | ||
| 103 | -```bash | ||
| 104 | -bash install_deps.sh | ||
| 105 | -``` | ||
| 106 | - | ||
| 107 | -安装完上述依赖后,可通过项目根目录requirements.txt继续安装python三方库依赖,命令如下。 | ||
| 108 | - | ||
| 109 | -```bash | ||
| 110 | -pip3 install -r requirements.txt | ||
| 111 | -``` | ||
| 112 | - | ||
| 113 | #### 软件安装 | 87 | #### 软件安装 |
| 114 | 88 | ||
| 115 | - **场景1:体验master版本能力或基于master版本进行开发** | 89 | - **场景1:体验master版本能力或基于master版本进行开发** |
| @@ -122,30 +96,30 @@ pip3 install -r requirements.txt | |||
| 122 | 96 | ||
| 123 | 请单击[下载链接](https://ascend.devcloud.huaweicloud.com/artifactory/cann-run-mirror/software/master/),选择最新时间版本,并根据产品型号和环境架构下载对应包。安装命令如下,更多指导参考《[CANN软件安装指南](https://www.hiascend.com/document/redirect/CannCommunityInstWizard)》。 | 97 | 请单击[下载链接](https://ascend.devcloud.huaweicloud.com/artifactory/cann-run-mirror/software/master/),选择最新时间版本,并根据产品型号和环境架构下载对应包。安装命令如下,更多指导参考《[CANN软件安装指南](https://www.hiascend.com/document/redirect/CannCommunityInstWizard)》。 |
| 124 | 98 | ||
| 125 | - - 安装CANN toolkit包 | 99 | + - 安装CANN toolkit包 |
| 126 | 100 | ||
| 127 | - ```bash | 101 | + ```bash |
| 128 | - # 确保安装包具有可执行权限 | 102 | + # 确保安装包具有可执行权限 |
| 129 | - chmod +x Ascend-cann-toolkit_${cann_version}_linux-${arch}.run | 103 | + chmod +x Ascend-cann-toolkit_${cann_version}_linux-${arch}.run |
| 130 | - # 安装命令 | 104 | + # 安装命令 |
| 131 | - ./Ascend-cann-toolkit_${cann_version}_linux-${arch}.run --install -install-path=${install_path} | 105 | + ./Ascend-cann-toolkit_${cann_version}_linux-${arch}.run --install --install-path=${install_path} |
| 132 | - ``` | 106 | + ``` |
| 133 | 107 | ||
| 134 | - - 安装CANN ops包(运行态依赖) | 108 | + - 安装CANN ops包(运行态依赖) |
| 135 | 109 | ||
| 136 | - ops包是运行态依赖,若仅编译算子,可不安装此包。 | 110 | + ops包是运行态依赖,若仅编译算子,可不安装此包。 |
| 137 | 111 | ||
| 138 | - ```bash | 112 | + ```bash |
| 139 | - # 确保安装包具有可执行权限 | 113 | + # 确保安装包具有可执行权限 |
| 140 | - chmod +x Ascend-cann-${soc_name}-ops_${cann_version}_linux-${arch}.run | 114 | + chmod +x Ascend-cann-${soc_name}-ops_${cann_version}_linux-${arch}.run |
| 141 | - # 安装命令 | 115 | + # 安装命令 |
| 142 | - ./Ascend-cann-${soc_name}-ops_${cann_version}_linux-${arch}.run --install --install-path=${install_path} | 116 | + ./Ascend-cann-${soc_name}-ops_${cann_version}_linux-${arch}.run --install --install-path=${install_path} |
| 143 | - ``` | 117 | + ``` |
| 144 | - | 118 | + |
| 145 | - - \$\{cann\_version\}:表示CANN包版本号。 | 119 | + - \$\{cann\_version\}:表示CANN包版本号。 |
| 146 | - - \$\{arch\}:表示CPU架构,如aarch64、x86_64。 | 120 | + - \$\{arch\}:表示CPU架构,如aarch64、x86_64。 |
| 147 | - - \$\{soc\_name\}:表示NPU型号名称。 | 121 | + - \$\{soc\_name\}:表示NPU型号名称。 |
| 148 | - - \$\{install\_path\}:表示指定安装路径,ops包需与toolkit包安装在相同路径,root 用户默认安装在`/usr/local/Ascend`目录。 | 122 | + - \$\{install\_path\}:表示指定安装路径,ops包需与toolkit包安装在相同路径,root用户默认安装在`/usr/local/Ascend`目录。 |
| 149 | 123 | ||
| 150 | - **场景2:体验已发布版本能力或基于已发布版本进行开发** | 124 | - **场景2:体验已发布版本能力或基于已发布版本进行开发** |
| 151 | 125 | ||
| @@ -164,8 +138,6 @@ pip3 install -r requirements.txt | |||
| 164 | 138 | ||
| 165 | - **检查CANN版本** | 139 | - **检查CANN版本** |
| 166 | 140 | ||
| 167 | -- **检查CANN安装** | ||
| 168 | - | ||
| 169 | ```bash | 141 | ```bash |
| 170 | # 查看CANN toolkit包版本信息(默认路径安装),WebIDE场景下将/usr/local替换为/home/developer | 142 | # 查看CANN toolkit包版本信息(默认路径安装),WebIDE场景下将/usr/local替换为/home/developer |
| 171 | cat /usr/local/Ascend/cann/${arch}-linux/ascend_toolkit_install.info | 143 | cat /usr/local/Ascend/cann/${arch}-linux/ascend_toolkit_install.info |
| @@ -183,19 +155,3 @@ source /usr/local/Ascend/cann/set_env.sh | |||
| 183 | # 指定路径安装 | 155 | # 指定路径安装 |
| 184 | # source ${install_path}/cann/set_env.sh | 156 | # source ${install_path}/cann/set_env.sh |
| 185 | ``` | 157 | ``` |
| 186 | - | ||
| 187 | -## 源码下载 | ||
| 188 | - | ||
| 189 | -请根据CANN软件版本下载对应分支源码,\$\{tag\_version\}表示分支标签名,分支标签与CANN版本配套关系参见[release仓库](https://gitcode.com/cann/release-management)。 | ||
| 190 | - | ||
| 191 | -```bash | ||
| 192 | -# 下载项目对应分支源码 | ||
| 193 | -git clone -b ${tag_version} https://gitcode.com/cann/ops-cv.git | ||
| 194 | -``` | ||
| 195 | - | ||
| 196 | -对于WebIDE环境,**已默认提供最新商发版本的项目源码**,如需获取其他版本源码,也需通过上述命令下载源码。 | ||
| 197 | - | ||
| 198 | -> [!NOTE] 注意 | ||
| 199 | -> | ||
| 200 | -> - gitcode平台在使用HTTPS协议的时候要配置并使用个人访问令牌代替登录密码进行克隆,推送等操作。 | ||
| 201 | -> - 若您的编译环境无法访问网络,无法通过git指令下载代码,请先在联网环境中下载源码,再手动上传至目标环境。 | ||
| @@ -1,372 +0,0 @@ | |||
| 1 | -# 算子调用方式 | ||
| 2 | - | ||
| 3 | -## 概述 | ||
| 4 | - | ||
| 5 | -算子可通过多种方式调用,本章以`AddExample`算子调用为例,详细介绍算子调用和执行过程。 | ||
| 6 | - | ||
| 7 | -> 说明:优先推荐aclnn接口方式调用,若不支持该方式,可采用构图方式调用算子。 | ||
| 8 | - | ||
| 9 | -- aclnn调用 **(推荐)**:以算子aclnnXxx接口方式(一套基于C语言的API,无需IR定义)调用算子。 | ||
| 10 | -- 图模式调用:以IR(Intermediate Representation)构图方式调用算子。 | ||
| 11 | - | ||
| 12 | -## aclnn调用 | ||
| 13 | - | ||
| 14 | -### 调用流程 | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | -### 示例代码 | ||
| 19 | - | ||
| 20 | -`AddExample`算子以aclnn接口形式调用的示例代码如下(详细代码参见[test_aclnn_add_example.cpp](../../../examples/add_example/examples/test_aclnn_add_example.cpp)),**仅为参考**,其他算子接口调用过程类似,请替换为实际aclnn接口。调用前,请按照环境安装的提示信息设置环境变量。 | ||
| 21 | - | ||
| 22 | -注意:如需调用本项目其他算子,可访问对应算子`examples`目录下的test\_aclnn\_\$\{op\_name\}.cpp,\$\{op\_name\}表示算子名。 | ||
| 23 | - | ||
| 24 | -```Cpp | ||
| 25 | -int main() | ||
| 26 | -{ | ||
| 27 | - // 1. 调用acl进行device/stream初始化 | ||
| 28 | - int32_t deviceId = 0; | ||
| 29 | - aclrtStream stream; | ||
| 30 | - auto ret = Init(deviceId, &stream); | ||
| 31 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); | ||
| 32 | - | ||
| 33 | - // 2. 构造输入与输出,需要根据API的接口自定义构造 | ||
| 34 | - aclTensor* selfX = nullptr; | ||
| 35 | - void* selfXDeviceAddr = nullptr; | ||
| 36 | - std::vector<int64_t> selfXShape = {32, 4, 4, 4}; | ||
| 37 | - std::vector<float> selfXHostData(2048, 1); | ||
| 38 | - ret = CreateAclTensor(selfXHostData, selfXShape, &selfXDeviceAddr, aclDataType::ACL_FLOAT, &selfX); | ||
| 39 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 40 | - | ||
| 41 | - aclTensor* selfY = nullptr; | ||
| 42 | - void* selfYDeviceAddr = nullptr; | ||
| 43 | - std::vector<int64_t> selfYShape = {32, 4, 4, 4}; | ||
| 44 | - std::vector<float> selfYHostData(2048, 1); | ||
| 45 | - ret = CreateAclTensor(selfYHostData, selfYShape, &selfYDeviceAddr, aclDataType::ACL_FLOAT, &selfY); | ||
| 46 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 47 | - | ||
| 48 | - aclTensor* out = nullptr; | ||
| 49 | - void* outDeviceAddr = nullptr; | ||
| 50 | - std::vector<int64_t> outShape = {32, 4, 4, 4}; | ||
| 51 | - std::vector<float> outHostData(2048, 1); | ||
| 52 | - ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out); | ||
| 53 | - CHECK_RET(ret == ACL_SUCCESS, return ret); | ||
| 54 | - | ||
| 55 | - // 3. 调用CANN算子库API,需要修改为具体的Api名称 | ||
| 56 | - uint64_t workspaceSize = 0; | ||
| 57 | - aclOpExecutor* executor; | ||
| 58 | - | ||
| 59 | - // 4. 调用aclnnAddExample第一段接口 | ||
| 60 | - ret = aclnnAddExampleGetWorkspaceSize(selfX, selfY, out, &workspaceSize, &executor); | ||
| 61 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAddExampleGetWorkspaceSize failed. ERROR: %d\n", ret); return ret); | ||
| 62 | - | ||
| 63 | - // 5. 根据第一段接口计算出的workspaceSize申请device内存 | ||
| 64 | - void* workspaceAddr = nullptr; | ||
| 65 | - if (workspaceSize > static_cast<uint64_t>(0)) { | ||
| 66 | - ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 67 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); | ||
| 68 | - } | ||
| 69 | - | ||
| 70 | - // 6. 调用aclnnAddExample第二段接口 | ||
| 71 | - ret = aclnnAddExample(workspaceAddr, workspaceSize, executor, stream); | ||
| 72 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAddExample failed. ERROR: %d\n", ret); return ret); | ||
| 73 | - | ||
| 74 | - // 7. (固定写法)同步等待任务执行结束 | ||
| 75 | - ret = aclrtSynchronizeStream(stream); | ||
| 76 | - CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret); | ||
| 77 | - | ||
| 78 | - // 8. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改 | ||
| 79 | - PrintOutResult(outShape, &outDeviceAddr); | ||
| 80 | - | ||
| 81 | - // 9. 释放aclTensor,需要根据具体API的接口定义修改 | ||
| 82 | - aclDestroyTensor(selfX); | ||
| 83 | - aclDestroyTensor(selfY); | ||
| 84 | - aclDestroyTensor(out); | ||
| 85 | - | ||
| 86 | - // 10. 释放device资源 | ||
| 87 | - aclrtFree(selfXDeviceAddr); | ||
| 88 | - aclrtFree(selfYDeviceAddr); | ||
| 89 | - aclrtFree(outDeviceAddr); | ||
| 90 | - if (workspaceSize > static_cast<uint64_t>(0)) { | ||
| 91 | - aclrtFree(workspaceAddr); | ||
| 92 | - } | ||
| 93 | - aclrtDestroyStream(stream); | ||
| 94 | - aclrtResetDevice(deviceId); | ||
| 95 | - | ||
| 96 | - // 11. acl去初始化 | ||
| 97 | - aclFinalize(); | ||
| 98 | - return 0; | ||
| 99 | -} | ||
| 100 | -``` | ||
| 101 | - | ||
| 102 | -### 编译与运行 | ||
| 103 | - | ||
| 104 | ->说明:对于项目内已实现的算子(非自定义算子),可通过根目录下[build.sh](../../../build.sh)直接运行算子,操作请参考[本地验证](./quick_op_invocation.md#本地验证)。 | ||
| 105 | - | ||
| 106 | -1. 前提条件。 | ||
| 107 | - 请参考本项目[源码编译](./quick_op_invocation.md#源码编译)完成目标算子的编译部署。 | ||
| 108 | - 当前提供的CMakeLists.txt样例仅针对自定义算子包场景,请在自定义算子包安装后,按安装提示设置相应的环境变量。 | ||
| 109 | - | ||
| 110 | -2. 创建CMakeLists.txt文件。 | ||
| 111 | - | ||
| 112 | - 在test\_aclnn\_\$\{op\_name\}.cpp同级目录下创建CMakeLists.txt文件,以`AddExample`算子为例,示例如下,请根据实际情况自行修改。 | ||
| 113 | - | ||
| 114 | - ```bash | ||
| 115 | - cmake_minimum_required(VERSION 3.14) | ||
| 116 | - # 设置工程名 | ||
| 117 | - project(ACLNN_EXAMPLE) | ||
| 118 | - | ||
| 119 | - # 设置C++编译标准 | ||
| 120 | - add_compile_options(-std=c++11) | ||
| 121 | - | ||
| 122 | - # 设置编译输出目录为当前目录下的bin文件夹 | ||
| 123 | - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "./bin") | ||
| 124 | - | ||
| 125 | - # 设置调试和发布模式的编译选项 | ||
| 126 | - set(CMAKE_CXX_FLAGS_DEBUG "-fPIC -O0 -g -Wall") | ||
| 127 | - set(CMAKE_CXX_FLAGS_RELEASE "-fPIC -O2 -Wall") | ||
| 128 | - | ||
| 129 | - # 获取LD_LIBRARY_PATH环境变量 | ||
| 130 | - if(NOT DEFINED ENV{LD_LIBRARY_PATH}) | ||
| 131 | - message(FATAL_ERROR "LD_LIBRARY_PATH environment variable is not set") | ||
| 132 | - endif() | ||
| 133 | - set(LD_LIB_PATH "$ENV{LD_LIBRARY_PATH}") | ||
| 134 | - | ||
| 135 | - # 分割路径列表并找到包含/vendors/的路径(仅自定义算子需要) | ||
| 136 | - string(REPLACE ":" ";" LD_LIB_LIST "${LD_LIB_PATH}") | ||
| 137 | - set(TARGET_PATH "") | ||
| 138 | - foreach(path ${LD_LIB_LIST}) | ||
| 139 | - # 匹配包含/vendors/的路径(不区分位置) | ||
| 140 | - if(path MATCHES "/vendors/") | ||
| 141 | - set(TARGET_PATH "${path}") | ||
| 142 | - break() | ||
| 143 | - endif() | ||
| 144 | - endforeach() | ||
| 145 | - if(NOT TARGET_PATH) | ||
| 146 | - message(FATAL_ERROR "未在LD_LIBRARY_PATH中找到包含/vendors/的路径") | ||
| 147 | - endif() | ||
| 148 | - if(TARGET_PATH MATCHES "/vendors/([^/]+)") | ||
| 149 | - set(TARGET_SUBDIR "${CMAKE_MATCH_1}") | ||
| 150 | - else() | ||
| 151 | - message(FATAL_ERROR "在路径${TARGET_PATH}中未找到/vendors/的直接子目录") | ||
| 152 | - endif() | ||
| 153 | - | ||
| 154 | - # 添加可执行文件(请替换为实际算子可执行文件),指定算子调用的*.cpp文件 | ||
| 155 | - add_executable(test_aclnn_add_example | ||
| 156 | - test_aclnn_add_example.cpp) | ||
| 157 | - | ||
| 158 | - # ASCEND_PATH(CANN软件包目录,请根据实际路径修改) | ||
| 159 | - if(NOT "$ENV{ASCEND_HOME_PATH}" STREQUAL "") | ||
| 160 | - set(ASCEND_PATH $ENV{ASCEND_HOME_PATH}) | ||
| 161 | - else() | ||
| 162 | - set(ASCEND_PATH "/usr/local/Ascend/cann") | ||
| 163 | - endif() | ||
| 164 | - | ||
| 165 | - # 设置头文件路径 | ||
| 166 | - set(INCLUDE_BASE_DIR "${ASCEND_PATH}/include") | ||
| 167 | - include_directories( | ||
| 168 | - ${INCLUDE_BASE_DIR} | ||
| 169 | - ${ASCEND_PATH}/opp/vendors/${TARGET_SUBDIR}/op_api/include # 仅自定义算子需要 | ||
| 170 | - # ${INCLUDE_BASE_DIR}/aclnn # 仅内置算子需要 | ||
| 171 | - ) | ||
| 172 | - include_directories( | ||
| 173 | - ${INCLUDE_BASE_DIR} | ||
| 174 | - ) | ||
| 175 | - | ||
| 176 | - # 链接所需的动态库 | ||
| 177 | - target_link_libraries(test_aclnn_add_example PRIVATE # 替换实际算子可执行文件 | ||
| 178 | - ${ASCEND_PATH}/lib64/libascendcl.so | ||
| 179 | - ${ASCEND_PATH}/lib64/libnnopbase.so | ||
| 180 | - ${ASCEND_PATH}/opp/vendors/${TARGET_SUBDIR}/op_api/lib/libcust_opapi.so # 仅自定义算子需要 | ||
| 181 | - # ${ASCEND_PATH}/lib64/libopapi_cv.so # 仅内置算子需要 | ||
| 182 | - ) | ||
| 183 | - | ||
| 184 | - # 安装目标文件到bin目录 | ||
| 185 | - install(TARGETS test_aclnn_add_example DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) | ||
| 186 | - ``` | ||
| 187 | - | ||
| 188 | -3. 创建run.sh文件。 | ||
| 189 | - | ||
| 190 | - 在test\_aclnn\_\$\{op\_name\}.cpp同级目录下创建run.sh文件,以`AddExample`算子为例,示例如下,请根据实际情况自行修改。 | ||
| 191 | - | ||
| 192 | - ```bash | ||
| 193 | - if [ -n "$ASCEND_INSTALL_PATH" ]; then # 实际CANN包安装路径 | ||
| 194 | - _ASCEND_INSTALL_PATH=$ASCEND_INSTALL_PATH | ||
| 195 | - elif [ -n "$ASCEND_HOME_PATH" ]; then | ||
| 196 | - _ASCEND_INSTALL_PATH=$ASCEND_HOME_PATH | ||
| 197 | - else | ||
| 198 | - _ASCEND_INSTALL_PATH="/usr/local/Ascend/cann" | ||
| 199 | - fi | ||
| 200 | - | ||
| 201 | - source ${_ASCEND_INSTALL_PATH}/bin/setenv.bash | ||
| 202 | - | ||
| 203 | - rm -rf build | ||
| 204 | - mkdir -p build | ||
| 205 | - cd build | ||
| 206 | - cmake ../ -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE # 执行构建命令 | ||
| 207 | - make | ||
| 208 | - cd bin | ||
| 209 | - ./test_aclnn_add_example # 替换为实际算子可执行文件名 | ||
| 210 | - ``` | ||
| 211 | - | ||
| 212 | -4. 运行run.sh文件。 | ||
| 213 | - 在run.sh文件所在路径执行如下命令: | ||
| 214 | - | ||
| 215 | - ```bash | ||
| 216 | - bash run.sh | ||
| 217 | - ``` | ||
| 218 | - | ||
| 219 | - 默认在当前执行路径 `/build/bin`下生成可执行文件test\_aclnn\_add\_example,运行结果如下: | ||
| 220 | - | ||
| 221 | - ```sh | ||
| 222 | - mean result[2046] is 2.000000 | ||
| 223 | - mean result[2047] is 2.000000 | ||
| 224 | - ``` | ||
| 225 | - | ||
| 226 | -## 图模式调用 | ||
| 227 | - | ||
| 228 | -### 调用流程 | ||
| 229 | - | ||
| 230 | - | ||
| 231 | - | ||
| 232 | -### 示例代码 | ||
| 233 | - | ||
| 234 | -`AddExample`算子以图方式调用的示例代码如下(详细代码参见[test_geir_add_example.cpp](../../../examples/add_example/examples/test_geir_add_example.cpp)),**仅为参考**,其他算子的调用过程类似,请替换为实际的算子原型。 | ||
| 235 | - | ||
| 236 | -如需调用本项目其他算子,可访问对应算子`examples`目录下的test\_geir\_\$\{op\_name\}.cpp,$\{op\_name\}表示算子名。 | ||
| 237 | - | ||
| 238 | -```CPP | ||
| 239 | -int main() { | ||
| 240 | - // 1. 创建图对象 | ||
| 241 | - Graph graph(graphName); | ||
| 242 | - | ||
| 243 | - // 2. 图全局编译选项初始化 | ||
| 244 | - Status ret = ge::GEInitialize(globalOptions); | ||
| 245 | - | ||
| 246 | - // 3. 创建AddExample算子实例 | ||
| 247 | - auto add1 = op::AddExample("add1"); | ||
| 248 | - | ||
| 249 | - // 4. 定义图输入输出向量 | ||
| 250 | - std::vector<Operator> inputs{}; | ||
| 251 | - std::vector<Operator> outputs{}; | ||
| 252 | - | ||
| 253 | - // 5. 准备输入数据 | ||
| 254 | - std::vector<int64_t> xShape = {32,4,4,4}; | ||
| 255 | - // 宏展开方式处理变量赋值 | ||
| 256 | - ADD_INPUT(1, x1, inDtype, xShape); | ||
| 257 | - ADD_INPUT(2, x2, inDtype, xShape); | ||
| 258 | - ADD_OUTPUT(1, y, inDtype, xShape); | ||
| 259 | - | ||
| 260 | - outputs.push_back(add1); | ||
| 261 | - | ||
| 262 | - // 6. 设置图对象的输入算子和输出算子 | ||
| 263 | - graph.SetInputs(inputs).SetOutputs(outputs); | ||
| 264 | - | ||
| 265 | - // 7. 创建session对象 | ||
| 266 | - ge::Session* session = new Session(buildOptions); | ||
| 267 | - | ||
| 268 | - // 8. session添加图 | ||
| 269 | - ret = session->AddGraph(graphId, graph, graphOptions); | ||
| 270 | - | ||
| 271 | - // 9. 运行图 | ||
| 272 | - ret = session->RunGraph(graphId, input, output); | ||
| 273 | - | ||
| 274 | - // 10. 释放资源 | ||
| 275 | - GEFinalize(); | ||
| 276 | - | ||
| 277 | - return 0; | ||
| 278 | -} | ||
| 279 | -``` | ||
| 280 | - | ||
| 281 | -### 编译与运行 | ||
| 282 | - | ||
| 283 | ->说明:对于项目内已实现的算子(非自定义算子),可通过根目录下[build.sh](../../../build.sh)直接运行算子,操作请参考[本地验证](./quick_op_invocation.md#本地验证)。 | ||
| 284 | - | ||
| 285 | -1. 前提条件。 | ||
| 286 | - 请参考本项目[源码编译](./quick_op_invocation.md#源码编译)完成目标算子的编译部署。 | ||
| 287 | - | ||
| 288 | -2. 创建CMakeLists.txt文件。 | ||
| 289 | - | ||
| 290 | - 在test\_geir\_\$\{op\_name\}.cpp同级目录下创建CMakeLists.txt文件,以`AddExample`算子为例,示例如下,请根据实际情况自行修改。 | ||
| 291 | - | ||
| 292 | - ```bash | ||
| 293 | - cmake_minimum_required(VERSION 3.14) | ||
| 294 | - | ||
| 295 | - # 设置工程名 | ||
| 296 | - project(GE_IR_EXAMPLE) | ||
| 297 | - | ||
| 298 | - if(NOT "$ENV{ASCEND_OPP_PATH}" STREQUAL "") | ||
| 299 | - get_filename_component(ASCEND_PATH $ENV{ASCEND_OPP_PATH} DIRECTORY) | ||
| 300 | - elseif(NOT "$ENV{ASCEND_HOME_PATH}" STREQUAL "") | ||
| 301 | - set(ASCEND_PATH $ENV{ASCEND_HOME_PATH}) | ||
| 302 | - else() | ||
| 303 | - set(ASCEND_PATH "/usr/local/Ascend/cann") | ||
| 304 | - endif() | ||
| 305 | - | ||
| 306 | - set(FWK_INCLUDE_DIR "${ASCEND_PATH}/compiler/include") | ||
| 307 | - | ||
| 308 | - message(STATUS "ASCEND_PATH: ${ASCEND_PATH}") | ||
| 309 | - | ||
| 310 | - file(GLOB files CONFIGURE_DEPENDS | ||
| 311 | - test_geir_add_example.cpp | ||
| 312 | - ) | ||
| 313 | - | ||
| 314 | - # 添加可执行文件(请替换为实际算子可执行文件) | ||
| 315 | - add_executable(test_geir_add_example ${files}) | ||
| 316 | - | ||
| 317 | - find_library(GRAPH_LIBRARY_DIR libgraph.so "${ASCEND_PATH}/compiler/lib64/stub") | ||
| 318 | - find_library(GE_RUNNER_LIBRARY_DIR libge_runner.so "${ASCEND_PATH}/compiler/lib64/stub") | ||
| 319 | - find_library(GRAPH_BASE_LIBRARY_DIR libgraph_base.so "${ASCEND_PATH}/compiler/lib64") | ||
| 320 | - | ||
| 321 | - # 链接所需的动态库 | ||
| 322 | - target_link_libraries(test_geir_add_example PRIVATE | ||
| 323 | - ${GRAPH_LIBRARY_DIR} | ||
| 324 | - ${GE_RUNNER_LIBRARY_DIR} | ||
| 325 | - ${GRAPH_BASE_LIBRARY_DIR} | ||
| 326 | - ) | ||
| 327 | - | ||
| 328 | - # 设置头文件路径 | ||
| 329 | - target_include_directories(test_geir_add_example PRIVATE | ||
| 330 | - ${FWK_INCLUDE_DIR}/graph/ | ||
| 331 | - ${FWK_INCLUDE_DIR}/ge/ | ||
| 332 | - ${ASCEND_PATH}/opp/built-in/op_proto/inc/ | ||
| 333 | - ${CMAKE_CURRENT_SOURCE_DIR} | ||
| 334 | - ${ASCEND_PATH}/compiler/include | ||
| 335 | - ) | ||
| 336 | - ``` | ||
| 337 | - | ||
| 338 | -3. 创建run.sh脚本。 | ||
| 339 | - | ||
| 340 | - 在test\_geir\_\$\{op\_name\}.cpp同级目录下创建run.sh文件,以`AddExample`算子为例,示例如下,请根据实际情况自行修改。 | ||
| 341 | - | ||
| 342 | - ```bash | ||
| 343 | - if [ -n "$ASCEND_INSTALL_PATH" ]; then # 实际CANN包安装路径 | ||
| 344 | - _ASCEND_INSTALL_PATH=$ASCEND_INSTALL_PATH | ||
| 345 | - elif [ -n "$ASCEND_HOME_PATH" ]; then | ||
| 346 | - _ASCEND_INSTALL_PATH=$ASCEND_HOME_PATH | ||
| 347 | - else | ||
| 348 | - _ASCEND_INSTALL_PATH="/usr/local/Ascend/cann" | ||
| 349 | - fi | ||
| 350 | - | ||
| 351 | - source ${_ASCEND_INSTALL_PATH}/bin/setenv.bash | ||
| 352 | - | ||
| 353 | - rm -rf build | ||
| 354 | - mkdir -p build | ||
| 355 | - cd build | ||
| 356 | - cmake ../ -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE # 执行构建命令 | ||
| 357 | - make | ||
| 358 | - ./test_geir_add_example # 替换为实际算子可执行文件名 | ||
| 359 | - ``` | ||
| 360 | - | ||
| 361 | -4. 运行run.sh脚本。 | ||
| 362 | - 在run.sh文件所在路径执行如下命令: | ||
| 363 | - | ||
| 364 | - ```bash | ||
| 365 | - bash run.sh | ||
| 366 | - ``` | ||
| 367 | - | ||
| 368 | - 默认在当前执行路径 `/build/bin`下生成可执行文件test\_geir\_add\_example,运行结果如下: | ||
| 369 | - | ||
| 370 | - ```sh | ||
| 371 | - INFO - [XIR]: Finalize ir graph session success | ||
| 372 | - ``` | ||
| @@ -61,7 +61,7 @@ def get_file_change_info_from_ci(changed_file_info_from_ci, ops_path): | |||
| 61 | """ | 61 | """ |
| 62 | or_file_path = os.path.realpath(changed_file_info_from_ci) | 62 | or_file_path = os.path.realpath(changed_file_info_from_ci) |
| 63 | if not os.path.exists(or_file_path): | 63 | if not os.path.exists(or_file_path): |
| 64 | - logging.error("[ERROR] change file is not exist, can not get file change info in this pull request.") | 64 | + logging.error("[ERROR] change file does not exist, can not get file change info in this pull request.") |
| 65 | return None | 65 | return None |
| 66 | 66 | ||
| 67 | def _compile_patterns(ops_path): | 67 | def _compile_patterns(ops_path): |
| @@ -58,7 +58,7 @@ def get_operator_info_from_ci(changed_file_info_from_ci, is_experimental): | |||
| 58 | """ | 58 | """ |
| 59 | or_file_path = os.path.realpath(changed_file_info_from_ci) | 59 | or_file_path = os.path.realpath(changed_file_info_from_ci) |
| 60 | if not os.path.exists(or_file_path): | 60 | if not os.path.exists(or_file_path): |
| 61 | - logging.error("[ERROR] change file is not exist, can not get file change info in this pull request.") | 61 | + logging.error("[ERROR] change file does not exist, can not get file change info in this pull request.") |
| 62 | return None | 62 | return None |
| 63 | with open(or_file_path) as or_f: | 63 | with open(or_file_path) as or_f: |
| 64 | lines = or_f.readlines() | 64 | lines = or_f.readlines() |
| @@ -53,7 +53,7 @@ def get_res_from_file(json_file): | |||
| 53 | get_res_from_file get the module name and module func from json_file | 53 | get_res_from_file get the module name and module func from json_file |
| 54 | """ | 54 | """ |
| 55 | if not os.path.exists(json_file): | 55 | if not os.path.exists(json_file): |
| 56 | - print("[ERROR]the json_file is not existed: ", json_file) | 56 | + print("[ERROR]the json_file does not exist: ", json_file) |
| 57 | sys.exit(1) | 57 | sys.exit(1) |
| 58 | with open(json_file, "r") as file_op: | 58 | with open(json_file, "r") as file_op: |
| 59 | ops_info_json = json.load(file_op) | 59 | ops_info_json = json.load(file_op) |
| @@ -176,7 +176,7 @@ update_install_infos() { | |||
| 176 | check_file_exist() { | 176 | check_file_exist() { |
| 177 | local path_param="${1}" | 177 | local path_param="${1}" |
| 178 | if [ ! -f "${path_param}" ]; then | 178 | if [ ! -f "${path_param}" ]; then |
| 179 | - logandprint "[ERROR]: ERR_NO:${FILE_NOT_EXIST};ERR_DES:The file (${path_param}) does not existed." | 179 | + logandprint "[ERROR]: ERR_NO:${FILE_NOT_EXIST};ERR_DES:The file (${path_param}) does not exist." |
| 180 | exit 1 | 180 | exit 1 |
| 181 | fi | 181 | fi |
| 182 | } | 182 | } |
| @@ -104,7 +104,7 @@ check_directory_exist() { | |||
| 104 | check_file_exist() { | 104 | check_file_exist() { |
| 105 | local path_param="${1}" | 105 | local path_param="${1}" |
| 106 | if [ ! -f "${path_param}" ]; then | 106 | if [ ! -f "${path_param}" ]; then |
| 107 | - logandprint "[ERROR]: ERR_NO:${FILE_NOT_EXIST};ERR_DES:The file (${path_param}) does not existed." | 107 | + logandprint "[ERROR]: ERR_NO:${FILE_NOT_EXIST};ERR_DES:The file (${path_param}) does not exist." |
| 108 | exit 1 | 108 | exit 1 |
| 109 | fi | 109 | fi |
| 110 | } | 110 | } |
| @@ -201,7 +201,7 @@ whl_uninstall_package() { | |||
| 201 | if [ ! -d "${_module_apth}/${_module}" ]; then | 201 | if [ ! -d "${_module_apth}/${_module}" ]; then |
| 202 | pip3 show "${_module}" > /dev/null 2>&1 | 202 | pip3 show "${_module}" > /dev/null 2>&1 |
| 203 | if [ $? -ne 0 ]; then | 203 | if [ $? -ne 0 ]; then |
| 204 | - logandprint "WARNING" "${_module} is not exist." | 204 | + logandprint "WARNING" "${_module} does not exist." |
| 205 | else | 205 | else |
| 206 | pip3 uninstall -y "${_module}" 1> /dev/null | 206 | pip3 uninstall -y "${_module}" 1> /dev/null |
| 207 | local ret=$? | 207 | local ret=$? |
目录树的
zh/子层级缩进与其他层级不一致:建议与上方层级对齐,改为: