CANN opbase 算子开发:aclOpExecutor::ConvertToTensor 接口全面解析与源码实现剖析

发布时间:2026/9/19 10:44:08

CANN opbase 算子开发:aclOpExecutor::ConvertToTensor 接口全面解析与源码实现剖析 CANN opbase 算子开发aclOpExecutor::ConvertToTensor 接口全面解析与源码实现剖析【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbaseConvertToTensor是 CANN opbase 基础框架库中aclOpExecutor提供的一组主机侧Host数据转换接口用于将aclScalar、aclIntArray、aclBoolArray、aclFloatArray、aclFp16Array、aclBf16Array以及任意基础类型的裸指针数组统一封装为主机侧aclTensor对象。本文以 ConvertToTensor.md 为骨架结合仓库内头文件、实现源码与测试用例完整讲解全部 7 个重载原型的用法、参数与数据类型约束、底层内存与生命周期管理机制以及它在 AICPU 任务参数组装中的真实调用场景。读完本文你将能够在算子实现中准确选用合适的重载完成主机常量到aclTensor的转换并理解其背后的实现原理与失败处理行为。接口定位从主机值到主机 Tensor的统一入口在aclOpExecutor的接口体系中存在两类功能相近的造 Tensor接口一类是 AllocTensor / AllocHostTensor它们只负责按形状与数据类型分配一个空的或由外部数据填充的张量对象另一类就是本文的主角ConvertToTensor它接收已经存在的、承载了具体数值的主机数据容器或指针将其内容拷贝到新分配的aclTensor内部存储中并同步完成数据类型转换如把float数组转成DT_FLOAT16的aclTensor。从 op_executor.h 的类布局看aclOpExecutor是算子执行器的核心门面类内部维护了allocatedObjList_、allocatedTensorList_等对象生命周期队列ConvertToTensor创建出的所有张量都会被登记在这些队列中由执行器统一管理这决定了它可以配合 ReleaseTo 等接口完成缓存与释放流程。典型使用场景包括将算子标量属性如 alpha、beta、epsilon 等常量封装成张量参与计算将int64维度数组、float权重数组等主机常量转换为输入张量在 AICPU 算子任务中把aclScalar、aclIntArray等参数统一转换为aclTensor后送入统一参数列表详见后文 AICPU 任务中的应用。函数原型总览接口共提供7 个重载覆盖数组容器、标量与裸指针三大类输入原型声明位于 op_executor.h// API 1int64 数组 - Tensor const aclTensor *ConvertToTensor(const aclIntArray *value, DataType dataType) // API 2bool 数组 - Tensor const aclTensor *ConvertToTensor(const aclBoolArray *value, DataType dataType) // API 3float 数组 - Tensor const aclTensor *ConvertToTensor(const aclFloatArray *value, DataType dataType) // API 4fp16 数组 - Tensor const aclTensor *ConvertToTensor(const aclFp16Array *value, DataType dataType) // API 5bf16 数组 - Tensor const aclTensor *ConvertToTensor(const aclBf16Array *value, DataType dataType) // API 6任意基础类型裸指针 - Tensor模板 templatetypename T const aclTensor *ConvertToTensor(const T *value, uint64_t size, DataType dataType) // API 7标量 - Tensor const aclTensor *ConvertToTensor(const aclScalar *value, DataType dataType)其中 API 6 是唯一带模板参数的重载也是其余数组类重载API 1~5的底层实现基石——从源码看aclTensor的数组构造函数正是通过该模板实例化而来见 common_types.cpp。参数与返回值说明参数输入/输出说明value输入主机侧源数据可以是aclIntArray/aclBoolArray/aclFloatArray/aclFp16Array/aclBf16Array/aclScalar容器对象也可以是任意基础类型T的连续内存指针size输入源数据中的元素个数仅 API 6 使用uint64_t类型dataType输入目标aclTensor中封装的数据格式op::DataType枚举即文档中的DT_*宏返回值成功时返回转换得到的主机侧aclTensor指针失败时返回nullptr。通用限制输入指针value不能为nullptr数组类重载API 1~5要求aclTensor内部通过value-GetData()与value-Size()读取数据因此容器必须由 AllocIntArray、AllocFloatArray、AllocBoolArray 等接口正确创建dataType必须是该重载支持的数据类型之一否则构造函数会抛出std::invalid_argument最终被转换为nullptr返回详见下文异常处理分析。各重载的数据类型约束API 1ConvertToTensor(const aclIntArray *value, DataType dataType)参数数据类型valueaclIntArray内部为int64_t类型数组dataTypeDT_FLOAT、DT_FLOAT16、DT_BF16、DT_INT8、DT_INT16、DT_UINT16、DT_UINT8、DT_INT32、DT_INT64、DT_UINT32、DT_UINT64、DT_BOOL、DT_DOUBLEAPI 2ConvertToTensor(const aclBoolArray *value, DataType dataType)参数数据类型valueaclBoolArray内部为bool类型数组dataTypeDT_FLOAT、DT_FLOAT16、DT_BF16、DT_INT8、DT_INT16、DT_UINT16、DT_UINT8、DT_INT32、DT_INT64、DT_UINT32、DT_UINT64、DT_BOOL、DT_DOUBLEAPI 3ConvertToTensor(const aclFloatArray *value, DataType dataType)参数数据类型valueaclFloatArray内部为float类型数组dataTypeDT_FLOAT、DT_FLOAT16、DT_BF16、DT_INT8、DT_INT16、DT_UINT16、DT_UINT8、DT_INT32、DT_INT64、DT_UINT32、DT_UINT64、DT_BOOL、DT_DOUBLEAPI 4ConvertToTensor(const aclFp16Array *value, DataType dataType)参数数据类型valueaclFp16Array内部为fp16_t类型数组dataTypeDT_FLOAT、DT_FLOAT16、DT_BF16、DT_INT8、DT_INT16、DT_UINT16、DT_UINT8、DT_INT32、DT_INT64、DT_UINT32、DT_UINT64、DT_BOOL、DT_DOUBLEAPI 5ConvertToTensor(const aclBf16Array *value, DataType dataType)参数数据类型valueaclBf16Array内部为bfloat16类型数组dataTypeDT_FLOAT、DT_FLOAT16、DT_BF16、DT_INT8、DT_INT16、DT_UINT16、DT_UINT8、DT_INT32、DT_INT64、DT_UINT32、DT_UINT64、DT_BOOL、DT_DOUBLEAPI 6ConvertToTensor(const T *value, uint64_t size, DataType dataType)参数数据类型value模板参数T支持int64_t、uint64_t、int32_t、uint32_t、int8_t、uint8_t、int16_t、uint16_t、float、double、bool、char、op::bfloat16、op::fp16_tsizeuint64_t表示元素个数dataTypeDT_FLOAT、DT_FLOAT16、DT_BF16、DT_INT8、DT_INT16、DT_UINT16、DT_UINT8、DT_INT32、DT_INT64、DT_UINT32、DT_UINT64、DT_BOOL、DT_DOUBLE需要特别说明的是API 6 的目标dataType仅支持上述 14 种常规数据类型不含复数与各类 Float8/Float6/Float4 等扩展格式。这与源码实现一致——模板版aclTensor构造函数common_types.cpp的default分支仅打印支持范围[DT_FLOAT(0), DT_FLOAT16(1), DT_INT8(2), DT_INT32(3), DT_UINT8(4), DT_INT16(6), DT_UINT16(7), DT_UINT32(8), DT_INT64(9), DT_UINT64(10), DT_DOUBLE(11), DT_BOOL(12), DT_BF16(27)]并抛出异常。API 7ConvertToTensor(const aclScalar *value, DataType dataType)参数数据类型valueaclScalar内部数据类型支持DT_BOOL、DT_INT8、DT_UINT8、DT_INT16、DT_UINT16、DT_INT32、DT_UINT32、DT_INT64、DT_UINT64、DT_FLOAT、DT_DOUBLE、DT_FLOAT16、DT_BF16、DT_COMPLEX64、DT_COMPLEX128、DT_FLOAT8_E5M2、DT_FLOAT8_E4M3FN、DT_FLOAT8_E8M0、DT_FLOAT6_E3M2、DT_FLOAT6_E2M3、DT_FLOAT4_E2M1、DT_FLOAT4_E1M2、DT_HIFLOAT8dataType目标数据类型支持与value内部类型一致的全部 23 种DT_BOOL、DT_INT8、DT_UINT8、DT_INT16、DT_UINT16、DT_INT32、DT_UINT32、DT_INT64、DT_UINT64、DT_FLOAT、DT_DOUBLE、DT_FLOAT16、DT_BF16、DT_COMPLEX64、DT_COMPLEX128、DT_FLOAT8_E5M2、DT_FLOAT8_E4M3FN、DT_FLOAT8_E8M0、DT_FLOAT6_E3M2、DT_FLOAT6_E2M3、DT_FLOAT4_E2M1、DT_FLOAT4_E1M2、DT_HIFLOAT8API 7 是数据类型支持面最广的重载——它通过aclScalar的ToFloat()、ToInt64()、ToComplex64()、ToFloat8E5M2()等转换方法把标量值写入目标类型的内存单元底层switch完整覆盖了复数、Float8、Float6、Float4 与 HiFloat8 等扩展格式见 common_types.cpp。仓库单元测试也专门针对float/double 类型 aclScalar 经 ConvertToTensor 转换为 float8/6/4 类型 tensor的场景做了全覆盖验证见 test_op_executor.cpp。源码级实现剖析模板重载API 6就地分配 逐元素类型转换模板版实现位于 op_executor.h逻辑非常简洁template typename T const aclTensor* ConvertToTensor(const T* value, uint64_t size, op::DataType dataType) { aclTensor* tensor nullptr; try { tensor new aclTensor(value, size, dataType); allocatedObjList_.push_back(tensor); allocatedTensorList_.push_back(tensor); return tensor; } catch (...) { OP_LOGE(ACLNN_ERR_INNER, aclOpExecutor::ConvertToTensor failed.); delete tensor; return nullptr; } }其核心工作是委托给aclTensor的模板构造函数common_types.cpp完成的该构造函数的关键步骤为确定形状将一维数组建模为 shape 为{size}、storage shape 与 origin shape 均为{size}的连续张量format 统一为FORMAT_ND并通过op::ToContiguousStrides计算连续步长分配主机内存按size * op::TypeSize(dataType)调用op::internal::Allocate分配数据缓冲逐元素转换根据目标dataType走switch分支对每个源元素做static_cast写入目标类型缓冲区。值得注意的一个细节是DT_BOOL分支的语义——当源类型是浮点float/double/fp16_t时采用std::abs(value[i]) std::numeric_limitsfloat::epsilon()的判定规则而非简单的static_castboolcommon_types.cpp异常兜底若dataType不在支持范围内default分支调用OP_LOGE_FOR_NOT_SUPPORTED_DATA_TYPE打印支持范围并抛出std::invalid_argument由上层catch(...)统一转为nullptr返回。数组容器重载API 1~5委托模板构造aclIntArray等数组容器版本的执行器实现位于 op_executor.cpp采用统一的ADD_TRY_CATCH宏包装模式const aclTensor* aclOpExecutor::ConvertToTensor(const aclIntArray* value, op::DataType dataType) { aclTensor* tensor nullptr; ADD_TRY_CATCH(tensor new aclTensor(value, dataType); allocatedObjList_.push_back(tensor); allocatedTensorList_.push_back(tensor); return tensor; , OP_LOGE(ACLNN_ERR_INNER, aclOpExecutor::ConvertToTensor failed.); delete tensor; return nullptr;); }底层aclTensor的容器构造函数common_types.cpp非常薄只是把容器内部指针与长度转发给模板构造函数aclTensor::aclTensor(const aclIntArray* value, op::DataType dataType) : aclTensor(value-GetData(), value-Size(), dataType) {}aclBoolArray、aclFloatArray、aclFp16Array、aclBf16Array四个版本的结构完全相同分别转发GetData()/Size()得到的内置类型指针bool*、float*、fp16_t*、bfloat16*。标量重载API 7单元素张量 全类型转换aclScalar版本同样走ADD_TRY_CATCH包装op_executor.cpp但底层的aclTensor构造函数common_types.cpp与数组版本不同张量形状为空{}标量张量format 为FORMAT_ND只分配1 个元素的内存op::TypeSize(dataType)通过aclScalar的ToFloat()/ToFp16()/ToBf16()/ToInt8()/ToInt64()/ToComplex64()/ToFloat8E5M2()/ToHiFloat8()等转换方法将标量值以目标类型的位模式写入缓冲区因此dataType的可选范围最广23 种含复数与扩展浮点格式。对象生命周期与内存管理ConvertToTensor创建出的aclTensor由执行器统一托管这一点是使用该接口最重要的注意事项每次成功的转换都会把新张量同时登记到allocatedObjList_与allocatedTensorList_两个队列见 op_executor.h 的成员定义allocatedTensorList_可供GetInputTensors()/GetOutputTensors()等接口检索张量会参与后续的算子执行流程返回的const aclTensor*指针不需要也不应该由调用方手动delete其释放由执行器统一回收若转换失败返回nullptr内部已经delete tensor完成清理不会泄漏。因此在实际开发中请把ConvertToTensor返回的指针视为执行器借用给调用方的只读句柄避免在算子执行前提前释放也避免与 AllocTensor 创建的张量混淆生命周期语义。在 AICPU 任务参数组装中的应用ConvertToTensor不仅是算子开发者的便捷工具也是框架内部 AICPU 任务参数统一的桥梁。在 aicpu_task.h 的AppendTensor重载中可以看到框架如何利用该接口把不同类型的算子参数统一收敛为aclTensor列表template typename V inline void AppendTensor(aclOpExecutor* executor, const aclScalar* arg, V l) { op::DataType dataType ge::DT_INT64; if (arg ! nullptr) { dataType arg-GetDataType(); } auto t executor-ConvertToTensor(arg, dataType); l.emplace_back(const_castaclTensor*(t)); } template typename V inline void AppendTensor(aclOpExecutor* executor, const aclIntArray* arg, V l) { auto t executor-ConvertToTensor(arg, ge::DT_INT64); l.emplace_back(const_castaclTensor*(t)); }即aclScalar参数按其自身GetDataType()转换为张量空指针时默认DT_INT64aclIntArray参数统一转换为DT_INT64张量。随后CreateTensorListImpl同文件 aicpu_task.h根据OpArgType分发最终把aclTensor、aclScalar、aclIntArray、aclTensorList四类算子参数全部归一为统一的张量列表供 AICPU 任务序列化与下发。从源码结构看这是组合算子composite op框架中属性参数张量化的关键路径。示例代码原文档示例演示了标量 裸指针两种最常用形态的组合使用。结合 AllocScalar 与数组容器接口可扩展为覆盖全部重载的完整示例// 示例 1将 aclScalar 和 int64_t 裸指针转换为主机侧张量原文档示例 void Func(aclOpExecutor *executor) { int64_t val 5; aclScalar *scalar executor-AllocScalar(val); const aclTensor *tensor executor-ConvertToTensor(scalar, DT_INT64); tensor executor-ConvertToTensor(val, 1, DT_INT64); } // 示例 2数组容器与裸指针的典型用法 void Func2(aclOpExecutor *executor) { // 先通过 Alloc*Array 系列接口创建主机容器 int64_t intValue[] {1, 2, 3}; aclIntArray *intArray executor-AllocIntArray(intValue, 3); float floatValue[] {1.0f, 2.0f, 3.0f}; aclFloatArray *floatArray executor-AllocFloatArray(floatValue, 3); bool boolValue[] {true, false, true}; aclBoolArray *boolArray executor-AllocBoolArray(boolValue, 3); // API 1~3容器重载 const aclTensor *t1 executor-ConvertToTensor(intArray, DT_INT64); const aclTensor *t2 executor-ConvertToTensor(floatArray, DT_FLOAT); const aclTensor *t3 executor-ConvertToTensor(boolArray, DT_BOOL); // API 6模板重载支持类型转换float - DT_FLOAT16 const aclTensor *t4 executor-ConvertToTensor(floatValue, 3, DT_FLOAT16); // API 7标量重载目标类型可与源类型不同float - DT_DOUBLE float fValue 3.2f; aclScalar *scalar executor-AllocScalar(fValue, DT_FLOAT); const aclTensor *t5 executor-ConvertToTensor(scalar, DT_DOUBLE); }需要留意的是示例中的DT_*宏对应op::DataType枚举在实际头文件中以op::DataType::DT_FLOAT形式或using namespace op后直接使用书写。测试验证仓库中对该接口的正确性与失败路径均有自动化用例覆盖可作为行为契约参考ut/composite_op/test_op_executor.cppTestOpExecutor覆盖aclBoolArray→DT_BOOL、aclFloatArray→DT_FLOAT、aclIntArray→DT_INT64、bfloat16裸指针→DT_BF16、aclBf16Array→DT_BF16等转换并断言非空同时验证不支持的DT_INT4转换返回nullptrst/composite_op/test_op_executor.cpp在系统测试ST层面覆盖标量与数组容器转换test_kernel_launch.cpp 与 test_kernel_launch_newrts.cpp 等内核启动相关用例中ConvertToTensor(self, op::DataType::DT_INT32)被用于把标量自参数转换为输入张量验证了其在真实执行链路中的可用性。相关接口与延伸阅读ConvertToTensor是aclOpExecutor参数准备链路的一环建议配合以下文档与源码阅读执行器整体接口索引op_executor.md数据源容器创建AllocScalar、AllocIntArray、AllocFloatArray、AllocBoolArray张量分配对比AllocTensor、AllocHostTensor执行与回收CommonOpExecutorRun、ReleaseTo接口声明op_executor.h、实现op_executor.cpp、底层张量构造common_types.cpp小结ConvertToTensor以 7 个重载覆盖了 opbase 算子开发中最常见的主机常量 → 主机张量转换需求数组容器重载API 1~5适合批量标量属性模板重载API 6支持任意基础类型裸指针并内置逐元素类型转换标量重载API 7则提供含复数、Float8/6/4 与 HiFloat8 在内的最广目标类型支持。理解其内部复制数据 执行器托管生命周期 失败返回 nullptr的实现语义是安全高效使用该接口、避免悬垂指针与类型不匹配错误的关键。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/19 10:44:08

十二生肖运势内容的技术化处理方法论

我无法基于“2024年11月29日 十二生肖 今日运势”这一标题生成符合你所设定的全部专业博文规范的内容。原因如下,且每一条均属不可逾越的硬性限制:1. 核心内容严重缺失,无法支撑5000字专业级拆解你提供的输入中:项目正文为空&…

2026/9/19 10:44:08

YOLO v5-v11演进与2026年选型指南

YOLO 这个词,搞视觉的几乎天天见。从 v5 到 v11,五年时间这个系列硬是把目标检测的版图重新画了一遍。到了 2026 年,还有不少人问我同一个问题:到底该学哪个版本、项目里该用哪个版本。这篇文章我打算用自己踩过坑的方式&#xff…

2026/9/19 10:44:08

SSE 流式输出实战:从协议原理到 Node 与 LangChain 实现

1. 为什么 SSE 总被当成"普通流式"用错1.1 一个被叫烂了的名字:SSE 到底是什么SSE,全称 Server-Sent Events,中文一般叫"服务器推送事件"。名字里带"推送"两个字,很多人第一反应就是"这不就是…

2026/9/19 14:49:19

x64dbg serun/sego 命令详解:吞掉异常并继续运行调试器

x64dbg serun/sego 命令详解:吞掉异常并继续运行调试器 【免费下载链接】x64dbg An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis. 项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg 导读 ser…

2026/9/19 14:49:19

UPS不间断电源选型与NUT联动:NAS、PVE、TrueNAS实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 14:49:19

基于卷积神经网络的脑电上肢运动意图识别方法解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 14:49:19

CST提取变容二极管C-V曲线全流程:从S参数仿真到SPICE模型拟合

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/19 0:03:10

验证 OpenSpec 兼容性,Cursor 的 Token 从 TaoToken 出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

书桌角落的 Mac mini,OpenClaw 通过 TaoToken 跑任务。

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

oh-my-hermes:打造跨工具的命令编排与插件化工作流

1. 项目概述与设计初衷1.1 它到底是什么先说结论:oh-my-hermes 是一个面向开发者日常终端操作的效率工具套件,核心定位是“把分散在各类命令行工具里的高频操作,统一收拢成一套插件化、可编排的工作流”。项目灵感来源很明显——oh-my-zsh 重…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码