API Interface Design Standards
Comparison of Three API Types
| Dimension | Basic API (basic_api) | High-level API (adv_api) | C API (c_api) |
|---|---|---|---|
| Function naming | UpperCamelCase: Add, Mul |
UpperCamelCase: Exp, Axpy |
asc_ prefix + snake_case: asc_add |
| Abstraction level | Direct mapping to hardware instructions | Encapsulates basic APIs to implement algorithms | Direct mapping to hardware instructions |
| Parameter style | LocalTensor<T>& |
LocalTensor<T>& + sharedTmpBuffer |
__ubuf__ T* pointer |
| Documentation style | @ingroup / @brief |
\brief / \param / \note |
Concise comments |
| Public entry | kernel_operator.h |
kernel_api.h |
asc_simd.h |
| Implementation location | impl/basic_api/ |
impl/adv_api/detail/<category>/<api>/ |
impl/c_api/ |
| Namespace | AscendC |
AscendC |
None (C style) |
Interface Design Principles
Output Parameters First
Output parameters precede input parameters:
// Correct: dst (output) comes first
void Add(const LocalTensor<T>& dst, const LocalTensor<T>& src0, const LocalTensor<T>& src1, ...);
Exception: In Tiling interfaces, output parameters are reference types (
uint32_t&) and are placed at the end of the parameter list by C++ convention:void GetAxpyMaxMinTmpSize(const AscendC::TensorShape& srcShape, const uint32_t typeSize, const bool isReuseSource, uint32_t& maxValue, uint32_t& minValue);
Data Flow Mode Support
Three data flow modes are supported:
- Continuous mode: fixed count parameter
- High-dimensional tiling mode: repeat + block_stride + repeat_stride parameters
- Synchronous mode: Depending on API type and actual need, C API uses
_syncsuffix, some C++ APIs useSyncsuffix
Parameter Naming Consistency
Parameters with the same semantics keep consistent naming across different APIs:
| Semantic | Parameter name |
|---|---|
| Destination operand | dstTensor / dst |
| Source operand | srcTensor / src0, src1 |
| Element count | calCount / count |
| Temporary buffer | sharedTmpBuffer / tmpBuffer |
| Iteration count | repeat / repeatTime |
| Address stride | block_stride / dstBlkStride |
| Mask | mask / mask0, mask1 |
Template Parameter Conventions
Type Parameters
- High-level API:
Tis the dst type,Uis the src type - Basic API:
Tis the data type
// High-level API — T=dst, U=src
template <typename T, typename U, bool isReuseSource = false>
__aicore__ inline void Axpy(const LocalTensor<T>& dstTensor, const LocalTensor<U>& srcTensor, ...);
// Basic API — T is unified
template <typename T>
__aicore__ inline void Add(const LocalTensor<T>& dst, const LocalTensor<T>& src0, ...);
Template Parameter Declaration
AlwaysBreakTemplateDeclarations: true (clang-format configuration) requires a line break between the template declaration and the subsequent function/class declaration:
template <typename T, typename U, bool isReuseSource = false>
__aicore__ inline void Axpy(...);
Reserved Parameters
Parameters that may be used in the future are given default values, with names starting with is to indicate boolean configuration:
bool isReuseSource = false
Algorithm Parameters
Use explicit types and meaningful names:
uint8_t taylorExpandLevel // Taylor expansion order
ReduceDim reduceDim // Reduction dimension
EngineType engine // Compute engine
Companion Attributes
| Attribute | Semantic | Example |
|---|---|---|
__gm__ |
global memory address space | __gm__ uint8_t* ptr |
__inout_pipe__(V) |
pipeline input/output annotation | __aicore__ inline __inout_pipe__(MTE2) void DataCopy(...) |
__in_pipe__(V) |
pipeline input annotation | __aicore__ inline __in_pipe__(V) void Copy(...) |
__out_pipe__(V) |
pipeline output annotation | __aicore__ inline __out_pipe__(MTE3) void Copy(...) |
__BLOCK_LOCAL__ __inline__ |
block-level thread-local variable | __BLOCK_LOCAL__ __inline__ TPipe* g_tPipePtr |
__ubuf__ |
UB address space | __ubuf__ half* dst |
Tiling Interface Design
Interface Naming
Kernel function Axpy ↔ Tiling function GetAxpyMaxMinTmpSize:
Get<ApiName>MaxMinTmpSize
Get<ApiName>TmpBufferFactorSize
Parameter Conventions
Taking Axpy as an example; different APIs may have different Tiling interface signatures—follow the actual design of similar APIs.
Input Parameters:
const AscendC::TensorShape& srcShape— input shape informationconst uint32_t typeSize— data type size (bytes)const bool isReuseSource— whether modifying the source operand is allowed (currently false)
Output Parameters (references):
uint32_t& maxValue— required maximum temporary spaceuint32_t& minValue— required minimum temporary space
Return value: void
Implementation Location
- Declaration:
include/adv_api/<category>/<api>_tiling.h - Implementation:
impl/adv_api/tiling/<category>/<api>_tiling_impl.cpp(or_tiling.cpp) - Registration: add the
.cppto thetiling_apitarget inimpl/adv_api/tiling/CMakeLists.txt
Constant Definitions
Tiling constants are defined with constexpr in the implementation file:
constexpr uint32_t AXPY_HALF_CALC_PROC = 4;
constexpr uint32_t AXPY_FLOAT_CALC_PROC = 1;
constexpr uint32_t AXPY_ONE_REPEAT_BYTE_SIZE = 256;
Assertion Usage
On the Tiling side, use ASCENDC_HOST_ASSERT instead of ASCENDC_ASSERT:
ASCENDC_HOST_ASSERT(inputSize > 0, return, "Input Shape size must be greater than 0.");
Public Header File Registration
High-level API Registration
After adding a new high-level API, you need to add include in the following files:
include/adv_api/kernel_api.h:
#include "math/axpy.h"
Architecture guards are managed internally by each sub-header file; kernel_api.h includes them directly.
include/adv_api/tiling_api.h:
#include "math/axpy_tiling.h"
Basic API Registration
Newly added basic APIs are registered in the corresponding main entry, for example kernel_operator.h.
Architecture Guards
- APIs supporting multiple architectures: list all supported architectures in
#if defined(__NPU_ARCH__) - APIs supporting only a specific architecture: restrict the architecture scope at include time
Interface and Implementation Separation
Public Header Files (include/)
- Contain interface documentation and inline forwarding definitions
#includethe corresponding architecture impl header before the forwarding definitions- Annotated with
__aicore__
Implementation Header Files (impl/)
- Contain
#pragma messagewarnings - For high-level API, architecture dispatch is performed by the public header via
#if __NPU_ARCH__selecting the corresponding impl file (e.g.,axpy_3510_impl.horaxpy_common_impl.h); for basic API, dispatch is performed by the*_intf_impl.hheader - Contain the concrete algorithm logic
Interface Implementation Patterns
High-level API Implementation Template
// include/adv_api/<category>/<api>.h
template <typename T, bool isReuseSource = false>
__aicore__ inline void ApiName(const LocalTensor<T>& dstTensor,
const LocalTensor<T>& srcTensor, ...)
{
ApiNameImpl<T, isReuseSource>(dstTensor, srcTensor, ...);
}
// impl/adv_api/detail/<category>/<api>/<api>_common_impl.h
template <typename T, bool isReuseSource>
__aicore__ inline void ApiNameImpl(const LocalTensor<T>& dstTensor,
const LocalTensor<T>& srcTensor, ...)
{
CHECK_FUNC_HIGHLEVEL_API(ApiName, (T, isReuseSource),
(dstTensor, srcTensor, ...));
// Implementation logic...
}
Algorithm Function and Intrinsics Separation
Complex APIs separate the public interface, algorithm parameter decomposition, and low-level intrinsics:
ApiName(...)— public interface (public header)ApiNameImpl(...)— algorithm parameter decomposition (impl header)ApiNameSub(...)— tiling loop logic (impl header)ApiNameIntrinsicsImpl(...)— low-level instruction calls (impl header)