- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
导读
本文系统讲解 asc-devkit(CANN 昇腾 AI 处理器算子开发语言)中 SIMD API 基础工具类AscendC::NumericLimits:它用于在 Kernel 内查询指定数据类型的最大值、最小值、无穷大、NaN 等极限值,并提供"标量返回 + 矢量填充"两种接口形态,是算子初始化缓冲区、构造哨兵值、做边界判断时最常用的工具类之一。读完本文,你将掌握全部 8 个接口(Max、Lowest、Min、Infinity、NegativeInfinity、QuietNaN、SignalingNaN、DeNormMin)的函数原型、参数约束、各数据类型的精确输出值,并能结合 接口头文件 的源码理解其底层位编码实现与产品支持差异。
NumericLimits 工具类概述
NumericLimits是 asc-devkit 提供的编译期(constexpr)数值极限查询工具类,用于查询指定数据类型的最大值、最小值、正负无穷大、安静 NaN、发信 NaN、最小正非正规值等属性,作用类似 C++ 标准库中的std::numeric_limits,但专为昇腾 AI Core 上的 Kernel 代码设计:接口全部以__aicore__标注、可在设备侧内联执行,并额外提供面向LocalTensor的矢量批量填充重载。
使用前需包含头文件:
#include "basic_api/kernel_operator_limits_intf.h"头文件的类定义位于AscendC命名空间,通过模板参数T指定待查询的数据类型,类定义原型如下(出自 接口头文件 与 简介文档):
template <typename T> struct NumericLimits { // 标量接口,返回值为标量 constexpr __aicore__ static inline T Max(); constexpr __aicore__ static inline T Lowest(); constexpr __aicore__ static inline T Min(); constexpr __aicore__ static inline T Infinity(); constexpr __aicore__ static inline T NegativeInfinity(); constexpr __aicore__ static inline T QuietNaN(); constexpr __aicore__ static inline T SignalingNaN(); constexpr __aicore__ static inline T DeNormMin(); // 矢量接口,为dstLocal前count个元素赋值 __aicore__ static inline void Max(const LocalTensor<T> &dstLocal, uint32_t count); __aicore__ static inline void Lowest(const LocalTensor<T> &dstLocal, uint32_t count); __aicore__ static inline void Min(const LocalTensor<T> &dstLocal, uint32_t count); __aicore__ static inline void Infinity(const LocalTensor<T> &dstLocal, uint32_t count); __aicore__ static inline void NegativeInfinity(const LocalTensor<T> &dstLocal, uint32_t count); __aicore__ static inline void QuietNaN(const LocalTensor<T> &dstLocal, uint32_t count); __aicore__ static inline void SignalingNaN(const LocalTensor<T> &dstLocal, uint32_t count); __aicore__ static inline void DeNormMin(const LocalTensor<T> &dstLocal, uint32_t count); };可以看出,每个属性都提供两种调用形态:
- 标量接口:
constexpr修饰、返回类型T的静态内联函数,可在编译期求值,适合作为常量使用; - 矢量接口:接受
LocalTensor<T>&目的操作数与元素个数count,将对应极限值批量写入张量的前count个元素。
8 个接口功能总览
| 接口名称 | 功能说明 | 数据类型 |
|---|---|---|
| Max | 返回指定数据类型的最大有限值。 | int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float |
| Lowest | 返回指定数据类型的最低有限值,即满足无其他有限值 y 符合 y < x 的有限值 x。 | int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float |
| Min | 返回指定数据类型的最小有限值(对浮点数为最小规约正数)。 | int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float |
| Infinity | 返回指定数据类型的正无穷大值。 | half、bfloat16_t、float |
| NegativeInfinity | 返回指定数据类型的负无穷大值。 | half、bfloat16_t、float |
| QuietNaN | 返回指定数据类型的安静 NaN 值(浮点尾数最高位为 1)。 | half、bfloat16_t、float |
| SignalingNaN | 返回指定数据类型的发信 NaN 值(浮点尾数最高位为 0)。 | half、bfloat16_t、float |
| DeNormMin | 返回指定数据类型的最小正的非正规值。 | half、bfloat16_t、float |
产品支持情况
NumericLimits 全部接口均为Ascend 950PR & 950DT 系列产品专属能力,其余产品线(Atlas A3 系列、Atlas A2 系列、Atlas 200I/500 A2 推理产品、Atlas 推理系列产品 AI Core / Vector Core、Atlas 训练系列产品)均不支持。从源码看,这与头文件中的__NPU_ARCH__编译期分支一一对应:当架构为 3510、5102、5162 时,接口才启用完整类型集(含 bfloat16_t)的支持检查,详见后文"源码实现原理"章节。
标量接口与矢量接口的通用说明
参数说明
矢量接口的公共参数如下(与 LocalTensor 的通用约定一致):
| 参数名 | 输入/输出 | 描述 |
|---|---|---|
| dst / dstLocal | 输出 | 目的操作数。类型为 LocalTensor,支持的 TPosition 为 VECIN / VECCALC / VECOUT。LocalTensor 的起始地址需要 32 字节对齐。 |
| count | 输入 | 输入数据元素个数。 |
返回值说明
- 标量接口:返回值为对应数据类型的极限值(类型为
T),且为constexpr,可在编译期参与常量表达式求值; - 矢量接口:无返回值(
void),通过写目的张量dst前count个元素完成赋值。
约束说明
- 标量接口无额外约束;
- 矢量接口内部使用 Memory 矢量计算下的数据填充接口 duplicate 填充前
count个元素,因此其地址对齐、count取值等约束需参照 duplicate 接口的约束说明。
接口逐一详解
Max:最大有限值
功能说明:返回指定数据类型的最大有限值(头文件见 Max.md)。
函数原型:
constexpr __aicore__ static inline T Max() // 标量接口 __aicore__ static inline void Max(const LocalTensor<T>& dst, uint32_t count) // 矢量接口支持数据类型(Ascend 950PR & 950DT):int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| uint8_t | 255 | 1111 1111 |
| int8_t | 127 | 0111 1111 |
| uint16_t | 65535 | 1111 1111 1111 1111 |
| int16_t | 32767 | 0111 1111 1111 1111 |
| half | 65504 | 0 11110 1111111111 |
| bfloat16_t | 3.4e+38 | 0 11111110 1111111 |
| uint32_t | 4294967295 | 1111 1111 1111 1111 1111 1111 1111 1111 |
| int32_t | 2147483647 | 0111 1111 1111 1111 1111 1111 1111 1111 |
| float | 3.4e+38 | 0 11111110 11111111111111111111111 |
调用示例:
// 标量接口:直接取得 int32_t 的最大值 2147483647 int32_t value = AscendC::NumericLimits<int32_t>::Max(); // 矢量接口:将 dstLocal 前 256 个元素全部填充为 int32_t 最大值 AscendC::NumericLimits<int32_t>::Max(dstLocal, 256);Lowest:最低有限值
功能说明:返回指定数据类型的最低有限值,即满足"无其他有限值 y 符合 y < x"的有限值 x。对整数类型即其最小可表示值,对浮点类型即其最大的负有限数(约等于负的最大值,区别于Min返回的最小正数)。详见 Lowest.md。
函数原型:
constexpr __aicore__ static inline T Lowest() __aicore__ static inline void Lowest(const LocalTensor<T>& dstLocal, uint32_t count)支持数据类型:与 Max 相同(int8_t、uint8_t、int16_t、uint16_t、half、bfloat16_t、int32_t、uint32_t、float)。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| uint8_t | 0 | 0000 0000 |
| int8_t | -128 | 1000 0000 |
| uint16_t | 0 | 0000 0000 0000 0000 |
| int16_t | -32768 | 1000 0000 0000 0000 |
| half | -65504 | 1 11110 1111111111 |
| bfloat16_t | -3.4e+38 | 1 11111110 1111111 |
| uint32_t | 0 | 0000 0000 0000 0000 0000 0000 0000 0000 |
| int32_t | -2147483648 | 1000 0000 0000 0000 0000 0000 0000 0000 |
| float | -3.4e+38 | 1 11111110 11111111111111111111111 |
调用示例:
int32_t value = AscendC::NumericLimits<int32_t>::Lowest(); // 标量:-2147483648 AscendC::NumericLimits<int32_t>::Lowest(dstLocal, 256); // 矢量:填充 256 个最低有限值Min:最小有限值
功能说明:返回指定数据类型的最小有限值;对浮点数类型来说,返回其最小规约正数(区别于Lowest的负向极值)。详见 Min.md。
函数原型:
constexpr __aicore__ static inline T Min() __aicore__ static inline void Min(const LocalTensor<T>& dst, uint32_t count)支持数据类型:与 Max 相同。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| uint8_t | 0 | 0000 0000 |
| int8_t | -128 | 1000 0000 |
| uint16_t | 0 | 0000 0000 0000 0000 |
| int16_t | -32768 | 1000 0000 0000 0000 |
| half | 6.1e-5 | 0 00001 0000000000 |
| bfloat16_t | 1.18e-38 | 0 00000001 0000000 |
| uint32_t | 0 | 0000 0000 0000 0000 0000 0000 0000 0000 |
| int32_t | -2147483648 | 1000 0000 0000 0000 0000 0000 0000 0000 |
| float | 1.18e-38 | 0 00000001 00000000000000000000000 |
调用示例:
int32_t value = AscendC::NumericLimits<int32_t>::Min(); // 标量:-2147483648 AscendC::NumericLimits<int32_t>::Min(dstLocal, 256); // 矢量:填充 256 个最小有限值注意:整数类型的
Min()与Lowest()输出相同(均为类型的最小值),而浮点类型两者语义不同——Lowest()返回负向极限(如 float 的 -3.4e38),Min()返回最小正规正数(如 float 的 1.18e-38)。
Infinity:正无穷大
功能说明:返回指定数据类型的正无穷大值(builtin_data_types)。详见 Infinity.md。
函数原型:
constexpr __aicore__ static inline T Infinity() __aicore__ static inline void Infinity(const LocalTensor<T>& dstLocal, uint32_t count)支持数据类型:half、bfloat16_t、float(仅浮点类型)。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| half | inf | 0 11111 0000000000 |
| bfloat16_t | inf | 0 11111111 0000000 |
| float | inf | 0 11111111 00000000000000000000000 |
调用示例:
float value = AscendC::NumericLimits<float>::Infinity(); // 标量:+inf AscendC::NumericLimits<float>::Infinity(dstLocal, 256); // 矢量:填充 256 个正无穷大值NegativeInfinity:负无穷大
功能说明:返回指定数据类型的负无穷大值。详见 NegativeInfinity.md。
函数原型:
constexpr __aicore__ static inline T NegativeInfinity() __aicore__ static inline void NegativeInfinity(const LocalTensor<T>& dstLocal, uint32_t count)支持数据类型:half、bfloat16_t、float。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| half | -inf | 1 11111 0000000000 |
| bfloat16_t | -inf | 1 11111111 0000000 |
| float | -inf | 1 11111111 00000000000000000000000 |
调用示例:
float value = AscendC::NumericLimits<float>::NegativeInfinity(); // 标量:-inf AscendC::NumericLimits<float>::NegativeInfinity(dstLocal, 256); // 矢量:填充 256 个负无穷大值QuietNaN:安静 NaN
功能说明:返回指定数据类型的**安静 NaN(Quiet NaN)**值,其浮点尾数最高位为 1,在参与运算时不触发浮点异常。详见 QuietNaN.md。
函数原型:
constexpr __aicore__ static inline T QuietNaN() __aicore__ static inline void QuietNaN(const LocalTensor<T>& dstLocal, uint32_t count)支持数据类型:half、bfloat16_t、float。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| half | nan | 0 11111 1000000000 |
| bfloat16_t | nan | 0 11111111 1000000 |
| float | nan | 0 11111111 10000000000000000000000 |
调用示例:
float value = AscendC::NumericLimits<float>::QuietNaN(); // 标量:quiet NaN AscendC::NumericLimits<float>::QuietNaN(dstLocal, 256); // 矢量:填充 256 个 NaN 值SignalingNaN:发信 NaN
功能说明:返回指定数据类型的**发信 NaN(Signaling NaN)**值,其浮点尾数最高位为 0;当运算操作数包含发信 NaN 时通常会触发浮点无效操作异常(信令)。详见 SignalingNaN.md。
函数原型:
constexpr __aicore__ static inline T SignalingNaN() __aicore__ static inline void SignalingNaN(const LocalTensor<T>& dstLocal, uint32_t count)支持数据类型:half、bfloat16_t、float。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| half | nan | 0 11111 0100000000 |
| bfloat16_t | nan | 0 11111111 0100000 |
| float | nan | 0 11111111 01000000000000000000000 |
调用示例:
float value = AscendC::NumericLimits<float>::SignalingNaN(); // 标量:signaling NaN AscendC::NumericLimits<float>::SignalingNaN(dstLocal, 256); // 矢量:填充 256 个 NaN 值对比 QuietNaN 与 SignalingNaN 的位编码(以 half 为例):两者指数位均为全 1(11111),区别仅在尾数——QuietNaN 尾数最高位为 1(
1000000000),SignalingNaN 尾数最高位为 0(0100000000),与 IEEE 754 标准定义一致。
DeNormMin:最小正非正规值
功能说明:返回指定数据类型的最小正的非正规值(subnormal / denormal 最小值),即浮点尾数最低位为 1、指数位全 0 时的最小可表示正数。详见 DeNormMin.md。
函数原型:
constexpr __aicore__ static inline T DeNormMin() __aicore__ static inline void DeNormMin(const LocalTensor<T>& dstLocal, uint32_t count)支持数据类型:half、bfloat16_t、float。
各数据类型输出:
| 数据类型 | 十进制数 | 二进制各 bit 位 |
|---|---|---|
| half | 5.96e-8 | 0 00000 0000000001 |
| bfloat16_t | 9.2e-41 | 0 00000000 0000001 |
| float | 1.4e-45 | 0 00000000 00000000000000000000001 |
调用示例:
float value = AscendC::NumericLimits<float>::DeNormMin(); // 标量:1.4e-45 AscendC::NumericLimits<float>::DeNormMin(dstLocal, 256); // 矢量:填充 256 个最小正非正规值源码实现原理深度解析
1. 编译期类型支持检查:static_assert + SupportType
接口头文件 kernel_operator_limits_intf.h 在实现入口处使用static_assert结合SupportType<T, ...>()做类型合法性检查。SupportType定义于 kernel_utils_ceil_oom_que.h,是一个编译期递归模板,逐一对T与候选类型做IsSameType匹配:
template <typename T, typename U, typename... Args> __aicore__ constexpr bool SupportType() { if constexpr (sizeof...(Args) > 0) { return IsSameType<T, U>::value || SupportType<T, Args...>(); } return IsSameType<T, U>::value; }因此,当调用NumericLimits<int64_t>::Max()这类不支持的类型时,编译器会在 Kernel 编译阶段直接报错"current data type is not supported on current device!",把错误拦截在编译期而非运行期。
2. 类型集随架构条件编译
从 接口头文件 可以看到,同一接口在不同__NPU_ARCH__下允许的类型集不同:
#if (__NPU_ARCH__ == 3510) || (__NPU_ARCH__ == 5102) || (__NPU_ARCH__ == 5162) static_assert(SupportType<T, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, half, float, bfloat16_t>(), ...); #else static_assert(SupportType<T, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, half, float>(), ...); #endif即仅 Ascend 950PR & 950DT(对应架构 3510 / 5102 / 5162)支持 bfloat16_t 这一类型,其余架构连Infinity等浮点接口也仅支持 half 与 float。这与前文"产品支持情况"中的表格完全一致,也从源码层面解释了文档中 bfloat16_t 仅在 950 系列可用的原因。
3. 极限值的位编码实现:GetScalarBitcodeValue
标量接口并非做运行时计算,而是直接返回预先算好的十六进制位编码(bitcode),通过联合体做位级重解释。辅助函数定义于 kernel_utils_struct_norm_sort.h:
template <typename T> constexpr __aicore__ inline uint64_t GetScalarBitcodeValue(T scalarValue) { union ScalarBitcode { __callee__ ScalarBitcode() {} T input; uint64_t output; } data; data.input = scalarValue; return data.output; }以Max()为例(接口头文件),每个类型分支用if constexpr匹配后返回对应编码,例如:
uint8_t→0xFFu(255,二进制1111 1111);int32_t→0x7FFFFFFFu(2147483647);half→0x7BFFu(65504,二进制0 11110 1111111111);float→0x7F7FFFFFu(3.4e38);bfloat16_t→0x7F7Fu(3.4e38,仅 950 系列分支)。
对照前文输出表可以发现:文档中每个十进制值与二进制位串,都能在源码的十六进制 bitcode 中找到精确对应。这正是该类全部标量接口标记constexpr的原因——位编码在编译期即可内联展开,设备侧零运行时开销。
4. 矢量接口统一委托 Duplicate
矢量接口实现极其简洁,全部委托给 Memory 矢量计算的数据填充接口Duplicate(接口头文件):
__aicore__ static inline void Max(const LocalTensor<T>& dst, uint32_t count) { Duplicate(dst, Max(), count); } __aicore__ static inline void Infinity(const LocalTensor<T>& dst, uint32_t count) { Duplicate(dst, Infinity(), count); } // ... 其余接口同理即:先由标量接口求出极限值,再由Duplicate把该标量广播填充到dst的前count个元素。这也解释了文档"矢量接口使用 duplicate 填充前 count 个元素"的约束来源——矢量接口的对齐、count 上限等要求均继承自 Duplicate 接口。
5. SIMT 模式编译保护
头文件开头(kernel_operator_limits_intf.h)还有一层编译保护:
#if defined(__NPU_COMPILER_INTERNAL_PURE_SIMT__) #error "kernel_operator_limits_intf.h cannot be used with compile flag --enable-simt enabled." #endif即该头文件(连同 NumericLimits 类)不能在开启--enable-simt的纯 SIMT 编译模式下使用,编译时会直接报错提示。
测试验证:参数化用例覆盖全部接口与类型组合
仓库在 test_operator_numeric_limits.cpp 中为 NumericLimits 提供了完整的 Kernel 侧用例(同目录下另有ascendc_case_mc62cm12aa版本):
- Kernel 内先
Duplicate(dstLocal, 0, count + 256)将缓冲区清零,再按category分别调用 8 个矢量接口之一,最后DataCopy回写 GM; - 通过
INSTANTIATE_TEST_CASE_P参数化展开全部组合:Max/Lowest/Min覆盖 9 种类型(uint8_t、int8_t、uint16_t、int16_t、uint32_t、int32_t、half、bfloat16_t、float),Infinity/NegativeInfinity/QuietNaN/SignalingNaN/DeNormMin覆盖 3 种浮点类型(half、bfloat16_t、float),合计 42 组用例; - 校验方式是对比设备侧输出与预期位模式(示例中验证写入后的字节),确保接口在不同类型下填充值与文档输出表一致。
该用例可以作为你自行验证 NumericLimits 行为、或编写自定义 Kernel 时的参考骨架。
完整可运行示例
以下组合了标量与矢量两种形态,演示一个典型的"初始化 + 使用"流程:
#include "kernel_operator.h" using namespace AscendC; constexpr int32_t BLOCK_LEN = 256; class KernelNumericLimits { public: __aicore__ inline KernelNumericLimits() {} __aicore__ inline void Init(GM_ADDR dstGm, uint32_t dstSize) { dstGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ float*>(dstGm), dstSize); pipe.InitBuffer(outQueue, 1, dstSize * sizeof(float)); } __aicore__ inline void Process() { LocalTensor<float> dstLocal = outQueue.AllocTensor<float>(); // 标量接口:取得各极限值 float maxVal = NumericLimits<float>::Max(); float minVal = NumericLimits<float>::Min(); float infVal = NumericLimits<float>::Infinity(); float nanVal = NumericLimits<float>::QuietNaN(); // 矢量接口:将正无穷大广播填充到前 BLOCK_LEN 个元素 NumericLimits<float>::Infinity(dstLocal, BLOCK_LEN); // 此后可结合 maxVal/minVal/nanVal 做边界判断或哨兵比较 // ... outQueue.EnQue(dstLocal); DataCopy(dstGlobal, outQueue.DeQue<float>()); outQueue.FreeTensor(dstLocal); } private: GlobalTensor<float> dstGlobal; TPipe pipe; TQue<TPosition::VECOUT, 1> outQueue; };使用建议与注意事项
- 优先使用标量接口做常量:8 个标量接口均为
constexpr,建议直接用于初始化局部常量或参与编译期表达式,避免重复调用产生额外开销。 - 区分 Min 与 Lowest 的语义:整数场景两者等价,浮点场景
Min()是最小规约正数、Lowest()是负向最大幅值,按业务语义选用,防止哨兵值设置错误。 - 注意类型白名单:
Max/Lowest/Min不适用于 int64_t、double 等类型;Infinity/NegativeInfinity/QuietNaN/SignalingNaN/DeNormMin仅适用于 half、bfloat16_t、float。非法类型会在编译期被static_assert拦截。 - bfloat16_t 与架构强相关:bfloat16_t 仅在 Ascend 950PR & 950DT(架构 3510/5102/5162)可用,跨架构移植 Kernel 时需确认目标产品的类型支持范围。
- 矢量接口受 Duplicate 约束:
dst起始地址需 32 字节对齐,TPosition 需为 VECIN/VECCALC/VECOUT,count取值需满足 duplicate 接口的约束。 - 禁止在 SIMT 编译模式下使用:开启
--enable-simt编译时包含该头文件会直接报错,SIMT 场景应选用 SIMT-API 下的等价能力。
相关资源
- 接口头文件:include/basic_api/kernel_operator_limits_intf.h
- 类型支持检查工具:impl/basic_api/utils/kernel_utils_ceil_oom_que.h
- 位编码工具:impl/basic_api/utils/kernel_utils_struct_norm_sort.h
- 矢量接口依赖的填充接口:Duplicate
- 目的操作数类型:LocalTensor
- 内置数据类型:builtin_data_types
- 接口测试用例:test_operator_numeric_limits.cpp
- 文档索引:numericlimits_utils.md
- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
相关推荐
NanaZip常见问题避坑指南:右键菜单不显示、安全模式失效等8大难题完整解决方案
NanaZip常见问题避坑指南:右键菜单不显示、安全模式失效等8大难题完整解决方案 NanaZip 是一款基于 7 Zip 深度定制的开源压缩软件,专为 Win
人工智能深度学习算子库CANNAscendasc-devkit 昇腾算子开发:TQue 队列资源管理 API 完整指南
asc devkit 昇腾算子开发:TQue 队列资源管理 API 完整指南 导读 TQue(Template Queue)是 asc devkit 中负责算子
人工智能深度学习算子库CANNAscend昇腾算子开发实战:ReduceRepeat 归约接口四大场景全解析(基于 asc-devkit 多场景样例)
昇腾算子开发实战:ReduceRepeat 归约接口四大场景全解析(基于 asc devkit 多场景样例) ReduceRepeat 是 CANN 昇腾AI处
人工智能深度学习算子库CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考