CANN opbase 基础张量操作接口(L0 层)详解:Cast、Contiguous、Transpose 等 11 个接口的用法与源码原理

发布时间:2026/9/18 17:47:32
CANN opbase 基础张量操作接口(L0 层)详解:Cast、Contiguous、Transpose 等 11 个接口的用法与源码原理 CANN opbase 基础张量操作接口L0 层详解Cast、Contiguous、Transpose 等 11 个接口的用法与源码原理【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读在 CANN 算子库框架opbase中Level0L0层接口是调用单个 Kernel 的 Host 侧细粒度 API是开发 aclnnLevel2 层接口的基础积木。本文以 docs/zh/api/nnopbase/opdev/L0/basic_l0_Interface.md 为核心系统讲解其收录的Cast、Contiguous、IsNullptr、Pad、ReFormat、Reshape、Slice、TransData、TransDataSpecial、Transpose、ViewCopy共 11 个基础张量操作接口的功能、函数原型、参数约束、调用示例与产品支持情况并结合仓库源码说明 L0 接口的命名空间、执行器创建、入参打包等底层机制。读完本文你将能够在自定义 aclnn 算子开发中熟练使用这些 L0 接口完成张量类型转换、内存布局规整、格式切换、切片与转置等基础操作。L0 接口在 CANN 算子开发体系中的定位Level0 与 Level2 的层级关系从 1_opdev_api_introduction.md 的定义可以看出CANN 的 Host 侧算子开发接口分为两层Level0 层接口L0表示调用单 Kernel 的 Host 侧 API提供细颗粒 API单 Kernel 下发和算子 API 开发的基础结构体如 Tensor 定义等与公共基础能力如 workspace 复用、引擎调度等。上层应用或 L2 层接口可通过 L0 接口的快速组装实现高性能计算。Level2 层接口L2对 L0 层接口的高层级封装内部通过调用单个或多个 L0 接口实现更灵活的功能。对外提供aclnnXxxGetWorkspaceSize与aclnnXxx两段式接口用户直接调用即可完成算子执行。L0 接口的返回值类型是 Tensor 类型结构如aclTensor*、std::tupleaclTensor*, aclTensor*、aclTensorList*最后一个参数固定为aclOpExecutor *executor类型与名称均不可变。L0 接口统一位于namespace l0op命名空间下这一命名空间在 include/nnopbase/opdev/op_dfx.h 中有明确声明。接口命名规范L0 接口名形如{op_type}{format}{dtype}例如l0op::AddNd表示 Add 算子输入均按 ND 格式计算l0op::MatMulNzFp162Fp16表示 MatMul 算子输入输出均按 NZ 格式计算其中2代表 To表示输入输出均为 fp16。L0 接口的头文件分布本文涉及的 11 个基础张量操作接口分布在以下头文件中见 1_opdev_api_introduction.md接口所属头文件Castaclnn_kernels/cast.hContiguous、ViewCopyaclnn_kernels/contiguous.hPadaclnn_kernels/pad.hReshapeaclnn_kernels/reshape.hSliceaclnn_kernels/slice.hTransposeaclnn_kernels/transpose.hTransData、TransDataSpecial、ReFormataclnn_kernels/transdata.hIsNullptraclnn_kernels/op_error_check.h11 个基础张量操作接口总览接口名核心功能一句话使用场景Cast将输入 tensor 转换为指定数据类型bool 转 uint8 后参与整型计算、精度转换Contiguous将非连续 tensor 转换为连续 tensorL2 接口的非连续输入喂给只支持连续输入的 L0 算子ViewCopy将连续 tensor 搬运到连续或非连续 tensor 上将计算结果写入非连续的输出 tensorPad按 paddings 对各维度填充 0张量补维、边界填充Reshape不改数据、转换 shape视图重塑、维度合并Slice从输入 tensor 提取切片分块处理、区域提取Transpose按 perm 重排维度维度交换如 NHWC 与 NCHW 的互换TransData转换 tensor 的 formatNC1HWC0 与 NCHW 等格式互转TransDataSpecial转换 tensor 的 format特殊 C0 规则与 TransData 类似但 C0 处理规则不同ReFormat将 viewFormat/originalFormat/storageFormat 统一为目标 format显式声明 tensor 的 format 视图IsNullptr判断指针是否为空并打印错误日志L0 接口入参的空指针校验数据类型转换Cast功能与原型Cast 将输入 tensor 转换为指定的数据类型const aclTensor *Cast(const aclTensor *self, op::DataType dstDtype, aclOpExecutor *executor)参数说明参数输入/输出说明self输入待转换的输入 tensor数据类型支持 FLOAT16、FLOAT、DOUBLE、BFLOAT16、INT8、UINT8、INT16、UINT16、INT32、UINT32、INT64、UINT64、BOOL、COMPLEX64、COMPLEX128数据格式支持 NDdstDtype输入转换后的目标 dtype支持的数据类型与 self 相同executor输入op 执行器包含了算子计算流程返回值类型为 dstDtype 的 tensor。注意BFLOAT16 仅适用于 Atlas A2 与 Atlas A3 训练/推理系列产品。实战示例bool 参与整型计算算子计算中经常遇到张量为布尔类型但需要进行整型运算的场景。文档给出的标准写法是先通过 Cast 将 bool 统一转换为 uint8// 标准写法创建OpExecutor auto uniqueExecutor CREATE_EXECUTOR(); auto selfCasted self; // 当self为布尔类型时利用Cast接口转换为uint8类型后可进行整型计算 if (self-GetDataType() op::DataType::DT_BOOL) { selfCasted l0op::Cast(self, op::DataType::DT_UINT8, uniqueExecutor.get()); CHECK_RET(selfCasted ! nullptr, ACLNN_ERR_PARAM_NULLPTR); }这里的CREATE_EXECUTOR()宏用于创建一个aclOpExecutor的生成工厂对象UniqueExecutor其定义见 CREATE_EXECUTOR 宏说明而CHECK_RET则是基于 IsNullptr 的常见返回校验宏。连续性与视图转换Contiguous、ViewCopy、ReshapeL2 级 API 的输入 tensor 可能是非连续的而 L0 级算子一般只支持连续 tensor 作为输入因此连续化与视图重排是 L0 接口使用频率最高的基础能力。Contiguous非连续转连续const aclTensor *Contiguous(const aclTensor *x, aclOpExecutor *executor)x待转换的输入 tensor数据类型和数据格式不限制输入不要求是连续内存但要求所表达的数据在 Storage 范围内。executorop 执行器。返回值转换成功返回连续 aclTensor失败返回 nullptr。约束要点输入必须是合法 tensorShape 和 Stride 所表示的数据必须在 Storage 大小范围内。文档给出的反例shape(2, 3), stride(10, 30), storageSize8数据实际空间超过了 Storage 大小 8该 tensor 非法Contiguous 返回 nullptr。// 标准写法创建OpExecutor auto uniqueExecutor CREATE_EXECUTOR(); // self如果非连续需要转换 auto selfContiguous l0op::Contiguous(self, executor);从 include/nnopbase/opdev/tensor_view_utils.h 提供的IsContiguous等工具接口可见连续性与 stride/shape 的关系是 opbase 框架的基础概念Contiguous 正是这类判断与搬运逻辑在 L0 层的封装。ViewCopy连续 tensor 搬运到非连续输出与 Contiguous 互为反向L2 接口的输出 tensor 可能是非连续的需要通过 ViewCopy 把计算得到的连续 tensor 搬运到目标输出上const aclTensor *ViewCopy(const aclTensor *x, const aclTensor *y, aclOpExecutor *executor)x输入 tensor数据类型和数据格式不限制必须保证是连续内存数据。y输出 tensor数据类型和数据格式不限制但数据类型、ViewShape 和数据格式要求与 x 一致。// 标准写法创建OpExecutor auto uniqueExecutor CREATE_EXECUTOR(); // 如果出参out是非连续Tensor需要把计算完的连续Tensor转非连续 auto viewCopyResult l0op::ViewCopy(absResult, out, executor);Reshape不改数据只改 shapeconst aclTensor *Reshape(const aclTensor *x, const op::Shape shape, aclOpExecutor *executor) const aclTensor *Reshape(const aclTensor *x, const aclIntArray *shape, aclOpExecutor *executor)x待转换的输入 tensor数据类型和数据格式不限制必须是连续内存数据。shape转换后的目标 shape支持aclIntArray*、op::Shape即 gert::Shape两种类型。约束说明Reshape 成功的前提是 x 的 ShapeSize 与目标 shape 的 ShapeSize 相等。例如 A 的 shape 为(1, 3, 256, 256)则 A 的 ShapeSize 1*3*256*256。当前不支持转换成空 tensorshape 中包含 0 的空 tensor。void Func(const aclTensor *x, const op::Shape shape, aclOpExecutor *executor) { auto ret l0op::Reshape(x, shape, executor); return; }数据提取与维度重排Slice、Transpose、PadSlice按 offset 和 size 提取切片const aclTensor *Slice(const aclTensor *x, const aclTensor *y, const aclTensor *offset, const aclTensor *size, aclOpExecutor *executor) const aclTensor *Slice(const aclTensor *x, const aclIntArray *offsets, const aclIntArray *size, aclOpExecutor *executor)参数说明参数输入/输出说明x输入输入 tensor数据类型支持 FLOAT16、FLOAT、BOOL、INT8、UINT8、INT16、UINT16、INT32、UINT32、INT64、BFLOAT16、UINT64数据格式支持 NDy输出切片后的输出 tensor数据类型与 x 相同offsets / offset输入表示输入 x 在各个维度切片的起始位置其形状为 x 的维度支持aclIntArray*与aclTensor*数据类型支持 INT32、INT64size输入输入 x 的各个维度切片的大小其形状为 x 的维度支持aclIntArray*、aclTensor*数据类型支持 INT32、INT64返回值类型与输入相同、shape 为 size 的 tensor。BFLOAT16 仅适用于 Atlas A2/A3 训练与推理系列产品。两种调用形态分别对应 host 侧数组与 device 侧 tensor 作为参数// 调用l0op::Slice对每一块进行处理 auto sliceRes l0op::Slice(self, offsetArray, sizeArray, executor); // 调用l0op::Slice对每一块进行处理 auto sliceRes l0op::Slice(xTensor, yTensor, offsetTensor, sizeTensor, executor);Transpose按 perm 重排维度Transpose 不改变 tensor 数据的值只是把输入 x 的 shape 按指定维度的排列顺序 perm 进行转置输出。提供两个重载// 输入和输出为不同地址 const aclTensor *Transpose(const aclTensor *x, const aclTensor *y, const aclTensor *perm, aclOpExecutor *executor) // 输入和输出同一地址原地 const aclTensor *Transpose(const aclTensor *x, const aclIntArray *perm, aclOpExecutor *executor)参数说明参数输入/输出说明x输入/输出原始输入 tensor需是连续内存数据数据类型支持 FLOAT16、FLOAT、INT8、INT16、INT32、INT64、UINT8、UINT16、UINT32、UINT64、BOOL、BFLOAT16数据格式支持 NDy输出转置后输出 tensor数据类型和数据格式同 xperm输入整型数组代表输入 tensor x 的维度支持aclIntArray*、aclTensor*类型最多支持 8 维转置取值需在[0, x的维度数量-1]范围内数据类型支持 INT32、INT64约束说明最多支持 8 维转置x 和 perm 的 dim 至多为 8且输入 x 和 perm 的 dim 维度必须一致。实战示例——结合Contiguous与AllocIntArray的完整流程// 标准写法创建OpExecutor参数检查 auto uniqueExecutor CREATE_EXECUTOR(); CHECK_RET(uniqueExecutor.get() ! nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); // 标准写法将输入self转换成连续的tensor auto selfContiguous l0op::Contiguous(self, uniqueExecutor.get()); CHECK_RET(selfContiguous ! nullptr, ACLNN_ERR_INNER_NULLPTR); int64_t dims selfContiguous-GetViewShape().GetDimNum(); int64_t valuePerm[dims] {0, 2, 1, 3}; // 表示对原始4维的中间2维做转置即交换1轴和2轴 auto perm executor-AllocIntArray(valuePerm, dims); selfContiguous l0op::Transpose(selfContiguous, perm, uniqueExecutor.get());其中executor-AllocIntArray(value, size)由aclOpExecutor提供用于在 host 侧申请并填充 int64 数组对象其声明见 include/nnopbase/opdev/op_executor.h同类接口还包括AllocScalar、AllocTensorList、AllocBoolArray、AllocFloatArray等详见 op_executor 接口说明。Pad按 paddings 各维度填充 0const aclTensor* Pad(const aclTensor* self, const aclTensor* paddings, aclOpExecutor* executor)self待填充的输入 tensor数据类型支持 FLOAT16、FLOAT、INT16、UINT16、INT32、INT64、BFLOAT16、INT8数据格式支持 ND。paddings输入 tensor 每个维度被填充的大小形状为[self.dim, 2]数据类型支持 INT32、INT64数据格式支持 ND。返回被填充了 0 的 tensor。注意BFLOAT16 和 INT8 仅适用于 Atlas A2/A3 训练与推理系列产品//调用l0op::Pad对self进行补维 l0op::Pad(self, paddings, executor);数据格式转换TransData、TransDataSpecial、ReFormatAscend 硬件上张量存在多种数据排布格式如 ND、NCHW、NC1HWC0、NZ 等L0 层提供了三个 format 相关接口。TransData转换到目标 primary formatconst aclTensor *TransData(const aclTensor *x, op::Format dstPrimaryFormat, int64_t groups, aclOpExecutor *executor)x待转换的 tensor数据类型支持 FLOAT16、FLOAT32、INT32、UINT32、INT8、UINT8。dstPrimaryFormat目标 format。groups分组参数用于分组转换时传入数据类型支持 INT64。约束说明当输入 tensor 数据类型为 FLOAT32、INT32、UINT32 时C0 只能按照 8 处理。// 将张量格式从NC1HWC0转换成NCHW auto transGradInput l0op::TransData(gradInputNC1HWC0, op::Format::FORMAT_NCHW, params.groups, executor); CHECK_RET(transGradInput ! nullptr, ACLNN_ERR_INNER_NULLPTR);TransDataSpecial特殊 C0 规则的 format 转换功能与 TransData 类似但当输入 tensor 数据类型为 FLOAT32、INT32、UINT32 时C0 只能按照 16 处理——这是两者最关键的差异实际选型时需根据目标格式的 C0 值决定const aclTensor *TransDataSpecial(const aclTensor *x, op::Format dstPrimaryFormat, int64_t groups, aclOpExecutor *executor)// 标准写法创建OpExecutor auto uniqueExecutor CREATE_EXECUTOR(); // 将gradOutputReFormat的format转换为NC1HWC0 auto gradOutputTransData l0op::TransDataSpecial(gradOutputReFormat, op::Format::FORMAT_NC1HWC0, 0, uniqueExecutor.get());ReFormat统一三种 format 视图与 TransData 不同ReFormat 不做数据重排而是在指定 format 和输入 x 的维度相同时将输入数据格式设置为目标 format。具体来说是把输入 tensor 的viewFormat、originalFormat、storageFormat 统一为指定的 formatconst aclTensor *ReFormat(const aclTensor *x, const op::Format format, aclOpExecutor *executornullptr)x需要被转换的 tensor数据类型支持 FLOAT16、FLOAT32、INT32、UINT32、INT8、UINT8。format目标 format。约束输入 tensor 的维度必须与指定 format 的维度相同。// 将输入reformat成NCHW格式 auto reformatInput l0op::ReFormat(unsqueezedInput, op::Format::FORMAT_NCHW); CHECK_RET(reformatInput ! nullptr, nullptr);关于 viewFormat、originalFormat、storageFormat 的读取与设置接口可参见 common_types 中的 Get/SetViewFormat、Get/SetOriginalFormat、Get/SetStorageFormatReFormat 正是通过统一这三者来实现格式视图的显式声明。参数校验IsNullptr功能与重载IsNullptr 判断输入的指针是否为空若为空指针返回 true 并打印错误日志否则返回 false。它为所有 L0 入参类型都提供了重载static inline bool IsNullptr(const aclTensor *tensor, const char *name) static inline bool IsNullptr(const aclTensorList *tensorList, const char *name) static inline bool IsNullptr(const aclScalar *scalar, const char *name) static inline bool IsNullptr(const aclIntArray *intArr, const char *name) static inline bool IsNullptr(const aclBoolArray *boolArr, const char *name) static inline bool IsNullptr(const aclFloatArray *floatArr, const char *name)name被检查指针的标识。若被检查指针为空打印的错误日志中会输出该标识便于定位是哪个参数为空。封装为通用校验宏文档给出的典型用法是将其封装为通用空指针校验宏配合#param将参数名作为日志标识传入#define OP_CHECK_NULL(param, retExpr) \ if (IsNullptr(param, #param)) { \ retExpr; \ }在实际 L0/L2 接口开发中IsNullptr也是CHECK_RET(param ! nullptr, ...)这类返回检查模式的底层支撑可用于接口入口统一校验避免对空指针继续下发 Kernel 导致异常。L0 接口通用开发模式与底层机制综合前文各示例一个标准的 L0 接口调用流程通常包含四个固定环节其底层机制均有源码支撑创建执行器通过CREATE_EXECUTOR()宏创建aclOpExecutor见 make_op_executor.h 相关宏与 CREATE_EXECUTOR 说明。aclOpExecutor记录整个 host 侧 API 运行的上下文信息如 L2 接口执行过程中的计算图、L0 算子 launch 子任务、workspace 地址和大小等。入参规整对非连续输入先执行l0op::Contiguous对需要 host 侧数组入参如 perm、offsets的场景使用executor-AllocIntArray等分配接口见 op_executor.h。调用 l0op 接口L0 接口统一在namespace l0op下最后一个参数固定为aclOpExecutor *executor。校验返回值所有 L0 接口失败时返回nullptr成功时返回指向新 tensor 的指针原地接口除外必须使用CHECK_RET(... ! nullptr, ...)或IsNullptr校验。此外include/nnopbase/opdev/op_dfx.h 中还定义了 L0 接口开发必须配套使用的宏OP_TYPE_REGISTER(kernelName)用于在 L0 接口最开始处注册 L0 算子L0_DFX(profilingName, ...)用于接口及 L0 接口入参的打印与 profiling 上报。完整的宏使用规范参见 常用宏表。产品支持情况汇总根据各接口文档中的产品支持说明11 个接口在不同硬件平台上的支持情况如下Ascend 950PR/Ascend 950DT均不支持其余以 Atlas 系列为准接口Atlas 训练系列910Atlas 推理系列310pAtlas 200I/500 A2 推理310bAtlas A2 训练/推理910bAtlas A3 训练/推理Cast支持支持支持支持支持Contiguous支持支持支持支持支持ViewCopy支持支持支持支持支持Reshape支持支持支持支持支持Pad支持支持不支持支持支持Slice支持支持不支持支持支持Transpose支持支持不支持支持支持TransData支持支持不支持支持支持TransDataSpecial支持支持不支持支持支持ReFormat支持支持不支持支持支持IsNullptr支持支持不支持支持支持从上表可看出Contiguous、ViewCopy、Reshape、Cast 四个接口在 Atlas 系列全平台支持实现机制为纯内存/视图操作不依赖硬件格式特性而 Pad、Slice、Transpose、TransData 系列与 IsNullptr 在 Atlas 200I/500 A2 推理产品310b上暂不支持开发时需结合目标产品进行能力判断。此外BFLOAT16数据类型Cast、Pad、Slice、Transpose 涉及与INT8Pad 涉及仅在 Atlas A2/A3 训练与推理系列产品上可用。结语CANN opbase 的 L0 基础张量操作接口是 aclnn 算子开发中复用率最高的积木Contiguous/ViewCopy 解决 L2 与 L0 之间的连续性鸿沟Cast 统一计算前的数据类型Transpose/Slice/Pad/Reshape 完成视图与区域的变换TransData/TransDataSpecial/ReFormat 处理硬件格式排布IsNullptr 则提供统一的入参防线。理解并熟练组合这 11 个接口是高效编写正确、健壮的 L2 层算子逻辑的基础结合 basic_l0_Interface.md 中每个接口的产品支持约束与数据类型限制可以显著降低跨平台算子适配的返工成本。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询