资讯动态

Ascend C BitwiseNot 接口全面解析:逐比特取反的高阶数学 API、Tiling 临时空间规划与源码实现

发布时间:2026/10/16 2:59:53 来源:尧图企业网站定制
人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载本文围绕 CANN asc-devkit 开源仓库中 BitwiseNot 接口文档 及其关联的 BitwiseNot、GetBitwiseNotMaxMinTmpSize、GetBitwiseNotTmpBufferFactorSize 三篇接口说明完整讲解昇腾 AI 处理器上对 LocalTensor 进行逐比特取反Bitwise Not的高阶数学计算接口包括函数原型、模板与实参配置、支持的数据类型与产品范围、调用示例与结果语义、配套的 Host 侧 Tiling 临时空间规划接口并结合仓库源码接口头文件、内核实现、参数校验、Tiling 实现与单元测试剖析其底层原理。读完本文你将掌握 BitwiseNot 的正确调用方式、UB 临时空间的规划方法以及从文档到源码到测试的完整证据链。接口定位数学计算高阶 API 家族中的按位运算成员BitwiseNot 属于 asc-devkit 中 SIMD-API 高阶数学计算math_computeAPI 家族。该家族除 BitwiseNot 外还包含同为按位运算的 BitwiseAnd、BitwiseOr、BitwiseXor以及逻辑运算 LogicalNot、LogicalAnd、LogicalOr、LogicalXor 等接口。BitwiseNot 的功能非常直接逐比特对输入数据进行取反按位非运算即对每个元素的二进制表示执行~x操作0 变 11 变 0。这一操作常用于掩码生成、补码计算、图像处理中的颜色反相、以及各类位操作场景是典型的单目单输入矢量运算。产品支持情况目前仅限 Ascend 950 系列根据 BitwiseNot.md 中的产品支持矩阵BitwiseNot 接口目前仅支持Ascend 950PR 950DT 系列产品支持其余产品线均不支持Atlas A3 系列产品不支持Atlas A2 系列产品不支持Atlas 200I/500 A2 推理产品不支持Atlas 推理系列产品 AI Core / Vector Core不支持Atlas 训练系列产品不支持从源码侧可以得到一致的印证内核实现头文件 bitwise_not.h 通过编译期宏__NPU_ARCH__判断仅当架构为3510、9201、5102、5162、3003、3113时才包含并编译 bitwise_not_3510_impl.h 中的实现同时该头文件还在文件顶部明确禁止了与--enable-simt编译标志混用#error bitwise_not.h cannot be used with compile flag --enable-simt enabled.即 BitwiseNot 只能用于纯 SIMD矢量编程场景。函数原型与参数详解BitwiseNot 的完整函数原型如下模板参数在前普通参数在后template const BitwiseNotConfig config DEFAULT_BITWISE_NOT_CONFIG, typename T __aicore__ inline void BitwiseNot(const LocalTensorT dst, const LocalTensorT src, const uint32_t count)模板参数说明表1 模板参数说明参数名描述configBitwiseNot 算法的相关配置可选配类型为BitwiseNotConfig具体定义如下方代码所示。其中参数的含义为isReuseSource该参数预留传入默认值 false 即可。T源操作数、目的操作数数据类型。支持的数据类型为int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t。BitwiseNotConfig的定义见 bitwise_not_utils.h 源码struct BitwiseNotConfig { bool isReuseSource; }; constexpr BitwiseNotConfig DEFAULT_BITWISE_NOT_CONFIG {false};从源码可以看到仓库提供了编译期常量DEFAULT_BITWISE_NOT_CONFIG {false}因此模板参数config在绝大多数情况下都可以省略使用默认值。isReuseSource字段当前为预留项用于标识是否复用源操作数的输入空间目前必须传入false——内核参数校验见下文参数校验小节会对该字段做强校验。实参普通参数说明表2 参数说明参数名称类型说明dst输出目的操作数。类型为 LocalTensor支持的 TPosition 为 VECIN/VECCALC/VECOUT。src输入源操作数。类型为 LocalTensor支持的 TPosition 为 VECIN/VECCALC/VECOUT。数据类型需要与目的操作数保持一致。count输入参与计算的元素个数。需要说明的是TPosition::VECIN/VECCALC/VECOUT三个逻辑位置在物理上都映射到Unified BufferUB参见 通用说明和约束 中的 TPosition 与物理内存映射关系表。也就是说参与 BitwiseNot 计算的 src 与 dst 都必须位于 AI Core 的 UB 上计算前通常需要先用DataCopy将 Global MemoryGM中的输入搬入 UB计算完成后再将结果搬回 GM完整流程见下文Kernel 侧完整调用流程。返回值说明无返回值void计算结果直接写入dst。约束说明使用 BitwiseNot 时必须遵守以下约束不支持源操作数与目的操作数地址重叠。即src与dst不能指向 UB 中的同一段地址空间这与基础 API 中单次迭代内支持源目的 100% 完全重叠的通用约定不同通用说明和约束属于该接口的额外限制需要开发者额外注意。操作数地址偏移对齐要求请参见通用说明和约束。其中与 BitwiseNot 直接相关的是UB 存储单元的起始地址要求 32 Byte 对齐L1 Buffer 同样为 32 Byte 对齐L0A/L0B 为 512 Byte 对齐L0C 为 64 Byte 对齐。调用示例与结果语义接口文档给出了最简调用示例AscendC::LocalTensoruint32_t dst, src; uint32_t count 512; // 参与计算的元素个数 AscendC::BitwiseNot(dst, src, count);示例运行结果接口文档原样摘录输入数据src: [ 91, 48, -71, 112, 64, -107, 74, -121, -103, -50, 112, -23, 15, ... -74] 输出数据dst: [-92, -49, 70, -113, -65, 106, -75, 120, 102, 49, -113, 22, -16, ... 73]结果的二进制语义解读注意示例中src的数据类型是uint32_t但输入值以带符号形式书写如-71、-107。逐比特取反的结果需要结合二进制的补码表示来理解对于无符号数~x等价于2^N - 1 - xN 为位宽如uint32_t的 N32。例如910x0000005B取反后为0xFFFFFFA4按有符号int32_t解读即为-92与示例输出一致。对于有符号负数其二进制即补码逐比特取反后等价于-x - 1。例如-710xFFFFFFB9取反为0x00000046即70与示例输出一致。因此BitwiseNot 对源数据的每一位含符号位统一翻转不区分符号这正是逐比特取反与数值取负Neg的本质区别。Kernel 侧完整调用流程在实际算子开发中BitwiseNot 需要与数据搬运、队列管理配合使用。仓库测试用例 test_operator_bitwise_not.cpp 给出了一个完整的可参考模板使用TQueTPosition::VECIN, 1输入队列和TQueTPosition::VECOUT, 1输出队列CopyIn阶段用DataCopy把 GlobalTensor 数据搬入 UBCompute阶段调用BitwiseNot(dstLocal, srcLocal, this-dataSize)CopyOut阶段把结果搬回 GM并对count不能按32/sizeof(T)整除的尾数部分做逐元素SetValue/GetValue回写__aicore__ inline void Compute() { PipeBarrierPIPE_ALL(); LocalTensorT dstLocal outQueue.AllocTensorT(); LocalTensorT srcLocal inQueue.DeQueT(); BitwiseNot(dstLocal, srcLocal, this-dataSize); outQueue.EnQueT(dstLocal); inQueue.FreeTensor(srcLocal); }源码级实现原理接口入口与编译期分派公开接口声明位于 include/adv_api/math/bitwise_not.h。该头文件通过__NPU_ARCH__编译期宏判断目标架构仅对支持的架构3510、9201、5102、5162、3003、3113引入内核实现 bitwise_not_3510_impl.h并把真正的计算逻辑转发给BitwiseNotImplconfig, T(dst, src, count)。内核实现类型分派与矢量寄存器运算bitwise_not_3510_impl.h 中的BitwiseNotImpl首先通过static_assertSupportTypeT, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t()在编译期强制校验数据类型必须是文档声明的 8 种类型之一随后按数据类型字节数做两条计算路径的分派sizeof(T) 8int64_t/uint64_t使用双寄存器特性Reg::RegTraitNumTwo单次repeat处理GetVecLen() / sizeof(T) * 2个元素其他类型使用单寄存器Reg::RegTensorT单次repeat处理GetVecLen() / sizeof(T)个元素。真正的计算在BitwiseNotCompute中完成核心调用链为寄存器级的Reg::Not(dstVreg, srcVreg, mask)矢量取反指令配合Reg::LoadAlign/Reg::StoreAlign完成 UB 数据的加载与回存并用Reg::UpdateMaskT, Trait(count)生成尾数掩码来处理不能被单次 repeat 整除的剩余元素Reg::LoadAlign(srcVreg, src i * oneRepElm); Reg::Not(dstVreg, srcVreg, mask); Reg::StoreAlign(dst i * oneRepElm, dstVreg, mask);可以看到整条计算被划分为repeatTime次循环每次双份处理加一次尾部处理以充分利用矢量单元的计算宽度。参数校验API Check在ASCENDC_CPU_DEBUG等调试路径下bitwise_not_check_c310.h 中的CheckFuncClassBitwiseNot会组合多组基础校验类完成运行期检查CalCountVerifyingParameters校验count参与计算元素个数的合法性TensorVerifyingParameters校验 dst/src 的 TPosition 必须是VECIN/VECOUT/VECCALC即必须位于 UBTensorReuseVerifyingParameters校验 dst 与 src 不得地址重叠对应上文不支持源操作数与目的操作数地址重叠约束IsReuseSourceVerifyingParametersfalse校验isReuseSource必须为 false预留参数强约束。Tiling 配套接口一GetBitwiseNotMaxMinTmpSizeBitwiseNot 的核函数Kernel侧计算需要开发者预留/申请临时空间。GetBitwiseNotMaxMinTmpSize 用于在 Host 侧获取预留/申请的最大和最小临时空间大小开发者基于此范围选择合适的空间大小作为 Tiling 参数传递到核函数侧使用。使用要点为保证功能正确预留/申请的临时空间大小不能小于最小临时空间大小在最小临时空间最大临时空间范围内随着临时空间增大核函数侧接口计算性能会有一定程度的优化提升。为了达到更好的性能开发者可以根据实际的内存使用情况进行空间预留/申请。函数原型void GetBitwiseNotMaxMinTmpSize(const platform_ascendc::PlatformAscendC ascendcPlatform, const AscendC::TensorShape srcShape, const uint32_t typeSize, const bool isReuseSource, uint32_t maxValue, uint32_t minValue)参数说明表1 接口参数列表参数名输入/输出功能ascendcPlatform输入输入的平台信息。PlatformAscendC 的定义请参见构造及析构函数。srcShape输入输入的 shape 信息参数类型为 AscendC::TensorShapege::Shape的类型别名。typeSize输入输入的数据类型大小单位为字节。比如输入的数据类型为 uint16_t此处应传入 2。isReuseSource输入该参数预留传入默认值 false 即可。maxValue输出BitwiseNot 接口能完成计算所需的最大临时空间大小超出该值的空间不会被该接口使用。最大空间大小为 0 表示计算不需要临时空间。请注意maxValue 仅作为参考值有可能大于 Unified BufferUB剩余空间的大小该场景下开发者需要根据 UB 剩余空间的大小来选取合适的临时空间大小。minValue输出BitwiseNot 接口能完成计算所需最小临时空间大小。最小空间大小为 0 表示计算不需要临时空间。调用示例std::vectorint64_t shape_vec {1024}; AscendC::TensorShape shape(shape_vec); uint32_t maxValue 0; uint32_t minValue 0; auto plat platform_ascendc::PlatformAscendC(context-GetPlatformInfo()); AscendC::GetBitwiseNotMaxMinTmpSize(plat, shape, 2, false, maxValue, minValue);Tiling 实现侧的证据Host 侧实现位于 bitwise_not_tiling_impl.cpp内部维护SUPPORT_TYPESIZE {1, 2, 4, 8}与 BitwiseNot 支持的 8 种整数类型1/2/4/8 字节一一对应typeSize不在该集合时会触发TypeSizeVerifyingParameters校验失败通过ASCENDC_HOST_ASSERT((npuArch NpuArch::DAV_3510 || npuArch NpuArch::DAV_9201), ...)校验 NPU 架构与接口文档仅 Ascend 950 系列支持的产品矩阵一致GetBitwiseNotMaxTmpSize与GetBitwiseNotMinTmpSize当前均返回 0即该接口当前版本的 BitwiseNot 计算不需要额外临时空间与测试用例的断言一致见下文测试用例验证。Tiling 配套接口二GetBitwiseNotTmpBufferFactorSizeGetBitwiseNotTmpBufferFactorSize 用于获取maxLivedNodeCount和extraBuf在固定空间大小的情况下通过这两个输出值可以推算算子单次最大计算元素数量maxLivedNodeCount最大存活节点数表示临时空间是单次计算数据量所占空间的多少倍extraBuf使用的额外临时空间大小单位为字节。单接口推算公式算子实现需要调用 BitwiseNot 接口开发者为其预留currBuff大小的空间利用 GetBitwiseNotTmpBufferFactorSize 接口得到maxLivedNodeCount、extraBuf输出值可推导算子单次最大计算元素数量为currentShapeSize (currBuff - extraBuf) / maxLivedNodeCount / typeSize多接口组合推算公式算子实现需要调用两个核函数侧 API如 KernelIntf1、KernelIntf2利用两个 GetXxxTmpBufferFactorSize其中 Xxx 为需要调用的两个高阶 API接口的两组输出值maxLivedNodeCount、extraBuf以及当前现有的临时空间分别推导单次最大计算元素数量再取较小值作为最终的单次计算规模currentShapeSize1 (currBuff - extraBuf1) / maxLivedNodeCount1 / typeSize currentShapeSize2 (currBuff - extraBuf2) / maxLivedNodeCount2 / typeSize currentShapeSize min(currentShapeSize1, currentShapeSize2)注意上文中的currBuff表示接口计算可用的空间需要去除用户输入输出等空间另外接口获取的maxLivedNodeCount值可能为 0计算时需要判断该值非 0避免除零错误。函数原型void GetBitwiseNotTmpBufferFactorSize(const platform_ascendc::PlatformAscendC ascendcPlatform, const uint32_t typeSize, uint32_t maxLivedNodeCount, uint32_t extraBuf)参数说明表1 参数列表参数名输入/输出功能ascendcPlatform输入输入的平台信息。PlatformAscendC 的定义请参见构造及析构函数。typeSize输入输入的数据类型大小单位为字节。maxLivedNodeCount输出最大存活节点数表示临时空间是单次计算数据量所占空间的多少倍。extraBuf输出使用的额外临时空间大小单位为字节。约束说明当利用 maxLivedNodeCount、extraBuf 反推出的currentShapeSize * typeSize 256B时currentShapeSize 按照256B / typeSize的值向上取整。这一约束与矢量计算以 256 Byte 为基本处理粒度的硬件特性相吻合。调用示例uint32_t maxLivedNodeCount 0; uint32_t extraBuf 0; auto plat platform_ascendc::PlatformAscendC(context-GetPlatformInfo()); AscendC::GetBitwiseNotTmpBufferFactorSize(plat, typeSize, maxLivedNodeCount, extraBuf);Host 侧 Tiling 与 Kernel 侧的配套使用流程GetXxxMaxMinTmpSize 系列 Tiling 接口的完整配套使用方法可参考更多样例该文档以同类数学接口 Asin 为例说明通用流程同样适用于 BitwiseNot 系列接口Host 侧在 Tiling 函数中构造AscendC::TensorShape shape(srcDims)描述输入形状调用GetBitwiseNotMaxMinTmpSize获取maxValue/minValue再通过platform_ascendc::PlatformAscendC(platformInfo).GetCoreMemSize(platform_ascendc::CoreMemType::UB, tailSize)获取 UB 剩余空间实际场景需减去已使用的 UB 空间并以tailSize maxValue ? maxValue : tailSize确定最终临时空间大小tmpSize写入 TilingData如srcSize、tmpBufferSize字段传给 KernelKernel 侧通过GET_TILING_DATA读取 TilingData用pipe.InitBuffer(tmpBuf, tmpBufferSize)按计算出的空间大小申请临时 Buffer之后即可安全调用 BitwiseNot 完成计算。这种Host 侧算空间、Kernel 侧按空间计算的配合方式能够避免临时空间申请不足导致的错误也能在 UB 空间允许的范围内最大化单次计算规模。测试用例验证仓库为 BitwiseNot 提供了两层测试验证内核功能测试test_operator_bitwise_not.cpp以BitwiseNotTestParams{dataTypeSize, inDataSize, calFunc}参数化方式覆盖8 种数据类型 × 3 种数据规模32 / 256 / 1024 元素即 uint8_t、int8_t、uint16_t、int16_t、uint32_t、int32_t、uint64_t、int64_t 全类型组合。测试将输入初始化为1二进制最低位为 1其余位为 0调用 BitwiseNot 后校验输出字节全为0x00精确验证了逐比特取反的语义~0x01 0xFE取uint8_t首字节即0x00。Tiling 接口测试test_tiling_v310.cpp 中的TestBitwiseNotTiling构造shapeDims {128}的 shape 与sizeof(float)4 字节的 typeSize断言GetBitwiseNotMaxMinTmpSize返回的maxVal、minVal均为 0GetBitwiseNotTmpBufferFactorSize返回的extraBuf、maxLivedNodesCnt均为 0——印证了当前版本 BitwiseNot 计算无需额外临时空间开发者调用这两个 Tiling 接口时可直接将返回值作为 0 处理或按通用流程将其作为空间下限/上限参考继续参与 UB 规划。关键源码路径速览内容仓库相对路径公开接口声明include/adv_api/math/bitwise_not.h配置结构体定义include/adv_api/math/bitwise_not_utils.hTiling 接口声明include/adv_api/math/bitwise_not_tiling.h内核实现Reg::Not 矢量取反impl/adv_api/detail/math/bitwise_not/bitwise_not_3510_impl.hTiling 实现临时空间计算impl/adv_api/tiling/math/bitwise_not_tiling_impl.cpp参数校验实现impl/adv_api/detail/api_check/kernel_check/math/bitwise_not/bitwise_not_check_c310.h内核功能测试tests/api/adv_api/math/bitwise_not/test_operator_bitwise_not.cppTiling 接口测试tests/api/adv_api/tiling/test_tiling_v310.cpp继续阅读BitwiseNot 接口页接口索引入口BitwiseAnd、BitwiseOr、BitwiseXor 等同类按位运算接口数学计算接口总览通用说明和约束TPosition 映射、地址对齐LocalTensor 数据结构赞分享人工智能深度学习算子库CANNAscend【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址https://gitcode.com/cann/asc-devkit点击查看免费下载相关推荐asc-devkit 高阶 API 实战BitwiseOr 逐比特或运算接口与 Host 侧临时空间规划指南asc devkit 高阶 API 实战BitwiseOr 逐比特或运算接口与 Host 侧临时空间规划指南 导读 本文围绕 CANN 昇腾 AI 处理器算子人工智能深度学习算子库CANNAscendUltimate Vocal Remover v5.6 安装教程30 分钟装好免费人声分离工具拿到干净伴奏Ultimate Vocal Remover v5.6 安装教程30 分钟装好免费人声分离工具拿到干净伴奏 Ultimate Vocal RemoverU人工智能深度学习算子库CANNAscendasc-devkit LogicalNot 高阶接口实战指南逐元素逻辑取反算子与临时空间规划asc devkit LogicalNot 高阶接口实战指南逐元素逻辑取反算子与临时空间规划 导读 LogicalNot 是 CANN asc devkit人工智能深度学习算子库CANNAscend上一篇Apache Pulsar 主题统计指标全解读从 partitioned-stats 到 stats-internal 的运维实战指南下一篇ai-marketing-skills eval 技能如何为任意AI功能自动搭建评估套件并检测回归创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑