文件最后提交记录最后更新时间
math仓的doc tools 工具检测的低错问题 Co-authored-by: caiwenwen<caiwenwen6@h-partners.com> # message auto-generated for no-merge-commit merge: !2461 merge master into master math仓的doc tools 工具检测的低错问题 Created-by: caiwenwen Commit-by: caiwenwen Merged-by: cann-robot Description: ## 描述 处理math仓的doc tools 工具检测的低错问题,包括markdown低错、htlm标签合入、链接是否可以正常跳转 ## 关联的Issue #关联issue#1262 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 更新全部文档 ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [ ] 新特性 - [ ] 性能优化 - [x] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!24611 个月前
【社区任务】Real算子AscendC实现 Co-authored-by: alfengyuan<yuanyaofeng@h-partners.com> # message auto-generated for no-merge-commit merge: !1774 merge 20260320 into master 【社区任务】Real算子AscendC实现 Created-by: alfengyuan Commit-by: alfengyuan Merged-by: cann-robot Description: 原设计文档评审pr:https://gitcode.com/cann/ops-math/pull/1634 # Real算子AscendC实现设计文档 ## 一、 需求背景 ### 1.1 需求来源 通过社区任务完成开源仓算子贡献的需求 ### 1.2 背景介绍 #### 1.2.1 Real算子实现优化 基于Real算子历史TBE版本使用AscendC 编程语言进行优化 Real算子(TBE)实现路径和相关API路径 - Real算子实现路径为: /usr/local/Ascend/cann-9.0.0/opp/built-in/op_impl/ai_core/tbe/impl/ops_legacy/dynamic/real.py - Real算子实现中的API路径: /usr/local/Ascend/cann-9.0.0/python/site-packages/tbe/dsl/compute/math.py #### 1.2.2 Real算子现状分析 通过对Real算子TBE版本的功能分析,当前支持的能力如下: - Input是float16/float32数据类型的时候,执行VS_add(x, 0)操作,直接返回原数据 - Input是complex32/complex64 数据类型的时候,创建TVM placeholder 调用 tbe.real(input) api生成 elsewise_single_real IR指令 - 自动调优,调用tbe.auto_schedule(res)进行自动调优 Real算子TBE版本的整体流程图如下图所示: ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/tbe.png) ## 二、 需求分析 ### 2.1 外部组件依赖 不涉及外部组件适配 ### 2.2 内部适配模块 内部aclnn接口已有,其他tiling,kernel,graph图需要适配 ### 2.3 需求模块设计 #### 2.3.1 AscendC算子原型 | 名称 | 类别 | dtype | format | shape | 介绍 |--|--|--|--|--|--| | input | 输入 | fp16/fp32/complex32/complex64 | ND | all | 输入tensor | Tout | 输入 | Int | ND | (1,) | 属性输入 | output | 输出 | fp16/fp32 | ND | 同输入 | 输出tensor - 相关约束: Atlas A2训练系列产品/Atlas 800I A2推理产品float16、float32、complex32、complex64 ## 三、 需求详细设计 ### 3.1 使能方式 | 上层框架 | 涉及的框架 | |---------|---------| | **TF训练/推理** | 不涉及 | | **PyTorch训练/推理** | 涉及 | | **ATC推理** | 涉及 | | **Aclnn直调** | 涉及 | | **OPAT调优** | 不涉及 | | **SGAT子图切分** | 不涉及 | ### 3.2 需求总体设计 #### 3.2.1 host侧设计 ##### 3.2.1.1 分核策略 参考库上类似算子Range,LinSpace,128个数据对齐,少于128个数据的单核,大于128数据的按128对齐后均分核 ``` totalLength: 总元素个数 totalCoreNum: AI Core总数 usedCoreNum: 实际使用的核数 分核逻辑: if (totalLength <= 128) { usedCoreNum = 1; // 小数据量单核处理 } else { // 128个数据对齐切分 numOfPerCore = Align128Ceil(totalLength / totalCoreNum); usedCoreNum = min(totalLength / numOfPerCore, totalCoreNum); } ``` ##### 3.2.1.2 数据分块和内存优化策略 UB总空间减去预留空间,再除以输出数据类型的字节数,再除以计算中间ub占用块(需要考虑开启Double Buffer)的情况, 对于非complex输入,数据直接拷贝到输出GM,需要UB空间为2(Double Buffer) 对于comoplex输入,数据需要拷贝到ub,提取实数,再拷贝输出,需要UB空间为 3(输入+输出,其中输入是输出的2倍) * 2(Double Buffer)= 6 | 输入类型 | inQueue | outQueue | 总倍数 | 说明 | |---------|---------|----------|:------:|------| | complex | 2x | 1x | 6 | 输入需存储完整复数(2x),双缓冲 | | real | 共享 | 共享 | 2 | TQueBind复用buffer | 具体实现公式参考如下代码块 ```cpp // 根据输入类型选择不同的UB倍数 bool isComplexInput = (inputDtype == DT_COMPLEX32 || inputDtype == DT_COMPLEX64); int64_t ubMultiplier = isComplexInput ? 6 : 2; // complex需要额外空间存放复数数据 // 计算单次循环可处理的元素数 int64_t ubAvailable = totalUbSize - RESERVED_UB_SIZE; // 预留256字节 int64_t ubOneLoopNum = Align128FloorSize(ubAvailable / (outputSize * ubMultiplier)); ``` ##### 3.2.1.3 tilingKey规划策略 根据输入类型确定tilingKey | 输入类型 | tilingKey | |---------|---------| | complex32 | 1 | | complex64 | 2 | | complex128 | -预留 | | float16 | 4 | | float32 | 5 | ```cpp enum class RealTilingKey : int64_t { TILINGKEY_COMPLEX32 = 1, // complex32 -> float16 TILINGKEY_COMPLEX64 = 2, // complex64 -> float TILINGKEY_FLOAT16 = 4, // float16 -> float16 (identity) TILINGKEY_FLOAT = 5 // float -> float (identity) }; ``` #### 3.2.2 kernel侧设计 ##### 3.2.2.1 kernel侧实现描述 Real算子针对不同输入类型采用不同的处理策略: 1. **复数输入(complex32/complex64)**: - 使用 GatherMask API提取复数实部 - 复数在内存中以交织方式存储:[real0, imag0, real1, imag1, ...] - 通过mask模式提取偶数索引位置的元素(实部) 2. **实数输入(float/float16)**: - 使用 TQueBind 实现零拷贝identity操作 - 输入输出共享同一块UB buffer,减少内存拷贝开销 ##### 3.2.2.2 AscendC实现流程图 ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/ascendc.png) ##### 3.2.2.3 TBE与AscendC实现流程图存在的差异点和原因 **整体架构对比:** ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 实现架构对比 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ TBE 架构: AscendC 架构: │ │ ┌──────────┐ ┌──────────┐ │ │ │ 用户代码 │ │ 用户代码 │ │ │ │(Python) │ │ (C++) │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │TBE DSL │ │AscendC │ │ │ │real.py │ │API调用 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ TVM │ │ 编译器 │ │ │ │IR生成 │ │直接编译 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │自动调度 │ │手动调度 │ │ │ │优化 │ │优化 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ └──────────┬───────────────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ MOVEMASK │ │ │ │ 硬件指令 │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` **详细对比表:** | 对比维度 | TBE实现 | AscendC实现 | 说明 | |---------|---------|------------|------| | **编程语言** | Python DSL | C++ Template | TBE更简洁,AscendC更底层 | | **调用入口** | real.py:real() | real.cpp:real() | 算子注册入口 | | **计算定义** | real_compute() | RealKernel::Process() | 计算逻辑定义 | | **API调用** | tbe.real(input) | GatherMask(dst, src, mode=1) | 高层API对比 | | **中间表示** | TVM IR (tir.real) | 无中间层 | TBE通过TVM IR | | **类型分发** | 运行时 if/else | 编译期 constexpr if | AscendC编译期优化 | | **形状分类** | classify() 自动 | 无需分类 | TBE支持多shape自动处理 | | **多核切分** | auto_schedule() 自动 | 手动计算 | TBE自动,AscendC手动 | | **UB切分** | auto_schedule() 自动 | 手动计算 ubMultiplier | TBE自动,AscendC手动 | | **双缓冲** | 框架自动管理 | 手动管理 TQue | TBE自动,AscendC手动 | | **流水线** | 框架自动优化 | 手动优化 | TBE自动优化 | | **指令映射** | "elewise_single_real""vector_real" | GatherMask(mode=1)MOVEMASK | 最终相同 | | **实数处理** | elewise_single_VS_add(x, 0) | TQueBind Identity | 实数类型优化方式不同 | | **编译产物** | .o / .json / .bin | .o / .bin | 构建产物略有差异 | **数据流对比:** ``` TBE数据流: AscendC数据流: ──────────── ──────────── GM → UB → Compute → UB → GM GM → UB → Compute → UB → GM ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ │ │ │ │ │ │ │ │ auto auto auto auto 手动 手动 手动 手动 ``` **关键差异原因:** 1. **设计理念不同**: - TBE:声明式编程,描述"做什么",框架自动优化"怎么做" - AscendC:命令式编程,明确指定"怎么做" 2. **自动化程度不同**: - TBE:高度自动化(分核、UB切分、双缓冲、流水线) - AscendC:手动控制所有细节 3. **灵活性不同**: - TBE:快速开发,但优化空间受限 - AscendC:开发复杂,但优化空间更大 4. **底层实现相同**: - 两者最终都调用 **MOVEMASK** CCE指令 - 复数内存布局相同:[r0,i0, r1,i1, ...] - 提取原理相同:提取偶数索引元素 差异的原因,tbe实现分核逻辑是框架自动调优的,AscendC实现参考的库上Range算子,和Linspace算子。 ### 3.3 支持硬件 | 支持的芯片版本 | 是否支持 | |---------|---------| | 香橙派OrangePi AIpro | 不支持 | | Atlas 200I/500 A2推理产品 | 不支持 | | Atlas 800I/T A2 | 支持 | ### 3.4 算子约束限制 - complex128 由AICPU原生支持,aclnn层面路由 - 不支持广播 ## 四、 特性交叉分析 ## 五、 可维可测分析 ### 5.1 精度标准/性能标准 精度和TBE保持完全一致。 性能参考Real算子任务书,有如下要求: - 算子整体性能需与原TBE实现算子持平 - 暂仅要求所有核参与计算场景下,性能不低于原TBE算子的 95%。 - 如小shape无法达标(10us以下场景相差3us),提供性能仿真图和分析结论证明AscendC实现和TBE完全一致或优于TBE实现 ### 5.2 兼容性分析 - proto算子原型,legacy仓有一份旧的,要完全兼容旧的 See merge request: cann/ops-math!17742 个月前
【社区任务】Real算子AscendC实现 Co-authored-by: alfengyuan<yuanyaofeng@h-partners.com> # message auto-generated for no-merge-commit merge: !1774 merge 20260320 into master 【社区任务】Real算子AscendC实现 Created-by: alfengyuan Commit-by: alfengyuan Merged-by: cann-robot Description: 原设计文档评审pr:https://gitcode.com/cann/ops-math/pull/1634 # Real算子AscendC实现设计文档 ## 一、 需求背景 ### 1.1 需求来源 通过社区任务完成开源仓算子贡献的需求 ### 1.2 背景介绍 #### 1.2.1 Real算子实现优化 基于Real算子历史TBE版本使用AscendC 编程语言进行优化 Real算子(TBE)实现路径和相关API路径 - Real算子实现路径为: /usr/local/Ascend/cann-9.0.0/opp/built-in/op_impl/ai_core/tbe/impl/ops_legacy/dynamic/real.py - Real算子实现中的API路径: /usr/local/Ascend/cann-9.0.0/python/site-packages/tbe/dsl/compute/math.py #### 1.2.2 Real算子现状分析 通过对Real算子TBE版本的功能分析,当前支持的能力如下: - Input是float16/float32数据类型的时候,执行VS_add(x, 0)操作,直接返回原数据 - Input是complex32/complex64 数据类型的时候,创建TVM placeholder 调用 tbe.real(input) api生成 elsewise_single_real IR指令 - 自动调优,调用tbe.auto_schedule(res)进行自动调优 Real算子TBE版本的整体流程图如下图所示: ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/tbe.png) ## 二、 需求分析 ### 2.1 外部组件依赖 不涉及外部组件适配 ### 2.2 内部适配模块 内部aclnn接口已有,其他tiling,kernel,graph图需要适配 ### 2.3 需求模块设计 #### 2.3.1 AscendC算子原型 | 名称 | 类别 | dtype | format | shape | 介绍 |--|--|--|--|--|--| | input | 输入 | fp16/fp32/complex32/complex64 | ND | all | 输入tensor | Tout | 输入 | Int | ND | (1,) | 属性输入 | output | 输出 | fp16/fp32 | ND | 同输入 | 输出tensor - 相关约束: Atlas A2训练系列产品/Atlas 800I A2推理产品float16、float32、complex32、complex64 ## 三、 需求详细设计 ### 3.1 使能方式 | 上层框架 | 涉及的框架 | |---------|---------| | **TF训练/推理** | 不涉及 | | **PyTorch训练/推理** | 涉及 | | **ATC推理** | 涉及 | | **Aclnn直调** | 涉及 | | **OPAT调优** | 不涉及 | | **SGAT子图切分** | 不涉及 | ### 3.2 需求总体设计 #### 3.2.1 host侧设计 ##### 3.2.1.1 分核策略 参考库上类似算子Range,LinSpace,128个数据对齐,少于128个数据的单核,大于128数据的按128对齐后均分核 ``` totalLength: 总元素个数 totalCoreNum: AI Core总数 usedCoreNum: 实际使用的核数 分核逻辑: if (totalLength <= 128) { usedCoreNum = 1; // 小数据量单核处理 } else { // 128个数据对齐切分 numOfPerCore = Align128Ceil(totalLength / totalCoreNum); usedCoreNum = min(totalLength / numOfPerCore, totalCoreNum); } ``` ##### 3.2.1.2 数据分块和内存优化策略 UB总空间减去预留空间,再除以输出数据类型的字节数,再除以计算中间ub占用块(需要考虑开启Double Buffer)的情况, 对于非complex输入,数据直接拷贝到输出GM,需要UB空间为2(Double Buffer) 对于comoplex输入,数据需要拷贝到ub,提取实数,再拷贝输出,需要UB空间为 3(输入+输出,其中输入是输出的2倍) * 2(Double Buffer)= 6 | 输入类型 | inQueue | outQueue | 总倍数 | 说明 | |---------|---------|----------|:------:|------| | complex | 2x | 1x | 6 | 输入需存储完整复数(2x),双缓冲 | | real | 共享 | 共享 | 2 | TQueBind复用buffer | 具体实现公式参考如下代码块 ```cpp // 根据输入类型选择不同的UB倍数 bool isComplexInput = (inputDtype == DT_COMPLEX32 || inputDtype == DT_COMPLEX64); int64_t ubMultiplier = isComplexInput ? 6 : 2; // complex需要额外空间存放复数数据 // 计算单次循环可处理的元素数 int64_t ubAvailable = totalUbSize - RESERVED_UB_SIZE; // 预留256字节 int64_t ubOneLoopNum = Align128FloorSize(ubAvailable / (outputSize * ubMultiplier)); ``` ##### 3.2.1.3 tilingKey规划策略 根据输入类型确定tilingKey | 输入类型 | tilingKey | |---------|---------| | complex32 | 1 | | complex64 | 2 | | complex128 | -预留 | | float16 | 4 | | float32 | 5 | ```cpp enum class RealTilingKey : int64_t { TILINGKEY_COMPLEX32 = 1, // complex32 -> float16 TILINGKEY_COMPLEX64 = 2, // complex64 -> float TILINGKEY_FLOAT16 = 4, // float16 -> float16 (identity) TILINGKEY_FLOAT = 5 // float -> float (identity) }; ``` #### 3.2.2 kernel侧设计 ##### 3.2.2.1 kernel侧实现描述 Real算子针对不同输入类型采用不同的处理策略: 1. **复数输入(complex32/complex64)**: - 使用 GatherMask API提取复数实部 - 复数在内存中以交织方式存储:[real0, imag0, real1, imag1, ...] - 通过mask模式提取偶数索引位置的元素(实部) 2. **实数输入(float/float16)**: - 使用 TQueBind 实现零拷贝identity操作 - 输入输出共享同一块UB buffer,减少内存拷贝开销 ##### 3.2.2.2 AscendC实现流程图 ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/ascendc.png) ##### 3.2.2.3 TBE与AscendC实现流程图存在的差异点和原因 **整体架构对比:** ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 实现架构对比 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ TBE 架构: AscendC 架构: │ │ ┌──────────┐ ┌──────────┐ │ │ │ 用户代码 │ │ 用户代码 │ │ │ │(Python) │ │ (C++) │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │TBE DSL │ │AscendC │ │ │ │real.py │ │API调用 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ TVM │ │ 编译器 │ │ │ │IR生成 │ │直接编译 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │自动调度 │ │手动调度 │ │ │ │优化 │ │优化 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ └──────────┬───────────────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ MOVEMASK │ │ │ │ 硬件指令 │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` **详细对比表:** | 对比维度 | TBE实现 | AscendC实现 | 说明 | |---------|---------|------------|------| | **编程语言** | Python DSL | C++ Template | TBE更简洁,AscendC更底层 | | **调用入口** | real.py:real() | real.cpp:real() | 算子注册入口 | | **计算定义** | real_compute() | RealKernel::Process() | 计算逻辑定义 | | **API调用** | tbe.real(input) | GatherMask(dst, src, mode=1) | 高层API对比 | | **中间表示** | TVM IR (tir.real) | 无中间层 | TBE通过TVM IR | | **类型分发** | 运行时 if/else | 编译期 constexpr if | AscendC编译期优化 | | **形状分类** | classify() 自动 | 无需分类 | TBE支持多shape自动处理 | | **多核切分** | auto_schedule() 自动 | 手动计算 | TBE自动,AscendC手动 | | **UB切分** | auto_schedule() 自动 | 手动计算 ubMultiplier | TBE自动,AscendC手动 | | **双缓冲** | 框架自动管理 | 手动管理 TQue | TBE自动,AscendC手动 | | **流水线** | 框架自动优化 | 手动优化 | TBE自动优化 | | **指令映射** | "elewise_single_real""vector_real" | GatherMask(mode=1)MOVEMASK | 最终相同 | | **实数处理** | elewise_single_VS_add(x, 0) | TQueBind Identity | 实数类型优化方式不同 | | **编译产物** | .o / .json / .bin | .o / .bin | 构建产物略有差异 | **数据流对比:** ``` TBE数据流: AscendC数据流: ──────────── ──────────── GM → UB → Compute → UB → GM GM → UB → Compute → UB → GM ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ │ │ │ │ │ │ │ │ auto auto auto auto 手动 手动 手动 手动 ``` **关键差异原因:** 1. **设计理念不同**: - TBE:声明式编程,描述"做什么",框架自动优化"怎么做" - AscendC:命令式编程,明确指定"怎么做" 2. **自动化程度不同**: - TBE:高度自动化(分核、UB切分、双缓冲、流水线) - AscendC:手动控制所有细节 3. **灵活性不同**: - TBE:快速开发,但优化空间受限 - AscendC:开发复杂,但优化空间更大 4. **底层实现相同**: - 两者最终都调用 **MOVEMASK** CCE指令 - 复数内存布局相同:[r0,i0, r1,i1, ...] - 提取原理相同:提取偶数索引元素 差异的原因,tbe实现分核逻辑是框架自动调优的,AscendC实现参考的库上Range算子,和Linspace算子。 ### 3.3 支持硬件 | 支持的芯片版本 | 是否支持 | |---------|---------| | 香橙派OrangePi AIpro | 不支持 | | Atlas 200I/500 A2推理产品 | 不支持 | | Atlas 800I/T A2 | 支持 | ### 3.4 算子约束限制 - complex128 由AICPU原生支持,aclnn层面路由 - 不支持广播 ## 四、 特性交叉分析 ## 五、 可维可测分析 ### 5.1 精度标准/性能标准 精度和TBE保持完全一致。 性能参考Real算子任务书,有如下要求: - 算子整体性能需与原TBE实现算子持平 - 暂仅要求所有核参与计算场景下,性能不低于原TBE算子的 95%。 - 如小shape无法达标(10us以下场景相差3us),提供性能仿真图和分析结论证明AscendC实现和TBE完全一致或优于TBE实现 ### 5.2 兼容性分析 - proto算子原型,legacy仓有一份旧的,要完全兼容旧的 See merge request: cann/ops-math!17742 个月前
refactor: 迁移 experimental 算子 tiling 模块至新公共头文件及命名空间 Co-authored-by: songkai111<songkai16@huawei.com> # message auto-generated for no-merge-commit merge: !2974 merge master into master refactor: 迁移 experimental 算子 tiling 模块至新公共头文件及命名空间 Created-by: songkai111 Commit-by: songkai111 Merged-by: cann-robot Description: ## 描述 将 experimental 目录下 22 个算子的 tiling 代码从旧公共头文件及命名空间迁移至新公共头文件及命名空间,统一 tiling 公共接口规范。 ### 改动原因 experimental 算子的 tiling 代码依赖了旧的公共头文件(tiling_base_util.hmath_tiling_templates_registry.htiling_base_class.h)及 Ops::Base 命名空间,需要迁移至新的公共头文件(tiling_util.htiling_templates_registry.htiling_base.h)及 Ops::Math::OpTiling 命名空间,以统一 tiling 公共接口规范。 ### 改动方法 1. 替换 #include 指令: - "op_host/tiling_base_util.h""op_host/tiling_util.h"(20 个文件) - "op_host/math_tiling_templates_registry.h""op_host/tiling_templates_registry.h"(2 个文件) - "op_host/tiling_base_class.h""op_host/tiling_base.h"(1 个文件) 2. 命名空间及 API 迁移: - Ops::Base::EnsureNotScalar()Ops::Math::OpTiling::EnsureNotScalar() - Ops::Base::IsRegbaseSocVersion()Ops::Math::OpTiling::IsRegbaseSocVersion() - using namespace Ops::Baseusing namespace Ops::Math::OpTiling(2 个文件) ### 涉及算子(22 个文件) - **conversion 算子**:col2_im、im2_col - **math 算子**:add_v2、atan、ceil_v2、cross、dot_v2、floor_div、floor_mod、ger_v2、greater_equal(arch35)、isin_part_v1、minimum、ones_like、real、select_v3、sinh、softsign(arch35)、square_v2、trilu(arch35)、trunc_v2 ## 关联的Issue - #1679 - https://gitcode.com/cann/ops-math/issues/1679 ## 测试 通过编译验证及算子冒烟测试。 ## 文档更新 无文档更新。 ## 类型标签 - [ ] Bug修复 - [ ] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [x] 其他,请描述:重构 - 迁移 tiling 公共头文件及命名空间 See merge request: cann/ops-math!29746 天前
【社区任务】Real算子AscendC实现 Co-authored-by: alfengyuan<yuanyaofeng@h-partners.com> # message auto-generated for no-merge-commit merge: !1774 merge 20260320 into master 【社区任务】Real算子AscendC实现 Created-by: alfengyuan Commit-by: alfengyuan Merged-by: cann-robot Description: 原设计文档评审pr:https://gitcode.com/cann/ops-math/pull/1634 # Real算子AscendC实现设计文档 ## 一、 需求背景 ### 1.1 需求来源 通过社区任务完成开源仓算子贡献的需求 ### 1.2 背景介绍 #### 1.2.1 Real算子实现优化 基于Real算子历史TBE版本使用AscendC 编程语言进行优化 Real算子(TBE)实现路径和相关API路径 - Real算子实现路径为: /usr/local/Ascend/cann-9.0.0/opp/built-in/op_impl/ai_core/tbe/impl/ops_legacy/dynamic/real.py - Real算子实现中的API路径: /usr/local/Ascend/cann-9.0.0/python/site-packages/tbe/dsl/compute/math.py #### 1.2.2 Real算子现状分析 通过对Real算子TBE版本的功能分析,当前支持的能力如下: - Input是float16/float32数据类型的时候,执行VS_add(x, 0)操作,直接返回原数据 - Input是complex32/complex64 数据类型的时候,创建TVM placeholder 调用 tbe.real(input) api生成 elsewise_single_real IR指令 - 自动调优,调用tbe.auto_schedule(res)进行自动调优 Real算子TBE版本的整体流程图如下图所示: ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/tbe.png) ## 二、 需求分析 ### 2.1 外部组件依赖 不涉及外部组件适配 ### 2.2 内部适配模块 内部aclnn接口已有,其他tiling,kernel,graph图需要适配 ### 2.3 需求模块设计 #### 2.3.1 AscendC算子原型 | 名称 | 类别 | dtype | format | shape | 介绍 |--|--|--|--|--|--| | input | 输入 | fp16/fp32/complex32/complex64 | ND | all | 输入tensor | Tout | 输入 | Int | ND | (1,) | 属性输入 | output | 输出 | fp16/fp32 | ND | 同输入 | 输出tensor - 相关约束: Atlas A2训练系列产品/Atlas 800I A2推理产品float16、float32、complex32、complex64 ## 三、 需求详细设计 ### 3.1 使能方式 | 上层框架 | 涉及的框架 | |---------|---------| | **TF训练/推理** | 不涉及 | | **PyTorch训练/推理** | 涉及 | | **ATC推理** | 涉及 | | **Aclnn直调** | 涉及 | | **OPAT调优** | 不涉及 | | **SGAT子图切分** | 不涉及 | ### 3.2 需求总体设计 #### 3.2.1 host侧设计 ##### 3.2.1.1 分核策略 参考库上类似算子Range,LinSpace,128个数据对齐,少于128个数据的单核,大于128数据的按128对齐后均分核 ``` totalLength: 总元素个数 totalCoreNum: AI Core总数 usedCoreNum: 实际使用的核数 分核逻辑: if (totalLength <= 128) { usedCoreNum = 1; // 小数据量单核处理 } else { // 128个数据对齐切分 numOfPerCore = Align128Ceil(totalLength / totalCoreNum); usedCoreNum = min(totalLength / numOfPerCore, totalCoreNum); } ``` ##### 3.2.1.2 数据分块和内存优化策略 UB总空间减去预留空间,再除以输出数据类型的字节数,再除以计算中间ub占用块(需要考虑开启Double Buffer)的情况, 对于非complex输入,数据直接拷贝到输出GM,需要UB空间为2(Double Buffer) 对于comoplex输入,数据需要拷贝到ub,提取实数,再拷贝输出,需要UB空间为 3(输入+输出,其中输入是输出的2倍) * 2(Double Buffer)= 6 | 输入类型 | inQueue | outQueue | 总倍数 | 说明 | |---------|---------|----------|:------:|------| | complex | 2x | 1x | 6 | 输入需存储完整复数(2x),双缓冲 | | real | 共享 | 共享 | 2 | TQueBind复用buffer | 具体实现公式参考如下代码块 ```cpp // 根据输入类型选择不同的UB倍数 bool isComplexInput = (inputDtype == DT_COMPLEX32 || inputDtype == DT_COMPLEX64); int64_t ubMultiplier = isComplexInput ? 6 : 2; // complex需要额外空间存放复数数据 // 计算单次循环可处理的元素数 int64_t ubAvailable = totalUbSize - RESERVED_UB_SIZE; // 预留256字节 int64_t ubOneLoopNum = Align128FloorSize(ubAvailable / (outputSize * ubMultiplier)); ``` ##### 3.2.1.3 tilingKey规划策略 根据输入类型确定tilingKey | 输入类型 | tilingKey | |---------|---------| | complex32 | 1 | | complex64 | 2 | | complex128 | -预留 | | float16 | 4 | | float32 | 5 | ```cpp enum class RealTilingKey : int64_t { TILINGKEY_COMPLEX32 = 1, // complex32 -> float16 TILINGKEY_COMPLEX64 = 2, // complex64 -> float TILINGKEY_FLOAT16 = 4, // float16 -> float16 (identity) TILINGKEY_FLOAT = 5 // float -> float (identity) }; ``` #### 3.2.2 kernel侧设计 ##### 3.2.2.1 kernel侧实现描述 Real算子针对不同输入类型采用不同的处理策略: 1. **复数输入(complex32/complex64)**: - 使用 GatherMask API提取复数实部 - 复数在内存中以交织方式存储:[real0, imag0, real1, imag1, ...] - 通过mask模式提取偶数索引位置的元素(实部) 2. **实数输入(float/float16)**: - 使用 TQueBind 实现零拷贝identity操作 - 输入输出共享同一块UB buffer,减少内存拷贝开销 ##### 3.2.2.2 AscendC实现流程图 ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/ascendc.png) ##### 3.2.2.3 TBE与AscendC实现流程图存在的差异点和原因 **整体架构对比:** ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 实现架构对比 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ TBE 架构: AscendC 架构: │ │ ┌──────────┐ ┌──────────┐ │ │ │ 用户代码 │ │ 用户代码 │ │ │ │(Python) │ │ (C++) │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │TBE DSL │ │AscendC │ │ │ │real.py │ │API调用 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ TVM │ │ 编译器 │ │ │ │IR生成 │ │直接编译 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │自动调度 │ │手动调度 │ │ │ │优化 │ │优化 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ └──────────┬───────────────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ MOVEMASK │ │ │ │ 硬件指令 │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` **详细对比表:** | 对比维度 | TBE实现 | AscendC实现 | 说明 | |---------|---------|------------|------| | **编程语言** | Python DSL | C++ Template | TBE更简洁,AscendC更底层 | | **调用入口** | real.py:real() | real.cpp:real() | 算子注册入口 | | **计算定义** | real_compute() | RealKernel::Process() | 计算逻辑定义 | | **API调用** | tbe.real(input) | GatherMask(dst, src, mode=1) | 高层API对比 | | **中间表示** | TVM IR (tir.real) | 无中间层 | TBE通过TVM IR | | **类型分发** | 运行时 if/else | 编译期 constexpr if | AscendC编译期优化 | | **形状分类** | classify() 自动 | 无需分类 | TBE支持多shape自动处理 | | **多核切分** | auto_schedule() 自动 | 手动计算 | TBE自动,AscendC手动 | | **UB切分** | auto_schedule() 自动 | 手动计算 ubMultiplier | TBE自动,AscendC手动 | | **双缓冲** | 框架自动管理 | 手动管理 TQue | TBE自动,AscendC手动 | | **流水线** | 框架自动优化 | 手动优化 | TBE自动优化 | | **指令映射** | "elewise_single_real""vector_real" | GatherMask(mode=1)MOVEMASK | 最终相同 | | **实数处理** | elewise_single_VS_add(x, 0) | TQueBind Identity | 实数类型优化方式不同 | | **编译产物** | .o / .json / .bin | .o / .bin | 构建产物略有差异 | **数据流对比:** ``` TBE数据流: AscendC数据流: ──────────── ──────────── GM → UB → Compute → UB → GM GM → UB → Compute → UB → GM ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ │ │ │ │ │ │ │ │ auto auto auto auto 手动 手动 手动 手动 ``` **关键差异原因:** 1. **设计理念不同**: - TBE:声明式编程,描述"做什么",框架自动优化"怎么做" - AscendC:命令式编程,明确指定"怎么做" 2. **自动化程度不同**: - TBE:高度自动化(分核、UB切分、双缓冲、流水线) - AscendC:手动控制所有细节 3. **灵活性不同**: - TBE:快速开发,但优化空间受限 - AscendC:开发复杂,但优化空间更大 4. **底层实现相同**: - 两者最终都调用 **MOVEMASK** CCE指令 - 复数内存布局相同:[r0,i0, r1,i1, ...] - 提取原理相同:提取偶数索引元素 差异的原因,tbe实现分核逻辑是框架自动调优的,AscendC实现参考的库上Range算子,和Linspace算子。 ### 3.3 支持硬件 | 支持的芯片版本 | 是否支持 | |---------|---------| | 香橙派OrangePi AIpro | 不支持 | | Atlas 200I/500 A2推理产品 | 不支持 | | Atlas 800I/T A2 | 支持 | ### 3.4 算子约束限制 - complex128 由AICPU原生支持,aclnn层面路由 - 不支持广播 ## 四、 特性交叉分析 ## 五、 可维可测分析 ### 5.1 精度标准/性能标准 精度和TBE保持完全一致。 性能参考Real算子任务书,有如下要求: - 算子整体性能需与原TBE实现算子持平 - 暂仅要求所有核参与计算场景下,性能不低于原TBE算子的 95%。 - 如小shape无法达标(10us以下场景相差3us),提供性能仿真图和分析结论证明AscendC实现和TBE完全一致或优于TBE实现 ### 5.2 兼容性分析 - proto算子原型,legacy仓有一份旧的,要完全兼容旧的 See merge request: cann/ops-math!17742 个月前
【社区任务】Real算子AscendC实现 Co-authored-by: alfengyuan<yuanyaofeng@h-partners.com> # message auto-generated for no-merge-commit merge: !1774 merge 20260320 into master 【社区任务】Real算子AscendC实现 Created-by: alfengyuan Commit-by: alfengyuan Merged-by: cann-robot Description: 原设计文档评审pr:https://gitcode.com/cann/ops-math/pull/1634 # Real算子AscendC实现设计文档 ## 一、 需求背景 ### 1.1 需求来源 通过社区任务完成开源仓算子贡献的需求 ### 1.2 背景介绍 #### 1.2.1 Real算子实现优化 基于Real算子历史TBE版本使用AscendC 编程语言进行优化 Real算子(TBE)实现路径和相关API路径 - Real算子实现路径为: /usr/local/Ascend/cann-9.0.0/opp/built-in/op_impl/ai_core/tbe/impl/ops_legacy/dynamic/real.py - Real算子实现中的API路径: /usr/local/Ascend/cann-9.0.0/python/site-packages/tbe/dsl/compute/math.py #### 1.2.2 Real算子现状分析 通过对Real算子TBE版本的功能分析,当前支持的能力如下: - Input是float16/float32数据类型的时候,执行VS_add(x, 0)操作,直接返回原数据 - Input是complex32/complex64 数据类型的时候,创建TVM placeholder 调用 tbe.real(input) api生成 elsewise_single_real IR指令 - 自动调优,调用tbe.auto_schedule(res)进行自动调优 Real算子TBE版本的整体流程图如下图所示: ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/tbe.png) ## 二、 需求分析 ### 2.1 外部组件依赖 不涉及外部组件适配 ### 2.2 内部适配模块 内部aclnn接口已有,其他tiling,kernel,graph图需要适配 ### 2.3 需求模块设计 #### 2.3.1 AscendC算子原型 | 名称 | 类别 | dtype | format | shape | 介绍 |--|--|--|--|--|--| | input | 输入 | fp16/fp32/complex32/complex64 | ND | all | 输入tensor | Tout | 输入 | Int | ND | (1,) | 属性输入 | output | 输出 | fp16/fp32 | ND | 同输入 | 输出tensor - 相关约束: Atlas A2训练系列产品/Atlas 800I A2推理产品float16、float32、complex32、complex64 ## 三、 需求详细设计 ### 3.1 使能方式 | 上层框架 | 涉及的框架 | |---------|---------| | **TF训练/推理** | 不涉及 | | **PyTorch训练/推理** | 涉及 | | **ATC推理** | 涉及 | | **Aclnn直调** | 涉及 | | **OPAT调优** | 不涉及 | | **SGAT子图切分** | 不涉及 | ### 3.2 需求总体设计 #### 3.2.1 host侧设计 ##### 3.2.1.1 分核策略 参考库上类似算子Range,LinSpace,128个数据对齐,少于128个数据的单核,大于128数据的按128对齐后均分核 ``` totalLength: 总元素个数 totalCoreNum: AI Core总数 usedCoreNum: 实际使用的核数 分核逻辑: if (totalLength <= 128) { usedCoreNum = 1; // 小数据量单核处理 } else { // 128个数据对齐切分 numOfPerCore = Align128Ceil(totalLength / totalCoreNum); usedCoreNum = min(totalLength / numOfPerCore, totalCoreNum); } ``` ##### 3.2.1.2 数据分块和内存优化策略 UB总空间减去预留空间,再除以输出数据类型的字节数,再除以计算中间ub占用块(需要考虑开启Double Buffer)的情况, 对于非complex输入,数据直接拷贝到输出GM,需要UB空间为2(Double Buffer) 对于comoplex输入,数据需要拷贝到ub,提取实数,再拷贝输出,需要UB空间为 3(输入+输出,其中输入是输出的2倍) * 2(Double Buffer)= 6 | 输入类型 | inQueue | outQueue | 总倍数 | 说明 | |---------|---------|----------|:------:|------| | complex | 2x | 1x | 6 | 输入需存储完整复数(2x),双缓冲 | | real | 共享 | 共享 | 2 | TQueBind复用buffer | 具体实现公式参考如下代码块 ```cpp // 根据输入类型选择不同的UB倍数 bool isComplexInput = (inputDtype == DT_COMPLEX32 || inputDtype == DT_COMPLEX64); int64_t ubMultiplier = isComplexInput ? 6 : 2; // complex需要额外空间存放复数数据 // 计算单次循环可处理的元素数 int64_t ubAvailable = totalUbSize - RESERVED_UB_SIZE; // 预留256字节 int64_t ubOneLoopNum = Align128FloorSize(ubAvailable / (outputSize * ubMultiplier)); ``` ##### 3.2.1.3 tilingKey规划策略 根据输入类型确定tilingKey | 输入类型 | tilingKey | |---------|---------| | complex32 | 1 | | complex64 | 2 | | complex128 | -预留 | | float16 | 4 | | float32 | 5 | ```cpp enum class RealTilingKey : int64_t { TILINGKEY_COMPLEX32 = 1, // complex32 -> float16 TILINGKEY_COMPLEX64 = 2, // complex64 -> float TILINGKEY_FLOAT16 = 4, // float16 -> float16 (identity) TILINGKEY_FLOAT = 5 // float -> float (identity) }; ``` #### 3.2.2 kernel侧设计 ##### 3.2.2.1 kernel侧实现描述 Real算子针对不同输入类型采用不同的处理策略: 1. **复数输入(complex32/complex64)**: - 使用 GatherMask API提取复数实部 - 复数在内存中以交织方式存储:[real0, imag0, real1, imag1, ...] - 通过mask模式提取偶数索引位置的元素(实部) 2. **实数输入(float/float16)**: - 使用 TQueBind 实现零拷贝identity操作 - 输入输出共享同一块UB buffer,减少内存拷贝开销 ##### 3.2.2.2 AscendC实现流程图 ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/ascendc.png) ##### 3.2.2.3 TBE与AscendC实现流程图存在的差异点和原因 **整体架构对比:** ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 实现架构对比 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ TBE 架构: AscendC 架构: │ │ ┌──────────┐ ┌──────────┐ │ │ │ 用户代码 │ │ 用户代码 │ │ │ │(Python) │ │ (C++) │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │TBE DSL │ │AscendC │ │ │ │real.py │ │API调用 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ TVM │ │ 编译器 │ │ │ │IR生成 │ │直接编译 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │自动调度 │ │手动调度 │ │ │ │优化 │ │优化 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ └──────────┬───────────────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ MOVEMASK │ │ │ │ 硬件指令 │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` **详细对比表:** | 对比维度 | TBE实现 | AscendC实现 | 说明 | |---------|---------|------------|------| | **编程语言** | Python DSL | C++ Template | TBE更简洁,AscendC更底层 | | **调用入口** | real.py:real() | real.cpp:real() | 算子注册入口 | | **计算定义** | real_compute() | RealKernel::Process() | 计算逻辑定义 | | **API调用** | tbe.real(input) | GatherMask(dst, src, mode=1) | 高层API对比 | | **中间表示** | TVM IR (tir.real) | 无中间层 | TBE通过TVM IR | | **类型分发** | 运行时 if/else | 编译期 constexpr if | AscendC编译期优化 | | **形状分类** | classify() 自动 | 无需分类 | TBE支持多shape自动处理 | | **多核切分** | auto_schedule() 自动 | 手动计算 | TBE自动,AscendC手动 | | **UB切分** | auto_schedule() 自动 | 手动计算 ubMultiplier | TBE自动,AscendC手动 | | **双缓冲** | 框架自动管理 | 手动管理 TQue | TBE自动,AscendC手动 | | **流水线** | 框架自动优化 | 手动优化 | TBE自动优化 | | **指令映射** | "elewise_single_real""vector_real" | GatherMask(mode=1)MOVEMASK | 最终相同 | | **实数处理** | elewise_single_VS_add(x, 0) | TQueBind Identity | 实数类型优化方式不同 | | **编译产物** | .o / .json / .bin | .o / .bin | 构建产物略有差异 | **数据流对比:** ``` TBE数据流: AscendC数据流: ──────────── ──────────── GM → UB → Compute → UB → GM GM → UB → Compute → UB → GM ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ │ │ │ │ │ │ │ │ auto auto auto auto 手动 手动 手动 手动 ``` **关键差异原因:** 1. **设计理念不同**: - TBE:声明式编程,描述"做什么",框架自动优化"怎么做" - AscendC:命令式编程,明确指定"怎么做" 2. **自动化程度不同**: - TBE:高度自动化(分核、UB切分、双缓冲、流水线) - AscendC:手动控制所有细节 3. **灵活性不同**: - TBE:快速开发,但优化空间受限 - AscendC:开发复杂,但优化空间更大 4. **底层实现相同**: - 两者最终都调用 **MOVEMASK** CCE指令 - 复数内存布局相同:[r0,i0, r1,i1, ...] - 提取原理相同:提取偶数索引元素 差异的原因,tbe实现分核逻辑是框架自动调优的,AscendC实现参考的库上Range算子,和Linspace算子。 ### 3.3 支持硬件 | 支持的芯片版本 | 是否支持 | |---------|---------| | 香橙派OrangePi AIpro | 不支持 | | Atlas 200I/500 A2推理产品 | 不支持 | | Atlas 800I/T A2 | 支持 | ### 3.4 算子约束限制 - complex128 由AICPU原生支持,aclnn层面路由 - 不支持广播 ## 四、 特性交叉分析 ## 五、 可维可测分析 ### 5.1 精度标准/性能标准 精度和TBE保持完全一致。 性能参考Real算子任务书,有如下要求: - 算子整体性能需与原TBE实现算子持平 - 暂仅要求所有核参与计算场景下,性能不低于原TBE算子的 95%。 - 如小shape无法达标(10us以下场景相差3us),提供性能仿真图和分析结论证明AscendC实现和TBE完全一致或优于TBE实现 ### 5.2 兼容性分析 - proto算子原型,legacy仓有一份旧的,要完全兼容旧的 See merge request: cann/ops-math!17742 个月前
【社区任务】Real算子AscendC实现 Co-authored-by: alfengyuan<yuanyaofeng@h-partners.com> # message auto-generated for no-merge-commit merge: !1774 merge 20260320 into master 【社区任务】Real算子AscendC实现 Created-by: alfengyuan Commit-by: alfengyuan Merged-by: cann-robot Description: 原设计文档评审pr:https://gitcode.com/cann/ops-math/pull/1634 # Real算子AscendC实现设计文档 ## 一、 需求背景 ### 1.1 需求来源 通过社区任务完成开源仓算子贡献的需求 ### 1.2 背景介绍 #### 1.2.1 Real算子实现优化 基于Real算子历史TBE版本使用AscendC 编程语言进行优化 Real算子(TBE)实现路径和相关API路径 - Real算子实现路径为: /usr/local/Ascend/cann-9.0.0/opp/built-in/op_impl/ai_core/tbe/impl/ops_legacy/dynamic/real.py - Real算子实现中的API路径: /usr/local/Ascend/cann-9.0.0/python/site-packages/tbe/dsl/compute/math.py #### 1.2.2 Real算子现状分析 通过对Real算子TBE版本的功能分析,当前支持的能力如下: - Input是float16/float32数据类型的时候,执行VS_add(x, 0)操作,直接返回原数据 - Input是complex32/complex64 数据类型的时候,创建TVM placeholder 调用 tbe.real(input) api生成 elsewise_single_real IR指令 - 自动调优,调用tbe.auto_schedule(res)进行自动调优 Real算子TBE版本的整体流程图如下图所示: ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/tbe.png) ## 二、 需求分析 ### 2.1 外部组件依赖 不涉及外部组件适配 ### 2.2 内部适配模块 内部aclnn接口已有,其他tiling,kernel,graph图需要适配 ### 2.3 需求模块设计 #### 2.3.1 AscendC算子原型 | 名称 | 类别 | dtype | format | shape | 介绍 |--|--|--|--|--|--| | input | 输入 | fp16/fp32/complex32/complex64 | ND | all | 输入tensor | Tout | 输入 | Int | ND | (1,) | 属性输入 | output | 输出 | fp16/fp32 | ND | 同输入 | 输出tensor - 相关约束: Atlas A2训练系列产品/Atlas 800I A2推理产品float16、float32、complex32、complex64 ## 三、 需求详细设计 ### 3.1 使能方式 | 上层框架 | 涉及的框架 | |---------|---------| | **TF训练/推理** | 不涉及 | | **PyTorch训练/推理** | 涉及 | | **ATC推理** | 涉及 | | **Aclnn直调** | 涉及 | | **OPAT调优** | 不涉及 | | **SGAT子图切分** | 不涉及 | ### 3.2 需求总体设计 #### 3.2.1 host侧设计 ##### 3.2.1.1 分核策略 参考库上类似算子Range,LinSpace,128个数据对齐,少于128个数据的单核,大于128数据的按128对齐后均分核 ``` totalLength: 总元素个数 totalCoreNum: AI Core总数 usedCoreNum: 实际使用的核数 分核逻辑: if (totalLength <= 128) { usedCoreNum = 1; // 小数据量单核处理 } else { // 128个数据对齐切分 numOfPerCore = Align128Ceil(totalLength / totalCoreNum); usedCoreNum = min(totalLength / numOfPerCore, totalCoreNum); } ``` ##### 3.2.1.2 数据分块和内存优化策略 UB总空间减去预留空间,再除以输出数据类型的字节数,再除以计算中间ub占用块(需要考虑开启Double Buffer)的情况, 对于非complex输入,数据直接拷贝到输出GM,需要UB空间为2(Double Buffer) 对于comoplex输入,数据需要拷贝到ub,提取实数,再拷贝输出,需要UB空间为 3(输入+输出,其中输入是输出的2倍) * 2(Double Buffer)= 6 | 输入类型 | inQueue | outQueue | 总倍数 | 说明 | |---------|---------|----------|:------:|------| | complex | 2x | 1x | 6 | 输入需存储完整复数(2x),双缓冲 | | real | 共享 | 共享 | 2 | TQueBind复用buffer | 具体实现公式参考如下代码块 ```cpp // 根据输入类型选择不同的UB倍数 bool isComplexInput = (inputDtype == DT_COMPLEX32 || inputDtype == DT_COMPLEX64); int64_t ubMultiplier = isComplexInput ? 6 : 2; // complex需要额外空间存放复数数据 // 计算单次循环可处理的元素数 int64_t ubAvailable = totalUbSize - RESERVED_UB_SIZE; // 预留256字节 int64_t ubOneLoopNum = Align128FloorSize(ubAvailable / (outputSize * ubMultiplier)); ``` ##### 3.2.1.3 tilingKey规划策略 根据输入类型确定tilingKey | 输入类型 | tilingKey | |---------|---------| | complex32 | 1 | | complex64 | 2 | | complex128 | -预留 | | float16 | 4 | | float32 | 5 | ```cpp enum class RealTilingKey : int64_t { TILINGKEY_COMPLEX32 = 1, // complex32 -> float16 TILINGKEY_COMPLEX64 = 2, // complex64 -> float TILINGKEY_FLOAT16 = 4, // float16 -> float16 (identity) TILINGKEY_FLOAT = 5 // float -> float (identity) }; ``` #### 3.2.2 kernel侧设计 ##### 3.2.2.1 kernel侧实现描述 Real算子针对不同输入类型采用不同的处理策略: 1. **复数输入(complex32/complex64)**: - 使用 GatherMask API提取复数实部 - 复数在内存中以交织方式存储:[real0, imag0, real1, imag1, ...] - 通过mask模式提取偶数索引位置的元素(实部) 2. **实数输入(float/float16)**: - 使用 TQueBind 实现零拷贝identity操作 - 输入输出共享同一块UB buffer,减少内存拷贝开销 ##### 3.2.2.2 AscendC实现流程图 ![](https://gitcode.com/alfengyuan/ops-math/blob/master/math/real/docs/ascendc.png) ##### 3.2.2.3 TBE与AscendC实现流程图存在的差异点和原因 **整体架构对比:** ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 实现架构对比 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ TBE 架构: AscendC 架构: │ │ ┌──────────┐ ┌──────────┐ │ │ │ 用户代码 │ │ 用户代码 │ │ │ │(Python) │ │ (C++) │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │TBE DSL │ │AscendC │ │ │ │real.py │ │API调用 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ TVM │ │ 编译器 │ │ │ │IR生成 │ │直接编译 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │自动调度 │ │手动调度 │ │ │ │优化 │ │优化 │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ └──────────┬───────────────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ MOVEMASK │ │ │ │ 硬件指令 │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` **详细对比表:** | 对比维度 | TBE实现 | AscendC实现 | 说明 | |---------|---------|------------|------| | **编程语言** | Python DSL | C++ Template | TBE更简洁,AscendC更底层 | | **调用入口** | real.py:real() | real.cpp:real() | 算子注册入口 | | **计算定义** | real_compute() | RealKernel::Process() | 计算逻辑定义 | | **API调用** | tbe.real(input) | GatherMask(dst, src, mode=1) | 高层API对比 | | **中间表示** | TVM IR (tir.real) | 无中间层 | TBE通过TVM IR | | **类型分发** | 运行时 if/else | 编译期 constexpr if | AscendC编译期优化 | | **形状分类** | classify() 自动 | 无需分类 | TBE支持多shape自动处理 | | **多核切分** | auto_schedule() 自动 | 手动计算 | TBE自动,AscendC手动 | | **UB切分** | auto_schedule() 自动 | 手动计算 ubMultiplier | TBE自动,AscendC手动 | | **双缓冲** | 框架自动管理 | 手动管理 TQue | TBE自动,AscendC手动 | | **流水线** | 框架自动优化 | 手动优化 | TBE自动优化 | | **指令映射** | "elewise_single_real""vector_real" | GatherMask(mode=1)MOVEMASK | 最终相同 | | **实数处理** | elewise_single_VS_add(x, 0) | TQueBind Identity | 实数类型优化方式不同 | | **编译产物** | .o / .json / .bin | .o / .bin | 构建产物略有差异 | **数据流对比:** ``` TBE数据流: AscendC数据流: ──────────── ──────────── GM → UB → Compute → UB → GM GM → UB → Compute → UB → GM ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ │ │ │ │ │ │ │ │ auto auto auto auto 手动 手动 手动 手动 ``` **关键差异原因:** 1. **设计理念不同**: - TBE:声明式编程,描述"做什么",框架自动优化"怎么做" - AscendC:命令式编程,明确指定"怎么做" 2. **自动化程度不同**: - TBE:高度自动化(分核、UB切分、双缓冲、流水线) - AscendC:手动控制所有细节 3. **灵活性不同**: - TBE:快速开发,但优化空间受限 - AscendC:开发复杂,但优化空间更大 4. **底层实现相同**: - 两者最终都调用 **MOVEMASK** CCE指令 - 复数内存布局相同:[r0,i0, r1,i1, ...] - 提取原理相同:提取偶数索引元素 差异的原因,tbe实现分核逻辑是框架自动调优的,AscendC实现参考的库上Range算子,和Linspace算子。 ### 3.3 支持硬件 | 支持的芯片版本 | 是否支持 | |---------|---------| | 香橙派OrangePi AIpro | 不支持 | | Atlas 200I/500 A2推理产品 | 不支持 | | Atlas 800I/T A2 | 支持 | ### 3.4 算子约束限制 - complex128 由AICPU原生支持,aclnn层面路由 - 不支持广播 ## 四、 特性交叉分析 ## 五、 可维可测分析 ### 5.1 精度标准/性能标准 精度和TBE保持完全一致。 性能参考Real算子任务书,有如下要求: - 算子整体性能需与原TBE实现算子持平 - 暂仅要求所有核参与计算场景下,性能不低于原TBE算子的 95%。 - 如小shape无法达标(10us以下场景相差3us),提供性能仿真图和分析结论证明AscendC实现和TBE完全一致或优于TBE实现 ### 5.2 兼容性分析 - proto算子原型,legacy仓有一份旧的,要完全兼容旧的 See merge request: cann/ops-math!17742 个月前
math仓的doc tools 工具检测的低错问题 Co-authored-by: caiwenwen<caiwenwen6@h-partners.com> # message auto-generated for no-merge-commit merge: !2461 merge master into master math仓的doc tools 工具检测的低错问题 Created-by: caiwenwen Commit-by: caiwenwen Merged-by: cann-robot Description: ## 描述 处理math仓的doc tools 工具检测的低错问题,包括markdown低错、htlm标签合入、链接是否可以正常跳转 ## 关联的Issue #关联issue#1262 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 更新全部文档 ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [ ] 新特性 - [ ] 性能优化 - [x] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!24611 个月前
README.md

Real

产品支持情况

产品 是否支持
Atlas A2 训练系列产品/Atlas A2 推理系列产品

功能说明

  • 算子功能:提取复数张量的实部(real part)。对于实数类型输入,输出等于输入(恒等操作)。

  • 计算公式:

outputi=real(inputi)={Re(inputi),if inputi is complexinputi,if inputi is realoutput_i=\text{real}(input_i)=\begin{cases} \text{Re}(input_i), & \text{if } input_i \text{ is complex} \\ input_i, & \text{if } input_i \text{ is real} \end{cases}

  • 与PyTorch对应:torch.real()
  • 与NumPy对应:np.real()

参数说明

参数名 输入/输出/属性 描述 数据类型 数据格式
input 输入 待提取实部的输入张量。 COMPLEX32, COMPLEX64, COMPLEX128, FLOAT16, FLOAT ND
output 输出 提取出的实部张量。 FLOAT16, FLOAT, DOUBLE ND
Tout 属性 可选属性,指定输出数据类型。默认值为DT_FLOAT(float32)。 Int -

数据类型映射

输入类型 输出类型 Tiling Key Tout值 说明
COMPLEX128 DOUBLE - - 提取复数实部 (AICPU only)
COMPLEX32 FLOAT16 1 1 提取复数实部
COMPLEX64 FLOAT 2 0 提取复数实部
FLOAT16 FLOAT16 4 1 恒等操作
FLOAT FLOAT 5 0 恒等操作

注:

  • COMPLEX128 类型仅支持 AICPU 实现,ascend910b 的 AICore 不支持该类型。
  • Tout值为数据类型枚举值(DT_FLOAT=0, DT_FLOAT16=1, DT_DOUBLE=11),可通过Tout属性可选指定输出类型。

约束说明

  • 输入张量的shape必须与输出张量的shape相同
  • 支持动态shape和动态rank
  • 输入数据不能为空

实现说明

目录结构

real/
├── op_host/                    # Host侧实现
│   ├── real_def.cpp           # 算子定义
│   ├── real_infershape.cpp    # Shape推导
│   └── real_tiling.cpp        # Tiling计算实现
├── op_kernel/                  # Kernel侧实现
│   ├── real.cpp               # Kernel入口
│   ├── real_kernel.h          # Kernel模板类实现
│   └── real_tiling.h          # Tiling数据结构定义
├── op_api/                     # API接口
│   ├── aclnn_real.cpp         # ACLNN接口实现
│   ├── aclnn_real.h           # ACLNN接口声明
│   ├── real.cpp               # 算子API实现
│   └── real.h                 # 算子API声明
├── docs/
│   └── aclnnReal.md           # API文档
├── examples/
│   └── test_aclnn_real.cpp    # ACLNN调用示例
└── tests/ut/                   # 单元测试
    ├── op_api/
    │   └── test_aclnn_real.cpp
    ├── op_host/
    │   └── test_real_tiling.cpp
    └── op_kernel/
        ├── test_real.cpp
        └── real_data/
            ├── gen_data.py
            └── compare_data.py

Tiling参数说明

  • totalUsedCoreNum: 实际使用的总核数
  • tailBlockNum: 大核数量(余数block数)
  • ubPartDataNum: 每次UB循环处理的元素数
  • smallCoreDataNum: 小核数据量(元素数)
  • smallCoreLoopNum: 小核UB循环次数
  • smallCoreTailDataNum: 小核最后一次循环的元素数
  • bigCoreDataNum: 大核数据量(元素数)
  • bigCoreLoopNum: 大核UB循环次数
  • bigCoreTailDataNum: 大核最后一次循环的元素数
  • tilingKey: 算子类型标识(1=complex32, 2=complex64, 4=float16, 5=float)
  • useNonInplace: 是否使用非inplace GatherMask路径(0=inplace, 1=非inplace)

多核处理策略(大小核分核)

  1. 对齐粒度

    • Complex类型:128B对齐(满足GatherMask inplace的256B源数据约束)
    • Real类型:32B对齐
  2. 分核策略(参考Exp算子):

    • 按输出数据类型字节数将总数据量对齐到对应block
    • totalBlocks = Align(totalLength * dataTypeLength, alignSize) / alignSize
    • ubPartDataNum >= totalLength:使用1核
    • 否则:coreNum = min(totalCoreNum, totalBlocks)
    • everyCoreBlockNum = totalBlocks / coreNumtailBlockNum = totalBlocks % coreNum
  3. 大小核分配

    • tailBlockNum 个核为大核,数据量 = (everyCoreBlockNum + 1) * alignSize / dataTypeLength
    • 其余核为小核,数据量 = everyCoreBlockNum * alignSize / dataTypeLength
    • 大小核负载差 ≤ 1 个 block
  4. 偏移计算

    • 大核:globalOffset = blockIdx * bigCoreDataNum
    • 小核:globalOffset = blockIdx * bigCoreDataNum - (bigCoreDataNum - smallCoreDataNum) * (blockIdx - tailBlockNum)
    • Complex类型输入:inputOffset = globalOffset * 2(每个元素占2个output元素空间)

Complex双路径策略

GatherMask inplace要求 count * 2 * sizeof(T) % 256 == 0,tiling据此选择路径:

  1. Inplace路径useNonInplace=0):

    • 适用:多核场景 / 单核且totalLength满足256B对齐
    • UB分配:inQueue(2x) × 2缓冲 = 4倍系数
    • GatherMask inplace:GatherMask(src, src, mode=1, ...),pipeline prefetch优化
  2. 非Inplace路径useNonInplace=1):

    • 适用:单核且totalLength不满足256B对齐(如complex32 [4,4]=16元素,16×2×2=64 < 256)
    • UB分配:inQueue(2x) + outQueue(1x) × 2缓冲 = 6倍系数
    • GatherMask非inplace:GatherMask(dst, src, mode=1, mask=count*2, repeatTimes=1)

调用说明

ACLNN API调用

参见 examples/test_aclnn_real.cpp 示例代码:

#include "aclnnop/aclnn_real.h"

// 1. 获取workspace大小
aclnnStatus aclnnRealGetWorkspaceSize(const aclTensor* self,
                                      aclTensor* out,
                                      uint64_t* workspaceSize,
                                      aclOpExecutor** executor);

// 2. 执行算子
aclnnStatus aclnnReal(void* workspace,
                      uint64_t workspaceSize,
                      aclOpExecutor* executor,
                      aclrtStream stream);

注意: ACLNN API使用selfout作为参数名,与图模式的input/output不同。

参考文献

贡献说明

贡献者 贡献方 贡献算子 贡献时间 贡献内容
alfengyuan 个人开发者 Real 2026/3/30 新增Real算子