ARTICLE DETAIL

资讯详情

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

CANN Runtime AI Core 栈空间配置指南:原理、配置与调优实践

CANN Runtime AI Core 栈空间配置指南:原理、配置与调优实践 CANN Runtime AI Core 栈空间配置指南原理、配置与调优实践【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime导读AI Core 栈空间AI Core Stack是 CANN Runtime 为每个 AI Core 分配的私有执行栈用于存放算子的局部变量与函数调用信息其大小直接决定了算子尤其是以 -O0 优化等级编译的调试算子能否正常运行。本文以 CANN runtime 开源仓库中的 AI Core 栈空间配置文档 为主体结合仓库源码src/acl/aclrt_impl/acl.cpp、src/runtime/api/impl/api_impl.cc、src/runtime/core/src/device/raw_device.cc等讲解栈空间的默认行为、底层分配链路、aclInit配置文件写法、参数取值约束与调优建议。读完本文你将能独立为应用配置合适的 AI Core 栈空间避免栈溢出导致的算子执行异常并能在源码层面理解该配置的生效原理。一、AI Core 栈空间是什么在 CANN 运行时中每个 AI Core 都拥有一块私有的堆栈空间其用途与 CPU 上的函数调用栈完全类似存储算子在执行过程中的局部变量保存函数调用信息返回地址、调用帧、寄存器上下文等。当应用进程执行aclrtSetDevice时CANN Runtime 会为每个 AI Core 分配大小为aicore_stack_size的 Device 内存作为栈空间所有 AI Core 的栈空间总占用为aicore_stack_size × aicore_num其中aicore_num为当前设备上参与执行的 AI Core 数量。也就是说栈空间占用的是Device设备侧内存而不是 Host 内存调整它会影响设备侧显存的可用总量。源码印证在 src/runtime/core/src/device/raw_device.cc#L960-L994 的RawDevice::AllocCustomerStackPhyBase()中自定义栈空间的物理内存总量按totalCoreNum * customerStackSize计算其中totalCoreNum props.aicNum props.aivNum即 AI Core 与 AI Vector 核心数量之和并通过DevMemAlloc在设备侧 DDR 中一次性分配。这从实现层面验证了栈空间按核数成倍占用 Device 内存的结论。默认大小aicore_stack_size 32KB即 32768 字节。该默认值在源码中体现为src/runtime/core/inc/kernel/elf.hpp#L68-L69 定义KERNEL_STACK_SIZE_32K 32768U、KERNEL_STACK_SIZE_16K 16384Usrc/runtime/core/inc/runtime.hpp#L827 中deviceCustomerStackSize_的初始值即KERNEL_STACK_SIZE_32K且注释明确其为全局共享所有 device 生效。二、为什么需要调整栈空间大小默认的 32KB 栈空间对大多数算子足够但存在明显短板调试场景栈需求激增以-O0方式编译的 AI Core 算子用于调试通常会保留大量局部变量、禁止寄存器复用其栈空间需求可能超过默认的 32KB。复杂算子递归/深调用链某些结构复杂或调用层级深的算子函数调用信息占用更多栈帧。不改配置的直接后果——栈溢出如果算子实际所需栈空间超过分配值会导致算子执行异常典型表现为栈溢出Stack Overflow出现难以定位的计算错误、任务失败甚至设备异常。因此用户需要在进程启动时通过aclInit初始化接口的 json 配置文件来配置合适的 AI Core 栈空间大小。注意栈空间占用的是 Device 内存且按 AI Core 数量成倍放大请按需设置避免盲目增大导致设备内存紧张。三、配置文件写法与示例aclInit接口接受一个 json 配置文件的路径作为参数其中StackSize字段用于配置栈空间大小。配置示例如下{ StackSize:{ aicore_stack_size:32768 } }字段说明字段含义单位StackSize栈空间配置的顶层容器节点-aicore_stack_size每个 AI Core 的私有栈空间大小Byte字节json 文件创建好之后在应用代码中通过aclInit传入该文件路径即可// 伪代码示意完整签名请参考 aclInit 接口说明 const char *configPath ./acl.json; // 配置文件路径可以为空指针 aclError ret aclInit(configPath);生效时机配置在aclInit阶段被解析并下发到 Runtime因此必须在进程启动阶段、任何aclrtSetDevice之前完成设置aclrtSetDevice执行时 Runtime 将按照该配置为每个 AI Core 预留栈空间。补充CANN Runtime 的aclInit配置文件中还支持simt_stack_sizeSIMT 算子每线程栈空间与simt_divergence_stack_sizeSIMT 分支栈空间等更多栈类配置见下文第四节。四、参数取值约束与平台上限在aicore_stack_size处设置栈空间大小时需要遵循以下取值规则详细说明同样记录在 aclInit 接口文档 中单位Byte字节。16K 对齐aicore_stack_size必须是 16KB 的整数倍若传入的值不是 16KB 的整数倍则会向上取整保证其为 16KB 的整数倍。最小值aicore_stack_size最小值为 32KB若传入值小于 32KB则按默认配置 32KB 处理。最大值按产品差异在Ascend 950PR / Ascend 950DT上aicore_stack_size最大值为128KB在Atlas A3 训练/推理系列产品、Atlas A2 训练/推理系列产品上最大值为192KB在Atlas 200I/500 A2 推理产品上最大值为7680KB。源码印证——对齐与最小值逻辑在 src/runtime/core/inc/runtime.hpp#L616-L622 的SetDeviceCustomerStackSize()中Runtime 仅在传入值val KERNEL_STACK_SIZE_32K32768 字节时才会生效并通过(val KERNEL_STACK_SIZE_16K - 1U) / KERNEL_STACK_SIZE_16K * KERNEL_STACK_SIZE_16K完成 16KB 向上取整小于等于 32KB 的值保持默认 32KB 不变。这与文档中16K 整数倍、最小值 32K的约束完全一致。源码印证——最大值校验RawDevice::AllocCustomerStackPhyBase()在分配前会与设备属性中的props.maxCustomerStackSize比较超过上限时返回错误码EE1011错误消息为 The AI Core stack size set by calling rtDeviceSetLimit must be less than or equal to ...参见 src/runtime/core/src/device/raw_device.cc#L960-L976。因此不同产品的maxCustomerStackSize差异最终体现为上文所列的最大值差异。五、源码视角配置如何从 aclInit 到达每个 AI Core理解底层调用链有助于判断配置在什么时机、以什么方式生效以及异常情况下如何排查。整个链路可归纳为三段5.1 阶段一aclInit 解析 json 并下发aclInit的实现位于 src/acl/aclrt_impl/acl.cpp#L382 的aclInitImpl。当传入的configPath非空时它会依次调用HandleDefaultDeviceAndStackSize(configPath)见 acl.cpp#L334-L351进而调用SetAllStackSizes批量处理所有栈类配置项。栈类配置项与 json key 的映射关系定义在 acl.cpp#L131-L134const std::maprtLimitType_t, std::string limitToKeyMap { {RT_LIMIT_TYPE_STACK_SIZE, aicore_stack_size}, {RT_LIMIT_TYPE_SIMT_STACK_SIZE, simt_stack_size}, {RT_LIMIT_TYPE_SIMT_DVG_WARP_STACK_SIZE, simt_divergence_stack_size}};5.2 阶段二JsonParser 提取配置值json 的解析由acl::JsonParser::GetStackSizeByType()完成位于 src/acl/common/json_parser.cpp#L408-L450。其逻辑要点首先将配置文件解析为 json 对象检查顶层是否包含StackSize键若不存在则直接返回视为未配置保持默认值若存在则读取StackSize下对应的类型名如aicore_stack_size的值作为size_t类型的字节数。5.3 阶段三rtDeviceSetLimit 下发 Runtime 并分配物理栈解析出的栈大小通过rtDeviceSetLimit(0, RT_LIMIT_TYPE_STACK_SIZE, stackSize)下发到 Runtime见 acl.cpp#L152对应 API 实现在 src/runtime/api/api_c_device.cc#L145-L153。Runtime 侧的处理位于 src/runtime/api/impl/api_impl.cc#L3167-L3193 的ApiImpl::DeviceSetLimit()if (type RT_LIMIT_TYPE_STACK_SIZE) { Runtime* rt Runtime::Instance(); rt-SetDeviceCustomerStackSize(val); // 16K 向上取整 全局生效 }随后在设备初始化阶段RawDevice::AllocCustomerStackPhyBase()按(aicNum aivNum) * customerStackSize分配整块 Device 内存作为客户栈物理基址见 raw_device.cc#L960-L994。算子任务真正执行前Context::GetStackBuffer()依据算子二进制声明的栈需求从该物理基址上按coreId偏移切分出每个 AI Core 的独立栈区见 src/runtime/core/src/context/context.cc#L2413-L2445。兼容性细节acl.cpp中SetStackSizeByType()对ACL_ERROR_RT_FEATURE_NOT_SUPPORT做了容错处理——当某平台不支持对应的 limit 类型例如非 950 平台上配置了simt_stack_size时仅打印告警日志并跳过不会导致aclInit失败参见 acl.cpp#L150-L159。六、进阶SIMT 算子栈与 Printf 维测空间对于支持 SIMTSingle Instruction Multiple Thread算子的平台目前仅 Ascend 950PR / Ascend 950DTStackSize容器下还可配置两个 SIMT 专用参数参数含义默认值对齐要求simt_stack_sizeSIMT 算子每个线程的栈空间大小1152 Byte128 的整数倍不足自动向上取整simt_divergence_stack_sizeSIMT 算子的分支Divergence栈空间大小1024 Byte128 的整数倍不足自动向上取整配置示例{ StackSize: { simt_stack_size: 1024, simt_divergence_stack_size: 512 } }此外aclInit配置文件还支持 SIMT Printf 维测空间大小simt_printf_fifo_size用于控制 SIMT 算子可 Printf 打印的空间大小默认值 2MB范围 1MB64MB取值须为 8 的整数倍示例如下{ simt_printf_fifo_size: 1048576 }源码印证这些配置的映射关系定义在 acl.cpp#L177-L179 的fifoSizeToKeyMapsimd_printf_fifo_size_per_core、simt_printf_fifo_size解析与下发逻辑分别在SetPrintFifoSizeByType()acl.cpp#L181-L207与JsonParser::GetPrintFifoSizeByType()src/acl/common/json_parser.cpp#L452-L485中。七、调优建议与注意事项按需设置宁小勿奢栈空间按 AI Core 数量成倍占用 Device 内存。设得过大可能挤占算子可用的设备内存甚至影响大模型/大 Tensor 场景的内存申请。建议先保持默认 32KB仅在算子报栈溢出或明确评估出栈需求后逐步上调。注意对齐与上下限手动配置时建议直接传 16KB 的整数倍且不小于 32768 的数值避免依赖向上取整和小于 32KB 按默认处理的隐式规则造成预期偏差同时确认目标产品的最大值128KB / 192KB / 7680KB超过上限会触发EE1011错误。调试算子重点关注以-O0编译用于调试的 AI Core 算子是最常见的超栈场景若调试期间出现栈溢出优先将aicore_stack_size调大如 64KB 起步后再重新触发任务。在 aclInit 阶段配置该配置仅在aclInit时读取生效且全局对所有 Device 生效不要在aclrtSetDevice之后再尝试修改。兼容性行为在部分平台配置不受支持的栈类参数不会导致aclInit失败但会被忽略仅告警日志配置前请确认目标产品的支持范围仅 950 系列支持 SIMT 相关栈配置。排查手段若配置后仍异常可结合 plog 日志确认aclInit阶段是否打印set aicore_stack_size xxx bytes success或对应的告警/错误日志相关日志输出点位于 acl.cpp#L160 与 raw_device.cc#L989-L991。八、总结AI Core 栈空间是 CANN Runtime 保证算子正常执行的关键资源之一默认 32KB按 AI Core 数量成倍占用 Device 内存可在aclInit的 json 配置文件中通过StackSize.aicore_stack_size按需调整。其完整生效链路为aclInit解析配置 →JsonParser::GetStackSizeByType提取数值 →rtDeviceSetLimit下发 → Runtime 16KB 对齐与平台上限校验 →RawDevice::AllocCustomerStackPhyBase按核分配物理栈 → 算子任务按核切分使用。掌握该配置的原理与约束即可从容应对调试算子、复杂算子的栈溢出问题并在多核设备上合理规划设备内存。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表