CANN Runtime 样例构建模式全解析:5 种 CMake 模式与 4 种 run.sh 模式的选择与实践
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
导读
CANN Runtime 开源仓库的example/目录下收录了大量可直接编译运行的示例程序,覆盖设备管理、Stream/Event、内存拷贝、自定义算子、Profiling、Adump 等能力。为了在不同功能需求下保持构建脚本的一致性,仓库沉淀了一套可复用的构建范式:5 种 CMake 构建模式(Pattern A~E)与 4 种 run.sh 运行模式(Pattern 1~4)。本文基于仓库内部的构建模式参考文档(.claude/skills/hlt-to-sample-generator/references/sample-build-patterns.md),结合example/目录中的真实CMakeLists.txt与run.sh,完整讲解每种模式的适用场景、关键特征、配置参数,并给出模式选择决策树,帮助你在开发新样例或移植样例时快速选型、一次编译通过。
构建模式总览
CANN Runtime 的样例构建体系围绕两条主线展开:
- CMake 模式(Pattern A~E):回答"该样例需要链接哪些库、引入哪些头文件路径、是否需要 AscendC kernel 编译基础设施"。
- run.sh 模式(Pattern 1~4):回答"该样例如何准备环境、构建、安装、运行与验证"。
| 模式 | 名称 | 核心特征 |
|---|---|---|
| CMake Pattern A | ACL-only | 最简单,仅链接libascendcl.so,无算子无 kernel |
| CMake Pattern B | ACL + opapi | 使用 aclnn 预置算子(如aclnnAdd) |
| CMake Pattern C | ACL + AscendC kernel | 通过ascendc_library编译自定义 kernel |
| CMake Pattern D | ACL + AscendC fatbin | kernel launch 场景,使用ascendc_fatbin_library |
| CMake Pattern E | Profiling / Adump 特定库 | 额外链接 msprofiler / ascend_dump 等库 |
| run.sh Pattern 1 | 简单构建运行 | source setenv.bash + cmake + make + 运行 |
| run.sh Pattern 2 | 构建 + 安装 + 验证 | 使用新式 cmake CLI,输出捕获到文件 |
| run.sh Pattern 3 | Full kernel 构建流水线 | 自动检测 SOC_VERSION / ASCENDC_CMAKE_DIR |
| run.sh Pattern 4 | 多进程/多程序 | IPC、跨进程、跨服务器场景 |
CMake Pattern A:ACL-only(最简构建)
适用场景:只使用基础 acl / aclrt 接口,不使用 aclnn 算子,不使用 AscendC kernel。
代表样例:example/1_basic_features/device/、example/1_basic_features/stream/、example/1_basic_features/event/、example/4_reliability/overflow_detection/。
cmake_minimum_required(VERSION 3.16.0) project(Runtime_Sample) include_directories( ${ASCEND_CANN_PACKAGE_PATH}/include ${CMAKE_CURRENT_SOURCE_DIR}/../../..) link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) add_executable(main main.cpp) target_compile_options(main PRIVATE -O2 -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -Wall -Werror) target_link_libraries(main PRIVATE ${ASCEND_CANN_PACKAGE_PATH}/lib64/libascendcl.so)关键特征:
- 只链接
libascendcl.so,这是 ACL 运行时对外提供的核心封装库(包含aclInit、aclrtSetDevice、aclrtMalloc等接口); - include 路径只有 CANN 安装包头文件(
${ASCEND_CANN_PACKAGE_PATH}/include)与 example 根目录,后者用于引用仓库级公共头文件; - 不需要
SOC_VERSION/ASCENDC_CMAKE_DIR环境变量,因为不涉及 AscendC kernel 编译,这也是 Pattern A 与 Pattern C/D 最直观的区别。
仓库中 example/1_basic_features/event/0_event_status/CMakeLists.txt 即采用此结构。注意编译选项中的-D_GLIBCXX_USE_CXX11_ABI=0是 CANN 生态的常见约定,用于与 CANN 安装包内的预编译库保持 ABI 一致,避免链接期符号冲突;-Wall -Werror则要求样例代码零警告。
CMake Pattern B:ACL + opapi(aclnn 预置算子)
适用场景:使用 aclnn 预置算子(如aclnnAdd),不使用自定义 AscendC kernel。
代表样例:example/0_quickstart/0_hello_cann、example/2_advanced_features/model_ri/0_simple_model。
cmake_minimum_required(VERSION 3.16.0) project(Runtime_Sample) include_directories( ${ASCEND_CANN_PACKAGE_PATH}/include ${ASCEND_CANN_PACKAGE_PATH}/aclnn ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ${CMAKE_CURRENT_SOURCE_DIR}/..) link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) add_executable(main main.cpp ../model_utils.cpp) target_link_libraries(main PRIVATE ${ASCEND_CANN_PACKAGE_PATH}/lib64/libascendcl.so ${ASCEND_CANN_PACKAGE_PATH}/lib64/libnnopbase.so ${ASCEND_CANN_PACKAGE_PATH}/lib64/libopapi.so)关键特征:
- include
${ASCEND_CANN_PACKAGE_PATH}/aclnn:提供aclnnop/aclnn_add.h等 aclnn 算子头文件; - 链接
libnnopbase.so+libopapi.so:aclnn 算子执行所需的算子基础库与算子 API 库,二者缺一不可; - 可能包含类别级共享源文件(如
../model_utils.cpp),此时额外 include${CMAKE_CURRENT_SOURCE_DIR}/..以引入类别级头文件。
关于仓库未发布 API:如果样例使用本仓库尚未随 CANN 发布(release)的接口,需要在include_directories最前面插入仓库自身的头文件路径,使仓库头文件优先于安装包头文件被解析:
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/external # repo 头文件优先 ${ASCEND_CANN_PACKAGE_PATH}/include ${ASCEND_CANN_PACKAGE_PATH}/aclnn ...)这里../../../../include/external指向仓库根目录的 include/external(即acl.h、acl_rt.h等公开头文件所在目录),保证样例能编译到仓库最新接口。以仓库内的 example/0_quickstart/0_hello_cann/CMakeLists.txt 为例,它还额外链接了libacl_rt.so,对应aclrtMalloc/aclrtMemcpy等纯 RT 接口;example/2_advanced_features/model_ri/0_simple_model 则在add_executable中追加../model_utils.cpp共享源码,是 Pattern B 带类别级共享文件的典型形态。
CMake Pattern C:ACL + AscendC kernel(ascendc_library)
适用场景:使用自定义 AscendC kernel,kernel 源文件通过ascendc_library编译为静态库。
代表样例:example/1_basic_features/memory/大部分样例、example/5_performance/adump/。
cmake_minimum_required(VERSION 3.16.0) project(Runtime_Sample) set(SOC_VERSION $ENV{SOC_VERSION}) set(ASCENDC_CMAKE_DIR $ENV{ASCENDC_CMAKE_DIR}) set(RUN_MODE "npu" CACHE STRING "run mode: npu") set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type Release/Debug (default Debug)" FORCE) set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/out" CACHE STRING "path for install()" FORCE) include(${ASCENDC_CMAKE_DIR}/ascendc.cmake) ascendc_library(kernels STATIC ../../../kernel_func/easy_OP.cpp) include_directories( ${ASCEND_CANN_PACKAGE_PATH}/include ${CMAKE_CURRENT_SOURCE_DIR}/../../..) link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) add_executable(main main.cpp) target_link_libraries(main PRIVATE ascendcl)关键特征:
- 需要环境变量
SOC_VERSION和ASCENDC_CMAKE_DIR,通常由 example/set_sample_env.sh 自动检测并导出(见下文 run.sh Pattern 3 的说明); include(${ASCENDC_CMAKE_DIR}/ascendc.cmake):引入 AscendC 构建基础设施,提供ascendc_library等函数;ascendc_library(kernels STATIC ...):将 kernel 源文件编译为静态库,第一个参数是库名,第二个参数是库类型(如 STATIC),后续为 kernel 源文件列表;- kernel 源文件统一放在 example/kernel_func/(如
easy_OP.cpp、kernel_add.cpp、kernel_ops.h),通过相对路径引用; - 链接
ascendcl(CMake target 名),这是 Pattern C 与 Pattern D 的又一区别点:Pattern C 直接写 target 名,Pattern D 链接具体.so路径。
ascendc.cmake的路径由ASCENDC_CMAKE_DIR指向,其典型位置是 CANN 安装包下的tikcpp/ascendc_kernel_cmake,与 ACL 库一样按主机架构区分(如x86_64-linux/、aarch64-linux/)。
CMake Pattern D:ACL + AscendC fatbin(kernel launch)
适用场景:kernel launch 样例(即使用<<<...>>>调用语法直接发射 kernel),需要ascendc_fatbin_library将一个或多个 kernel 编译为 fatbin。
代表样例:example/2_advanced_features/kernel/0_launch_kernel。
cmake_minimum_required(VERSION 3.16.0) project(Kernel_Launch_Sample) set(SOC_VERSION $ENV{SOC_VERSION}) set(ASCENDC_CMAKE_DIR $ENV{ASCENDC_CMAKE_DIR}) set(RUN_MODE "npu" CACHE STRING "run mode: npu") set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type Release/Debug (default Debug)" FORCE) set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/out" CACHE STRING "path for install()" FORCE) file(GLOB KERNEL_FILES ../../../kernel_func/add_custom.cpp) include(${ASCENDC_CMAKE_DIR}/ascendc.cmake) ascendc_fatbin_library(ascendc_kernels ${KERNEL_FILES}) include_directories( ${ASCEND_CANN_PACKAGE_PATH}/include ${CMAKE_CURRENT_SOURCE_DIR}/../../..) link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) add_executable(main main.cpp ../file_ops.cpp) target_link_libraries(main PRIVATE ${ASCEND_CANN_PACKAGE_PATH}/lib64/libacl_rt.so)关键特征:
- 使用
ascendc_fatbin_library()将 kernel 编译为 fatbin(可执行二进制镜像),供 host 侧在运行时加载发射; - 链接
libacl_rt.so(而非libascendcl.so)——kernel launch 场景需要rtKernelLaunch等底层 RT 接口; - 通常配合
install()步骤将产物部署到out/bin/、out/lib/,host 程序运行时通过LD_LIBRARY_PATH找到 fatbin。
仓库实际实现 example/2_advanced_features/kernel/0_launch_kernel/CMakeLists.txt 展示了更完整的形式:用file(GLOB KERNEL_FILES_SIMPLE .../add_custom.cpp)与file(GLOB KERNEL_FILES_PLACEHOLDER .../add_custom_tiling.cpp)分别声明两组 kernel,再分别调用ascendc_fatbin_library()产出ascendc_kernels_simple与ascendc_kernels_placeholder,最后用install(TARGETS ... RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})部署可执行文件,对应out/bin/目录。
CMake Pattern E:Profiling / Adump 特定库
适用场景:性能分析(profiling)或精度调试(adump)。该模式并非独立范式,而是针对特定库的"追加式"配置。
Profiling 变体
代表样例:example/5_performance/profiling/。
cmake_minimum_required(VERSION 3.16.0) project(Profiling_Sample) set(ASCEND_CANN_PACKAGE_PATH $ENV{ASCEND_HOME_PATH}) include_directories( ${ASCEND_CANN_PACKAGE_PATH}/include ${ASCEND_CANN_PACKAGE_PATH}/include/driver ${ASCEND_CANN_PACKAGE_PATH}/include/acl ${ASCEND_CANN_PACKAGE_PATH}/runtime/include ${CMAKE_CURRENT_SOURCE_DIR}/../../..) link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) add_executable(main main.cpp) target_link_libraries(main PRIVATE ${ASCEND_CANN_PACKAGE_PATH}/lib64/libmsprofiler.so ${ASCEND_CANN_PACKAGE_PATH}/lib64/libascendcl.so ${ASCEND_CANN_PACKAGE_PATH}/lib64/libprofapi.so)关键特征:
- 使用
$ENV{ASCEND_HOME_PATH}而非 CMake 变量ASCEND_CANN_PACKAGE_PATH——直接在 CMake 层读取环境变量,要求运行环境已正确导出ASCEND_HOME_PATH(通常由set_env.sh完成); - 额外 include:
include/driver、include/acl、runtime/include,这些目录对应驱动层接口、ACL 头文件与运行时头文件,供msprof与aprof相关 API 使用; - 链接
libmsprofiler.so+libprofapi.so,前者是 msprof 采样/采集核心库,后者是 profiling 的公开 API 库。仓库中的 example/5_performance/profiling/0_create_config/CMakeLists.txt 即完全采用此写法。
Adump 变体
Adump(精度比对/张量 dump)基于Pattern C(带ascendc.cmake与ascendc_library),在此基础上额外链接libascend_dump.so与libopapi.so:
target_link_libraries(main PRIVATE ${ASCEND_CANN_PACKAGE_PATH}/lib64/libascendcl.so ${ASCEND_CANN_PACKAGE_PATH}/lib64/libnnopbase.so ${ASCEND_CANN_PACKAGE_PATH}/lib64/libopapi.so ${ASCEND_CANN_PACKAGE_PATH}/lib64/libascend_dump.so)仓库实现 example/5_performance/adump/0_adump_args/CMakeLists.txt 与文档完全一致:在 include 中同时引入${ASCEND_CANN_PACKAGE_PATH}/aclnn,链接libascendcl.so、libnnopbase.so、libopapi.so、libascend_dump.so。libascend_dump.so提供aclmdlInitDump/aclrtSetDumpConfig等 dump 接口,用于在算子输出阶段抓取张量数据。
run.sh Pattern 1:简单构建运行
适用场景:Pattern A / Pattern B 样例(不涉及 AscendC kernel)。
set -e _ASCEND_INSTALL_PATH=$ASCEND_INSTALL_PATH source $_ASCEND_INSTALL_PATH/bin/setenv.bash SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "${SCRIPT_DIR}" BUILD_DIR="${SCRIPT_DIR}/build" mkdir -p "${BUILD_DIR}" cd "${BUILD_DIR}" cmake .. -DASCEND_CANN_PACKAGE_PATH="${_ASCEND_INSTALL_PATH}" make -j$(nproc) cd "${SCRIPT_DIR}" ./build/main关键特征:
- 先
source .../bin/setenv.bash初始化 CANN 运行环境(导出ASCEND_HOME_PATH、LD_LIBRARY_PATH等); - 经典两段式构建:
cmake ..生成构建系统 +make -j$(nproc)并行编译; - 直接运行
./build/main,不做 install、不做输出捕获。
仓库中的 example/0_quickstart/0_hello_cann/run.sh 是该模式的增强版:它额外source .../common/resolve_cann_env.sh并调用resolve_cann_env,自动探测 CANN 安装路径(见下文"环境自动探测"),再进入build/目录执行 cmake 与 make,最后打印可执行文件位置并运行./build/main。
run.sh Pattern 2:构建 + 安装 + 验证
适用场景:需要 install 步骤或有输出验证的样例。
set -e _ASCEND_INSTALL_PATH=$ASCEND_INSTALL_PATH source $_ASCEND_INSTALL_PATH/bin/setenv.bash rm -rf build mkdir -p build cmake -B build -DASCEND_CANN_PACKAGE_PATH=${_ASCEND_INSTALL_PATH} cmake --build build -j cmake --install build ./build/main | tee output_msg.txt关键特征:
- 使用新式 cmake CLI:
cmake -B build(指定构建目录)、cmake --build build -j(并行构建)、cmake --install build(执行安装规则); - 通过
| tee output_msg.txt将程序输出同时回显并捕获到文件,便于后续比对验证。
仓库中的 example/1_basic_features/event/0_event_status/run.sh 即采用 Pattern 2:从ASCEND_HOME_PATH解析 CANN 路径并 sourcebin/setenv.bash(若未设置环境变量则直接报错退出),随后执行三条新式 cmake 命令,最后./build/main | tee output_msg.txt。注意该脚本要求调用前已source <cann_path>/set_env.sh,这是它比 Pattern 1 更依赖用户环境的原因。
run.sh Pattern 3:Full kernel 构建流水线
适用场景:Pattern C / Pattern D 样例(需要 AscendC kernel 编译),这是所有模式中自动化程度最高的一个。
set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" EXAMPLE_DIR="$(cd "${SCRIPT_DIR}/../../.." && pwd)" source "${EXAMPLE_DIR}/common/resolve_cann_env.sh" resolve_cann_env detect_sample_env # 调用 set_sample_env.sh 自动检测 SOC_VERSION / ASCENDC_CMAKE_DIR # 构建参数 SOC_VERSION="${SOC_VERSION}" BUILD_TYPE="Debug" BUILD_DIR="${SCRIPT_DIR}/build" INSTALL_PREFIX="${SCRIPT_DIR}/out" cmake -B "${BUILD_DIR}" \ -DSOC_VERSION="${SOC_VERSION}" \ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \ -DASCEND_CANN_PACKAGE_PATH="${ASCEND_INSTALL_PATH}" cmake --build "${BUILD_DIR}" -j$(nproc) cmake --install "${BUILD_DIR}" # 运行 "${INSTALL_PREFIX}/bin/main" "${RUN_MODE}"关键特征:
- 使用
set -euo pipefail严格模式,任何一步失败立即终止; - 通过 example/common/resolve_cann_env.sh 的
resolve_cann_env自动定位 CANN 安装路径; - 通过
detect_sample_env调用 example/set_sample_env.sh自动检测SOC_VERSION/ASCENDC_CMAKE_DIR,无需用户手动设置; - 将
SOC_VERSION/ASCENDC_CMAKE_DIR显式传给 cmake(后者在 CMake 侧通过set(... $ENV{...})读取); - 使用新式
cmake --build/--installCLI,最终从out/bin/运行带 run mode 参数的可执行文件。
仓库实现 example/2_advanced_features/kernel/0_launch_kernel/run.sh 完整展示了这一流水线:它定义detect_sample_env(若SOC_VERSION、ASCENDC_CMAKE_DIR已导出则跳过检测),校验环境变量与ascendc.cmake存在性后,用getopt解析-r/--run-mode参数(取值为simple或placeholder),构建并 install 到out/,随后生成测试数据、运行out/bin/ascendc_kernels_bbit,最后用md5sum与 Python 脚本比对输出结果——这是"构建 + 安装 + 验证"在 kernel 场景下的完整闭环。
run.sh Pattern 4:多进程/多程序
适用场景:IPC、跨进程、跨服务器样例,典型形态是proc_a.cpp+proc_b.cpp两个可执行文件,或server.cpp+client.cpp的服务端/客户端组合。
实现要点:这类样例无法用单一可执行文件验证,脚本通常分别构建并启动多个程序,并使用文件协调机制——进程间通过写 "done" 文件作为完成信号来同步时序,避免竞态。仓库中 example/1_basic_features/memory/10_ipc_memory_withpid、example/1_basic_features/memory/11_ipc_memory_withoutpid 等 IPC 样例即属于此模式(每个样例包含两个.cpp与各自的run.sh)。
环境自动探测:resolve_cann_env.sh 与 set_sample_env.sh
run.sh Pattern 3 之所以能做到"零手动配置",依赖 example 根目录的两个配套脚本,这也是样例构建体系中重要的基础设施:
example/common/resolve_cann_env.sh的resolve_cann_env函数按优先级探测 CANN 安装路径:
- 环境变量
ASCEND_INSTALL_PATH、ASCEND_HOME_PATH; - 常用默认位置:
${HOME}/Ascend/cann、${HOME}/Ascend/ascend-toolkit/latest、/usr/local/Ascend/cann、/usr/local/Ascend/ascend-toolkit/latest、/opt/Ascend/cann; - 对每个候选路径,先确认存在
set_env.sh或bin/setenv.bash,再调用resolve_cann_has_acl_layout检查该路径是否存在标准的 ACL 布局(include/acl/acl.h+lib64/libacl_rt.so,同时兼容<arch>-linux架构目录布局); - 命中后导出
ASCEND_INSTALL_PATH与ASCEND_HOME_PATH并 source 对应环境脚本;全部失败则打印已检查路径清单并提示手动设置。
example/set_sample_env.sh进一步自动检测SOC_VERSION与ASCENDC_CMAKE_DIR:
- 它会编译并运行 example/tools/get_soc_version/get_soc_version.cpp,这个小工具直接调用
aclrtGetSocName()获取与样例构建完全一致的 SOC 名称字符串(get_soc_version.cpp注释明确说明该接口无需aclInit,因此 helper 轻量且快速); - 再按架构候选路径(如
${cann_path}/tikcpp/ascendc_kernel_cmake)定位包含ascendc.cmake的目录; - 最终导出
ASCEND_INSTALL_PATH、ASCEND_HOME_PATH、SOC_VERSION、ASCENDC_CMAKE_DIR四个变量。以source方式执行即可在当前 shell 生效。
模式选择决策树
将上述模式串起来,可形成如下决策路径:
是否使用 aclnn 预置算子? ├── 否 → 是否使用自定义 AscendC kernel? │ ├── 否 → Pattern A (ACL-only) │ └── 是 → 是否使用 <<<>>> 调用语法(kernel launch)? │ ├── 否 → Pattern C (ascendc_library) │ └── 是 → Pattern D (ascendc_fatbin_library) └── 是 → 是否使用 model RI 或其他高级 API? ├── 否 → Pattern B (ACL+opapi) └── 是 → Pattern B + 可能需要 repo 未发布头文件 + 可能需要特定链接库 是否是 profiling/adump? ├── 是 → Pattern E (特定库)对应 run.sh 的选择:
- Pattern A / B → run.sh Pattern 1 或 2;
- Pattern C / D → run.sh Pattern 3(kernel 编译必须走自动检测流水线);
- 多进程/多程序(IPC、跨服务器)→ run.sh Pattern 4。
常见问题与排错建议
结合上述模式特征,编译样例时的常见问题可以快速定位:
SOC_VERSION未定义 /ASCENDC_CMAKE_DIR为空:说明走了 Pattern C/D 却没有执行 Pattern 3 的 run.sh,或set_sample_env.sh检测失败。确认 CANN 安装路径下存在tikcpp/ascendc_kernel_cmake/ascendc.cmake,并以source方式运行set_sample_env.sh后再编译。- 找不到
aclnnop/aclnn_add.h:Pattern B 必须 include${ASCEND_CANN_PACKAGE_PATH}/aclnn,并链接libnnopbase.so与libopapi.so,三者缺一不可。 - 链接
libascendcl.so与libacl_rt.so的选择困惑:kernel launch 场景(Pattern D)用libacl_rt.so;纯 ACL/算子场景(Pattern A/B)用libascendcl.so;Pattern C 则直接用 CMake target 名ascendcl。 - 链接期
GLIBCXX相关符号错误:确认编译选项包含-D_GLIBCXX_USE_CXX11_ABI=0,与 CANN 安装包预编译库保持一致。 - 运行期找不到
.so:检查是否 source 了setenv.bash,或参考 Pattern D 的out/lib路径配置LD_LIBRARY_PATH。
总结
CANN Runtime 样例构建体系通过 5 种 CMake 模式覆盖"纯 ACL → aclnn 算子 → 自定义 AscendC kernel → kernel launch → 性能/精度工具"的完整能力梯度,并以 4 种 run.sh 模式解决环境准备、构建、安装、验证与多进程编排的自动化问题。编写新样例时,只需对照决策树选定 CMake 与 run.sh 模式,再参考仓库中对应代表样例的CMakeLists.txt与run.sh拷贝改造即可,这也是该模式参考文档被沉淀为样例生成工具核心参考资料的原因。
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考