CoshV2 算子
Ascend C 自定义算子,逐元素计算输入 tensor 的双曲余弦值。对标 PyTorch torch.cosh(input) 接口。
算子说明
数学公式
out = cosh(self) = (exp(self) + exp(-self)) / 2
实际实现使用数值稳定公式,避免中间结果溢出:
cosh(x) = exp(|x| - ln2) + exp(-|x|) / 2
支持规格
| 项目 | 说明 |
|---|---|
| 目标芯片 | Ascend 910B3 (arch32, DAV_2201) |
| CANN 版本 | 9.0.0 |
| 数据类型 | float16, float32, bfloat16 |
| 调用方式 | ACLNN 两段式接口 |
| 输入维度 | 任意 shape,最大 8 维 |
| 数据格式 | ND |
ACLNN 接口
// 第一段:计算 workspace 大小
aclnnStatus aclnnCoshV2GetWorkspaceSize(
const aclTensor* self,
aclTensor* out,
uint64_t* workspaceSize,
aclOpExecutor** executor);
// 第二段:执行计算
aclnnStatus aclnnCoshV2(
void* workspace,
uint64_t workspaceSize,
aclOpExecutor* executor,
aclrtStream stream);
精度标准
| 数据类型 | 精度标准 | 说明 |
|---|---|---|
| float16 | 双千分之一 | 相对误差 < 0.001 的比例 >= 99.9% |
| float32 | 双万分之一 | 相对误差 < 0.0001 的比例 >= 99.99% |
| bfloat16 | 双千分之一 | 中间计算使用 float32 |
特殊值处理
| 输入 | 输出 | 说明 |
|---|---|---|
| 0 | 1.0 | cosh(0) = 1 |
| +inf | +inf | 正无穷 |
| -inf | +inf | cosh 为偶函数 |
| NaN | NaN | 保持 NaN |
目录结构
cosh/
├── CMakeLists.txt # 顶层构建配置
├── build.sh # 一键构建脚本
├── op_host/ # Host 侧实现
│ ├── cosh_v2_def.cpp # 算子原型注册
│ ├── cosh_v2_infershape.cpp # Shape 推导
│ ├── CMakeLists.txt
│ └── arch32/
│ └── cosh_v2_tiling.cpp # Tiling 实现 (Ascend910B)
├── op_kernel/ # Kernel 侧实现
│ ├── cosh_v2_arch32.cpp # Kernel 入口
│ ├── CMakeLists.txt
│ └── arch32/
│ ├── cosh.h # Kernel 类定义与计算逻辑
│ ├── cosh_v2_tiling_data.h # TilingData 结构体
│ └── cosh_v2_tiling_key.h # TilingKey 模板参数定义
├── tests/ # 测试
│ ├── ut/ # 单元测试 (Host 侧 Tiling + InferShape)
│ └── st/ # 系统测试 (ACLNN 端到端)
├── probe/ # 穿刺验证工程
└── docs/ # 文档
├── DEVELOPMENT_LOG.md # 开发日志
├── REQUIREMENT_ANALYSIS.md # 需求分析
├── cosh_DETAILED_DESIGN.md # 详细设计
├── cosh_ITERATION_PLAN.md # 迭代计划
├── cosh_TEST_DESIGN.md # 测试设计
├── final_precision_report.md # 精度验收报告
└── final_code_review_report.md # 代码检视报告
构建方法
环境要求
- CANN 9.0.0 已安装
ASCEND_HOME_PATH环境变量已设置(如/home/developer/Ascend/ascend-toolkit/latest)- GCC 9.4.0+, C++17
编译算子包
# 编译(生成 Kernel 二进制 + 安装包)
bash build.sh --soc=ascend910b -j8
# 清理构建产物
bash build.sh --make_clean
编译成功后产物:
- Kernel 二进制:
build/op_kernel/ascendc_kernels/binary/ascend910b/ - 安装包:
build/custom_opp_ubuntu_aarch64.run
安装算子包
# 安装自定义算子包
./build/custom_opp_ubuntu_aarch64.run --full
运行时配置
# 配置自定义算子库路径
export LD_LIBRARY_PATH=<安装路径>/vendors/cosh_v2_custom/op_api/lib/:$LD_LIBRARY_PATH
测试方法
运行单元测试 (UT)
# 方法一:通过 build.sh
bash build.sh --soc=ascend910b -u
# 方法二:直接运行
cd tests/ut && ./run.sh
UT 测试内容:
- InferShape 测试(6 条):1D/多维/4D/动态/大 shape/标量
- Tiling 测试(73 条):fp16/fp32/bf16 各路径、单/双缓冲、边界值、阈值、多核分配
运行系统测试 (ST)
# 方法一:通过 build.sh(需先安装算子包)
bash build.sh --soc=ascend910b -s
# 方法二:直接运行
cd tests/st && bash run.sh
# 方法三:一次性运行全部测试
bash build.sh --soc=ascend910b -a
ST 测试内容:
- 端到端 ACLNN 接口调用,在真实 NPU 上执行
- 71 条用例覆盖 3 种 dtype、1D~8D 维度、特殊值、边界值
- 精度对比 CPU golden (std::cosh)
测试用例文件
| 文件 | 说明 |
|---|---|
tests/st/testcases/l0_test_cases.csv |
L0 门槛用例 23 条 |
tests/st/testcases/l1_test_cases.csv |
L1 功能用例 500 条 |
实现要点
- 模板化设计:通过
<typename T, int BUFFER_MODE>模板参数支持 6 个 TilingKey 组合 - 数值稳定性:使用
exp(|x|-ln2)替代exp(x)避免中间溢出 - 统一 fp32 中间计算:fp16/bf16 均 Cast 到 fp32 计算后 Cast 回原类型
- 双缓冲流水:totalNum > 1024 时启用双缓冲,MTE2 与 Vector 计算并行
- DataCopyPad:安全处理非对齐尾块数据搬运
- 动态多核:使用
GetCoreNumAiv()获取核数,禁止写死
测试结果
| 指标 | 结果 |
|---|---|
| UT 通过率 | 79/79 = 100% |
| ST 通过率 | 71/71 = 100% |
| fp16 精度 | 满足双千分之一 |
| fp32 精度 | 满足双万分之一 |
| bf16 精度 | 满足双千分之一 |