Cast

函数功能

根据源操作数和目的操作数Tensor的数据类型进行精度转换。

在介绍不同的类型转换模式之前,先介绍下浮点数的表示方式:

表1 精度转换规则

src类型

dst类型

类型转换模式介绍

float

float

将src 按照round_mode 取整,仍以float 格式存入dst 中。

示例:输入0.5

CAST_RINT 模式输出0.0,CAST_FLOOR 模式输出0.0,CAST_CEIL 模式出1.0,CAST_ROUND 模式输出1.0,CAST_TRUNC 模式输出0.0。

half

将src 按照round_mode 取到half所能表示的数,以half格式(溢出默认按照饱和处理)存入dst中。

示例:输入0.5+2-12,写成float的表示形式:2-1 * (1+2-11),因此E=-1+127=126,M=2-11

half的指数位可以表示的出2-1,有E=-1+15=14,但half只有10 bit尾数位,因此灰色部分要进行舍入。

CAST_RINT 模式舍入得尾数0000000000,E=14,M=0,最终表示的结果为0.5;

CAST_FLOOR 模式舍入得尾数0000000000,E=14,M=0,最终表示的结果为0.5;

CAST_CEIL 模式舍入得尾数0000000001,E=14,M=2-10,最终表示的结果为0.5+2-11

CAST_ROUND 模式舍入得尾数0000000001,E=14,M=2-10,最终表示的结果为0.5+2-11

CAST_TRUNC 模式舍入得尾数0000000000,E=14,M=0,最终表示的结果为0.5;

CAST_ODD 模式舍入得尾数0000000001,E=14,M=2-10,最终表示的结果为0.5+2-11

int64_t

将src按照round_mode取整,以int64_t格式(溢出默认按照饱和处理)存入dst中。

示例:输入222+0.5

CAST_RINT 模式输出222,CAST_FLOOR 模式输出222,CAST_CEIL 模式出222 + 1,CAST_ROUND 模式输出222+1,CAST_TRUNC 模式输出222

int32_t

将src按照round_mode取整,以int32_t格式(溢出默认按照饱和处理)存入dst中。

示例:输入222 + 0.5

CAST_RINT 模式输出222,CAST_FLOOR 模式输出222 ,CAST_CEIL 模式出222+1,CAST_ROUND 模式输出222+1,CAST_TRUNC 模式输出222

int16_t

将src按照round_mode取整,以int16_t格式(溢出默认按照饱和处理)存入dst中。

示例:输入222+0.5

CAST_RINT 模式输出215-1,CAST_FLOOR 模式输出215-1,CAST_CEIL 模式出215-1,CAST_ROUND 模式输出215-1,CAST_TRUNC 模式输出215-1(溢出处理)。

half

float

将src以float格式存入dst中,不存在精度转换问题,无舍入模式。

示例:输入1.5-2-10,输出1.5-2-10

int32_t

将src按照round_mode取整,以int32_t格式存入dst中。

示例:输入-1.5

CAST_RINT 模式输出-2,CAST_FLOOR 模式输出-2,CAST_CEIL 模式出-1,CAST_ROUND 模式输出-2,CAST_TRUNC 模式输出-1。

int16_t

将src按照round_mode取整,以int16_t格式(溢出默认按照饱和处理)存入dst中。

示例:输入27-0.5

CAST_RINT 模式输出27,CAST_FLOOR 模式输出27-1,CAST_CEIL 模式出27,CAST_ROUND 模式输出27,CAST_TRUNC 模式输出27-1。

int8_t

将src按照round_mode取整,以int8_t格式(溢出默认按照饱和处理)存入dst中。

示例:输入27-0.5

CAST_RINT 模式输出27-1,CAST_FLOOR 模式输出27-1,CAST_CEIL 模式出27-1,CAST_ROUND 模式输出27-1,CAST_TRUNC 模式输出27-1(溢出处理)。

uint8_t

将src按照round_mode取整,以uint8_t格式(溢出默认按照饱和处理)存入dst中。

示例:输入1.75

CAST_RINT 模式输出2,CAST_FLOOR 模式输出1,CAST_CEIL 模式出2,CAST_ROUND 模式输出2,CAST_TRUNC 模式输出1。

uint8_t

half

将src以half格式存入dst中,不存在精度转换问题,无舍入模式。;

示例:输入1,输出1.0

int8_t

half

将src以half格式存入dst中,不存在精度转换问题,无舍入模式。

示例:输入-1,输出-1.0

int16_t

half

将src按照round_mode取到half所能表示的数,以half格式存入dst中。

示例:输入212+2,写成half的表示形式:212 * (1+2-11),要求E=12+15=27,M=2-11

由于half只有10 bit尾数位,因此灰色部分要进行舍入。

CAST_RINT 模式舍入得尾数0000000000,E=27,M=0,最终表示的结果为212

CAST_FLOOR 模式舍入得尾数0000000000,E=27,M=0,最终表示的结果为212

CAST_CEIL 模式舍入得尾数0000000001,E=27,M=2-10,最终表示的结果为212+4;

CAST_ROUND 模式舍入得尾数0000000001,E=27,M=2-10,最终表示的结果为212+4;

CAST_TRUNC 模式舍入得尾数0000000000,E=27,M=0,最终表示的结果为212

float

将src以float格式存入dst中,不存在精度转换问题,无舍入模式。

示例:输入215-1,输出215-1

int32_t

float

将src按照round_mode取到float所能表示的数,以float格式存入dst中。

示例:输入225+3,写成float的表示形式:225 * (1+2-24+2-25),要求E=25+127=152, M=2-24+2-25

由于float只有23 bit尾数位,因此灰色部分要进行舍入。

CAST_RINT 模式舍入得尾数00000000000000000000001,E=152,M=2-23,最终表示的结果为225+4;

CAST_FLOOR 模式舍入得尾数00000000000000000000000,E=152,M=0,最终表示的结果为225

CAST_CEIL 模式舍入得尾数00000000000000000000001,E=152,M=2-23,最终表示的结果为225+4;

CAST_ROUND 模式舍入得尾数00000000000000000000001,E=152,M=2-23,最终表示的结果为225+4;

CAST_TRUNC 模式舍入得尾数00000000000000000000000,E=152,M=0,最终表示的结果为225

int64_t

将src以int64_t格式存入dst中,不存在精度转换问题,无舍入模式。

示例:输入231-1,输出231-1

int16_t

将src以int16_t格式(溢出默认按照饱和处理)存入dst中,不存在精度转换问题,无舍入模式。

示例:输入231-1,输出215-1

int64_t

int32_t

将src以int32_t格式(溢出默认按照饱和处理)存入dst中,不存在精度转换问题,无舍入模式。

示例:输入231,输出231-1

float

将src按照round_mode取到float所能表示的数,以float格式存入dst中。

示例:输入235+212+211,写成float的表示形式:235 * (1+2-23+2-24),要求E=35+127=162,M=2-23+2-24

由于float只有23 bit尾数位,因此灰色部分要进行舍入。

CAST_RINT 模式舍入得尾数00000000000000000000010,E=162,M=2-22,最终表示的结果为235+213

CAST_FLOOR 模式舍入得尾数00000000000000000000001,E=162,M=2-23,最终表示的结果为225+212

CAST_CEIL模式舍入得尾数00000000000000000000010,E=162,M=2-22,最终表示的结果为225+213

CAST_ROUND模式舍入得尾数00000000000000000000010,E=162,M=2-22,最终表示的结果为225+213

CAST_TRUNC模式舍入得尾数00000000000000000000001,E=162,M=2-23,最终表示的结果为225+212

函数原型

表2 0-3级接口原型定义

接口级别

原型定义

0级接口

  • mask参数使用逐bit模式,该模式的具体介绍请参考表3中的mask参数说明:

    template <typename T1, typename T2> __aicore__ inline void Cast(const LocalTensor<T1>& dstLocal, const LocalTensor<T2>& srcLocal, const RoundMode& round_mode, uint64_t mask[2], const uint8_t repeatTimes, const UnaryRepeatParams& repeatParams);

  • mask参数使用连续模式,该模式的具体介绍请参考表3中的mask参数说明:

    template <typename T1, typename T2> __aicore__ inline void Cast(const LocalTensor<T1>& dstLocal, const LocalTensor<T2>& srcLocal, const RoundMode& round_mode, uint64_t mask, const uint8_t repeatTimes, const UnaryRepeatParams& repeatParams);

2级接口

template <typename T1, typename T2> __aicore__ inline void Cast(const LocalTensor<T1>& dstLocal, const LocalTensor<T2>& srcLocal, const RoundMode& round_mode, uint32_t calCount);

参数说明

表3 0级接口参数说明

参数名

输入/输出

描述

dstLocal

输出

目的操作数。

类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。

Atlas 训练系列产品,支持的数据类型见表5

Atlas推理系列产品AI Core,支持的数据类型见表6

Atlas A2训练系列产品,支持的数据类型见表7

srcLocal

输入

源操作数。

类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。

Atlas 训练系列产品,支持的数据类型见表5

Atlas推理系列产品AI Core,支持的数据类型见表6

Atlas A2训练系列产品,支持的数据类型见表7

round_mode

输入

精度转换处理模式,类型是RoundMode。

RoundMode为枚举类型,用以控制精度转换处理模式,具体定义为:

enum class RoundMode {
    CAST_NONE = 0,  // 在转换有精度损失时表示CAST_RINT模式,不涉及精度损失时表示不取整
    CAST_RINT,      // rint,四舍六入五成双取整
    CAST_FLOOR,     // floor,向负无穷取整
    CAST_CEIL,      // ceil,向正无穷取整
    CAST_ROUND,     // round,四舍五入取整
    CAST_TRUNC,     // trunc,向零取整
    CAST_ODD,       // Von Neumann rounding,最近邻奇数取整
};

对于Atlas 训练系列产品,CAST_ROUND表示反向0取整,远离0,对正数 x.y 变成(x+1),对负数 -x.y,变成 -(x+1)。

mask

输入

mask用于控制每次迭代内参与计算的元素。

  • 连续模式:表示前面连续的多少个元素参与计算。数据类型为uint64。取值范围和操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同。当源操作数或目的操作数为16位时,mask∈[1, 128];当源操作数或目的操作数为32位时,mask∈[1, 64];当源操作数或目的操作数为64位时,mask∈[1, 32]。
  • 逐bit模式:可以按位控制哪些元素参与计算,bit位的值为1表示参与计算,0表示不参与。参数类型为长度为2的uint64_t类型数组。

    例如,mask=[8, 0],8=0b1000,表示仅第4个元素参与计算。

    参数取值范围和操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同。当源操作数或目的操作数为16位时,mask[0]、mask[1]∈[0, 264-1]并且不同时为0;当源操作数或目的操作数为32位时,mask[1]为0,mask[0]∈(0, 264-1];当源操作数或目的操作数为64位时,mask[1]为0,mask[0]∈(0, 232-1]。

  • 当源操作数和目的操作数位数不同时,以数据类型的字节较大的为准。例如,源操作数为half类型,目的操作数为int32_t类型,计算mask时以int32_t为准。

repeatTimes

输入

重复迭代次数。矢量计算单元,每次读取连续的256 Bytes数据进行计算,为完成对输入数据的处理,必须通过多次迭代(repeat)才能完成所有数据的读取与计算。repeatTimes表示迭代的次数。关于该参数的具体描述请参考重复迭代次数-Repeat times

UnaryRepeatParams

输入

控制操作数地址步长的数据结构。结构体内包含操作数相邻迭代间相同block的地址步长,操作数同一迭代内不同block的地址步长等参数。

该数据结构的定义请参考UnaryRepeatParams

相邻迭代间相同block的地址步长参数的详细说明请参考相邻迭代间相同block的地址步长;同一迭代内不同block的地址步长参数请参考同一迭代内不同block的地址步长

表4 2级接口参数说明

参数名

输入/输出

描述

dstLocal

输出

目的操作数。

类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。

Atlas 训练系列产品,支持的数据类型见表5

Atlas推理系列产品AI Core,支持的数据类型见表6

Atlas A2训练系列产品,支持的数据类型见表7

srcLocal

输入

源操作数。

类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。

Atlas 训练系列产品,支持的数据类型见表5

Atlas推理系列产品AI Core,支持的数据类型见表6

Atlas A2训练系列产品,支持的数据类型见表7

round_mode

输入

精度转换处理模式,类型是RoundMode。

RoundMode为枚举类型,用以控制精度转换处理模式,具体定义为:

enum class RoundMode {
    CAST_NONE = 0,  // 在转换有精度损失时表示CAST_RINT模式,不涉及精度损失时表示不取整
    CAST_RINT,      // rint,四舍六入五成双取整
    CAST_FLOOR,     // floor,向负无穷取整
    CAST_CEIL,      // ceil,向正无穷取整(C语言ceil)
    CAST_ROUND,     // round,四舍五入取整
    CAST_TRUNC,     // trunc,向零取整
    CAST_ODD,       // Von Neumann rounding,最近邻奇数取整
};

calCount

输入

输入数据元素个数。

表5 Atlas 训练系列产品 Cast指令参数说明

src 数据类型

dst 数据类型

roundMode supported

half

float

CAST_NONE

int32_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

int8_t

CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

uint8_t

CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

float

half

CAST_NONE, CAST_ODD

int32_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

uint8_t

half

CAST_NONE

int8_t

half

CAST_NONE

int32_t

float

CAST_NONE

表6 Atlas推理系列产品AI Core Cast指令参数说明

src数据类型

dst数据类型

roundMode supported

halfBlock

half

int32_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

int16_t

CAST_RINT

None

float

CAST_NONE

None

int8_t

CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

None

uint8_t

CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

None

float

int32_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

half

CAST_NONE, CAST_ODD

None

uint8_t

half

CAST_NONE

None

int8_t

half

CAST_NONE

None

int16_t

half

CAST_NONE

None

int32_t

float

CAST_NONE

None

表7 Atlas A2训练系列产品 Cast指令参数说明

src数据类型

dst数据类型

roundMode supported

halfBlock

half

int32_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

int16_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

float

CAST_NONE

None

int8_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

None

uint8_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

None

float

float

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

int32_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

half

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_ODD, CAST_NONE

None

int64_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

int16_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

float

bfloat16_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

bfloat16_t

float

CAST_NONE

None

int32_t

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

uint8_t

half

CAST_NONE

None

int8_t

half

CAST_NONE

None

int16_t

half

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

None

float

CAST_NONE

None

int32_t

float

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC, CAST_NONE

None

int16_t

CAST_NONE

None

int64_t

CAST_NONE

None

int64_t

int32_t

CAST_NONE

None

float

CAST_RINT, CAST_FLOOR, CAST_CEIL, CAST_ROUND, CAST_TRUNC

None

返回值

支持的型号

Atlas 训练系列产品

Atlas推理系列产品AI Core

Atlas A2训练系列产品

注意事项

调用示例

本样例中只展示Compute流程中的部分代码。本样例的srcLocal为half类型,dstLocal为int32_t类型,计算mask时以int32_t为准。

如果您需要运行样例代码,请将该代码段拷贝并替换样例模板中Compute函数的部分代码即可。

结果示例如下:

输入数据(srcLocal): [6.938 -8.86 -0.2263 ... 1.971 1.778]
输出数据(dstLocal): 
[7 -8 0 ... 2 2]

样例模板

为了方便您快速运行指令中的参考样例,本章节提供样例模板。

您可以将以下样例模板作为代码框架,只需将具体指令中的样例片段拷贝替换下文代码段中的加粗内容即可。
#include "kernel_operator.h"
namespace AscendC {
class KernelCast {
public:
    __aicore__ inline KernelCast() {}
    __aicore__ inline void Init(__gm__ uint8_t* srcGm, __gm__ uint8_t* dstGm)
    {
        srcGlobal.SetGlobalBuffer((__gm__ half*)srcGm);
        dstGlobal.SetGlobalBuffer((__gm__ int32_t*)dstGm);
        pipe.InitBuffer(inQueueSrc, 1, 512 * sizeof(half));
        pipe.InitBuffer(outQueueDst, 1, 512 * sizeof(int32_t));
    }
    __aicore__ inline void Process()
    {
        CopyIn();
        Compute();
        CopyOut();
    }
private:
    __aicore__ inline void CopyIn()
    {
        LocalTensor<half> srcLocal = inQueueSrc.AllocTensor<half>();
        DataCopy(srcLocal, srcGlobal, 512);
        inQueueSrc.EnQue(srcLocal);
    }
    __aicore__ inline void Compute()
    {
        LocalTensor<half> srcLocal = inQueueSrc.DeQue<half>();
        LocalTensor<int32_t> dstLocal = outQueueDst.AllocTensor<int32_t>();

        Cast(dstLocal, srcLocal, RoundMode::CAST_CEIL, 512);

        outQueueDst.EnQue<int32_t>(dstLocal);
        inQueueSrc.FreeTensor(srcLocal);
    }
    __aicore__ inline void CopyOut()
    {
        LocalTensor<int32_t> dstLocal = outQueueDst.DeQue<int32_t>();
        DataCopy(dstGlobal, dstLocal, 512);
        outQueueDst.FreeTensor(dstLocal);
    }
private:
    TPipe pipe;
    TQue<QuePosition::VECIN, 1> inQueueSrc;
    TQue<QuePosition::VECOUT, 1> outQueueDst;
    GlobalTensor<half> srcGlobal;
    GlobalTensor<int32_t> dstGlobal;
};
} // namespace AscendC
extern "C" __global__ __aicore__ void cast_simple_kernel(__gm__ uint8_t* srcGm, __gm__ uint8_t* dstGm)
{
    AscendC::KernelCast op;
    op.Init(srcGm, dstGm);
    op.Process();
}

更多样例

更多地,您可以参考以下样例,了解如何使用Cast指令的0级接口,进行更灵活的操作、实现更高级的功能。

如果您需要运行样例代码,请将代码段拷贝并替换单目指令样例模板中Compute函数的加粗部分代码即可。