十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CANN Runtime Device管理接口全解析:设备设置、查询、P2P交互与资源限制实战指南

CANN Runtime Device管理接口全解析:设备设置、查询、P2P交互与资源限制实战指南 CANN Runtime Device管理接口全解析设备设置、查询、P2P交互与资源限制实战指南【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime导读Device设备管理是 CANN Runtime 编程模型的入口与基石任何算子下发、内存分配、Stream 编排都建立在一个可用的 Device 之上。本文基于 CANN Runtime 设备管理接口文档系统梳理约 40 个aclrt*设备管理接口的分类、语义、参数与约束并结合开源仓库中的头文件声明、示例工程与枚举定义帮助读者掌握设备生命周期管理Set/Reset、设备信息查询、Device 间 P2P 数据交互、溢出状态检测、设备 ID 映射用户/逻辑/物理以及 Device 资源限制配置等核心能力可直接指导多卡训练、容器化部署与故障定位场景下的编程实践。一、接口全景Device 管理能力地图Device 管理接口全部以aclrt前缀命名声明于 acl_rt.h。按照功能可划分为以下七大类功能类别代表接口核心用途设备生命周期aclrtSetDevice/aclrtResetDevice/aclrtResetDeviceForce指定运算 Device、释放 Device 资源设备状态查询aclrtGetDevice/aclrtGetDeviceCount/aclrtQueryDeviceStatus/aclrtGetRunMode/aclrtGetSocName/aclrtDeviceGetUuid获取当前 Device、可用数量、运行模式、芯片版本等设备性能与利用率aclrtGetDeviceUtilizationRate/aclrtGetDeviceInfo/aclrtGetDevicesTopo/aclrtDeviceGetStreamPriorityRange/aclrtGetDeviceCapability查询 Cube/Vector 利用率、设备属性、拓扑关系、Stream 优先级范围、特性支持P2P 数据交互aclrtDeviceCanAccessPeer/aclrtDeviceEnablePeerAccess/aclrtDeviceDisablePeerAccess/aclrtDevicePeerAccessStatusDevice 间数据交互的查询、开启、关闭溢出检测与同步aclrtGetOverflowStatus/aclrtResetOverflowStatus/aclrtSynchronizeDevice/aclrtSynchronizeDeviceWithTimeout获取/清除溢出状态、设备级同步设备 ID 映射aclrtGetLogicDevIdByUserDevId等 6 个转换接口用户设备 ID、逻辑设备 ID、物理设备 ID 之间互转资源限制与高级能力aclrtDeviceSetLimit/aclrtDeviceGetLimit/aclrtDeviceL2CacheFlush/aclrtDeviceGetHostAtomicCapabilities/aclrtDeviceGetP2PAtomicCapabilities/aclrtDeviceGetPCIBusId/aclrtDeviceGetByPCIBusId/aclrtDeviceGetBareTgid/aclrtRegDeviceStateCallback/aclrtSetTsDevice/aclrtSetDeviceSatMode/aclrtGetDeviceSatMode资源限制、L2 Cache 清空、原子操作能力、PCI Bus ID、进程 ID、状态回调等通用返回值约定除aclrtGetSocName外所有接口均返回aclError类型返回 0 表示成功返回其他值表示失败错误码定义请参见 aclError。各接口参数中用到的枚举、结构体类型可在 25-02_Enumerations.md 与 25-04_Structs.md 中查询。二、设备生命周期管理Set 与 Reset设备生命周期管理是整个 Runtime 编程的入口和出口几乎所有业务代码都以aclrtSetDevice开始、以aclrtResetDevice/aclrtResetDeviceForce结束。仓库示例 0_device_normal/main.cpp 展示了这一标准流程CHECK_ERROR(aclInit(nullptr)); CHECK_ERROR(aclrtSetDevice(deviceId)); // 指定运算 Device隐式创建默认 Context/Stream // ... 业务处理分配内存、下发算子、同步... CHECK_ERROR(aclrtSynchronizeDevice()); CHECK_ERROR(aclrtDestroyStream(stream)); CHECK_ERROR(aclrtResetDeviceForce(deviceId)); // 复位 Device释放资源 CHECK_ERROR(aclFinalize());2.1 aclrtSetDevice指定运算 DeviceaclError aclrtSetDevice(int32_t deviceId)功能指定当前线程中用于运算的 Device。多 Device 场景下可在进程中通过该接口切换到其它 Device不同线程可指定同一个 Device 用于运算。默认 Context 机制调用本接口会隐式创建默认 Context其中包含一个默认 Stream。在同一个进程的多个线程中如果通过aclrtSetDevice指定相同的 Device这些线程将共享同一个默认 Context。这正是多线程编程中 1_device_multi_thread/main.cpp 无需显式创建 Context 即可并发使用同一 Device 的底层原因。参数deviceId为 Device ID取值范围为[0, 可用的Device数量-1]可用数量通过aclrtGetDeviceCount获取。约束IPV350 上不支持默认 Context 和默认 Stream不能依赖本接口隐式创建的资源。2.2 aclrtResetDevice引用计数式复位aclError aclrtResetDevice(int32_t deviceId)释放默认 Context、默认 Stream 以及默认 Context 下创建的所有 Stream若任务还未完成系统会等待任务完成后再释放。引用计数语义关键本接口内部涉及引用计数实现建议与aclrtSetDevice配对使用。aclrtSetDevice每调用一次引用计数加一aclrtResetDevice每调用一次引用计数减一计数减到 0 时才真正释放 Device 资源。若多次调用aclrtSetDevice而不调用 Reset进程退出时也会自动释放本进程使用的 Device 资源。复位前资源释放顺序若要复位的 Device 上存在显式创建的 Context、Stream、Event建议按如下顺序调用否则可能导致业务异常aclrtDestroyEvent释放Event -- aclrtDestroyStream释放显式Stream -- aclrtDestroyContext释放显式Context -- aclrtResetDevice2.3 aclrtResetDeviceForce强制复位aclError aclrtResetDeviceForce(int32_t deviceId)释放的资源范围与aclrtResetDevice相同默认 Context、默认 Stream 及其下所有 Stream。不要求配对本接口可与aclrtSetDevice配对使用也可不配对。不配对时针对同一个 Device调用一次或多次aclrtSetDevice后仅需调用一次aclrtResetDeviceForce即可释放资源// 与 aclrtSetDevice 接口配对使用 aclrtSetDevice(1) - aclrtResetDeviceForce(1) - aclrtSetDevice(1) - aclrtResetDeviceForce(1) // 与 aclrtSetDevice 接口不配对使用 aclrtSetDevice(1) - aclrtSetDevice(1) - aclrtResetDeviceForce(1)多线程约束多线程场景下针对同一个 Device如果每个线程都各自调用 Set 和 ResetForce后执行的 ResetForce 会因为资源已被先执行的线程释放而报错。正确方式是仅在最后一个线程执行结束时调用一次aclrtResetDeviceForce时间线 ----------------------------------------------------------------------------- 线程1aclrtSetDevice(1) 线程2aclrtSetDevice(1) aclrtResetDeviceForce(1)混用规则两个 Reset 接口可以混用但调用次数与顺序有严格限制。正确方式是两个 Reset 接口分别与 Set 配对且aclrtResetDeviceForce在aclrtResetDevice之后错误方式包括引用计数减到 0 后再调用任一 Reset 接口或 ResetForce 先于 ResetDevice 调用# 混用时的正确方式 aclrtSetDevice(1) - aclrtResetDevice(1) - aclrtSetDevice(1) - aclrtResetDeviceForce(1) aclrtSetDevice(1) - aclrtSetDevice(1) - aclrtResetDevice(1) - aclrtResetDeviceForce(1) # 混用时的错误方式 aclrtSetDevice(1) - aclrtSetDevice(1) - aclrtResetDevice(1)--aclrtResetDevice(1)--aclrtResetDeviceForce(1) aclrtSetDevice(1) - aclrtSetDevice(1) - aclrtResetDevice(1)--aclrtResetDeviceForce(1)--aclrtResetDeviceForce(1) aclrtSetDevice(1) - aclrtSetDevice(1) - aclrtResetDeviceForce(1)--aclrtResetDevice(1)三、设备信息查询从数量到能力的全方位探测3.1 aclrtGetDeviceCount 与 aclrtGetDeviceaclError aclrtGetDeviceCount(uint32_t *count) // 获取可用 Device 数量 aclError aclrtGetDevice(int32_t *deviceId) // 获取当前正在使用的 Device IDaclrtGetDeviceCount是几乎所有 Device 管理接口的前置查询aclrtSetDevice、aclrtGetDeviceUtilizationRate、aclrtQueryDeviceStatus、P2P 系列接口等都以它返回的数量确定 Device ID 的取值范围[0, count-1]。在 2_device_P2P/main.cpp 中示例先查询数量并判断deviceCount 2才继续执行 P2P 流程否则直接跳过这是多卡程序的标准防御写法。aclrtGetDevice用于获取当前正在使用的 Device ID。约束如果没有提前调用aclrtSetDevice指定计算设备调用本接口会返回错误。3.2 aclrtGetRunMode判断 AI 软件栈运行模式aclError aclrtGetRunMode(aclrtRunMode *runMode)返回当前 AI 软件栈的运行模式类型为 aclrtRunMode 枚举。仓库中该枚举定义了两个取值ACL_HOST表示 AI 软件栈运行在 Host 侧ACL_DEVICE表示 AI 软件栈运行在 Device 的 Control CPU 或板端环境上。从枚举注释可以看到ACL_DEVICE选项在 Ascend 950PR/Ascend 950DT、Atlas A3 系列、Atlas A2 系列产品上均不支持。典型用途应用据此判断自身是运行在 Host 侧还是 Device 侧从而决定内存分配策略Host 内存 vs Device 内存和同步方式。3.3 aclrtQueryDeviceStatus设备健康状态探测aclError aclrtQueryDeviceStatus(int32_t deviceId, aclrtDeviceStatus *deviceStatus)查询 Device 是正常可用还是异常不可用。deviceStatus类型为 aclrtDeviceStatus 枚举定义于 25-02_Enumerations.md。该接口适合在训练/推理任务启动前做设备健康检查规避把任务下发到异常 Device 上。注意IPV350 不支持该接口。3.4 aclrtGetSocName查询 AI 处理器版本const char *aclrtGetSocName()返回当前运行环境 AI 处理器版本名称的字符串指针可用于软件栈根据 SoC 名称做差异化路径分发。返回值有两点特殊语义获取失败时返回空指针若运行环境上 Device 数量大于 1固定返回 Device 0 的版本名称。3.5 aclrtGetDeviceUtilizationRateCube/Vector 利用率查询aclError aclrtGetDeviceUtilizationRate(int32_t deviceId, aclrtUtilizationInfo *utilizationInfo)查询 Device 上 Cube、Vector、AI CPU 等的利用率结果写入 aclrtUtilizationInfo 结构体。以下约束务必注意查询 Vector 利用率时若结果为 -1表示 Vector 不存在当前版本不支持查询 Device 内存利用率查询得到的结果为 -1开启 Profiling 功能时不支持调用本接口返回值无实际意义Atlas A2 训练/推理系列、Atlas 训练系列、Atlas 推理系列产品在昇腾虚拟化实例场景下同样不支持本接口。3.6 aclrtGetDeviceInfo设备属性查询aclError aclrtGetDeviceInfo(uint32_t deviceId, aclrtDevAttr attr, int64_t *value)按属性项查询指定 Device 的信息。属性类型aclrtDevAttr定义于 25-02_Enumerations.md从仓库枚举可以看到至少包括ACL_DEVICE_INFO_AI_CORE_NUMAI Core 数量、ACL_DEVICE_INFO_VECTOR_CORE_NUMVector Core 数量、ACL_DEVICE_INFO_L2_SIZEL2 Buffer 大小单位 Byte等。程序据此可动态适配不同算力的芯片。3.7 aclrtGetDeviceCapability 与 aclrtGetDevicesTopoaclError aclrtGetDeviceCapability(int32_t deviceId, aclrtDevFeatureType devFeatureType, int32_t *value) aclError aclrtGetDevicesTopo(uint32_t deviceId, uint32_t otherDeviceId, uint64_t *value)aclrtGetDeviceCapability查询指定 Device 是否支持某特性输出值取ACL_DEV_FEATURE_SUPPORT(1)或ACL_DEV_FEATURE_NOT_SUPPORT(0)。这两个宏在 acl_rt.h 中定义为0x00000001与0x00000000与文档描述一致。aclrtGetDevicesTopo获取两个 Device 之间的网络拓扑关系。拓扑值通过位掩码宏表达全部定义于 acl_rt.h宏定义值含义ACL_RT_DEVS_TOPOLOGY_HCCS0x01ULL通过 HCCSHuawei Cache Coherence System华为缓存一致性系统连接ACL_RT_DEVS_TOPOLOGY_PIX0x02ULL通过同一个 PCIe Switch 连接ACL_RT_DEVS_TOPOLOGY_PIB0x04ULL预留值暂不支持ACL_RT_DEVS_TOPOLOGY_PHB0x08ULL通过 PCIe Host Bridge 连接ACL_RT_DEVS_TOPOLOGY_SYS0x10ULL通过 SMP对称多处理连接NUMA 节点间互连ACL_RT_DEVS_TOPOLOGY_SIO0x20ULL片内连接两个 DIE 之间通过该方式连接ACL_RT_DEVS_TOPOLOGY_HCCS_SW0x40ULL通过 HCCS Switch 连接约束aclrtGetDevicesTopo不支持在 Atlas 200I/500 A2 推理产品的 Ascend RC 形态下调用IPV350 不支持。3.8 其他查询类接口速览aclrtDeviceGetStreamPriorityRange(int32_t *leastPriority, int32_t *greatestPriority)查询硬件支持的 Stream 最低、最高优先级创建带优先级的 Stream 前先查询取值范围。aclrtDeviceGetUuid(int32_t deviceId, aclrtUuid *uuid)获取 Device 的唯一标识 UUID用于跨进程/跨机识别同一物理设备。产品支持上仅 Ascend 950 系列、Atlas A3 系列、Atlas A2 系列支持。aclrtDeviceGetPCIBusId/aclrtDeviceGetByPCIBusIdDevice ID 与 PCI Bus ID格式domain:bus:device.function如0000:3d:00.0之间的双向转换。len缓冲区长度必须大于等于 1312 个字符加结尾\0。约束虚拟机/容器场景返回虚拟化层分配的虚拟 PCI Bus ID仅保证当前虚拟机/容器内合法唯一非 PCIe 互连形态如 HCCS、Unified Bus的设备返回ACL_ERROR_RT_FEATURE_NOT_SUPPORT。aclrtDeviceGetBareTgid(int32_t *pid)获取当前进程 ID。接口内部已适配物理机、虚拟机场景在需要配合 aclrtMemExportToShareableHandle 做物理内存共享时务必使用本接口获取进程 ID 而非自行取 pid否则可能导致后续使用异常。四、Device 间 P2P 数据交互CANN Runtime 支持同一主机内多个 Device 之间的直接数据交互P2P无需经过 Host 中转。仓库示例 2_device_P2P/main.cpp 完整演示了查询支持 → 双向开启 → 跨设备拷贝 → 关闭的全流程是学习 P2P 编程的最佳入口。4.1 交互流程与四个核心接口aclError aclrtDeviceCanAccessPeer(int32_t *canAccessPeer, int32_t deviceId, int32_t peerDeviceId) aclError aclrtDeviceEnablePeerAccess(int32_t peerDeviceId, uint32_t flags) aclError aclrtDeviceDisablePeerAccess(int32_t peerDeviceId) aclError aclrtDevicePeerAccessStatus(int32_t deviceId, int32_t peerDeviceId, int32_t *status)标准流程与示例代码对应uint32_t deviceCount 0; CHECK_ERROR(aclrtGetDeviceCount(deviceCount)); // 先确认至少 2 个 Device CHECK_ERROR(aclrtSetDevice(0)); int32_t canAccessPeer 0; CHECK_ERROR(aclrtDeviceCanAccessPeer(canAccessPeer, 0, 1)); // 查询 0 能否访问 1 if (canAccessPeer 1) { CHECK_ERROR(aclrtDeviceEnablePeerAccess(1, 0)); // 开启 Device0 - Device1 方向 // 在 Device 0 上申请并初始化 P2P 内存 CHECK_ERROR(aclrtMalloc(dev0, memSize, ACL_MEM_MALLOC_HUGE_FIRST_P2P)); // 切换到 Device 1 CHECK_ERROR(aclrtSetDevice(1)); CHECK_ERROR(aclrtDeviceEnablePeerAccess(0, 0)); // 开启 Device1 - Device0 方向 CHECK_ERROR(aclrtMalloc(dev1, memSize, ACL_MEM_MALLOC_HUGE_FIRST_P2P)); // Device 间直接拷贝不经过 Host CHECK_ERROR(aclrtMemcpy(dev1, memSize, dev0, memSize, ACL_MEMCPY_DEVICE_TO_DEVICE)); CHECK_ERROR(aclrtSynchronizeDevice()); // 关闭双向交互并释放资源 CHECK_ERROR(aclrtDeviceDisablePeerAccess(0)); CHECK_ERROR(aclrtResetDeviceForce(1)); CHECK_ERROR(aclrtSetDevice(0)); CHECK_ERROR(aclrtDeviceDisablePeerAccess(1)); CHECK_ERROR(aclrtResetDeviceForce(0)); }4.2 关键语义与约束单向性aclrtDeviceEnablePeerAccess开启的是单向数据交互。例如当前 Device ID 为 0调用本接口指定 Device 1 后仅 0→1 方向可行若要启用 1→0 方向需切换到 Device 1 后再次调用并指定 Device 0。Device 级作用域开启/关闭数据交互均为 Device 级操作。flags参数保留参数当前必须设置为 0。aclrtDevicePeerAccessStatus输出0 表示未开启数据交互1 表示已开启。若传入的 Device ID 超出[0, 可用的Device数量-1]区间查询结果为 0 或直接返回ACL_ERROR_RT_PARAM_INVALID。适用范围来自文档约束仅支持物理机和容器场景仅支持同一个 PCIe Switch 内 Device 间数据交互AI Server 场景跨 PCIe Switch 也支持仅支持同一个物理机/容器内的 Device 间交互仅支持同一个进程内、线程间的 Device 间交互不支持跨进程Atlas 推理系列产品在 Control CPU 开放形态下应用运行在 Device 的 Control CPU 上P2P 系列接口不支持 Device 间数据交互Atlas 200I/500 A2 推理产品与 IPV350 不支持 P2P 系列接口。五、溢出状态检测与设备同步5.1 浮点溢出状态Get 与 ResetaclError aclrtGetOverflowStatus(void *outputAddr, size_t outputSize, aclrtStream stream) aclError aclrtResetOverflowStatus(aclrtStream stream)aclrtGetOverflowStatus获取当前 Device 下所有 Stream上任务的溢出状态并将状态值拷贝到用户申请的 Device 内存中。异步接口outputAddr用户申请的 Device 内存例如通过aclrtMalloc申请outputSize固定为 64 Bytestream指定用于下发溢出状态查询任务的 Stream。aclrtResetOverflowStatus清除当前 Device 下所有 Stream 上任务的溢出状态同样为异步接口。对于 Ascend 950PR/Ascend 950DT、Atlas A3 系列、Atlas A2 系列产品查询/清除的溢出状态是进程级别的。结合 aclrtSetDeviceSatMode设置浮点计算结果输出模式与aclrtGetDeviceSatMode查询当前模式使用可实现饱和截断 vs 溢出报错两种浮点行为的探测与恢复。aclrtSetDeviceSatMode设置成功后仅对后续新创建的 Stream 生效对已创建的 Stream 不生效。5.2 设备级同步SynchronizeDeviceaclError aclrtSynchronizeDevice(void) aclError aclrtSynchronizeDeviceWithTimeout(int32_t timeout)aclrtSynchronizeDevice阻塞当前线程直到与当前线程绑定的 Context 所对应的 Device 完成运算。aclrtSynchronizeDeviceWithTimeout在基础上支持超时退出适合应用异常时自行退出防挂死timeout -1永久等待行为与aclrtSynchronizeDevice一致timeout 0具体的超时时间单位毫秒超时退出时返回ACL_ERROR_RT_STREAM_SYNC_TIMEOUT。多 Device 场景下等待的是当前 Context 对应的 Device因此切换 Device 后要重新理解当前语义。六、用户设备 ID、逻辑设备 ID、物理设备 ID 映射容器与多卡场景下存在三种设备 ID理解其映射关系是正确使用ASCEND_RT_VISIBLE_DEVICES环境变量的前提。6.1 三种 ID 的定义与基本关系用户设备 IDUser Dev ID应用层通过aclrtSetDevice传入的 Device ID。逻辑设备 IDLogic Dev IDRuntime 内部的设备索引。物理设备 IDPhy Dev ID物理机上真实的设备编号。基本规则若未设置ASCEND_RT_VISIBLE_DEVICES环境变量逻辑设备 ID 与用户设备 ID 相同非容器场景下物理设备 ID 与逻辑设备 ID 相同。6.2 容器 环境变量的映射示例文档以容器场景且设置ASCEND_RT_VISIBLE_DEVICES环境变量为例通过环境变量设置的 Device ID 依次为1、2对应的 Device 索引值依次为0、1通过aclrtSetDevice设置的用户设备 ID 为0即索引值 0因此用户设备 ID0 对应逻辑设备 ID1容器中的逻辑设备 ID1 又映射到物理设备 ID6最终实际使用 ID 为 6 的物理设备进行计算。ASCEND_RT_VISIBLE_DEVICES的详细介绍可参考仓库中的 环境变量参考文档。6.3 六个转换接口接口功能aclrtGetLogicDevIdByUserDevId(userDevid, logicDevId)用户设备 ID → 逻辑设备 IDaclrtGetUserDevIdByLogicDevId(logicDevId, userDevid)逻辑设备 ID → 用户设备 IDaclrtGetLogicDevIdByPhyDevId(phyDevId, logicDevId)物理设备 ID → 逻辑设备 IDaclrtGetPhyDevIdByLogicDevId(logicDevId, phyDevId)逻辑设备 ID → 物理设备 IDaclrtGetUserDevIdByPhyDevId(phyDevId, userDevId)物理设备 ID → 用户设备 IDaclrtGetPhyDevIdByUserDevId(userDevId, phyDevId)用户设备 ID → 物理设备 ID重要提示来自文档aclrtGetLogicDevIdByPhyDevId与aclrtGetPhyDevIdByLogicDevId两个接口中逻辑设备 ID的语义描述并不正确其参数实际对应的是用户设备 ID。为修复该问题Runtime 提供了aclrtGetUserDevIdByPhyDevId与aclrtGetPhyDevIdByUserDevId作为替代。新代码应优先使用语义正确的替代接口避免因命名歧义引入设备选择错误。七、Device 资源限制与高级能力7.1 aclrtDeviceSetLimit / aclrtDeviceGetLimit进程级资源限制aclError aclrtDeviceSetLimit(aclrtDeviceLimit limit, size_t value) aclError aclrtDeviceGetLimit(aclrtDeviceLimit limit, size_t *value)用途设置/获取当前进程的 Device 资源限制例如 SIMT 算子栈空间、SIMT Printf 维测空间等。资源类型枚举 aclrtDeviceLimit 定义于 acl_rt.h共 5 项typedef enum aclrtDeviceLimit { ACL_RT_DEV_LIMIT_SIMT_STACK_SIZE 0, // SIMT 算子栈空间大小 ACL_RT_DEV_LIMIT_SIMT_DVG_WARP_STACK_SIZE 1, // SIMT DVG WARP 栈空间大小 ACL_RT_DEV_LIMIT_SIMD_STACK_SIZE 2, // SIMD 栈空间大小 ACL_RT_DEV_LIMIT_SIMD_PRINTF_FIFO_SIZE_PER_CORE 3, // SIMD Printf 每 Core FIFO 大小 ACL_RT_DEV_LIMIT_SIMT_PRINTF_FIFO_SIZE 4, // SIMT Printf FIFO 大小 } aclrtDeviceLimit;调用时机建议在aclInit之后、aclrtSetDevice之前调用确保资源限制生效。若多次调用aclrtSetDevice需注意 Set/Reset 引用计数配对引用计数减到 0 后先重新调用aclrtDeviceSetLimit再调用aclrtSetDevice配置才能生效aclInit -- aclrtDeviceSetLimit第一次设置 -- aclrtSetDevice配置生效 -- 业务处理 -- aclrtResetDevice重置 Device 资源 -- aclrtDeviceSetLimit第二次设置 -- aclrtSetDevice配置生效配置优先级通过本接口或aclInit接口均可配置资源限制值后配置的覆盖先配置的本接口更灵活便于运行时调整。作用域配置作用于当前进程所有 Device 共用同一套配置无法为不同 Device 设置不同值。Device 0 依赖本接口内部固定使用 Device 0 进行设置。若设置了ASCEND_RT_VISIBLE_DEVICES且不包含 Device 0则通过本接口或aclInit配置资源限制均会失败因此使用该环境变量时需确保其值包含 Device 0。aclrtDeviceGetLimit读取语义读取的是进程内配置的瞬时值不保证多线程并发安全。典型陷阱先 Set 栈大小 A 并 SetDevice 生效后查询得 A随后再 Set 为 B 但未重新 SetDevice此时查询得 B而实际生效的资源限制仍为 A。产品差异Atlas A3 系列、Atlas A2 系列查询ACL_RT_DEV_LIMIT_SIMT_STACK_SIZE、ACL_RT_DEV_LIMIT_SIMT_DVG_WARP_STACK_SIZE、ACL_RT_DEV_LIMIT_SIMT_PRINTF_FIFO_SIZE时返回ACL_ERROR_RT_FEATURE_NOT_SUPPORTAscend 950 系列查询ACL_RT_DEV_LIMIT_SIMT_STACK_SIZE返回对齐后 ×32每 warp 线程数的值如设置 256 查询返回 8192查询ACL_RT_DEV_LIMIT_SIMT_DVG_WARP_STACK_SIZE返回对齐后的值不乘线程数如设置 512 查询返回 512。7.2 其他高级能力接口aclrtDeviceL2CacheFlush(void *rsv)清空当前 Device 的 L2 Cache接口返回即表示清空完成rsv预留参数当前必须传nullptr。约束仅 Ascend 950 系列支持昇腾虚拟化实例场景不支持不建议高频调用影响业务性能若清空期间该 Device 上有并发业务执行L2 Cache 可能被再次占用导致清空无效。aclrtDeviceGetHostAtomicCapabilities(uint32_t *capabilities, const aclrtAtomicOperation *operations, uint32_t count, int32_t deviceId)查询指定 Device 与 Host 之间支持的原子操作详情。capabilities为位掩码数组每一位代表对不同数据类型原子操作的支持情况1 支持 / 0 不支持count必须与两个数组长度一致否则可能导致未定义行为。aclrtDeviceGetP2PAtomicCapabilities(...)查询一个 AI Server 内两个 DevicesrcDeviceId、dstDeviceId之间支持的原子操作详情参数语义同 Host 版本。aclrtRegDeviceStateCallback(const char *regName, aclrtDeviceStateCallback callback, void *args)注册 Device 状态回调不支持重复注册。当 Device 状态变化时如调用aclrtSetDevice、aclrtResetDevice等Runtime 触发回调。regName注册名称需保持唯一且以\0结尾callback为 NULL 表示取消注册。回调原型如下typedef enum { ACL_RT_DEVICE_STATE_SET_PRE 0, // 调用 set 接口如 aclrtSetDevice之前 ACL_RT_DEVICE_STATE_SET_POST, // 调用 set 接口之后 ACL_RT_DEVICE_STATE_RESET_PRE, // 调用 reset 接口如 aclrtResetDevice之前 ACL_RT_DEVICE_STATE_RESET_POST, // 调用 reset 接口之后 } aclrtDeviceState; typedef void (*aclrtDeviceStateCallback)(uint32_t devId, aclrtDeviceState state, void* args);该回调机制可用于上层框架如训练调度器感知设备被占用/释放的时机实现资源感知的调度。aclrtSetTsDevice(aclrtTsId tsId)设置本次计算使用的 Task Schedule。aclrtTsId定义如下若 AI 处理器中只有 AI CORE Task Schedule 而没有 VECTOR Core Task Schedule则设置无效默认使用 AI CORE Task Scheduletypedef enum aclrtTsId { ACL_TS_ID_AICORE 0, // 使用 AI CORE Task Schedule ACL_TS_ID_AIVECTOR 1, // 使用 VECTOR Core Task Schedule ACL_TS_ID_RESERVED 2, } aclrtTsId;aclrtSetDeviceSatMode/aclrtGetDeviceSatMode设置/查询当前 Device 的浮点计算结果输出模式配合溢出检测使用详见第五节。八、实战多卡 P2P 与设备管理的推荐编码范式综合上述接口给出一个兼顾正确性与健壮性的 Device 管理编码范式可直接迁移到多卡训练、集合通信等场景// 1. 初始化并获取设备数量 CHECK_ERROR(aclInit(nullptr)); uint32_t deviceCount 0; CHECK_ERROR(aclrtGetDeviceCount(deviceCount)); if (deviceCount 2) { /* 提示设备不足并退出 */ } // 2. 按需查询设备健康状态与能力 aclrtDeviceStatus status; CHECK_ERROR(aclrtQueryDeviceStatus(0, status)); if (status ! /* 正常状态枚举 */) { /* 处理异常设备 */ } // 3. 每个工作线程指定自己的 Device线程内 Set/Reset 严格配对 void worker(int32_t deviceId) { CHECK_ERROR(aclrtSetDevice(deviceId)); // ... 业务逻辑 ... CHECK_ERROR(aclrtSynchronizeDevice()); CHECK_ERROR(aclrtResetDeviceForce(deviceId)); // 或 ResetDevice 配对使用 } // 4. P2P 场景先查询、再双向开启、最后按序关闭 int32_t canAccess 0; CHECK_ERROR(aclrtDeviceCanAccessPeer(canAccess, 0, 1)); if (canAccess 1) { CHECK_ERROR(aclrtDeviceEnablePeerAccess(1, 0)); // 切换 Device 后开启反向 CHECK_ERROR(aclrtSetDevice(1)); CHECK_ERROR(aclrtDeviceEnablePeerAccess(0, 0)); // ... 跨设备 memcpy ... CHECK_ERROR(aclrtDeviceDisablePeerAccess(0)); CHECK_ERROR(aclrtResetDeviceForce(1)); CHECK_ERROR(aclrtSetDevice(0)); CHECK_ERROR(aclrtDeviceDisablePeerAccess(1)); } CHECK_ERROR(aclFinalize());关于各接口具体支持的产品型号Ascend 950PR/950DT、Atlas A3/A2 系列、Atlas 200I/500 A2、Atlas 推理/训练系列、IPV350 等请以 04_device_management.md 中每个接口的产品支持情况小节为准——不同接口的支持矩阵差异较大如 P2P 系列不支持 Atlas 200I/500 A2 与 IPV350aclrtDeviceL2CacheFlush仅支持 Ascend 950 系列编码前务必核对。九、总结CANN Runtime 的 Device 管理接口覆盖了从选设备、用设备、还设备的生命周期管理到设备数量/状态/能力/拓扑的全面探测再到 P2P 数据交互、溢出检测、ID 映射与资源限制等高级能力。掌握本组接口时需重点把握三条主线配对与计数aclrtSetDevice与aclrtResetDevice/aclrtResetDeviceForce的引用计数语义是多线程、多卡程序避免资源泄漏与误释放的关键先查询后使用设备数量、健康状态、P2P 支持、特性支持、拓扑关系都应先查询再使用这是设备无关编程的基础语义边界P2P 单向性、溢出状态的进程级语义、ID 映射接口的命名歧义、资源限制的 Device 0 依赖与配置值≠生效值陷阱都是实践中容易踩坑的地方。如需深入实践可结合仓库示例 1_basic_features/device 下的0_device_normal、1_device_multi_thread、2_device_P2P、3_device_identity_mapping等工程进行对照学习各接口的完整枚举、结构体定义可查阅 25-02_Enumerations.md 与 25-04_Structs.md。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表