人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载导读在昇腾 AI 处理器算子开发中内核函数Kernel运行在 AI Core 上其编写环境与标准 C 宿主程序存在差异许多通用库函数无法直接使用。asc-devkit 在AscendC::Std命名空间下提供了轻量的数学函数集合覆盖绝对值abs、平方根sqrt、向上取整除法ceil_div等常用标量运算统一了 Host 侧与 AI Core 侧的调用方式。阅读本文后你将掌握这些数学函数的函数原型、数据类型约束、产品支持情况、典型调用场景并能结合源码理解其底层实现与测试验证方式直接应用于算子内核的迭代次数计算、数据规范化等场景。一、模块概览cpp_stdlib 数学函数族AscendC::Std数学函数位于仓库 docs/zh/api/Utils-API/cpp_stdlib/math_functions/math_functions.md 所描述的能力域中官方 API 文档将该目录下的函数划分为abs计算输入数据的绝对值ceil_div计算两个整数相除后向上取整的结果sqrt计算输入数据的平方根。此外同目录下的 CeilDivision.md 还记录了面向 AI Core 侧的AscendC::CeilDivision全局函数。从源码结构看这些函数都通过头文件 include/utils/std/cmath.h 统一对外暴露并在编译期展开到 impl/utils/std/cmath 目录下的具体实现文件中形成接口声明 内核实现的经典分层sqrt.hAscendC::Std::sqrt实现abs.hAscendC::Std::abs实现ceil_division.hAscendC::Std::ceil_div实现含通用向上取整除法核心ceil_align.h基于ceil_division的向上取整对齐divide.h普通整数除法封装。需要注意include/utils/std/cmath.h 中对 SIMT 编译模式做了显式拦截当启用--enable-simt编译标志时即__NPU_COMPILER_INTERNAL_PURE_SIMT__被定义编译期直接报错cmath.h cannot be used with compile flag --enable-simt enabled.提示该数学函数族仅适用于 SIMD向量编程模型。二、abs获取输入数据的绝对值2.1 函数原型与参数说明官方文档 abs.md 给出的函数原型为template typename T __aicore__ inline T abs(const T src)参数类型说明T模板参数输入数据src的数据类型当前支持int8_t、int16_t、int32_t、float、int64_tsrc接口参数源操作数输入该接口的返回值为输入数据的绝对值且无额外约束约束说明为空。2.2 源码实现与编译期类型校验在 impl/utils/std/cmath/abs.h 中abs的实现非常简洁template typename T __aicore__ inline T abs(const T src) { static_assert( is_one_ofT, int8_t, int16_t, int32_t, float, int64_t(), current data type is not supported on current device!); return ::abs(src); }两个值得关注的实现细节编译期类型约束实现通过static_assert type_traits/is_one_of.h 限定模板参数 T 只能是文档声明的五种类型。若传入uint32_t等不支持的类型会在编译阶段直接报错而不是运行时产生未定义行为这保证了类型安全。内建函数转发函数体直接转发到全局::abs(src)借助编译器的内建实现完成取绝对值运算同时在ASCENDC_CPU_DEBUG宏开启时引入标准cmath见 abs.h使该接口可参与 CPU 侧调试如 tests/api/utils/std/cmath/test_abs.cpp 中通过SetGCoreType(2)设置的 GCore 仿真场景。2.3 调用示例官方文档给出的最小示例int64_t src -2; int64_t result AscendC::Std::abs(src); // result: 2在实际内核中abs常与标量读取配合使用例如 tests/api/utils/std/cmath/test_abs.cpp 展示了从 GlobalTensor 取值后直接取绝对值的写法GlobalTensorT dst_global; dst_global.SetGlobalBuffer(reinterpret_cast__gm__ T*(dst_gm), dataSize); Std::abs(dst_global.GetValue(0)); PipeBarrierPIPE_ALL();测试用例通过宏展开对int8_t、float、int16_t、int32_t、int64_t五种支持类型逐一执行 8192 元素的用例与文档声明的数据类型完全对应。三、sqrt计算输入数据的平方根3.1 函数原型与参数说明官方文档 sqrt.md 给出的函数原型为template typename T __aicore__ inline T sqrt(const T src)参数类型说明T模板参数输入数据src的数据类型当前支持float、int64_tsrc接口参数源操作数输入3.2 约束与返回值说明输入必须为非负数若输入为负数接口返回值无意义。返回值为输入数据的平方根。对于int64_t类型的数据计算结果将被截断为整数。例如sqrt(4)得到整数2而sqrt(2)在int64_t场景下会截断为1。3.3 源码实现与测试验证impl/utils/std/cmath/sqrt.h 的实现与abs同构template typename T __aicore__ inline T sqrt(const T src) { static_assert(is_one_ofT, float, int64_t(), current data type is not supported on current device!); return ::sqrt(src); }同样在编译期通过is_one_of做类型约束并转发至全局::sqrt。测试文件 tests/api/utils/std/cmath/test_sqrt.cpp 仅对float与int64_t两种类型生成用例与文档声明一致。调用示例int64_t src 4; int64_t result AscendC::Std::sqrt(src); // result: 2四、ceil_div整数向上取整除法4.1 函数原型与参数说明官方文档 ceil_div.md 给出的函数原型为template typename T, typename U __host__ __aicore__ inline constexpr auto ceil_div(const T a, const U b);参数类型说明T模板参数参数a的数据类型必须为整型U模板参数参数b的数据类型必须为整型a接口参数被除数输入b接口参数除数输入该接口可在Host 侧和 AI Core 侧使用__host__ __aicore__双端标注头文件路径为utils/std/cmath.h。返回值一般情况下由decltype(T{} / U{})推导得到即两个操作数经整型提升后的公共类型。4.2 约束说明文档明确的三条约束T 和 U 必须为整型支持int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t当 b 为 0 时结果为 0对于有符号输入调用方需确保a 0且b 0。此外针对Ascend 950PR950DT 系列产品即Ascend 950架构在 vector 侧使用时接口入参仅支持uint32_t类型在 VFVector Fetch向量抓取场景下返回值需使用static_cast转换为uint16_t类型并确保向上取整结果在uint16_t可表示范围内。这一约束源于 VF Hardware Loop 编码规范更多规范内容可参考《Hardware Loop 编码规范》。4.3 源码实现有符号与无符号的差异化处理impl/utils/std/cmath/ceil_division.h 是ceil_div的核心实现它分为两层第一层ceil_div_generic通用向上取整除法。先通过static_assert强制 T、U 为整型随后借助integer_traits对signed char、short、int、long、long long的特化将公共类型转换为对应的无符号类型再分两条路径计算有符号公共类型直接采用(a b - 1) / b公式。源码注释说明其安全性依据a INT_MAX、b INT_MAXINT_MAX INT_MAX在无符号运算下不会溢出无符号公共类型当a接近UINT_MAX时a b - 1可能回绕溢出因此改用无溢出的分支无关形式min(a, 1 (a - 1) / b)其中min来自 impl/utils/std/algorithm/min.h。template typename T, typename U __host__ __aicore__ inline constexpr auto ceil_div_generic(const T a, const U b) { static_assert(is_integral_vT, AscendC::Std::ceil_div: T must be an integral type); static_assert(is_integral_vU, AscendC::Std::ceil_div: U must be an integral type); using Prom decltype(T{} / U{}); using UProm make_unsigned_tProm; auto a1 static_castUProm(a); auto b1 static_castUProm(b); if constexpr (is_signed_impl_vProm) { return static_castProm((a1 b1 - 1) / b1); } else { // 无符号场景min(a, 1 (a - 1) / b) 避免 (a b - 1) 溢出回绕 return min(a1, static_castUProm(1) ((a1 - 1) / b1)); } }第二层ceil_div对外入口。先处理b 0的边界情况返回 0与文档约束一致随后依据编译目标分发Host 侧__NPU_HOST__直接走通用实现设备侧__NPU_DEVICE__在Ascend 950系列架构__NPU_ARCH__为 3510、5102、3003、3113且启用SPLIT_CORE_VEC的 VF 场景下会调用get_repeat_ceiling硬件取整指令定义于 impl/basic_api/utils/kernel_utils_ceil_oom_que.h其余场景回退到通用实现。这也从源码层面印证了文档中950 系列 VF 场景入参仅支持uint32_t的约束来源。4.4 测试验证tests/api/utils/std/cmath/test_ceil_div.cpp 是ceil_div的专项单测覆盖了有符号与无符号的关键边界using AscendC::Std::ceil_div; static_assert(ceil_div(8192U, 2048U) 4U); // 整除向上取整后仍为 4 static_assert(ceil_div(8193U, 2048U) 5U); // 有余数向上取整为 5 static_assert(ceil_div(0U, 2048U) 0U); // 被除数为 0 static_assert(ceil_div(8192, 0) 0); // 除数为 0返回 0 TEST_F(TEST_CEIL_DIV, SIGNED_CASE) { EXPECT_EQ(ceil_div(33, 16), 3); EXPECT_EQ(ceil_div(32, 16), 2); EXPECT_EQ(ceil_div(1, 0), 0); }注意其中使用static_assert在编译期验证constexpr求值能力说明ceil_div可在编译期常量上下文中使用如模板元编程、常量表达式计算。4.5 典型实战场景计算向量循环迭代次数ceil_div在算子内核中最典型的用途是根据数据总量与单次处理的元素数计算循环次数确保尾块不足一拍的剩余数据也被完整处理。官方文档提供的示例基于__simd_vf__VF 向量函数将 repeatTime 强转为uint16_t以满足 950 系列 VF Hardware Loop 规范template typename T __simd_vf__ inline void AddCustom(__local_mem__ T *dst, __local_mem__ T *src0, __local_mem__ T *src1, uint32_t count) { AscendC::Reg::RegTensorT srcReg0; AscendC::Reg::RegTensorT srcReg1; AscendC::Reg::RegTensorT dstReg; AscendC::Reg::MaskReg mask; constexpr uint32_t oneRepeatSize AscendC::GetVecLen() / sizeof(T); uint16_t repeatTime static_castuint16_t(AscendC::Std::ceil_div(count, oneRepeatSize)); for (uint16_t i 0; i repeatTime; i) { mask AscendC::Reg::UpdateMaskT(count); AscendC::Reg::LoadAlign(srcReg0, src0 i * oneRepeatSize); AscendC::Reg::LoadAlign(srcReg1, src1 i * oneRepeatSize); AscendC::Reg::Add(dstReg, srcReg0, srcReg1, mask); AscendC::Reg::StoreAlign(dst i * oneRepeatSize, dstReg, mask); } }代码中oneRepeatSize由AscendC::GetVecLen() / sizeof(T)推导单次重复可处理的数据量count与它的向上取整除法即得到所需重复次数repeatTime。这种数据量 ÷ 单拍容量向上取整的模式在 tiling 计算、数据搬运分块中同样大量使用。五、相关函数补充CeilDivision 与 ceil_align5.1 AscendC::CeilDivisionAI Core 侧全局函数除AscendC::Std::ceil_div外同目录文档 CeilDivision.md 记录了命名空间AscendC下的非Std版本接口__aicore__ constexpr inline int32_t CeilDivision(int32_t num1, int32_t num2)其语义与ceil_div一致——计算两个整数相除后向上取整参数num1为被除数、num2为除数当num2为 0 时结果为 0且仅支持num1、num2为正数场景。与模板版本的差异在于该接口仅面向 AI Core 侧__aicore__参数类型固定为int32_t适用于非 VF 的常规向量计算场景。其调用示例与ceil_div类似同样以count / oneRepeatSize的方式计算迭代次数repeatTimes。5.2 ceil_align向上取整对齐在 impl/utils/std/cmath/ceil_align.h 中AscendC::Std::ceil_align基于ceil_division组合出向上对齐语义template typename T, typename U __host__ __aicore__ inline constexpr auto ceil_align(const T num1, const U num2) { return ceil_division(num1, num2) * num2; }即ceil_align(num1, num2) ceil(num1 / num2) * num2将num1向上对齐到num2的整数倍。典型用途是计算对齐后的缓冲区大小例如srcDataSize CeilDivision(dataSizeIn, srcAlignSize) * srcAlignSize见 tests/api/basic_api/ascendc_case_ascend950pr_9599/ascendc_case_ascend950pr_9599_aiv_basic/test_operator_vec_mainscalar.cpp该模式在测试代码中用于将输入数据大小按对齐粒度向上取整后再分配空间。5.3 divide普通整数除法impl/utils/std/cmath/divide.h 提供不带取整语义的普通除法封装template typename T, typename U __host__ __aicore__ inline constexpr auto divide(const T num1, const U num2) { return num1 / num2; }与ceil_div形成对照需要向下取整或精确整除结果时使用divide需要保证尾块被覆盖时使用ceil_div。六、产品支持情况与使用建议6.1 产品支持矩阵四个数学函数在当前仓库文档中记录的产品支持情况如下以官方文档为准产品系列abs / sqrt / ceil_divCeilDivisionAscend 950PR950DT 系列支持支持Atlas A3 系列不支持支持Atlas A2 系列不支持支持Atlas 200I/500 A2 推理产品不支持不支持Atlas 推理系列产品AI Core / Vector Core不支持不支持Atlas 训练系列产品不支持不支持可见AscendC::Std版本的数学函数是面向 950 新架构的轻量实现而CeilDivision的适配面更广额外覆盖 A2、A3 系列。在跨系列算子开发时应根据目标 SoC 选择对应接口并注意 950 系列上ceil_div的 VF 场景uint32_t入参限制。6.2 实战要点小结类型先行abs支持 5 种类型含浮点sqrt仅支持float与int64_tceil_div支持 8 种整型类型不符会在编译期被static_assert拦截无需担心运行时错误。取整语义循环迭代次数、分块计算一律使用ceil_div/ceil_align保证尾块覆盖纯除法使用divide。符号约束有符号输入调用ceil_div时须保证a 0、b 0除数为 0 返回 0。VF 场景Ascend 950 系列 VF 函数中ceil_div入参用uint32_t返回值用static_castuint16_t强转并确保结果在uint16_t范围内。七、进一步阅读API 文档入口math_functions.md、abs.md、sqrt.md、ceil_div.md头文件入口include/utils/std/cmath.h源码实现impl/utils/std/cmathabs.h、sqrt.h、ceil_division.h、ceil_align.h、divide.h单元测试tests/api/utils/std/cmathtest_abs.cpp、test_sqrt.cpp、test_ceil_div.cpp相关编码规范《Hardware Loop 编码规范》赞分享人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载相关推荐AscendCasc-devkitConv3DTranspose Tiling 之 SetOutputPadding 接口详解用法、参数与源码级实现剖析AscendCasc devkitConv3DTranspose Tiling 之 SetOutputPadding 接口详解用法、参数与源码级实现剖析人工智能深度学习算子库CANNAscendasc-devkit 中 TensorDesc 类详解在 AscendC 算子中解析动态 Shape 与数据指针asc devkit 中 TensorDesc 类详解在 AscendC 算子中解析动态 Shape 与数据指针 在 AscendC 算子开发中当一个 Ke人工智能深度学习算子库CANNAscendasc-devkit 高阶 API 详解AscendC::LogicalOr 按元素逻辑或运算的用法与实现原理asc devkit 高阶 API 详解AscendC::LogicalOr 按元素逻辑或运算的用法与实现原理 本文以 asc devkit 开源仓库中 SI人工智能深度学习算子库CANNAscend上一篇密码安全新范式Vault密码策略全解析下一篇300GB PS2 库压到 150GBchdman 转 CHD 后交给 ROMm 扫描入库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考