CANN opbase aclTensor::SetIntData 详解向 Host 侧张量批量写入整型数据【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读SetIntData是 CANN opbase 基础框架库中aclTensor提供的一组数据写入接口之一专门用于将int64_t类型内存块中的数据批量写入由AllocHostTensor申请的 Host 侧张量并在写入前按目标数据类型自动完成类型转换。本文以 SetIntData 官方英文文档 为主体结合仓库源码与单元测试完整讲解其函数原型、参数语义、返回值与约束、调用示例、底层实现原理及最佳实践帮助算子开发者正确、高效地完成 Host 侧张量的初始化与数据填充。功能概述在编写自定义算子、构造aclnn入参或做算子调试时经常需要在 Host 侧准备张量数据例如构造输入、构造权重、准备用于校验的期望数据。SetIntData正是为此提供的一条便捷通道针对通过AllocHostTensor申请得到的 Host 侧aclTensor用一块int64_t类型的内存初始化张量数据。其核心价值在于「一处 int64 内存、多种目标数据类型」数据源统一以int64_t形式提供写入时按照dataType参数指定的目标类型做类型转换后再落盘到张量存储区省去了开发者手工static_cast和逐元素拷贝的工作。函数原型void SetIntData(const int64_t *value, uint64_t size, op::DataType dataType)该接口是aclTensor的成员函数声明位于 include/nnopbase/opdev/common_types.h通过input-SetIntData(...)方式调用。参数说明参数输入/输出说明value输入指向需要写入 aclTensor 的数据内存指针类型为const int64_t*。size输入需要写入的元素个数类型为uint64_t表示从value指向的数组中读取并写入的元素数量。dataType输入目标数据类型类型为op::DataType即ge::DataType。数据会先转换为该指定类型再写入 aclTensor。其中op::DataType枚举的常用取值及其数值对应关系从源码中不支持类型的错误提示可以确认包括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)。返回值说明无返回值void。约束说明入参指针value不能为空nullptr。该接口仅对 Host 侧张量生效从源码实现看只有当张量的TensorPlacement为kOnHost时才会执行数据写入详见下文源码解析。size应不大于value指向数组的实际长度也不应超过目标张量的元素个数否则会造成越界读写。调用示例官方文档给出的最小示例初始化一块 int64 内存赋值给 input 的前 10 个元素。// 初始化一块 int64 内存赋值给 input 的前 10 个元素 void Func(const aclTensor *input) { int64_t myArray[10]; input-SetIntData(myArray, 10, DT_INT64); }更贴合实际工程场景的完整流程是「先申请 Host 张量再写入数据」例如#include nnopbase/opdev/common_types.h void InitTensor(aclOpExecutor executor) { // 1. 通过 AllocHostTensor 申请 shape 为 {100} 的 host 侧张量 aclTensor *tensor executor.AllocHostTensor({100}, op::DataType::DT_INT32, op::Format::FORMAT_ND); if (tensor nullptr) { return; } // 2. 用 int64 内存块初始化数据写入时自动转换为 DT_INT32 int64_t data[100] {1}; tensor-SetIntData(data, 100, op::DataType::DT_INT32); }也可以对同一个张量以不同目标类型多次调用SetIntData利用类型转换能力一次性完成多份数据准备。源码级实现原理1. 调用链SetIntData → SetData → 逐元素类型转换SetIntData本身只是一个薄封装真正的逻辑在SetData模板中。实现位于 src/nnopbase/common/utils/common_types.cppvoid aclTensor::SetIntData(const int64_t* value, uint64_t size, op::DataType dataType) { SetData(value, size, dataType); }而SetData模板common_types.cpp#L658-L666首先校验张量是否为 Host 侧GetPlacement() op::TensorPlacement::kOnHost然后按元素循环调用单元素写入template typename T void aclTensor::SetData(const T* value, uint64_t size, op::DataType dataType) { if (this-GetPlacement() op::TensorPlacement::kOnHost) { for (uint64_t i 0; i size; i) { SetData(i, value[i], dataType); } } }2. 数据类型分派与转换规则单元素写入函数SetData(int64_t index, const T value, op::DataType dataType)common_types.cpp#L588-L656按dataType做 switch 分派将int64_t源值转换为目标类型后写入存储地址整型目标DT_INT8→int8_t、DT_INT16→int16_t、DT_INT32→int32_t、DT_INT64→int64_t以及对应的无符号类型DT_UINT8/16/32/64浮点目标DT_FLOAT→float、DT_DOUBLE→double、DT_FLOAT16→op::fp16_t、DT_BF16→op::bfloat16布尔目标DT_BOOL走专门的SetDataByBoolcommon_types.cpp#L568-L586对浮点及各类自定义浮点类型fp16、bfloat16、Float8/Float6/Float4 系列、HiFloat4/8按「绝对值是否大于等于float精度 epsilon」判定布尔值其余类型直接static_castbool其余类型落入default分支通过OP_LOGE_FOR_NOT_SUPPORTED_DATA_TYPE上报不支持的数据类型错误并打印支持范围[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)]。常规类型的转换通过SetDataByDataTypecommon_types.cpp#L556-L566完成直接static_castdataType(value)对于自定义浮点类型为避免类型转换歧义先经double中转再转换。这意味着int64_t源数据写入浮点目标时可能存在精度损失写入整型目标时可能存在截断/溢出开发者需自行保证数值范围合理。3. 前置依赖AllocHostTensorSetIntData的使用前提是张量由AllocHostTensor申请得到。aclOpExecutor提供了大量重载src/nnopbase/composite_op/aclnn_engine/op_executor.cpp#L410-L527典型形式包括AllocHostTensor(const op::Shape shape, op::DataType datatype, op::Format format)按 shape 申请空 Host 张量申请后配合SetIntData填充数据AllocHostTensor(const int64_t* value, uint64_t size, op::DataType dataType)直接用int64_t数组初始化 Host 张量等效于「申请 SetIntData」两步合并。从源码结构看AllocHostTensor内部创建aclTensor对象并登记到allocatedObjList_/allocatedTensorList_中统一管理生命周期返回值失败时如非法数据类型返回nullptr。接口族内同级的还有SetBoolData、SetFloatData、SetFp16Data、SetBf16Data以及 Float8/Float6/Float4/HiFloat 等各类自定义浮点数据写入接口common_types.cpp#L677-L742SetIntData与它们共用同一套SetData核心逻辑。测试用例验证仓库单元测试 tests/nnopbase/ut/composite_op/test_op_executor.cpp#L99-L112 对SetIntData的典型用法做了覆盖验证先通过executor.AllocHostTensor({100}, DataType::DT_DOUBLE, Format::FORMAT_ND)申请一个 100 元素的 Host 张量再以同一块int64_t data[100]分别以DT_INT64、DT_UINT64、DT_INT32、DT_UINT32、DT_INT16、DT_UINT16、DT_INT8、DT_UINT8、DT_DOUBLE等目标类型反复调用SetIntData验证了「int64 数据源 任意受支持目标类型」的转换写入路径。功能测试 tests/nnopbase/st/composite_op/test_op_executor.cpp 中也有对应场景读者可结合测试代码验证接口行为。使用注意事项与最佳实践仅限 Host 侧张量SetIntData只对TensorPlacement kOnHost的张量写入生效源码通过GetPlacement()判断。如果对 Device 侧张量调用数据不会写入请改用其他设备侧数据搬运机制。确保指针非空value传入nullptr属于未定义行为调用前务必判空文档约束亦明确「入参指针不能为空」。控制元素个数size是待写入的元素个数而不是字节数。value数组长度与目标张量容量都要大于等于size防止越界。注意类型转换语义int64_t源数据写入窄整型如DT_INT8或浮点如DT_FLOAT时会按 C 转换规则发生截断或精度损失写入DT_BOOL时采用「绝对值 ≥ float epsilon」的判定规则。业务上应保证数值范围在目标类型可表示范围内。匹配数据类型枚举dataType需落在源码支持的枚举范围内否则会触发OP_LOGE_FOR_NOT_SUPPORTED_DATA_TYPE错误日志。支持范围以源码中打印的[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)]为准。与接口族协同使用若源数据本身就是浮点或自定义浮点类型可优先选用SetFloatData、SetFp16Data、SetBf16Data等对应接口避免不必要的 int64 中转转换。相关文档SetIntData 英文文档 与 SetIntData 中文文档common_types 接口族总览英文 与 common_types 接口族总览中文接口声明include/nnopbase/opdev/common_types.h核心实现src/nnopbase/common/utils/common_types.cppHost 张量申请实现src/nnopbase/composite_op/aclnn_engine/op_executor.cpp单元测试tests/nnopbase/ut/composite_op/test_op_executor.cpp【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考