文件最后提交记录最后更新时间
[CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Co-authored-by: gcw_YBIAEfqJ<wangweidong15@huawei.com> # message auto-generated for no-merge-commit merge: !2110 merge cann_0407 into master [CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Created-by: gcw_YBIAEfqJ Commit-by: gcw_YBIAEfqJ Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> Experimental自定义算子:LogAddExp算子支持Ascend950 AscendC实现 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> https://gitcode.com/cann/ops-math/issues/1183 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [x] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!21101 个月前
[CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Co-authored-by: gcw_YBIAEfqJ<wangweidong15@huawei.com> # message auto-generated for no-merge-commit merge: !2110 merge cann_0407 into master [CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Created-by: gcw_YBIAEfqJ Commit-by: gcw_YBIAEfqJ Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> Experimental自定义算子:LogAddExp算子支持Ascend950 AscendC实现 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> https://gitcode.com/cann/ops-math/issues/1183 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [x] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!21101 个月前
[CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Co-authored-by: gcw_YBIAEfqJ<wangweidong15@huawei.com> # message auto-generated for no-merge-commit merge: !2110 merge cann_0407 into master [CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Created-by: gcw_YBIAEfqJ Commit-by: gcw_YBIAEfqJ Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> Experimental自定义算子:LogAddExp算子支持Ascend950 AscendC实现 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> https://gitcode.com/cann/ops-math/issues/1183 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [x] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!21101 个月前
[CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Co-authored-by: gcw_YBIAEfqJ<wangweidong15@huawei.com> # message auto-generated for no-merge-commit merge: !2110 merge cann_0407 into master [CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Created-by: gcw_YBIAEfqJ Commit-by: gcw_YBIAEfqJ Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> Experimental自定义算子:LogAddExp算子支持Ascend950 AscendC实现 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> https://gitcode.com/cann/ops-math/issues/1183 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [x] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!21101 个月前
[CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Co-authored-by: gcw_YBIAEfqJ<wangweidong15@huawei.com> # message auto-generated for no-merge-commit merge: !2110 merge cann_0407 into master [CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Created-by: gcw_YBIAEfqJ Commit-by: gcw_YBIAEfqJ Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> Experimental自定义算子:LogAddExp算子支持Ascend950 AscendC实现 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> https://gitcode.com/cann/ops-math/issues/1183 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [x] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!21101 个月前
[CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Co-authored-by: gcw_YBIAEfqJ<wangweidong15@huawei.com> # message auto-generated for no-merge-commit merge: !2110 merge cann_0407 into master [CANNBot]LogAddExp算子支持Ascend950 AscendC实现 #2105 Created-by: gcw_YBIAEfqJ Commit-by: gcw_YBIAEfqJ Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> Experimental自定义算子:LogAddExp算子支持Ascend950 AscendC实现 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> https://gitcode.com/cann/ops-math/issues/1183 ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] Bug修复 - [x] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-math!21101 个月前
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

LogAddExp 自定义算子

功能说明

LogAddExp 算子计算两个输入张量的 log-sum-exp 运算:

logaddexp(x, y) = max(x, y) + ln(1 + e^(-|x - y|))

该公式等价于 ln(e^x + e^y),但采用数值稳定形式,可避免直接计算 e^x + e^y 时的上溢出问题。

对标:PyTorch torch.logaddexp

支持规格

数据类型

输入 x 输入 y 输出 out
float32 float32 float32
float16 float16 float16
bfloat16 bfloat16 bfloat16

注意:x 和 y 的数据类型必须一致。

Shape

  • 最大维度数:3(支持 1D、2D、3D)
  • 支持广播:x 和 y 满足 NumPy 广播规则

广播规则

支持以下广播模式:

广播模式 示例
标量广播 [1] + [N][N]
单维度广播 [1, N] + [M, N][M, N]
双向广播 [M, 1] + [1, N][M, N]
维度扩展 [N] + [M, N][M, N]
3D 多维广播 [1, 1, N] + [B, M, N][B, M, N]

目标芯片

  • Ascend 910B3(arch32 架构)

使用方法

aclnn API 调用

#include "aclnn/acl_meta.h"

// 第一步:获取 workspace 大小和执行器
uint64_t workspaceSize = 0;
aclOpExecutor* executor = nullptr;
auto ret = aclnnLogAddExpGetWorkspaceSize(
    x_tensor,         // 输入张量 x
    y_tensor,         // 输入张量 y
    output_tensor,    // 输出张量
    &workspaceSize,   // 输出:workspace 大小
    &executor         // 输出:执行器句柄
);

// 第二步:分配 workspace 内存
void* workspace = nullptr;
if (workspaceSize > 0) {
    aclrtMalloc(&workspace, workspaceSize, ACL_MEM_MALLOC_NORMAL_ONLY);
}

// 第三步:执行算子
ret = aclnnLogAddExp(workspace, workspaceSize, executor, stream);

// 第四步:同步并释放资源
aclrtSynchronizeStream(stream);
if (workspace) aclrtFree(workspace);

张量创建示例

// 创建 float32 张量,shape [4, 8]
std::vector<int64_t> shape = {4, 8};
aclTensor* tensor = aclCreateTensor(
    shape.data(), shape.size(),
    ACL_FLOAT,          // 数据类型
    nullptr, 0,         // strides(nullptr 表示连续)
    0,                  // offset
    ACL_FORMAT_ND,      // 格式
    device_ptr          // 设备内存指针
);

完整示例参考

参见 tests/st/test_aclnn_log_add_exp.cpp,其中包含完整的初始化、数据准备、调用和精度比对流程。

精度说明

数据类型 精度标准 真实 NPU 表现 备注
float32 rtol=1e-4 100% 通过 全量 23 条用例
float16 rtol=1e-3 88.9% 通过 2 条边缘用例失败,均为单元素精度超限
bfloat16 rtol=1e-3 93.3% 通过 1 条边缘用例失败,为单元素精度超限

说明:fp16/bf16 失败用例均为极端边缘情况,失败元素集中在小负数区域(-0.08 ~ -0.02),属于 fp16/bf16 格式固有的精度限制,并非算子实现问题。中间计算已使用 fp32 升精度(Cast→fp32→Cast back)。

构建方法

前提条件

  • CANN Toolkit 已安装(路径:/home/developer/Ascend/cann-9.0.0 或其他版本)
  • 已设置环境变量:source /home/developer/Ascend/cann-9.0.0/bin/setenv.bash

编译自定义算子包

cd ops/log_add_exp
bash build.sh

编译成功后,算子包位于 build/custom_opp_ubuntu_aarch64.run

安装算子包

bash build/custom_opp_ubuntu_aarch64.run

算子安装到:/home/developer/Ascend/latest/vendors/log_add_exp_custom/

测试方法

运行 UT(单元测试)

cd tests/ut
mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug
make -j4
./log_add_exp_ut

预期结果:40/40 PASS

运行 ST(系统测试)

cd tests/st
bash run.sh

默认运行 59 条测试用例。

ST 测试支持两种模式:

  • Mock 模式(CPU Golden):无需 NPU,用于开发验证
  • 真实 NPU 模式:需要 NPU 设备,验证实际精度

运行性能测试

cd tests/st
bash run_performance.sh

目录结构

ops/log_add_exp/
├── README.md                          # 本文档
├── CMakeLists.txt                     # 顶层构建脚本
├── build.sh                           # 编译脚本
├── op_host/                           # Host 侧实现
│   ├── log_add_exp_def.cpp            # 算子定义(aclnn API 注册)
│   ├── log_add_exp_infershape.cpp     # InferShape(广播规则实现)
│   └── arch32/
│       └── log_add_exp_tiling.cpp    # Tiling 实现(含广播分析)
├── op_kernel/                         # Device 侧实现
│   └── arch32/
│       └── log_add_exp.h             # Kernel 实现(核心计算逻辑)
├── tests/
│   ├── st/                            # 系统测试
│   │   ├── test_aclnn_log_add_exp.cpp # ST 测试工程(59 条用例)
│   │   ├── CMakeLists.txt
│   │   └── run.sh                     # ST 运行脚本
│   └── ut/                            # 单元测试
│       └── log_add_exp_ut.cpp         # UT(40 条用例)
├── docs/
│   ├── DEVELOPMENT_LOG.md             # 开发日志
│   ├── REQUIREMENT_ANALYSIS.md        # 需求分析文档
│   ├── DETAILED_DESIGN.md             # 详细设计文档
│   ├── log_add_exp_TEST_DESIGN.md     # 测试设计文档
│   └── PERFORMANCE_REPORT.md          # 性能报告
└── build/                             # 编译输出目录
    └── custom_opp_ubuntu_aarch64.run  # 算子包

实现说明

核心计算步骤

Kernel 内部将公式分解为以下 8 步向量运算:

tmp = x - y          (Sub)
tmp = |tmp|          (Abs)
tmp = -tmp           (Muls, factor=-1)
tmp = e^tmp          (Exp)
tmp = tmp + 1        (Adds, scalar=1)
tmp = ln(tmp)        (Ln)
out = max(x, y)      (Max)
out = out + tmp      (Add)

精度保证

  • fp32:全程 fp32 计算,精度最高
  • fp16/bf16:输入 Cast 升至 fp32,执行 8 步计算,结果 Cast 回原始类型

广播实现

广播通过 stride=0 + 逐元素索引计算实现,无需展开数据,内存高效。广播开销 < 0.2%(相比非广播场景)。