
跨版本 CANN Runtime 兼容性探测实战利用版本查询、CANN 特性与 Device 能力接口编写可分支的 Runtime 程序【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime跨版本编译与运行时兼容是 CANN 应用从开发环境移植到生产环境或升级 CANN 版本时最常见的坑不同版本接口签名可能变化、SoC 架构可能不同、可选能力未必全量下发。本文以仓库中的 3_cross_version/0_runtime_compatibility 样例为核心讲解如何用aclsysGetVersionStr/aclsysGetVersionNum查询 CANN 版本、用aclGetCannAttributeList/aclGetCannAttribute探测特性支持、用aclrtGetSocName/aclrtCheckArchCompatibility检查架构兼容性、用aclrtGetDeviceCapability查询 Device 能力最终写出先探测、再分支的健壮 Runtime 程序。导读本文面向需要在不同 CANN 版本或不同昇腾产品环境中交付的开发者。读完后你将掌握一套可复用的兼容性探测套路在aclInit之后、正式提交计算任务之前先查询软件版本与硬件能力再根据探测结果走不同的分支逻辑避免因依赖的接口或特性在目标环境不存在而导致运行失败。文中所有结论均来自当前仓库的样例实现main.cpp与公开头文件声明acl_rt.h、acl_base_rt.h。跨版本兼容问题的典型场景在 CANN 生态中同一份源码要在多种环境上运行是常态典型场景包括CANN 版本升级新版本可能废弃旧接口例如aclsysGetCANNVersion已被标记为 deprecated需改用aclsysGetVersionStr与aclsysGetVersionNum见 acl_rt.h也可能新增能力枚举。硬件代际差异Ascend 950 系列、Atlas A2 系列、Atlas A3 系列对算子、特性如 BF16、JIT 编译的支持情况不同。同型号不同固件/驱动版本同一 SoC 在不同驱动版本下某些 Device 能力可能未使能。跨版本编程的核心原则是不要假设环境而是显式探测后再做分支。本文的样例正是围绕探测这一动作组织起来的。样例总体结构与运行流程样例位于 example/0_quickstart/3_cross_version/0_runtime_compatibility目录下包含文件作用main.cpp主程序串行执行四组探测逻辑run.sh一键编译 运行 结果校验脚本CMakeLists.txtCMake 构建配置链接libacl_rt.soREADME.md样例说明与编译运行指引主程序 main.cpp 的顶层控制流为aclInit(nullptr)完成 ACL 初始化aclrtSetDevice(deviceId)绑定查询用 Device示例固定使用 device 0依次执行QueryCannVersion()、QueryCannAttributes()、QueryCompatibilityAndCapability()任一步失败即短路后续步骤无论成功与否都调用aclrtResetDeviceForce(deviceId)复位 Device 并调用aclFinalize()去初始化且分别检查返回值并记录错误码。这个初始化 → 探测 → 清理骨架是所有跨版本程序都应当遵循的标准姿势探测阶段失败时同样要保证清理逻辑执行防止残留状态影响下一次初始化。第一类探测CANN 软件版本查询版本查询是兼容性判断的第一道关卡。样例中的QueryCannVersion()使用两个配套接口main.cppchar pkgName[] runtime; char versionStr[ACL_PKG_VERSION_MAX_SIZE] {}; int32_t versionNum 0; CHECK_ERROR(aclsysGetVersionStr(pkgName, versionStr)); CHECK_ERROR(aclsysGetVersionNum(pkgName, versionNum)); INFO_LOG(CANN package [%s] version string: %s, pkgName, versionStr); INFO_LOG(CANN package [%s] version number: %d, pkgName, versionNum);两个接口的语义依据 acl_rt.h 中的注释aclsysGetVersionStr(char* pkgName, char* versionStr)按包名查询版本输出为字符串形式如9.1.0。versionStr缓冲区大小应使用ACL_PKG_VERSION_MAX_SIZE常量声明。aclsysGetVersionNum(char* pkgName, int32_t* versionNum)输出为整数形式如90100000便于程序直接做大小比较与分支。注意pkgName传入的是包名runtime即查询 CANN runtime 组件的版本。CANN 安装由多个组件包构成可按需分别查询。此外旧接口aclsysGetCANNVersion已被标记为 deprecated见 acl_rt.h新代码应直接使用上述两个接口。实战价值versionNum是整型可直接与编译期宏或最低版本阈值比较例如版本号 某阈值才启用新接口路径这是实现条件分支的最简单手段。第二类探测CANN 特性支持情况版本号能反映软件包是什么版本但无法反映当前环境实际使能了哪些可选能力。为此CANN 提供特性列表机制aclGetCannAttributeList获取当前环境支持的 CANN 特性枚举列表aclGetCannAttribute查询某个特性的支持值。样例中的QueryCannAttributes()main.cppconst aclCannAttr* attrList nullptr; size_t attrCount 0; CHECK_ERROR(aclGetCannAttributeList(attrList, attrCount)); INFO_LOG(CANN attribute count: %zu, attrCount); const size_t printCount std::minsize_t(attrCount, 3); for (size_t i 0; i printCount; i) { int32_t value 0; CHECK_ERROR(aclGetCannAttribute(attrList[i], value)); INFO_LOG(CANN attribute %s support value: %d, CannAttrToString(attrList[i]), value); }关键点aclGetCannAttributeList的第二个出参attrCount给出当前环境支持的特性个数程序据此可以动态遍历整个列表无需把特性枚举写死。aclGetCannAttribute(aclCannAttr cannAttr, int32_t* value)针对单个特性返回其支持值1 表示支持0 表示不支持。样例为便于阅读用CannAttrToString()把枚举值转成名字字符串其中还包含default: return ACL_CANN_ATTR_UNKNOWN分支说明新版本可能引入本样例编译期未知的新枚举值——这正是跨版本兼容的典型考验程序不应因遇到未知枚举而崩溃应优雅降级处理。aclCannAttr枚举定义于 acl_base_rt.htypedef enum { ACL_CANN_ATTR_UNDEFINED -1, ACL_CANN_ATTR_INF_NAN 0, // 是否支持 Inf/NaN 相关处理 ACL_CANN_ATTR_BF16 1, // 是否支持 BF16 ACL_CANN_ATTR_JIT_COMPILE 2 // 是否支持 JIT 编译 } aclCannAttr;对应接口声明见 acl_base_rt.h 与 acl_base_rt.h。在示例输出中三个特性ACL_CANN_ATTR_INF_NAN、ACL_CANN_ATTR_BF16、ACL_CANN_ATTR_JIT_COMPILE的支持值均为 1说明示例环境三项能力均已使能。实战价值当某个算子或功能如 BF16 计算依赖特定 CANN 特性时先aclGetCannAttribute探测再决定是否走该路径可避免在不支持的环境上误用能力导致运行异常。第三类探测SoC 架构兼容性除软件能力外程序还应确认自身编译/适配的 SoC 架构与当前设备是否匹配。样例的QueryCompatibilityAndCapability()main.cpp分两步const char* socName aclrtGetSocName(); if (socName nullptr || std::strlen(socName) 0U) { WARN_LOG(aclrtGetSocName returned empty soc name. Skip architecture compatibility check.); } else { int32_t canCompatible 0; CHECK_ERROR(aclrtCheckArchCompatibility(socName, canCompatible)); INFO_LOG(Architecture compatibility for %s: %d, socName, canCompatible); } int32_t capability 0; CHECK_ERROR(aclrtGetDeviceCapability(deviceId, ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV, capability)); INFO_LOG(Device capability ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV: %d, capability);三个接口要点aclrtGetSocName()返回当前环境的 SoC 名称如Ascend910B3。样例先校验返回值非空再继续后续检查这是防御性编程的体现——若拿不到 SoC 名则跳过架构兼容性检查而不是直接失败。aclrtCheckArchCompatibility(const char* socVersion, int32_t* canCompatible)检查指定 SoC 与当前运行环境的架构兼容性出参canCompatible非 0 表示兼容声明见 acl_rt.h。示例输出中Architecture compatibility for Ascend910B3: 1表明架构兼容。aclrtGetDeviceCapability查询指定 Device 的特定能力输入deviceId与能力类型aclrtDevFeatureType输出能力值声明见 acl_rt.h。样例查询的是ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIVTsCPU 任务更新是否同时支持 AIC 与 AIV枚举值为 1见 acl_rt.h。aclrtDevFeatureType枚举中另一项ACL_FEATURE_SYSTEM_MEMQ_EVENT_CROSS_DEV 21系统内存队列事件跨 Device 支持也属于同类可探测能力见 acl_rt.h需要时可一并查询。实战价值当程序依赖TsCPU 任务更新同时支持 AIC/AIV这类细粒度能力时先探测再决策能显著降低在异构产品系列如 Atlas A2 与 A3上运行的适配成本。初始化与清理的正确姿势跨版本程序的环境管理同样关键。样例在主流程中的用法CHECK_ERROR(aclInit(nullptr)); // 初始化 ACL CHECK_ERROR(aclrtSetDevice(deviceId)); // 指定 Device // ... 探测逻辑 ... aclError cleanupRet aclrtResetDeviceForce(deviceId); // 复位 Device if (cleanupRet ! ACL_SUCCESS) { ERROR_LOG(Operation failed: aclrtResetDeviceForce(deviceId) returned error code %d, ...); ret ret 0 ? -1 : ret; } cleanupRet aclFinalize(); // ACL 去初始化 if (cleanupRet ! ACL_SUCCESS) { ERROR_LOG(Operation failed: aclFinalize() returned error code %d, ...); ret ret 0 ? -1 : ret; }值得借鉴的两个工程细节使用aclrtResetDeviceForce而非普通aclrtResetDevice探测程序在查询阶段就可能因为环境异常留下未完成的任务强制复位能更彻底地清理 Device 状态适合这种一次性探测程序。清理阶段不中断主流程aclrtResetDeviceForce与aclFinalize的返回值被单独捕获并记录错误码即使探测失败也会走完清理只有当清理也失败时才影响最终返回码。这种尽力清理策略避免了资源泄漏与错误被掩盖的问题。编译与运行实战样例的运行脚本 run.sh 自动完成找环境 → 编译 → 运行 → 校验全流程cd ${git_clone_path}/example/0_quickstart/3_cross_version/0_runtime_compatibility # ${install_root} 替换为 CANN 安装根目录默认安装在 /usr/local/Ascend 目录 source ${install_root}/cann/set_env.sh bash run.shrun.sh的关键逻辑run.sh通过resolve_cann_env.sh位于 example/common/resolve_cann_env.sh解析 CANN 安装路径并导出ASCEND_INSTALL_PATH用 CMake 构建构建参数-DASCEND_CANN_PACKAGE_PATH${ASCEND_INSTALL_PATH}指定 CANN 包路径运行./build/main并将输出同时写入output_msg.txt用grep校验输出中是否出现成功标记[SUCCESS] Runtime compatibility sample completed successfully据此判定样例执行结果保证看起来跑完不等于真正跑通。构建配置方面CMakeLists.txt 通过include_directories(${ASCEND_CANN_PACKAGE_PATH}/include)引入 CANN 头文件、link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64)引入链接路径最终链接libacl_rt.so。编译选项-stdc17、-D_GLIBCX_USE_CXX11_ABI0、-Wall -Werror保证了与 CANN 运行时的 ABI 一致性和严格的编译告警检查。示例输出解读在一台已安装 CANN 9.1.0 的环境如 Atlas A2/A3 或 Ascend 950 系列产品上运行样例预期输出如下[INFO] CANN package [runtime] version string: 9.1.0 [INFO] CANN package [runtime] version number: 90100000 [INFO] CANN attribute count: 3 [INFO] CANN attribute ACL_CANN_ATTR_INF_NAN support value: 1 [INFO] CANN attribute ACL_CANN_ATTR_BF16 support value: 1 [INFO] CANN attribute ACL_CANN_ATTR_JIT_COMPILE support value: 1 [INFO] Architecture compatibility for Ascend910B3: 1 [INFO] Device capability ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV: 1 [INFO] [SUCCESS] Runtime compatibility sample completed successfully [SUCCESS] Runtime compatibility sample executed successfully.逐行解读版本查询结果9.1.0对应整数90100000即主版本 9、次版本 1、补丁 0编码为9*10^7 1*10^6 0。特性列表当前环境共支持 3 个 CANN 特性且 Inf/NaN、BF16、JIT 编译全部使能。架构兼容SoC 名称为Ascend910B3aclrtCheckArchCompatibility返回 1表示架构兼容。Device 能力ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV返回 1表示该能力已使能。最后两行分别是程序内部与脚本侧的成功标记脚本正是通过检索这一标记完成自动化验收。需要注意具体输出随环境而变化不同版本、不同产品上特性个数、SoC 名称、能力值都可能不同这正是本样例希望演示的环境差异可探测、可分支的核心理念。跨版本编程面向样例工程的兼容性检查清单综合上述探测手段可沉淀出一份面向样例工程乃至正式应用的跨版本兼容性检查清单版本分级用aclsysGetVersionNum获取整数版本号与编译期宏或运行时阈值比较决定是否启用仅在新版本提供的接口/行为。特性探测用aclGetCannAttributeList获取全部特性再用aclGetCannAttribute逐个确认所需特性避免依赖未使能能力。架构校验用aclrtGetSocName获取 SoC 名必要时用aclrtCheckArchCompatibility校验架构兼容性拿不到 SoC 名时应降级跳过而不是硬失败。能力查询用aclrtGetDeviceCapability查询细粒度 Device 能力如 TsCPU 任务更新支持范围按能力值走不同下发路径。防御性处理对未知的枚举值如未来新增的 CANN 特性、DevFeatureType使用 default 分支优雅处理不让程序崩溃。生命周期健壮探测失败也要保证aclrtResetDeviceForceaclFinalize执行并单独记录清理阶段的错误码。自动化验收运行脚本中通过grep检索程序内打印的成功标记来判定结果而不是只看进程退出码。延伸阅读跨版本探测与下面两个快速入门主题配合使用效果更佳example/0_quickstart/2_system_info/README.md系统版本与运行模式查询了解如何获取更全面的环境信息。example/0_quickstart/1_error_handling/README.md接口可用性判断与错误处理掌握CHECK_ERROR等宏背后的错误码处理思路与本文的探测流程互为补充。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考