CANN opbase 数据类型工具:IsIntegralType 整数类型判定接口解析
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
本指南围绕 CANN opbase 算子库中op命名空间下的IsIntegralType接口展开,系统讲解其功能语义、函数原型、判定范围与源码实现,并结合头文件与单元测试给出算子开发中的典型使用场景。读完本文,你将掌握如何在算子实现中快速判断ge::DataType是否为整数类型,并了解它与IsFloatingType、IsComplexType、CanCast等数据类型工具函数的协作方式。
接口定位:opdev 数据类型工具族中的一员
在 CANN opbase 算子库中,算子开发者需要频繁处理ge::DataType枚举类型,例如在 Shape 推导、tiling 计算、参数校验等环节判断输入张量的数据类型。为统一此类判断逻辑,opbase 在 data_type_utils 接口总览 下提供了一组以Is、To、Check等动词命名的工具函数,包括:
- 类型分类判断:
IsBasicType、IsNumberType、IsRealNumberType、IsComplexType、IsFloatingType、IsIntegralType - 类型转换:
ToDataType、ToOpDataType、ToAclDataType、ToString - 类型运算与查询:
TypeSize、CanCast、PromoteType、CheckType
IsIntegralType是其中用于整数类型判定的核心函数,也是CanCast、PromoteType等复合逻辑的底层依赖之一。
功能说明与判定范围
IsIntegralType用于判断输入的数据类型是否为整数类型。根据接口文档,被判定为整数类型的包括以下 8 种:
| 整数类型 | 对应的 ge::DataType 枚举值 | 位宽 |
|---|---|---|
| Int8 | DT_INT8 | 8 位有符号 |
| Int16 | DT_INT16 | 16 位有符号 |
| Int32 | DT_INT32 | 32 位有符号 |
| Int64 | DT_INT64 | 64 位有符号 |
| Uint8 | DT_UINT8 | 8 位无符号 |
| Uint16 | DT_UINT16 | 16 位无符号 |
| Uint32 | DT_UINT32 | 32 位无符号 |
| Uint64 | DT_UINT64 | 64 位无符号 |
值得注意的是,bool(DT_BOOL)不在单参数版本的整数判定范围内。opbase 为 bool 单独提供了双参数重载版本(详见后文),使用时需要显式传入开关。
函数原型与参数说明
单参数版本的函数原型如下:
bool IsIntegralType(const ge::DataType type)| 参数 | 输入/输出 | 说明 |
|---|---|---|
| type | 输入 | 输入的数据类型,类型为ge::DataType枚举。 |
type参数用于传入待判定的数据类型,实际取值来自ge::DataType枚举,例如ge::DataType::DT_INT32。- 接口以值传递方式接收参数,不会修改调用方数据,也不依赖外部状态,因此可以在热路径中安全调用。
返回值说明
- 若
type属于上述 8 种整数类型之一,返回true; - 否则返回
false,包括浮点、复数、bool、字符串等非整数类型。
源码实现解析
IsIntegralType定义在 include/nnopbase/opdev/data_type_utils.h 中,实现为头文件内联函数,通过逐一与 8 个整数类型枚举值比较得出结果:
inline bool IsIntegralType(const ge::DataType type) { return (type == ge::DataType::DT_INT8 || type == ge::DataType::DT_INT16 || type == ge::DataType::DT_INT32 || type == ge::DataType::DT_INT64 || type == ge::DataType::DT_UINT8 || type == ge::DataType::DT_UINT16 || type == ge::DataType::DT_UINT32 || type == ge::DataType::DT_UINT64); }从源码结构可以归纳出三个实现要点:
- 全枚举显式比较:实现没有使用
CheckType的容器查找方式,而是用 8 个||短路比较直接判定。由于ge::DataType是枚举类型,编译期即可完成常量折叠,运行时开销极低,适合在算子的高频校验路径中反复调用。 - inline 内联设计:函数体声明为
inline,定义于头文件,与IsFloatingType、IsComplexType、TypeSize等接口同文件并列,保证零额外调用开销,也便于算子侧直接包含头文件使用。 - DT_MAX 之外的防御边界:同文件中的 TypeSize 等函数会先检查枚举值是否落在
[DT_FLOAT, DT_MAX)合法区间内;而IsIntegralType对任何未列出的枚举值一律返回false,语义上等价于"未知类型不属于整数类型"。
同一头文件在文件顶部还定义了若干短名常量(如i1 = DT_INT8、i4 = DT_INT32、u1 = DT_UINT8等),用于kPromoteTypesLookup类型提升表的紧凑书写,这也从侧面说明 8 种整数类型在类型运算体系中的基础地位。
含 bool 的重载版本:IsIntegralType(含 bool)
opbase 额外提供了带include_bool参数的重载版本,专门用于需要把 bool 视为整数的场景,其文档见 IsIntegralType(含bool):
bool IsIntegralType(const ge::DataType type, const bool include_bool)| 参数 | 输入/输出 | 说明 |
|---|---|---|
| type | 输入 | 输入的数据类型。 |
| include_bool | 输入 | 是否将 bool 视为整数类型。 |
源码实现如下(include/nnopbase/opdev/data_type_utils.h):
inline bool IsIntegralType(const ge::DataType type, const bool include_bool) { bool is_integral = IsIntegralType(type); return include_bool ? (is_integral || (type == ge::DataType::DT_BOOL)) : is_integral; }include_bool为true时,DT_BOOL也被视为整数类型;include_bool为false时,行为与单参数版本完全一致。
这一设计体现了 opbase 对"bool 是否算整数"这一语义分歧的显式处理:默认不将 bool 归入整数,需要时由调用方显式声明,避免在算子间产生隐式约定不一致。
调用示例
基础用法:非整数类型提前返回
以下示例来自接口文档,用于在算子入口校验数据类型:
// 校验dtype是否为整数类型,不是则提前返回 void Func(const ge::DataType type) { if (!IsIntegralType(type)) { return; } // 后续执行算子计算逻辑 }含 bool 的用法
// 校验dtype是否为整数类型(含bool),不是则提前返回 void Func(const ge::DataType type) { if (!IsIntegralType(type, true)) { return; } // 后续执行算子计算逻辑 }与错误码结合的参数校验
在实际算子实现中,通常配合日志与错误码使用,例如仅当类型为整数时才执行后续逻辑,否则记录错误并返回:
#include "opdev/data_type_utils.h" aclnnStatus Func(const ge::DataType type) { if (!op::IsIntegralType(type)) { // 记录错误日志并返回失败码,例如 ACLNN_INVALID_PARAM return ACLNN_INVALID_PARAM; } // 执行整数类型专属的算子计算逻辑 return ACLNN_SUCCESS; }在算子开发中的典型应用场景
IsIntegralType在 opbase 的类型体系中承担"整数性判定"这一基础职责,从同头文件的源码可以确认它与以下函数存在直接协作关系:
CanCast的类型安全校验(include/nnopbase/opdev/data_type_utils.h):CanCast在判断"浮点类型能否强转为整数类型"时调用IsIntegralType(to, false),明确禁止浮点到整数的隐式转换,防止精度丢失:
inline bool CanCast(const ge::DataType from, const ge::DataType to) { if (IsComplexType(from) && !IsComplexType(to)) { return false; } if (IsFloatingType(from) && IsIntegralType(to, false)) { return false; } if (from != ge::DataType::DT_BOOL && to == ge::DataType::DT_BOOL) { return false; } return true; }与
IsFloatingType、IsComplexType互补:同头文件中的IsFloatingType覆盖浮点/低精度浮点(含DT_BF16、DT_FLOAT8_E4M3FN、DT_FLOAT4_E2M1等新型低精度类型),IsComplexType覆盖三种复数类型。三者共同构成"整数 / 浮点 / 复数"的类型三分法,算子侧可按此组合实现完整的类型分支。单元测试印证:仓库的 test_data_type_utils.cpp 对同族接口
CanCast、CheckType等进行了断言验证(如EXPECT_TRUE(op::CanCast(op::DataType::DT_INT32, op::DataType::DT_FLOAT))),从侧面印证了IsIntegralType作为底层判定的正确性直接影响上层转换语义。
注意事项与版本提示
- 头文件 include/nnopbase/opdev/data_type_utils.h 中定义的接口位于
op命名空间,是当前推荐使用的版本。 - 仓库中还存在旧版头文件 include/nnopbase/opdev/op_common/data_type_utils.h,其函数位于
opcommon命名空间,功能与新版基本一致,但头文件内带有#warning编译告警,提示该头文件预计于 2027 年 6 月弃用,建议迁移到include/nnopbase/opdev下的新接口。 - 单参数版本不把 bool 视为整数;若业务语义需要将 bool 纳入整数范围,请使用双参数重载并传入
include_bool = true。
相关资源索引
- 接口文档:IsIntegralType、IsIntegralType(含bool)、data_type_utils 接口总览
- 头文件:include/nnopbase/opdev/data_type_utils.h(
op命名空间,推荐)、include/nnopbase/opdev/op_common/data_type_utils.h(opcommon命名空间,将弃用) - 源文件:src/nnopbase/common/utils/data_type_utils.cpp(
ToString、ToDataType、CalcShapeBytes等非内联实现) - 测试用例:tests/nnopbase/ut/composite_op/test_data_type_utils.cpp、tests/nnopbase/st/composite_op/test_data_type_utils.cpp
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考