CANN稀疏算子编码规范 AscendC 编码规则 R5-R10【免费下载链接】ops-sparse本项目是CANN提供的高性能稀疏矩阵计算的算子库专注于优化稀疏矩阵的计算效率。项目地址: https://gitcode.com/cann/ops-sparseR5: 圈复杂度 ≤ 20函数的 Cyclomatic Complexity 不超过 20超过需拆分子函数。错误示例圈复杂度超标的长函数// CCN 1基础 1if 1for 1if ... 23 void ProcessMatrix(int m, int n, int k, const float* A, const float* B, float* C) { if (m 0) { for (int i 0; i m; i) { if (i % 2 0) { ProcessEvenRow(i, A, B, C, n, k); } else { ProcessOddRow(i, A, B, C, n, k); } // ... 还有 20 行条件判断 } } else if (m 0) { ClearZero(C, n, k); } else { HandleError(); } }正确示例拆分成子函数// CCN 3 (m 0, i%20, m 0) void ProcessMatrix(int m, int n, int k, const float* A, const float* B, float* C) { if (m 0) { ProcessRows(0, m, A, B, C, n, k); } else { HandleMatrixZeroOrError(m, C, n, k); } } // CCN 2 (i%20 分支) void ProcessRows(int start, int end, ...) { for (int i start; i end; i) { (i % 2 0) ? ProcessEvenRow(...) : ProcessOddRow(...); } }计算方式按分支数量if/else if每出现一次 1for/while每出现一次 1caseswitch 分支每出现一次 1/||逻辑运算每出现一次 1R6: 嵌套深度 ≤ 5最大嵌套层级不超过 5超过需提取内层循环/分支为独立函数。错误示例嵌套深度 7 层void CopyBlocks(...) { for (int batch 0; batch numBatches; batch) { // 1 for (int block 0; block numBlocks; block) { // 2 for (int tile 0; tile numTiles; tile) { // 3 for (int row 0; row tileHeight; row) { // 4 for (int col 0; col tileWidth; col) { // 5 if (mask[batch][block][tile][row][col]) { // 6 if (validElement(batch, block, tile, row, col)) { // 7 ← 超标 dst[...] src[...]; } } } } } } } }正确示例拆分为单层处理函数void CopyBlocks(...) { for (int batch 0; batch numBatches; batch) { for (int block 0; block numBlocks; block) { CopyBlockBatch(batch, block, ...); } } } // 嵌套深度3tile row col void CopyBlockBatch(int batch, int block, ...) { for (int tile 0; tile numTiles; tile) { CopyTile(batch, block, tile, ...); } } // 嵌套深度4row col mask valid void CopyTile(int batch, int block, int tile, ...) { for (int row 0; row tileHeight; row) { CopyTileRow(batch, block, tile, row, ...); } } // 嵌套深度4col mask validCheck valid void CopyTileRow(int batch, int block, int tile, int row, ...) { for (int col 0; col tileWidth; col) { if (mask[...]) { CopyIfValid(batch, block, tile, row, col, src, dst); } } }R7: 函数行数 ≤ 50 (NBNC)NBNCNon-Blank Non-Comment lines非空非注释行不超过 50超过需拆分为多个函数。统计方式空行不算纯注释行以//或/* */开头不算混合行代码 注释只计代码部分函数签名 函数体开闭括号{/}各算 1 行模板函数template ...不计行错误示例NBNC 65 行template typename T void ComputeSpMV( __gm__ T* a, __gm__ T* x, __gm__ T* y, const SpMVTilingData tiling, int batchCount) { __gm__ T* outPtr y; __gm__ T* matrixPtr a; __gm__ T* vectorPtr x; int m tiling.m; int n tiling.n; T alpha tiling.alpha; T beta tiling.beta; // ... 60 行逻辑处理 return; }正确示例按功能拆分template typename T void ComputeSpMV( __gm__ T* a, __gm__ T* x, __gm__ T* y, const SpMVTilingData tiling, int batchCount) { // NBNC 15 PreparePointers(a, x, y, tiling); for (int b 0; b batchCount; b) { ComputeOneBatch(b); } WriteBackResults(y); }R8: 除零防御除法/取模运算的被除数必须校验非零特别是来自外部输入的变量如coreNum、blockCount。错误示例coreNum可能为 0void TilingKernel(int totalElements, int coreNum) { int perCore totalElements / coreNum; // ← 风险coreNum 可能为 0 int remainder totalElements % coreNum; // ← 同样风险 // ... }正确示例先校验再运算void TilingKernel(int totalElements, int coreNum) { if (coreNum 0) { OP_LOGE(TilingKernel, coreNum must be positive, got %d, coreNum); return; } int perCore totalElements / coreNum; int remainder totalElements % coreNum; // ... }特别关注所有通过GetAivCoreCount获取的数值都可能返回 0获取失败必须先判零再用于除法。R9: 许可证头所有源码文件.cpp / .h / .c必须包含标准许可证头CSV 文件除外。标准许可证头模板/** * Copyright (c) 2026 Huawei Technologies Co., Ltd. * This program is free software, you can redistribute it and/or modify it under the terms and conditions of * CANN Open Software License Agreement Version 2.0 (the License). * Please refer to the License for details. You may not use this file except in compliance with the License. * THIS SOFTWARE IS PROVIDED ON AN AS IS BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. * See LICENSE in the root of the software repository for the full text of the License. */例外文件.csv测试用例表.gitignore/.clang-format等配置文件自动生成的文件在文件顶部注明自动生成来源R10: 禁止 extern 引用禁止在 Kernel/Host 代码中使用extern C声明外部函数接口应通过头文件 include 引入。错误示例直接 extern 声明 kernel_do// 在 host.cpp 中直接 extern 声明 extern C void spmv_kernel_do(uint8_t* x, uint8_t* y, uint8_t* workSpace, uint32_t numBlocks, const SpMVTilingData tiling, void* stream);正确示例通过头文件引入// spmv_host.cpp #include spmv_kernel.h // kernel_do 在该头文件中声明 // spmv_kernel.h #pragma once void spmv_kernel_do(/* ... */);例外在 kernel.cpp 中声明 kernel 入口函数时可以使用extern C这是 Ascend C 的要求。【免费下载链接】ops-sparse本项目是CANN提供的高性能稀疏矩阵计算的算子库专注于优化稀疏矩阵的计算效率。项目地址: https://gitcode.com/cann/ops-sparse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考