CANN Runtime msproftx 扩展接口完全指南:Stamp 事件标记、范围打点与 Tensor 信息上报实战
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
导读
本文基于 CANN 开源运行时仓库(cann/runtime)中的 msproftx 扩展接口文档,系统讲解 msproftx 扩展接口的完整使用方式。msproftx 是 CANN Profiling 体系中面向用户的自定义打点能力,用于在采集任务中标注瞬时事件(Stamp)、时间范围(Push/Pop、Range)以及调用栈信息,最终在 Profiling 解析导出的msprof_tx summary数据中呈现。读完本文,你将掌握 11 个 msproftx 扩展接口的调用约束与配对关系、如何在aclprofStart/aclprofStop之间组织打点流程、如何在多线程场景下用 Range 接口代替线程栈接口,以及如何在 Torch 场景下上报 Tensor 信息,并深入理解其底层实现原理。
一、msproftx 扩展接口概述
msproftx(MS-Prof TX,即 Profiling 自定义打点扩展)是 CANN Runtime Profiling 能力中面向用户的扩展打点接口集。与 19-01 数据采集接口中的aclprofStart/aclprofStop等粗粒度采集控制接口不同,msproftx 允许用户在自己的业务代码中插入细粒度的性能标记,从而把"业务语义"(例如模型加载、前向传播、算子下发、预处理等阶段)映射到采集到的性能数据上。
从源码声明看,这些接口定义在 include/external/acl/acl_prof.h 中(MSVP_PROF_API导出),底层实现由 src/dfx/msprof/collector/dvvp/profimpl/adapter/src/msproftx_adaptor.cpp 中的ProfAcl*系列函数转发给 msprof_tx_manager.cpp 中的MsprofTxManager单例完成。调用 msproftx 相关接口的前提是:在aclprofCreateConfig创建配置时使能采集类型ACL_PROF_MSPROFTX(其值为0x0080ULL,定义见 acl_prof.h)。
1.1 接口全景一览
按功能可以把 11 个扩展接口划分为五类:
| 分类 | 接口 | 功能定位 |
|---|---|---|
| 标记对象管理 | aclprofCreateStamp/aclprofDestroyStamp | 创建 / 释放 msproftx 事件标记(Stamp)对象 |
| 标记描述 | aclprofSetStampTraceMessage | 为 Stamp 携带字符串描述,展示在msprof_tx summary中 |
| 瞬时事件标记 | aclprofMark/aclprofMarkEx | 记录瞬时事件(Mark),后者可下打到指定 Stream |
| 时间跨度标记 | aclprofPush/aclprofPop、aclprofRangeStart/aclprofRangeStop | 记录一段时间的开始与结束,前者线程内嵌套,后者可跨线程 |
| Tensor 信息上报 | aclprofRangePushEx/aclprofRangePop | 在 Torch 场景下上报 Tensor 信息 |
| 工具函数 | aclprofStr2Id | 将字符串(如算子名)转换为哈希 ID |
1.2 使用前提与整体调用约束
- 调用时机:msproftx 相关接口必须在 aclprofStart 与 aclprofStop 之间调用,且
aclprofStart的 aclprofConfig 数据需与aclprofStop保持一致,采集类型需包含ACL_PROF_MSPROFTX。 - 配对使用:
aclprofCreateStamp/aclprofDestroyStamp、aclprofPush/aclprofPop、aclprofRangeStart/aclprofRangeStop、aclprofRangePushEx/aclprofRangePop均为成对接口。 - 推荐调用顺序:
aclprofStart→aclprofCreateStamp→aclprofSetStampTraceMessage→aclprofMark→(aclprofPush/aclprofPop)或(aclprofRangeStart/aclprofRangeStop)→aclprofDestroyStamp→aclprofStop。
二、标记对象生命周期管理:aclprofCreateStamp 与 aclprofDestroyStamp
2.1 aclprofCreateStamp:创建事件标记
void *aclprofCreateStamp()功能说明:创建 msproftx 事件标记对象。后续调用aclprofMark、aclprofSetStampTraceMessage、aclprofPush、aclprofRangeStart时,都需要把该指针作为入参传入,用于标识记录的是同一个事件的时间跨度。
返回值:
- 返回
void*指针:成功; - 返回
nullptr:失败(例如未先调用aclprofStart)。
约束:必须与aclprofDestroyStamp配对使用,且需在aclprofStart之后调用。
源码佐证:在 msprof_tx_manager.cpp 的CreateStamp()实现中,会先检查MsprofTxManager是否已初始化(即是否已通过aclprofStart触发MsprofTxInit),未初始化时记录EK0002错误并返回nullptr;初始化后从内存池stampPool_->CreateStamp()取出 Stamp。也就是说,Stamp 并非普通堆对象,而是从预分配的内存池(CURRENT_STAMP_SIZE指定池容量)中分配,这有利于高频打点场景下的内存稳定性。
2.2 aclprofSetStampTraceMessage:为标记携带描述信息
aclError aclprofSetStampTraceMessage(void *stamp, const char *msg, uint32_t msgLen)功能说明:为 msproftx 事件标记携带字符串描述。该描述会出现在 Profiling 解析并导出的结果中的msprof_tx summary数据里,便于在分析工具中快速识别打点含义(例如 "model_load_mark"、"forward_pass_push")。
参数说明:
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| stamp | 输入 | Stamp 指针,指代 msproftx 事件标记,即aclprofCreateStamp的返回值 |
| msg | 输入 | Stamp 信息字符串指针 |
| msgLen | 输入 | 字符串长度 |
返回值:返回0表示成功,返回其他值表示失败,参见 aclError。
约束:需在aclprofCreateStamp与aclprofDestroyStamp之间调用。
源码佐证:底层 SetStampTraceMessage 实现中定义了MAX_MSG_LEN = 128,若msgLen >= 128会报错并返回失败;合法的消息通过strncpy_s拷入 Stamp 内部的message字段并补\0。因此建议描述字符串长度控制在 127 字节以内。
2.3 aclprofDestroyStamp:释放事件标记
void aclprofDestroyStamp(void *stamp)功能说明:释放 msproftx 事件标记对象,将 Stamp 归还内存池(而非直接free)。实现见 DestroyStamp,对nullptr入参会记录EK0006参数错误。
参数说明:
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| stamp | 输入 | Stamp 指针,即aclprofCreateStamp的返回值 |
返回值:无。
约束:与aclprofCreateStamp配对使用,且应在aclprofStop之前调用。
三、瞬时事件标记:aclprofMark 与 aclprofMarkEx
3.1 aclprofMark:标记瞬时事件
aclError aclprofMark(void *stamp)功能说明:标记一个瞬时事件(如"模型加载完成"、"执行结束")。调用后,Profiling 自动在 Stamp 中写入当前时间戳,并将Event type设置为Mark,表示完成一次 msproftx 采集打点。
参数说明:
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| stamp | 输入 | Stamp 指针,即aclprofCreateStamp的返回值 |
返回值:返回0表示成功,其他值表示失败,参见 aclError。
约束:在aclprofCreateStamp与aclprofDestroyStamp之间调用。
源码佐证:Mark() 实现中,startTime与endTime均取当前系统周期计数值(PlatformSysCycleTime()),eventType置为EventType::MARK,随后通过ReportStampData上报。
3.2 aclprofMarkEx:带 Stream 的瞬时打点
aclError aclprofMarkEx(const char *msg, size_t msgLen, aclrtStream stream)功能说明:向指定的 Stream 流上下发打点任务,用于标识 Host 侧打点与 Device 侧打点任务之间的对应关系。与aclprofMark相比,aclprofMarkEx不依赖 Stamp 对象,而是直接把消息字符串与 Stream 关联起来。
参数说明:
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| msg | 输入 | 打点信息字符串指针 |
| msgLen | 输入 | 字符串长度,最大支持 127 字符 |
| stream | 输入 | 指定 Stream,类型定义参见 aclrtStream |
返回值:返回0表示成功,其他值表示失败,参见 aclError。
约束:无。
源码佐证:实现分两步完成(见 MarkEx / MarkExPoint):
- 先校验
msg、stream非空且strlen(msg) == msgLen、消息长度在1 ~ MAX_MESSAGE_LEN-1范围内; - 调用注册的 Runtime 回调
rtProfilerTraceExFunc_(即rtProfilerTraceEx),携带markId、MARKEX_MODEL_ID = 0xFFFFFFFF、MARKEX_TAG_ID = 11以及 Stream 指针,把打点任务下发到 Device 侧; - 将消息拷贝进
MsprofTxInfo后通过 reporter 上报。
此外,源码中定义了MARKEX_MAX_CYCLE = 1000与MARKEX_RANGE_TAG_ID = 12(Range 型打点使用的 tag),从源码结构可以推断其用于控制 MarkEx 相关任务索引的循环复用,以及区分瞬时/范围两类 Device 打点任务。
四、时间跨度标记:Push/Pop 与 RangeStart/RangeStop
时间跨度标记用于度量一段代码的执行耗时,msproftx 提供了两套语义等价、但使用场景不同的接口。
4.1 aclprofPush 与 aclprofPop:线程内嵌套范围
aclError aclprofPush(void *stamp) aclError aclprofPop()功能说明:aclprofPush记录时间跨度开始时间,aclprofPop记录结束时间。调用aclprofPush后,Profiling 自动在 Stamp 中记录开始时间戳,并将Event type设置为Push/Pop;aclprofPop记录结束时间戳。
参数说明(aclprofPush):
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| stamp | 输入 | Stamp 指针,即aclprofCreateStamp的返回值 |
返回值:均为返回0成功,其他值失败,参见 aclError。
约束:
- 与
aclprofPop成对使用,表示时间跨度的开始与结束; - 在
aclprofCreateStamp与aclprofDestroyStamp之间调用; - 不能跨线程调用。若需要跨线程,请使用
aclprofRangeStart/aclprofRangeStop。
源码佐证:Push记录startTime后把 Stamp 压入 Stamp 池的线程栈(stampPool_->MsprofStampPush(stamp));Pop从栈中弹出 Stamp(弹栈失败会报EK0002,提示检查aclprofPush/aclprofPop配对),写入endTime并将eventType置为PUSH_OR_POP后上报。由于是"栈"语义,Push/Pop 天然支持嵌套,即先 Push A 再 Push B、然后依次 Pop B、Pop A,可形成嵌套范围。
4.2 aclprofRangeStart 与 aclprofRangeStop:可跨线程的范围标记
aclError aclprofRangeStart(void *stamp, uint32_t *rangeId) aclError aclprofRangeStop(uint32_t rangeId)功能说明:aclprofRangeStart记录时间跨度开始,aclprofRangeStop记录结束。调用aclprofRangeStart后,Profiling 自动在 Stamp 中记录开始时间戳,将Event type设置为Start/Stop,生成一个进程唯一的 id,并把 Stamp 保存在以进程粒度维护的一个 map中。aclprofRangeStop通过该唯一 id 找到对应的 Stamp 并记录结束时间戳。
参数说明:
| 接口 | 参数名 | 输入/输出 | 说明 |
|---|---|---|---|
| aclprofRangeStart | stamp | 输入 | Stamp 指针,即aclprofCreateStamp的返回值 |
| aclprofRangeStart | rangeId | 输出 | msproftx 事件标记的唯一标识,用于跨线程时区分 |
| aclprofRangeStop | rangeId | 输入 | msproftx 事件标记的唯一标识 |
返回值:均为返回0成功,其他值失败,参见 aclError。
约束:
- 与
aclprofRangeStop成对使用; - 在
aclprofCreateStamp与aclprofDestroyStamp之间调用; - 可以跨线程调用(这是与 Push/Pop 最核心的区别)。
源码佐证:RangeStart(见 RangeStart)通过stampPool_->GetIdByStamp(stamp)生成唯一rangeId,并置stamp->isEnable = 1;RangeStop通过stampPool_->GetStampById(rangeId)反查 Stamp,若查不到(例如传入了未由aclprofRangeStart返回的 id)会报EK0001参数错误。rangeId之所以能跨线程,正是因为它的保存粒度是进程级 map,而非线程栈。
4.3 Push/Pop 与 Range 的选择建议
| 维度 | aclprofPush / aclprofPop | aclprofRangeStart / aclprofRangeStop |
|---|---|---|
| 嵌套支持 | 支持(栈语义) | 不支持嵌套,仅区间对 |
| 跨线程 | 不支持 | 支持 |
| 结束定位 | 无参数,自动弹栈 | 通过 rangeId 精确定位 |
| 典型场景 | 单线程内嵌套调用链 | 异步任务、多线程流水线 |
选型原则:如果打点发生在同一线程且存在嵌套调用结构(如外层"前向传播"包内层"算子分发"),优先用 Push/Pop;如果开始与结束发生在不同线程(如生产者-消费者、异步回调),必须改用 RangeStart/RangeStop。
五、Torch 场景 Tensor 信息上报:aclprofRangePushEx / aclprofRangePop 与 aclprofStr2Id
5.1 功能定位
在aclrt和<<<>>>(kernel 启动)场景下,用户可在算子加载接口前先调用aclprofRangePushEx上报 Tensor 信息,之后再调用aclprofRangePop,完成 Profiling 数据的上报。调用aclprofRangePushEx后,Profiling 判断messageType为MESSAGE_TYPE_TENSOR_INFO时,会缓存 Tensor 信息;调用aclprofRangePop时再将缓存的 Tensor 信息上报。
5.2 aclprofRangePushEx
aclError aclprofRangePushEx(aclprofEventAttributes *attr)参数说明:
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| attr | 输入 | 需要上报的 Tensor 信息,结构体详见 aclprofEventAttributes |
返回值:返回0成功,其他值失败,参见 aclError。
约束:与aclprofRangePop配对使用,先aclprofRangePushEx后aclprofRangePop。
5.3 aclprofRangePop
aclError aclprofRangePop()功能说明:上报缓存的 Tensor 信息(即aclprofRangePushEx缓存的那份数据)。
返回值:返回0成功,其他值失败,参见 aclError。
约束:与aclprofRangePushEx配对使用。
5.4 aclprofStr2Id:字符串转哈希 ID
uint64_t aclprofStr2Id(const char *message)功能说明:msproftx 用于将字符串(例如算子名)转化为哈希 ID。在构造 Tensor 信息上报时,用哈希 ID 代替冗长的字符串,可以显著降低打点数据的体积。
参数说明:
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| message | 输入 | 字符信息,例如算子名 |
返回值:返回哈希 ID;如果返回uint64_t类型的最大值则说明失败,其他值表示成功。
约束:与aclprofRangePushEx和aclprofRangePop配合使用,在aclprofRangePushEx之前调用。
5.5 数据结构:aclprofEventAttributes 与相关结构体
在 acl_prof.h 中定义了与 Tensor 信息上报配套的公共结构体,其布局已冻结以保持二进制兼容(新字段只能追加在尾部并提升ACL_PROF_EVENT_ATTR_VERSION):
#define ACL_PROF_EVENT_ATTR_VERSION 1 #define ACL_PROF_TENSOR_DATA_SHAPE_LEN 8 // shape 维度上限 typedef struct aclprofTensor { uint32_t type; // tensor类型, 0: input, 1: output uint32_t format; // format类型: aclFormat uint32_t dataType; // dataType类型 aclDataType uint32_t shapeDim; // shape dim <= 8 uint32_t shape[ACL_PROF_TENSOR_DATA_SHAPE_LEN]; // tensor内存大小 } aclprofTensor; typedef struct aclprofTensorInfo { uint64_t opNameId; // 通过 uint64_t aclprofStr2Id(const char *message) 得到 uint64_t opTypeId; uint32_t resv; uint32_t tensorNum; uint32_t kernelType; uint32_t blockNums; void* stream; // stream信息 aclprofTensor* tensors; } aclprofTensorInfo; typedef struct aclprofEventAttributes { uint16_t version; uint16_t size; uint32_t messageType; // MESSAGE_TYPE_TENSOR_INFO union Message { aclprofTensorInfo* tensorInfo; } message; } aclprofEventAttributes;关键说明:
aclprofEventAttributes.messageType只有枚举ACL_PROF_MESSAGE_TYPE_TENSOR_INFO(值0)一个取值;aclprofTensor.shape的维度上限为 8(ACL_PROF_TENSOR_DATA_SHAPE_LEN),shapeDim不得大于 8;- 头文件允许通过定义
ACL_PROF_TENSOR_INFO_DEFINED来屏蔽官方结构定义、使用用户自定义结构,但前提是保持与上述冻结布局的二进制兼容; - 从源码结构可以推断:
aclprofStr2Id得到的opNameId/opTypeId与字符串的对应关系会在 Profiling 解析阶段还原,从而在msprof_tx summary中展示可读的算子名。
六、源码级实现链路与关键细节
6.1 调用链总览
从仓库源码可以梳理出 msproftx 的完整调用链:
应用代码 → aclprofCreateStamp / aclprofMark / aclprofPush ... (include/external/acl/acl_prof.h 声明) → ProfAclCreateStamp / ProfAclMark / ProfAclPush ... (src/dfx/msprof/collector/dvvp/profimpl/adapter/src/msproftx_adaptor.cpp) → MsprofTxManager::CreateStamp / Mark / Push ... (src/dfx/msprof/collector/dvvp/msprof/msproftx/src/msprof_tx_manager.cpp) → stampPool_(Stamp 内存池)+ reporter_(数据上报)6.2 关键实现要点
初始化与生命周期:
MsprofTxManager::Init()会创建ProfStampPool并初始化(容量为CURRENT_STAMP_SIZE字节),初始化失败会上报EK0201环境错误;UnInit()会依次反初始化 stampPool 与 reporter。manager 的初始化由aclprofStart流程触发(MsprofTxInit回调),因此文档要求"必须在aclprofStart/aclprofStop之间调用"是有实现依据的。错误处理:所有入参校验失败都会通过
MSPROF_INPUT_ERROR上报EK0006(参数为空)、EK0001(参数非法)或EK0002(接口顺序错误)等错误码,返回对应的ACL_ERROR_INVALID_PARAM等 aclError。这些错误码在 docs/zh/error_code_ref 中有对应说明。线程信息采集:每次上报(
ReportStampData)都会用OsalGetTid()记录当前线程 ID,MarkEx还会用OsalGetPid()记录进程 ID——这是跨线程 Range 语义能够在解析端正确归位的关键。Device 侧打点:
aclprofMarkEx与 Range 型 Device 打点通过rtProfilerTraceEx运行时接口把任务下发到 Stream,tagId区分瞬时(11)与范围(12)两种打点任务,modelId固定为0xFFFFFFFF。
6.3 产品支持情况
根据接口文档,msproftx 扩展接口在以下产品上支持,在IPV350 上不支持:
- Ascend 950PR / Ascend 950DT:支持
- Atlas A3 训练系列产品 / Atlas A3 推理系列产品:支持
- Atlas A2 训练系列产品 / Atlas A2 推理系列产品:支持
- Atlas 200I/500 A2 推理产品:支持
- Atlas 推理系列产品:支持
- Atlas 训练系列产品:支持
- IPV350:不支持
另外,从 msproftx_adaptor.cpp 可以看到,所有接口在helper host 侧会直接拒绝执行并记录EK0004(接口不支持)错误,即 msproftx 打点只能运行在业务侧进程。
七、完整实战示例
仓库在 example/5_performance/profiling/1_msproftx 提供了可直接编译运行的 msproftx 样例(main.cpp+run.sh)。该样例除演示瞬时事件aclprofMark外,还演示了aclprofPush/aclprofPop的嵌套范围标记与aclprofRangeStart/aclprofRangeStop的非嵌套范围标记,便于对照 NVTX 的常见使用模式。
7.1 样例核心流程
#include "acl/acl.h" #include "acl/acl_prof.h" // 创建带描述信息的 Stamp void* stamp = aclprofCreateStamp(); aclprofSetStampTraceMessage(stamp, "forward_pass_push", strlen("forward_pass_push")); // ... 初始化 Runtime 与 Profiling ... aclprofConfig* config = aclprofCreateConfig( deviceIdList, 1, ACL_AICORE_ARITHMETIC_UTILIZATION, nullptr, ACL_PROF_ACL_API | ACL_PROF_TASK_TIME | ACL_PROF_MSPROFTX); // 注意 ACL_PROF_MSPROFTX aclprofStart(config); // 瞬时事件 aclprofMark(loadMark); // 非嵌套范围(可跨线程) uint32_t rangeId = 0; aclprofRangeStart(preprocessRange, &rangeId); // ... 预处理逻辑 ... aclprofRangeStop(rangeId); // 嵌套范围(线程内) aclprofPush(outerRangePush); aclprofPush(innerRangePush); // ... 内层逻辑 ... aclprofPop(); // ... 外层逻辑 ... aclprofPop(); aclprofStop(config); aclprofDestroyStamp(stamp);7.2 编译与运行
环境安装详情以及运行详情见 example 目录下的 README。运行步骤如下:
# ${install_root} 替换为 CANN 安装根目录,默认安装在 /usr/local/Ascend 目录 source ${install_root}/cann/set_env.sh export ASCEND_INSTALL_PATH=${install_root}/cann # Profiling 样例的 run.sh 还会读取 ASCEND_HOME_PATH,请一并设置为同一路径 export ASCEND_HOME_PATH=${install_root}/cann # 编译运行 bash run.sh7.3 样例输出
[INFO] -------- Start -------- [INFO] Preprocess range start [INFO] Preprocess range stop [INFO] Nested operator dispatch range start [INFO] Nested operator dispatch range stop [INFO] Model execute start [INFO] Model execute end [INFO] -------- End --------运行完成后,采集数据落盘到样例指定的./output目录(aclprofInit的第一个参数指定结果路径)。在 Profiling 解析并导出结果中,可通过msprof_tx summary数据查看本次打点的完整时间线:各 Stamp 的描述字符串、事件类型(Mark / Push/Pop / Start/Stop)、开始与结束时间戳等。
7.4 样例中的关键实践点
- 样例的 main.cpp 将"创建 Stamp + 设置描述"封装为
CreateStampWithMessage,并集中用StampSet管理多个 Stamp,结束时统一aclprofDestroyStamp——这是推荐的对象管理方式,避免漏释放; - 每个 Stamp 在创建后、使用前均校验非空,失败时立即
aclprofDestroyStamp清理并返回,体现了正确的错误处理范式; - 在打点外围用
aclprofGetStepTimestamp(stepInfo, ACL_STEP_START/END, stream)记录 step 边界,将业务打点与训练 step 对齐(相关接口见 19-01 数据采集接口)。
八、注意事项与常见问题
- 忘记使能采集类型:
aclprofCreateConfig的dataTypeConfig必须包含ACL_PROF_MSPROFTX,否则打点数据不会被采集(样例中为ACL_PROF_ACL_API | ACL_PROF_TASK_TIME | ACL_PROF_MSPROFTX)。 - 接口顺序:
aclprofCreateStamp必须在aclprofStart之后、aclprofDestroyStamp必须在aclprofStop之前;违反顺序会得到EK0002类错误。 - 配对与生命周期:Push 之后必须 Pop、RangeStart 之后必须 RangeStop、PushEx 之后必须 Pop;否则会造成 Stamp 泄漏在栈/map 中或导致后续 Pop 弹栈失败。
- 消息长度:
aclprofSetStampTraceMessage的消息长度须小于 128 字节(源码中MAX_MSG_LEN = 128),aclprofMarkEx的消息长度最大支持 127 字符,超限会返回失败。 - 跨线程限制:Push/Pop 不能跨线程;跨线程场景请改用 RangeStart/RangeStop,其
rangeId是进程唯一的,并以进程级 map 保存 Stamp。 - 不支持的场景:IPV350 产品不支持全部 msproftx 扩展接口;helper host 侧调用同样会被拒绝。
- 性能开销:Stamp 对象从预分配内存池中分配,打点数据通过 reporter 异步上报;但仍建议控制打点频率与消息长度,避免对热路径产生不必要的开销。
九、参考资料
- msproftx 扩展接口官方文档(本文主体来源)
- 数据采集接口(aclprofStart / aclprofStop 等)
- 接口声明与公共结构体定义
- 底层实现:MsprofTxManager
- 接口适配层:msproftx_adaptor.cpp
- msproftx 实战样例
- aclError 错误码说明
- 数据结构说明(aclprofEventAttributes)
- Profiling 数据采集指南(开发指南)
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考