news 2026/9/18 14:12:01

CANN opbase 算子开发指南:aclTensor 公共类型接口(common_types)全面解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN opbase 算子开发指南:aclTensor 公共类型接口(common_types)全面解析

CANN opbase 算子开发指南:aclTensor 公共类型接口(common_types)全面解析

【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase

本文围绕 CANN opbase 基础框架库中面向算子开发的common_types接口集合展开。该集合封装了算子开发中最常用的数据容器类型aclTensoraclScalaraclStorageaclArray等的属性读写接口,覆盖 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/SetStorageShapeGetOriginalShape/SetOriginalShapeGetViewShape/SetViewShape
  • Format 属性GetStorageFormat/SetStorageFormatGetOriginalFormat/SetOriginalFormatGetViewFormat/SetViewFormat
  • Stride 与视图偏移GetViewStrides/SetViewStrides
  • 元信息NumelGetDataTypeIsEmpty
  • 数据填充SetDataSetDataTypeSetBoolDataSetIntDataSetFloatDataSetFp16DataSetBf16Data
  • 溢出校验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::Shapegert::Shape,对应文档中反复出现的“gert 命名空间 > Shape”;
  • op::Formatge::Format,是包含 NCHW、ND 等多种取值的枚举;
  • op::DataTypege::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::TensorV2tensor_),与 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(目标数据类型,写入前会做类型转换)。约束:入参指针不能为空。

官方示例(以SetBoolDataSetFp16Data为例):

// 初始化一块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); }

SetFloatDataSetIntDataSetBf16Data的用法完全一致,仅内存指针类型不同。从实现看(common_types.cpp),这五个接口最终全部委托给SetData(value, size, dataType),因此同样只对 host 侧 tensor 生效,并且支持“源数据类型与目标 dataType 不同”的隐式转换——例如SetBoolData(myArray, 10, DT_INT64)会把 bool 数组转换为 int64 后写入。op::fp16_top::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),包括:

  • 基础类型:boolint8_t/16_t/32_t/64_tuint8_t/16_t/32_t/64_tfloatdouble
  • 半精度/低精度类型:op::fp16_top::bfloat16op::Float8E5M2op::Float8E4M3FNop::Float8E8M0op::Float6E3M2op::Float6E2M3op::Float4E2M1op::Float4E1M2op::HiFloat4op::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、存储对象、地址、偏移与类型
aclStorageaclStorage(void *addr)GetAddr()SetAddr()GetWorkspaceOffset()SetStorageOffset()描述一块片上内存空间,支持 workspace 偏移管理
aclArrayaclArray(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)打印各类对象的可读字符串,便于调试
新型数据格式SetFloat8E5M2DataSetFloat8E4M3FNDataSetHiFloat4Data填充 float8/float6/float4/hifloat 系列新格式数据

与源码对应:aclStorageaclArrayaclTensoraclTensorListaclScalaraclScalarList等类均定义在 include/nnopbase/opdev/common_types.h;其中aclStorageextend_成员用于串联“ViewCopy/Reshape 这类无 kernel 节点的特殊算子”的输入输出存储关系(见 common_types.h),aclScalar内部通过联合体v_t存储多种标量表示(common_types.h)。

八、实战小结:接口选用速查

根据前文分析,将常用场景与推荐接口整理如下:

场景推荐接口注意事项
读取内存实际排布GetStorageShape()/GetStorageFormat()Storage 描述物理内存
记录/还原变换前形态GetOriginalShape()/GetOriginalFormat()与 transdata 节点语义相关
以逻辑形状复用内存GetViewShape()/GetViewFormat()View 与 Storage 元素总数应一致
读取/定制各维 strideGetViewStrides()/SetViewStrides()stride 不支持负数;SetViewShape会重置 stride 为连续值
获取元素总数Numel()基于 ViewShape 计算,勿与Size()(基于 StorageShape 的字节数)混淆
判断空 tensorIsEmpty()ViewShape 任一分量维度为 0 即为空
填充 host 侧数据SetData/SetBoolData/SetIntData/SetFloatData/SetFp16Data/SetBf16Data仅对AllocHostTensor申请的 host 侧 tensor 生效;指针不可为空
修改 dtypeSetDataType()dtype 位宽变化时自动重算内存尺寸
标量降精度前守卫CheckOverflows<to>()溢出返回 true,返回前应处理

编写算子 host 侧逻辑时,建议遵循以下经验法则:

  1. 先明确视角:涉及物理内存的操作(如计算地址、判断尺寸)读取 Storage 属性;涉及算子逻辑输入输出形状的推导使用 View 属性;涉及格式还原的记录 Origin 属性。
  2. 视图操作注意顺序:修改 ViewShape 后若需要非连续 stride,务必再调用SetViewStrides,否则会被重置为连续值。
  3. host 数据填充先申请SetData系列只作用于AllocHostTensor得到的 host 侧 tensor,对 device 侧 tensor 调用不会生效。
  4. 空 tensor 早退IsEmpty()判定的是维度为 0,算子主逻辑前先判空可避免越界与无效计算。
  5. 标量转换先校验:涉及 fp16/bf16/窄整数等降精度转换时,用CheckOverflows做前置守卫。

参考文档索引

  • 接口总览:docs/zh/api/nnopbase/opdev/common_types/common_types.md
  • 各接口详细说明:docs/zh/api/nnopbase/opdev/common_types/ 目录下的GetStorageShape.mdSetViewStrides.mdNumel.mdCheckOverflows.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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 14:11:47

OTDR与GIS融合的光纤智能监控:从长度域到地理域的故障定位实践

简介&#xff1a;一份面向光纤网络运维与智能监控方向的研究文献&#xff0c;内容聚焦基于GIS和OTDR的光纤智能监控系统设计&#xff0c;尤其针对航天发射场等关键场景的光纤线路维护需求。系统将地理信息系统的空间定位能力与OTDR实时监测能力结合&#xff0c;实现光纤故障快速…

作者头像 李华
网站建设 2026/9/18 14:09:55

组织效能分析自动化:从PPTX报告到可复算系统

简介&#xff1a;这份PPT研究报告聚焦组织效能的底层逻辑、方法论框架与案例解析&#xff0c;面向企业管理者、HR从业者及组织发展顾问&#xff0c;帮助其系统理解组织效能内涵&#xff0c;并从经营、运营、人力三个层面找到效能提升的撬动点。内容涵盖组织效能的核心要素与影响…

作者头像 李华
网站建设 2026/9/18 14:09:33

LVGL多页面切换实战:从界面编辑器到代码整合全攻略

做嵌入式GUI开发的朋友&#xff0c;肯定都有过这种经历&#xff1a;界面从设计稿到真机&#xff0c;中间隔着一条又宽又深的河。特别是搞多页面切换的时候&#xff0c;逻辑本身不复杂&#xff0c;但代码量一上来&#xff0c;页面管理的琐碎细节能把人折磨到怀疑人生。后来我接触…

作者头像 李华
网站建设 2026/9/18 14:09:28

POD135伪开漏I/O电气规范:从JESD8-21C-01到DDR内存接口实战

简介&#xff1a;JEDEC JESD8-21C-01 2022 POD135 标准文档面向数字接口电路设计工程师、芯片验证人员及硬件系统架构师&#xff0c;聚焦1.35V伪开漏&#xff08;Pseudo Open Drain&#xff09;I/O接口的电气规范与设计约束。该标准由JEDEC于2022年6月发布&#xff0c;是对2019…

作者头像 李华