CANN opbase 算子开发指南:aclTensor 公共类型接口(common_types)全面解析
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
本文围绕 CANN opbase 基础框架库中面向算子开发的
common_types接口集合展开。该集合封装了算子开发中最常用的数据容器类型aclTensor、aclScalar、aclStorage、aclArray等的属性读写接口,覆盖 Storage/Origin/View 三套 Shape 与 Format 的管理、Stride 与偏移量访问、数据填充与类型转换、溢出校验等能力。读完本文,你将掌握如何在算子 host 侧代码中正确构造、读写并校验 aclTensor 的各类属性,理解其背后的内存排布与逻辑视图模型,并能结合仓库源码定位每个接口的实现细节。
一、common_types 是什么:算子开发的数据容器接口层
在 CANN 算子库(opbase)中,算子既要在 host 侧完成入参描述、形状推导与数据准备,也要在 device 侧执行计算。aclTensor是连接这两侧的核心数据容器:它描述一块张量的 shape、dtype、format 等属性,并记录数据所处位置(device 侧或 host 侧),同时以视图(view)的方式支持同一块内存被不同算子以不同逻辑形状使用。
common_types是 opdev(算子开发接口)命名空间下的一组公共类型与成员函数,其索引文档位于 docs/zh/api/nnopbase/opdev/common_types/common_types.md,对外暴露以下 26 个常用接口,外加一批标记为“预留接口”的底层能力:
- Shape 属性:
GetStorageShape/SetStorageShape、GetOriginalShape/SetOriginalShape、GetViewShape/SetViewShape - Format 属性:
GetStorageFormat/SetStorageFormat、GetOriginalFormat/SetOriginalFormat、GetViewFormat/SetViewFormat - Stride 与视图偏移:
GetViewStrides/SetViewStrides - 元信息:
Numel、GetDataType、IsEmpty - 数据填充:
SetData、SetDataType、SetBoolData、SetIntData、SetFloatData、SetFp16Data、SetBf16Data - 溢出校验:
CheckOverflows
这些接口的声明集中在 include/nnopbase/opdev/common_types.h,实现位于 src/nnopbase/common/utils/common_types.cpp,因此文档、声明与实现三者一一对应,便于按名检索。
1.1 类型别名与底层依赖
从 common_types.h 可以看到,op命名空间为这些接口统一了类型别名:
namespace op { constexpr uint64_t MAX_DIM_NUM = 25; using Strides = FVector<int64_t, MAX_DIM_NUM>; using ShapeVector = FVector<int64_t, MAX_DIM_NUM>; using Shape = gert::Shape; using Format = ge::Format; using DataType = ge::DataType; using Tensor = gert::TensorV2; using StorageShape = gert::StorageShape; using StorageFormat = gert::StorageFormat; using TensorPlacement = gert::TensorPlacement; }由此可以看出:
op::Shape即gert::Shape,对应文档中反复出现的“gert 命名空间 > Shape”;op::Format即ge::Format,是包含 NCHW、ND 等多种取值的枚举;op::DataType即ge::DataType,包含 float16、float32、int64、bool 等类型;op::Strides是容量上限为 25 的FVector<int64_t>(MAX_DIM_NUM = 25),这决定了 aclTensor 最多支持 25 维的张量描述。
1.2 三种 Shape / Format 的含义
理解common_types的核心在于区分 Storage、Origin、View 三套属性,它们分别描述张量在不同阶段的形态:
| 属性前缀 | 含义 | 典型场景 |
|---|---|---|
| Storage(存储) | aclTensor 在内存上的实际排布,即实际运行时数据落地的 shape/format | 描述物理内存布局,例如[10, 20]表示内存中按 10×20 连续排布 |
| Origin(原始) | aclTensor 在经历 transdata 节点前(如果存在该节点)的原始 shape/format,即 tensor 的 shape 数学描述 | 记录数据变换前的逻辑源头,便于格式还原与推导 |
| View(视图) | aclTensor 的逻辑 shape/format,即算子使用时可以将该 tensor 视为的形状 | 同一内存以不同逻辑形状复用,例如把[10, 20]视为[2, 5, 20] |
三者中,Storage 描述“内存里是什么”,Origin 描述“变换前是什么”,View 描述“逻辑上当成什么”。View 与 Storage 往往维度数不同但元素总数一致,这正是视图复用内存的基础。
二、Shape 属性接口:Get/Set StorageShape、OriginalShape、ViewShape
2.1 GetStorageShape / SetStorageShape
GetStorageShape用于获取 aclTensor 的 StorageShape(内存实际排布):
gert::Shape GetStorageShape()无入参,返回gert::Shape,例如一个三维 shape 返回[10, 20, 30]。对应的设置接口原型为:
void SetStorageShape(const op::Shape &shape)参数shape为输入参数,数据类型为op::Shape(即gert::Shape)。官方调用示例:
// 将input的StorageShape设置为[1, 2, 3, 4, 5] void Func(aclTensor *input) { gert::Shape newShape; for (int64_t i = 1; i <= 5; i++) { newShape.AppendDim(i); } input->SetStorageShape(newShape); }从实现看,SetStorageShape不只是简单赋值,还会联动调整 tensor 的字节大小:common_types.cpp 中先写入MutableStorageShape(),再调用tensor_->SetSize(op::CalcShapeBytes(...))按新 storage shape 重算内存大小,保证“shape 变了、内存尺寸同步更新”。
2.2 GetOriginalShape / SetOriginalShape
GetOriginalShape获取 aclTensor 的 OriginShape——即经历 transdata 节点前(如果存在)的原始 shape 数学描述:
gert::Shape GetOriginalShape()SetOriginalShape与之对应,原型为:
void SetOriginalShape(const op::Shape &shape)官方示例:
// 将input的OriginShape设置为[1, 2, 3, 4, 5] void Func(aclTensor *input) { gert::Shape newShape; for (int64_t i = 1; i <= 5; i++) { newShape.AppendDim(i); } input->SetOriginalShape(newShape); }与SetStorageShape不同,SetOriginalShape的实现只更新tensor_->MutableOriginShape()(见 common_types.cpp),不触发内存尺寸重算,因为原始 shape 只是数学描述,不直接影响物理内存布局。
2.3 GetViewShape / SetViewShape
GetViewShape获取 aclTensor 的逻辑 shape(ViewShape),文档给出了一个非常直观的例子:
- StorageShape 为
[10, 20]:表示该 aclTensor 在内存上按照[10, 20]排布; - ViewShape 为
[2, 5, 20]:在算子使用时,该 aclTensor 可被视为一块[2, 5, 20]的数据使用。
gert::Shape GetViewShape()SetViewShape的原型为:
void SetViewShape(const op::Shape &shape)官方示例:
// 将input的ViewShape设置为[1, 2, 3, 4, 5] void Func(aclTensor *input) { gert::Shape newShape; for (int64_t i = 1; i <= 5; i++) { newShape.AppendDim(i); } input->SetViewShape(newShape); }值得注意的实现细节:SetViewShape在写入viewShape_的同时,会自动调用op::ToContiguousStrides(viewShape_, viewStrides_)按“连续张量”规则重新推导 ViewStrides(见 common_types.cpp)。也就是说,一旦设置 ViewShape,ViewStrides 会被重置为连续排布的 stride。如果视图是非连续切片(如扩 stride 后的 view),必须在SetViewShape之后显式调用SetViewStrides覆盖默认值。
2.4 Numel:元素总数与 Size 的区别
Numel获取 aclTensor 的总元素个数:
int64_t Numel()官方示例:
// 获取input的总元素个数 void Func(const aclTensor *input) { int64_t num = input->Numel(); }从实现看,Numel()返回的是ViewShape的元素总数,而Size()返回的是StorageShape的字节规模(见 common_types.cpp):
int64_t aclTensor::Size() const { return GetStorageShape().GetShapeSize(); } int64_t aclTensor::Numel() const { return GetViewShape().GetShapeSize(); }因此在视图场景下,Numel()表示算子逻辑视角的元素个数,与底层存储的字节数不一定一一对应,两者不要混用。
三、Format 属性接口:Get/Set StorageFormat、OriginalFormat、ViewFormat
3.1 GetStorageFormat / SetStorageFormat
GetStorageFormat获取 aclTensor 在内存中的排布格式,例如 NCHW、ND 等:
op::Format GetStorageFormat()返回op::Format(即ge::Format枚举)。SetStorageFormat原型:
void SetStorageFormat(op::Format format)官方示例:
// 将input的Storage Format置为ND格式 void Func(const aclTensor *input) { input->SetStorageFormat(ge::FORMAT_ND); }3.2 GetOriginalFormat / SetOriginalFormat
GetOriginalFormat获取 OriginFormat——一般表示 aclTensor 在经历 transdata 节点前(如果存在)的原始 Format 信息:
op::Format GetOriginalFormat()SetOriginalFormat原型:
void SetOriginalFormat(op::Format format)官方示例:
// 将input的OriginFormat置为ND格式 void Func(const aclTensor *input) { input->SetOriginalFormat(ge::FORMAT_ND); }3.3 GetViewFormat / SetViewFormat
GetViewFormat获取 aclTensor 的逻辑 Format(ViewFormat):
op::Format GetViewFormat()SetViewFormat原型:
void SetViewFormat(op::Format format)官方示例:
// 将input的ViewFormat置为ND格式 void Func(const aclTensor *input) { input->SetViewFormat(ge::FORMAT_ND); }3.4 Format 实现的分流:Storage 走底层、View 走本地成员
三类 Format 的实现策略并不相同(见 common_types.cpp):
void aclTensor::SetStorageFormat(op::Format format) { tensor_->SetStorageFormat(format); } void aclTensor::SetOriginalFormat(op::Format format) { tensor_->SetOriginFormat(format); } void aclTensor::SetViewFormat(op::Format format) { viewFormat_ = format; }- StorageFormat、OriginalFormat 被写入底层
gert::TensorV2(tensor_),与 device 侧内存管理联动; - ViewFormat 则仅保存在 aclTensor 自身的
viewFormat_成员中(对应头文件中的op::Format viewFormat_;,见 common_types.h),因为它只是算子逻辑视角的描述,不影响物理排布。
这也印证了上文的结论:View 系属性是 aclTensor 层的“轻量视图”,Storage/Origin 系属性才是底层张量对象的“重量级描述”。
四、Stride 与视图偏移:GetViewStrides / SetViewStrides
4.1 GetViewStrides
GetViewStrides返回 aclTensor 各个维度的 stride 大小:
FVector<int64_t> GetViewStrides()返回值是FVector对象(即op::Strides),里面存放每一维的 stride。官方示例:
// 获取input的View Stride并依次打印出每一维的stride大小 void Func(const aclTensor *input) { auto strides = input->GetViewStrides(); for (int64_t stride : strides) { std::cout << stride << std::endl; } }4.2 SetViewStrides
SetViewStrides提供左值引用与右值引用两个重载:
SetViewStrides(const op::Strides &strides) SetViewStrides(op::Strides &&strides)参数strides类型为FVector<int64_t>,表示 aclTensor 每一维的 stride 大小,取值不支持负数。官方示例演示了如何将最后一维的 stride 扩大 8 倍:
// 将input最后一维的stride扩大8倍。 void Func(const aclTensor *input) { auto strides = input->GetViewStrides(); strides[strides.size() - 1] *= 8; input->SetViewStrides(strides); }实现上,左值版本直接拷贝赋值viewStrides_ = strides;,右值版本使用std::move移动赋值(见 common_types.cpp)。结合 2.3 节的结论:ViewShape 变化会自动重置 stride 为连续值,因此调整 stride 的正确顺序是“先 SetViewShape、再 SetViewStrides”。
4.3 测试用例印证
仓库的单元测试对 View 语义进行了充分验证。在 tests/nnopbase/st/composite_op/test_acl_op_api.cpp 中,构造不同维度数的 tensor 后直接断言其GetViewStrides()结果:
EXPECT_EQ(a->GetViewStrides(), op::Strides({1})); EXPECT_EQ(a->GetViewStrides(), op::Strides({2, 1})); EXPECT_EQ(a->GetViewStrides(), op::Strides({8, 2, 1})); EXPECT_EQ(a->GetViewStrides(), op::Strides({8, 1}));这组断言验证了:新建 tensor 的 ViewStrides 默认按连续排布推导(最后一维为 1,向前逐维累乘),与SetViewShape内部调用ToContiguousStrides的逻辑完全一致。该文件还通过ShapeEq(tensorName->GetViewShape(), viewShape)校验 ViewShape 与构造入参的一致性,可作为接口行为的回归基线。
五、数据读写接口:GetDataType、IsEmpty 与 SetData 系列
5.1 GetDataType / SetDataType
GetDataType获取 aclTensor 中元素的数据类型:
op::DataType GetDataType()返回op::DataType(即ge::DataType),包含 float16、float32 等类型。SetDataType用于修改数据类型:
void SetDataType(op::DataType dataType)官方示例:
// 将input的数据类型设置为int64 void Func(const aclTensor *input) { input->SetDataType(DT_INT64); }实现上SetDataType有一个关键联动:当新旧类型的字节宽度不同时(op::TypeSize不同),会在SetDataType之后调用tensor_->SetSize(op::CalcShapeBytes(...))重算 tensor 字节数(见 common_types.cpp),避免 dtype 改变后内存尺寸不匹配。
5.2 IsEmpty
IsEmpty判断 aclTensor 是否为空 tensor:
bool IsEmpty()为空返回true,否则返回false。官方示例演示了空 tensor 的防御性编程:
// 判断input为空tensor则return,否则获取他的数据类型 void Func(const aclTensor *input) { if (input->IsEmpty()) { return; } op::DataType dataType = input->GetDataType(); }从实现看,“空 tensor”的判定标准是ViewShape 中存在任一维度为 0(见 common_types.cpp):
bool aclTensor::IsEmpty() const { bool isEmpty = false; for (size_t i = 0; i < viewShape_.GetDimNum(); i++) { if (viewShape_[i] == 0) { isEmpty = true; break; } } return isEmpty; }这也提示:Shape 中只要有一个维度为 0(例如[0, 5]),该 tensor 即被判定为空,算子应尽早跳过这类输入以避免越界访问。
5.3 SetData:单元素与整块内存两种形态
SetData针对通过AllocHostTensor申请得到的 host 侧 tensor,提供两种重载:
设置指定索引处的值:
void SetData(int64_t index, const T value, op::DataType dataType)用一块已有内存初始化 tensor 数据:
void SetData(const T *value, uint64_t size, op::DataType dataType)
参数说明:
| 参数 | 输入/输出 | 说明 |
|---|---|---|
| index | 输入 | 需要修改 aclTensor 的第几个元素。 |
| value | 输入 | 单元素版本:将指定元素修改为 value 的值;内存版本:指向需要写入 aclTensor 的数据内存指针。 |
| size | 输入 | 需要写入的元素个数。 |
| dataType | 输入 | 数据类型为op::DataType(即ge::DataType)。将数据转为指定的 dataType 后,再写入 aclTensor。 |
官方示例:
// 初始化一块int64_t内存,分别将input的前10个数字,置为该内存的内容。并将input的第11个数字置为myArray的第一个数字。 void Func(const aclTensor *input) { int64_t myArray[10]; input->SetData(myArray, 10, DT_INT64); input->SetData(10, myArray[0], DT_INT64); }实现层面的几个关键行为(见 common_types.cpp):
- 两版
SetData都只在GetPlacement() == op::TensorPlacement::kOnHost时生效,device 侧 tensor 调用会被静默跳过; - 内存版本本质上是逐元素调用单元素版本:
for (uint64_t i = 0; i < size; i++) { SetData(i, value[i], dataType); }; - 单元素版本按
dataType的 switch 分支调用SetDataByDataType<T, X>做类型转换后写入对应地址,支持 DT_FLOAT、DT_FLOAT16、DT_BF16、DT_INT8/16/32/64、DT_UINT8/16/32/64、DT_DOUBLE、DT_BOOL 等类型; - 对不支持的 dataType 会记录
OP_LOGE_FOR_NOT_SUPPORTED_DATA_TYPE错误日志并给出可用的 dtype 范围。
5.4 类型化数据填充:SetBoolData / SetIntData / SetFloatData / SetFp16Data / SetBf16Data
common_types为常用 host 侧数据类型提供了类型化填充接口,全部针对AllocHostTensor申请的 host 侧 tensor:
| 接口 | 内存指针类型 | 说明 |
|---|---|---|
SetBoolData(const bool *value, uint64_t size, op::DataType dataType) | bool | 用 bool 内存初始化 tensor 数据 |
SetIntData(const int64_t *value, uint64_t size, op::DataType dataType) | int64_t | 用 int64 内存初始化 tensor 数据 |
SetFloatData(const float *value, uint64_t size, op::DataType dataType) | float | 用 float 内存初始化 tensor 数据 |
SetFp16Data(const op::fp16_t *value, uint64_t size, op::DataType dataType) | op::fp16_t | 用 float16 内存初始化 tensor 数据 |
SetBf16Data(const op::bfloat16 *value, uint64_t size, op::DataType dataType) | op::bfloat16 | 用 bfloat16 内存初始化 tensor 数据 |
三个参数value(数据内存指针)、size(元素个数)、dataType(目标数据类型,写入前会做类型转换)。约束:入参指针不能为空。
官方示例(以SetBoolData和SetFp16Data为例):
// 初始化一块bool内存,将其转为int64后,赋值给input的前10个元素 void Func(const aclTensor *input) { bool myArray[10]; input->SetBoolData(myArray, 10, DT_INT64); } // 初始化一块fp16内存,赋值给input的前10个元素 void Func(const aclTensor *input) { fp16_t myArray[10]; input->SetFp16Data(myArray, 10, DT_FLOAT16); }SetFloatData、SetIntData、SetBf16Data的用法完全一致,仅内存指针类型不同。从实现看(common_types.cpp),这五个接口最终全部委托给SetData(value, size, dataType),因此同样只对 host 侧 tensor 生效,并且支持“源数据类型与目标 dataType 不同”的隐式转换——例如SetBoolData(myArray, 10, DT_INT64)会把 bool 数组转换为 int64 后写入。op::fp16_t与op::bfloat16分别定义在 include/nnopbase/opdev/fp16_t.h 和 include/nnopbase/opdev/bfloat16.h,作为 op 命名空间的半精度类型供算子使用。
5.5 AllocHostTensor 与 SetData 的配合
SetData系列的使用前提是 host 侧 tensor,对应申请接口为AllocHostTensor(见 docs/zh/api/nnopbase/opdev/op_executor/AllocHostTensor.md),典型形态:
aclTensor *AllocHostTensor(const op::Shape &shape, op::DataType dataType, op::Format format = op::Format::FORMAT_ND)典型配合流程为:先用AllocHostTensor申请 host 侧 tensor,再用SetData/SetIntData/SetFloatData等接口填充数据,之后将该 tensor 作为算子输入参与调度。这是构造“以数据为输入”的算子测试或 host 侧数据准备的标准路径。
六、标量溢出校验:CheckOverflows
6.1 接口说明
CheckOverflows用于校验 aclScalar 中保存的标量数值在转换为目标数据类型时是否溢出:
template<typename to> bool CheckOverflows()参数to为模板参数,表示要转换的目标数据类型。返回值:如果存在溢出返回true,否则返回false。
官方示例:
// 判断input转为fp16和int16是否会发生溢出 void Func(const aclScalar *input) { if (input->CheckOverflows<fp16_t>()) { return; } if (input->CheckOverflows<int16_t>()) { return; } }6.2 实现与支持的类型
该模板在 common_types.cpp 定义,并在文件末尾显式实例化了一大批目标类型(common_types.cpp),包括:
- 基础类型:
bool、int8_t/16_t/32_t/64_t、uint8_t/16_t/32_t/64_t、float、double - 半精度/低精度类型:
op::fp16_t、op::bfloat16、op::Float8E5M2、op::Float8E4M3FN、op::Float8E8M0、op::Float6E3M2、op::Float6E2M3、op::Float4E2M1、op::Float4E1M2、op::HiFloat4、op::HiFloat8 - 复数类型:
std::complex<float>、std::complex<double>
在实际算子开发中,CheckOverflows常用于“标量属性转换前守卫”:例如把用户传入的标量降精度到 fp16 或收紧到窄整数类型前,先做溢出检查,避免数值失真或回绕。它在头文件中的声明(common_types.h)带有明确的注释:“检查 scalar 转换成目标数据类型是否会溢出,true: 溢出,false: 不溢出”,与文档语义完全一致。
七、预留接口与底层容器速览
common_types索引页末尾提供了 预留接口 文档,集中列出了一批后续可能变更或废弃、不建议开发者使用的接口,开发者无需关注。但浏览该表有助于理解 aclTensor 体系的内部结构,下表摘录其中的关键类别:
| 类别 | 代表性接口 | 作用 |
|---|---|---|
| aclTensor 构造 | aclTensor(const op::Shape &shape, op::DataType dataType, op::Format format, void *tensorDataAddr)等多组重载 | 描述 device/host 侧张量的 shape、dtype、format 及数据地址 |
| aclTensor 内部属性 | GetTensor()、GetStorage()、GetStorageAddr()、GetViewOffset()、GetPlacement()、IsView() | 访问底层 gert::Tensor、存储对象、地址、偏移与类型 |
| aclStorage | aclStorage(void *addr)、GetAddr()、SetAddr()、GetWorkspaceOffset()、SetStorageOffset() | 描述一块片上内存空间,支持 workspace 偏移管理 |
| aclArray | aclArray(const T *value, uint64_t size)、Size()、GetData()、ToString() | 描述 host 侧数组(bool/int64/float/fp16/bf16 五类) |
| aclScalar 系列 | aclScalar(int32_t value)等多组构造、ToInt64()、ToFp16()、ToBf16()、ToStr() | 描述标量数字及其类型转换 |
| ToString 系列 | ToString(const aclTensor* t)、ToString(aclDataType dataType)等 | 打印各类对象的可读字符串,便于调试 |
| 新型数据格式 | SetFloat8E5M2Data、SetFloat8E4M3FNData、SetHiFloat4Data等 | 填充 float8/float6/float4/hifloat 系列新格式数据 |
与源码对应:aclStorage、aclArray、aclTensor、aclTensorList、aclScalar、aclScalarList等类均定义在 include/nnopbase/opdev/common_types.h;其中aclStorage的extend_成员用于串联“ViewCopy/Reshape 这类无 kernel 节点的特殊算子”的输入输出存储关系(见 common_types.h),aclScalar内部通过联合体v_t存储多种标量表示(common_types.h)。
八、实战小结:接口选用速查
根据前文分析,将常用场景与推荐接口整理如下:
| 场景 | 推荐接口 | 注意事项 |
|---|---|---|
| 读取内存实际排布 | GetStorageShape()/GetStorageFormat() | Storage 描述物理内存 |
| 记录/还原变换前形态 | GetOriginalShape()/GetOriginalFormat() | 与 transdata 节点语义相关 |
| 以逻辑形状复用内存 | GetViewShape()/GetViewFormat() | View 与 Storage 元素总数应一致 |
| 读取/定制各维 stride | GetViewStrides()/SetViewStrides() | stride 不支持负数;SetViewShape会重置 stride 为连续值 |
| 获取元素总数 | Numel() | 基于 ViewShape 计算,勿与Size()(基于 StorageShape 的字节数)混淆 |
| 判断空 tensor | IsEmpty() | ViewShape 任一分量维度为 0 即为空 |
| 填充 host 侧数据 | SetData/SetBoolData/SetIntData/SetFloatData/SetFp16Data/SetBf16Data | 仅对AllocHostTensor申请的 host 侧 tensor 生效;指针不可为空 |
| 修改 dtype | SetDataType() | dtype 位宽变化时自动重算内存尺寸 |
| 标量降精度前守卫 | CheckOverflows<to>() | 溢出返回 true,返回前应处理 |
编写算子 host 侧逻辑时,建议遵循以下经验法则:
- 先明确视角:涉及物理内存的操作(如计算地址、判断尺寸)读取 Storage 属性;涉及算子逻辑输入输出形状的推导使用 View 属性;涉及格式还原的记录 Origin 属性。
- 视图操作注意顺序:修改 ViewShape 后若需要非连续 stride,务必再调用
SetViewStrides,否则会被重置为连续值。 - host 数据填充先申请:
SetData系列只作用于AllocHostTensor得到的 host 侧 tensor,对 device 侧 tensor 调用不会生效。 - 空 tensor 早退:
IsEmpty()判定的是维度为 0,算子主逻辑前先判空可避免越界与无效计算。 - 标量转换先校验:涉及 fp16/bf16/窄整数等降精度转换时,用
CheckOverflows做前置守卫。
参考文档索引
- 接口总览:docs/zh/api/nnopbase/opdev/common_types/common_types.md
- 各接口详细说明:docs/zh/api/nnopbase/opdev/common_types/ 目录下的
GetStorageShape.md、SetViewStrides.md、Numel.md、CheckOverflows.md等 25 个文件 - 预留接口:docs/zh/api/nnopbase/opdev/common_types/reserved_interface_common_types.md
- 接口声明:include/nnopbase/opdev/common_types.h
- 接口实现:src/nnopbase/common/utils/common_types.cpp
- host 侧 tensor 申请:docs/zh/api/nnopbase/opdev/op_executor/AllocHostTensor.md
- 相关测试:tests/nnopbase/st/composite_op/test_acl_op_api.cpp
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考