Cast
Applicability
|
Product |
Supported |
|---|---|
|
Atlas 350 Accelerator Card |
√ |
|
|
x |
|
|
x |
|
|
x |
|
|
x |
|
|
x |
|
|
x |
Function Usage
Converts the data type precision. Converts the source operand of the U type to the destination operand of the T type based on the specified conversion mode.
Prototype
template <typename T = DefaultType, typename U = DefaultType, const CastTrait& trait = castTrait, typename S, typename V> __simd_callee__ inline void Cast(S& dstReg, V& srcReg, MaskReg& mask)
Parameters
|
Parameter |
Description |
|---|---|
|
T |
Data type of the destination operand. |
|
U |
Data type of the source operand. |
|
trait |
Type conversion mode structure. There are RegLayout, SatMode, MaskMergeMode, and RoundMode. To enable SatMode, use this API together with the API in SetCtrlSpr(ISASI). |
|
S |
srcReg type, for example, RegTensor<float>. It is automatically inferred by the compiler and does not need to be specified. |
|
V |
dstReg type, for example, RegTensor<int32_t>. It is automatically inferred by the compiler and does not need to be specified. |
|
Parameter |
Input/Output |
Description |
|---|---|---|
|
dstReg |
Output |
Destination operand. The type is RegTensor. For details about the data types supported by the Atlas 350 Accelerator Card, see Table 3, Table 4, Table 5 and Table 6. |
|
srcReg |
Input |
Source operand. The type is RegTensor. For details about the data types supported by the Atlas 350 Accelerator Card, see Table 3, Table 4, Table 5 and Table 6. |
|
mask |
Input |
Valid indication of the source operand element operation. For details, see MaskReg. Note: mask for data type conversion is filtered based on the larger value of sizeof(dtype) in the input and output types. |
|
src dtype |
dst dtype |
mode |
round mode |
sat mode |
layout mode |
|---|---|---|---|---|---|
|
half |
int4x2_t |
MaskMergeMode::ZEROING |
RoundMode::CAST_RINT, RoundMode::CAST_ROUND, RoundMode::CAST_FLOOR, RoundMode::CAST_CEIL, RoundMode::CAST_TRUNC |
SatMode::NO_SAT SatMode::SAT |
RegLayout::ZERO, RegLayout::ONE, RegLayout::TWO, RegLayout::THREE |
|
float |
int16_t |
RegLayout::ZERO RegLayout::ONE |
|||
|
half |
int8_t |
||||
|
half |
uint8_t |
||||
|
float |
int64_t |
||||
|
float |
int32_t |
RegLayout::UNKNOWN |
|||
|
half |
int16_t |
||||
|
half |
int32_t |
SatMode::UNKNOWN |
RegLayout::ZERO RegLayout::ONE |
|
src dtype |
dst dtype |
mode |
round mode |
sat mode |
layout mode |
|---|---|---|---|---|---|
|
half |
float |
MaskMergeMode::ZEROING |
RoundMode::UNKNOWN |
SatMode::UNKNOWN |
RegLayout::ZERO RegLayout::ONE |
|
bfloat16_t |
float |
||||
|
hifloat8_t |
half |
||||
|
float |
bfloat16_t |
RoundMode::CAST_RINT, RoundMode::CAST_ROUND, RoundMode::CAST_FLOOR, RoundMode::CAST_CEIL, RoundMode::CAST_TRUNC |
SatMode::NO_SAT SatMode::SAT |
||
|
float |
half |
RoundMode::CAST_ODD, RoundMode::CAST_RINT, RoundMode::CAST_ROUND, RoundMode::CAST_FLOOR RoundMode::CAST_CEIL, RoundMode::CAST_TRUNC |
|||
|
half |
hifloat8_t |
RoundMode::CAST_ROUND, RoundMode::CAST_HYBRID |
|||
|
float |
hifloat8_t |
RegLayout::ZERO, RegLayout::ONE, RegLayout::TWO, RegLayout::THREE |
|||
|
float |
fp8_e5m2_t |
RoundMode::CAST_RINT |
|||
|
float |
fp8_e4m3fn_t |
||||
|
hifloat8_t |
float |
RoundMode::UNKNOWN |
SatMode::UNKNOWN |
||
|
fp8_e4m3fn_t |
float |
||||
|
fp8_e5m2_t |
float |
||||
|
bfloat16_t |
fp4x2_e2m1_t |
RoundMode::CAST_RINT, RoundMode::CAST_ROUND, RoundMode::CAST_FLOOR, RoundMode::CAST_CEIL, RoundMode::CAST_TRUNC |
RegLayout::UNKNOWN |
||
|
bfloat16_t |
fp4x2_e1m2_t |
||||
|
fp4x2_e2m1_t |
bfloat16_t |
RoundMode::UNKNOWN |
|||
|
fp4x2_e1m2_t |
bfloat16_t |
||||
|
bfloat16_t |
half |
RoundMode::CAST_RINT, RoundMode::CAST_ROUND, RoundMode::CAST_FLOOR, RoundMode::CAST_CEIL, RoundMode::CAST_TRUNC |
SatMode::NO_SAT SatMode::SAT |
||
|
half |
bfloat16_t |
SatMode::UNKNOWN |
|||
|
bfloat16_t |
fp8_e8m0_t |
RoundMode::UNKNOWN |
RegLayout::ZERO RegLayout::ONE |
||
|
fp8_e8m0_t |
bfloat16_t |
|
src dtype |
dst dtype |
mode |
round mode |
layout mode |
|---|---|---|---|---|
|
int4x2_t |
half |
MaskMergeMode::ZEROING |
RoundMode::UNKNOWN |
RegLayout::ZERO, RegLayout::ONE, RegLayout::TWO, RegLayout::THREE |
|
int4x2_t |
bfloat16_t |
|||
|
uint8_t |
half |
RegLayout::ZERO RegLayout::ONE |
||
|
int8_t |
half |
|||
|
int16_t |
float |
|||
|
int64_t |
float |
RoundMode::CAST_RINT, RoundMode::CAST_ROUND, RoundMode::CAST_FLOOR, RoundMode::CAST_CEIL, RoundMode::CAST_TRUNC |
||
|
int16_t |
half |
RegLayout::UNKNOWN |
||
|
int32_t |
float |
|
src dtype |
dst dtype |
mode |
sat mode |
layout mode |
|---|---|---|---|---|
|
uint32_t |
uint8_t |
MaskMergeMode::ZEROING |
SatMode::NO_SAT SatMode::SAT |
RegLayout::ZERO, RegLayout::ONE, RegLayout::TWO, RegLayout::THREE |
|
int32_t |
uint8_t |
|||
|
uint16_t |
uint8_t |
RegLayout::ZERO RegLayout::ONE |
||
|
int16_t |
uint8_t |
|||
|
uint32_t |
uint16_t |
|||
|
uint32_t |
int16_t |
|||
|
int32_t |
uint16_t |
|||
|
int32_t |
int16_t |
|||
|
uint8_t |
uint16_t |
RoundMode::UNKNOWN |
||
|
int8_t |
int16_t |
|||
|
uint16_t |
uint32_t |
|||
|
int16_t |
uint32_t |
|||
|
int16_t |
int32_t |
|||
|
int32_t |
int64_t |
|||
|
uint8_t |
uint32_t |
RegLayout::ZERO, RegLayout::ONE, RegLayout::TWO, RegLayout::THREE |
||
|
int8_t |
int32_t |
|||
|
int16_t |
int4x2_t |
|||
|
int4x2_t |
int16_t |
|||
|
int64_t |
int32_t |
SatMode::NO_SAT SatMode::SAT |
RegLayout::ZERO RegLayout::ONE |
|
Conversion Mode |
Conversion Rule |
|---|---|
|
CAST_RINT |
Rounding to the nearest even number when a number is halfway between two others. Examples: Input: 3.3; output: 3 Input: 5.9; output: 6 Input: 5.5; output 6. Because 6 is an even number and 5 is an odd number, the value is rounded up to 6. Input: 4.5; output: 4 (4 is an even number) Input: –2.4; output: 2 Input: –3.6; output: –4 |
|
CAST_ROUND |
Rounding away from zero when a number is halfway between two others. Examples: Input: 3.3; output: 3 Input: 5.9; output: 6 Input: 5.5; output: 6. Because 6 is farther from 0 than 5, the value is rounded up to 6. Input: –2.4; output: 2 Input: –3.6; output: –4 Input: –6.5; output: –7. Because –7 is farther from 0 than –6, the value is rounded down to –7. |
|
CAST_FLOOR |
Rounding toward negative infinity. Examples: Input: 3.2; output: 3 Input: 7.9; output: 7 Input: –4.6; output: –5 Input: –3.1; output: –4 The output is closer to negative infinity than the input. |
|
CAST_CEIL |
Rounding toward positive infinity. Examples: Input: 3.2; output: 4 Input: 7.9; output: 8 Input: –4.6; output: –4 Input: –3.1; output: –3 The output is closer to positive infinity than the input. |
|
CAST_TRUNC |
Rounding toward zero. Examples: Input: 3.2; output: 3 Input: 7.9; output: 7 Input: –4.6; output: –4 Input: –3.1; output: –3 The output is closer to 0 than the input. |
|
src dtype |
dst dtype |
Rounding Rule |
|---|---|---|
|
float |
half |
CAST_ODD: rounding to the nearest odd number. The half has 10 bits of mantissa, and float has 23 bits of mantissa. When converting float to half, 13 bits are discarded. The least significant bit of float16 is marked in yellow y, and the discarded precision of float is marked in red. float +/-a.xxxxxxxxx00000100000000: If the bit in y is 0 (even number), rounding is performed, and half a.xxxxxxxxx1 is obtained. float +/-a.xxxxxxxxx11000100000000: If the bit in y is 1 (odd number), no rounding is performed, and half a.xxxxxxxxx1 is obtained. Example: Input: float 123.23333, represented in binary as follows: sign:0, exponent:10000101, mantissa:11101100111011101110111 float_exponent = 0b10000101 = 133 half_exponent - 15 = 133 - 127 half_exponent = 21 = 0b10101 The 14th bit of float_mantissa is 1 (odd number), so no rounding is performed and the last 13 bits are discarded. 11101100111011101110111 half_mantissa = 1110110011 obtained Therefore, the binary value of half is: sign:0, exponent:10101, mantissa:1110110011 half = 123.2 |
|
float |
bfloat16_t |
The binary rule of float is as follows: sign:1bit,exponent:8bit mantissa:23bit The binary rule of bfloat16_t is as follows: sign:1bit,exponent:8bit,mantissa:7bit CAST_RINT: rounding to the nearest even number when a number is halfway between two others. Examples: 1. float32_mantissa:00100000010000010000000 If the discarded precision is less than 0b1000000000000000, which is equivalent to [0, 0.5), no rounding is performed. bfloat16_mantissa:0010000 is obtained. 2. float32_mantissa:00110001000000000000000 If the discarded precision is equal to 0b1000000000000000 and the least significant bit of bf16 is an even number, no rounding is performed. bfloat16_mantissa:0011000 is obtained. 3. float32_mantissa:00110011000000000000000 If the discarded precision is equal to 0b1000000000000000 and the least significant bit of bf16 is an odd number, rounding is performed. bfloat16_mantissa:0011010 is obtained. 4. float32_mantissa:00100001010000010000000 If the discarded precision is greater than 0b1000000000000000, which is equivalent to (0.5, 1), rounding is performed. bfloat16_mantissa:0010001 is obtained. CAST_ROUND: rounding away from zero when a number is halfway between two others. Examples: 1. float32_mantissa:00100000010000010000000 If the discarded precision is less than 0b1000000000000000, which is equivalent to [0, 0.5), no rounding is performed. bfloat16_mantissa:0010000 is obtained. 2. float32_mantissa:00110001000000000000000 The discarded precision is equal to 0b1000000000000000. After rounding, the value is farther away from 0. Therefore, rounding is performed. bfloat16_mantissa:0011001 is obtained. 3. float32_mantissa:00100001010000010000000 If the discarded precision is greater than 0b1000000000000000, which is equivalent to (0.5, 1), rounding is performed. bfloat16_mantissa:0010001 is obtained. CAST_FLOOR: rounding toward negative infinity. 1. float32_mantissa:00100000010000010000000: If the float32 value is positive, no rounding is performed, and bfloat16_mantissa:0010000 is obtained. 2. float32_mantissa:00110001000000000000000 If the float32 value is negative, rounding is performed, and bfloat16_mantissa:0011001 is obtained. CAST_CEIL: rounding toward positive infinity. 1. float32_mantissa:00100000010000010000000: If the float32 value is positive, rounding is performed, and bfloat16_mantissa:0010001 is obtained. 2. float32_mantissa:00110001000000000000000 If the float32 value is negative, no rounding is performed, and bfloat16_mantissa:0011000 is obtained. CAST_TRUNC: rounding toward zero. 1. float32_mantissa:00100000010000010000000: No rounding is performed, and the red precision is directly discarded. The result is bfloat16_mantissa:001000. Complete example: Input the float32 value 205.75, represented in binary as: sign:0, exponent:10000110, mantissa:10011011100000000000000 CAST_RINT float32_mantissa = 0b10011011100000000000000 If the discarded precision is greater than 0b1000000000000000, which is equivalent to (0.5, 1), rounding is performed. bfloat16_mantissa = 0b1001110 is obtained. Therefore, the binary value of bfloat16 is as follows: sign:0, exponent:10000110, mantissa:1001110 bfloat16 = 206 |
|
bfloat16_t |
half |
The binary rule of bfloat16_t is as follows: sign:1bit,exponent:8bit,mantissa:7bit The binary rule of float16 is as follows: sign:1bit,exponent:5bit,mantissa:10bit The mantissa bit difference is 3 bits. When bfloat16_exponent = exponent – 127 ≥ –14: Since bfloat16 has lower precision and float16 has higher precision, converting from bfloat16 to float16 does not reduce precision. Example 1: bfloat16_mantissa = 0b1011000 -> float16_maintissa = 0b1011000000. No rounding is performed on the binary bits, and only three 0s need to be added to the lower bits. When bfloat16_exponent = exponent – 127 < –14: Example 2: When exponent is 108 and bfloat16_exponent is exponent – 127 = –19 < –14, the exponent must be increased by 5 to be equal to float16_exponent because the minimum value of float16_exponent (exponent – 14) is –14 and cannot represent –19. In addition, the mantissa needs to be divided by 2 to the power of 5 because the bf16 computation formula is as follows: bf16 = s × (2^(e – 127)) × (man) = s × (2^(e – 127 + 5)) × (man * 2^(–5)). By multiplying the exponent and dividing the mantissa by the same factor, the final value remains unchanged. Assume that bfloat16_mantissa = 0b1011011. The bfloat16 mantissa is computed as follows: 1 + man/128. The binary representation is as follows: 0b1.1011011. When the exponent bit is multiplied by 2 to the power of 5, the mantissa must be divided by 2 to the power of 5, and the decimal point is moved five places to the left. Therefore, bfloat16_mantissa is 0b0.000011011011. The mantissa has 12 bits. Because float16 has only 10-bit mantissa, the two least significant bits need to be discarded in the following CAST modes, and whether to round is determined based on the rounding mode. In the current example, the discarded precision midpoint is 0b10. CAST_RINT: rounding to the nearest even number when a number is halfway between two others. When bfloat16_mantissa is less than or equal to 10 bits, rounding is not required. When bfloat16_mantissa is greater than 10 bits, examples similar to example 2 are as follows: (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: bfloat16_mantissa = 0b0.00001101100xxx 0xxx < 1000. Output: float16_mantissa = 0b0.0000110110 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: bfloat16_mantissa = 0b0.00001101100xxx 1x1x > 1000. Output: float16_mantissa = 0b0.0000110111 (3) When the discarded precision is equal to the discarded precision midpoint and the 10th bit is an even number, no rounding is performed. Example: bfloat16_mantissa = 0b0.00001101100xxx 0 % 2 == 0. Output: float16_mantissa = 0b0.0000110110 (4) When the discarded precision is equal to the discarded precision midpoint and the 10th bit is an odd number, rounding is performed. Example: bfloat16_mantissa = 0b0.00001100010xxx 1 % 2 == 1. Output: float16_mantissa = 0b0.0000110001 CAST_ROUND: rounding away from zero when a number is halfway between two others. When bfloat16_mantissa is less than or equal to 10 bits, rounding is not required. When bfloat16_mantissa is greater than 10 bits, examples similar to example 2 are as follows: (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: bfloat16_mantissa = 0b0.00001101100xxx 0xxx < 1000. Output: float16_mantissa = 0b0.0000110110 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: bfloat16_mantissa = 0b0.00001101100xxx 1x1x > 1000. Output: float16_mantissa = 0b0.0000110111 (3) When the discarded precision is equal to the discarded precision midpoint, rounding away from zero is used. Therefore, rounding is performed. Example: bfloat16_mantissa = 0b0.00001101100xxx Output: float16_mantissa = 0b0.0000110111 CAST_FLOOR: rounding toward negative infinity. When bfloat16_mantissa is less than or equal to 10 bits, rounding is not required. When bfloat16_mantissa is greater than 10 bits, examples similar to example 2 are as follows: (1) When the sign bit S is 0, rounding is not performed for positive numbers. Example: bfloat16_mantissa = 0b0.00001101100xxx Output: float16_mantissa = 0b0.0000110110 (2) When the sign bit S is 1, rounding is performed for negative numbers. Example: bfloat16_mantissa = 0b0.00001101100xxx Output: float16_mantissa = 0b0.0000110111 CAST_CEIL: rounding toward positive infinity. When bfloat16_mantissa is less than or equal to 10 bits, rounding is not required. When bfloat16_mantissa is greater than 10 bits, examples similar to example 2 are as follows: (1) When the sign bit S is 0, rounding is performed for positive numbers. Example: bfloat16_mantissa = 0b0.00001101100xxx Output: float16_mantissa = 0b0.0000110111 (2) When the sign bit S is 1, rounding is not performed for negative numbers. Example: bfloat16_mantissa = 0b0.00001101100xxx Output: float16_mantissa = 0b0.0000110110 CAST_TRUNC: rounding toward zero. When bfloat16_mantissa is less than or equal to 10 bits, rounding is not required. When bfloat16_mantissa is greater than 10 bits, examples similar to example 2 are as follows: (1) The extra precision is directly discarded, and no rounding is performed. Example: bfloat16_mantissa = 0b0.00001101100xxx Output: float16_mantissa = 0b0.0000110110 Complete example: Input the bfloat16 value 2.90573e-06, represented in binary as follows: sign:0, exponent:01101100, mantissa:1000011 bfloat16_exponent = 108 – 127 = -19 < –14. The minimum value of float16_exponent is –14. Therefore, bfloat16_exponent is incremented by 5, and the decimal point of bfloat16_mantissa is shifted leftward. 5 digits, 1.1000011 -> 0.000011000011 CAST_RINT The discarded precision 11 is greater than the discarded precision midpoint 10. Therefore, rounding is performed. bfloat16_mantissa = 0.0000110001 The final binary value of float16 is as follows: sign:0, exponent: 00000, mantissa = 0000110001 The decimal value computed using the formula is as follows: float16=0.00000293 |
|
half |
bfloat16_t |
The binary rule of half is as follows: sign:1bit,exponent:5bit,mantissa:10bit The binary rule of bfloat16_t is as follows: sign:1bit,exponent:8bit,mantissa:7bit CAST_RINT: rounding to the nearest even number when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint 100, no rounding is performed. Example: half_mantissa = 0111010011 Output: bfloat16_mantissa = 0111010 (2) When the discarded precision is greater than the discarded precision midpoint 100, rounding is performed. Example: half_mantissa = 0111010111 Output: bfloat16_mantissa = 0111011 (3) When the rounding precision is equal to the discarded precision midpoint 100, the least significant bit of bfloat16 is an even number, and no rounding is performed. Example: half_mantissa = 0111010100 Output: bfloat16_mantissa = 0111010 (4) When the rounding precision is equal to the discarded precision midpoint 100, the least significant bit of bfloat16 is an odd number, and rounding is performed. Example: half_mantissa = 0111010100 Output: bfloat16_mantissa = 0111011 CAST_ROUND: rounding to the nearest integer. Rounding away from zero when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint 100, no rounding is performed. Example: half_mantissa = 0111010011 Output: bfloat16_mantissa = 0111010 (2) When the discarded precision is greater than the discarded precision midpoint 100, rounding is performed. Example: half_mantissa = 0111010111 Output: bfloat16_mantissa = 0111011 (3) When the rounding precision is equal to the discarded precision midpoint 100, rounding away from zero is used. There, rounding is performed. Example: half_mantissa = 0111010100 Output: bfloat16_mantissa = 0111011 CAST_FLOOR: rounding toward negative infinity. (1) When the input is positive, no rounding is performed. Example: half_mantissa = 0111010011 Output: bfloat16_mantissa = 0111010 (2) When the input is negative, rounding is performed. Example: half_mantissa = 0111010011 Output: bfloat16_mantissa = 0111011 CAST_CEIL: rounding toward positive infinity. (1) When the input is positive, rounding is performed. Example: half_mantissa = 0111010011 Output: bfloat16_mantissa = 0111011 (2) When the input is negative, no rounding is performed. Example: half_mantissa = 0111010011 Output: bfloat16_mantissa = 0111010 CAST_TRUNC: rounding toward zero. The extra precision is directly discarded. Example: half_mantissa = 0111010011 Output: bfloat16_mantissa = 0111010 Complete example: Input: half 0.131 Binary value: sign:0, exponent:01100, mantissa:0000110001 half_exponent = 12 – 15 = bfloat16_exp – 127 bfloat16_exp = 124 = 0b1111100 In CAST_ROUND mode: half_mantissa = 0000110001 The discarded precision is less than the discarded precision midpoint 100, and no rounding is performed. Therefore, the result is as follows: bfloat16_mantissa = 0000110 Therefore, the binary value of bfloat16 is as follows: sign:0, exponent:1111100, mantissa: 0000110 The decimal value computed using the formula is as follows: bfloat16 = 0.130859 |
|
float |
fp8_e4m3fn_t |
The binary rule of float is as follows: sign:1bit,exponent:8bit mantissa:23bit The binary rule of fp8_e4m3fn_t is as follows: sign:1bit,exponent:4bit,mantissa:3bit The 20 bits need to be discarded, and the discarded precision midpoint is 0b10000000000000000000. CAST_RINT: rounding to the nearest even number when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: float_mantissa = 01100100110000000000000 Output: fp8_e4m3fn_t_mantissa = 011 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: float_mantissa = 01110100110000000000000 Output: fp8_e4m3fn_t_mantissa = 100 (3) When the rounding precision is equal to the discarded precision midpoint, the least significant bit of fp8_e4m3fn_t is an even number, and no rounding is performed. Example: float_mantissa = 01010000000000000000000 Output: fp8_e4m3fn_t_mantissa = 010 (4) When the rounding precision is equal to the discarded precision midpoint, the least significant bit of fp8_e4m3fn_t is an odd number, and rounding is performed. Example: float_mantissa = 01110000000000000000000 Output: fp8_e4m3fn_t_mantissa = 100 Complete example: Input: float 1.233 Binary: sign:0, exponent:01111111, mantissa:00111011101001011110010 float_exponent = 127-127 = fp8_e4m3fn_t_exp - 7 fp8_e4m3fn_t_exp = 7 = 0b0111 CAST_RINT float_mantissa = 00111011101001011110010 The discarded precision is greater than the discarded precision midpoint, and rounding is performed. Therefore, the result is as follows: fp8_e4m3fn_t_mantissa = 010 Therefore, the binary value of fp8_e4m3fn_t is as follows: sign:0, exponent:0111, mantissa: 010 The decimal value computed using the formula is as follows: fp8_e4m3fn_t=1.25 |
|
float |
fp8_e5m2_t |
The binary rule of float is as follows: sign:1bit,exponent:8bit mantissa:23bit The binary rule of fp8_e5m2_t is as follows: sign:1bit,exponent:5bit,mantissa:2bit The 21 bits need to be discarded, and the discarded precision midpoint is 0b100000000000000000000. CAST_RINT: rounding to the nearest even number when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: float_mantissa = 01000100110000000000000 Output: fp8_e5m2_t_mantissa = 01 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: float_mantissa = 01101001100000000000000 Output: fp8_e5m2_t_mantissa = 10 (3) When the rounding precision is equal to the discarded precision midpoint, the least significant bit of fp8_e5m2_t is an even number, and no rounding is performed. Example: float_mantissa = 00100000000000000000000 Output: fp8_e5m2_t_mantissa = 00 When the rounding precision is equal to the discarded precision midpoint, the least significant bit of fp8_e5m2_t is an odd number, and rounding is performed. Example: float_mantissa = 0110000000000000000000 Output: fp8_e5m2_t_mantissa = 10 Complete example: Input: float32 1.233 Binary: sign:0, exponent:01111111, mantissa:00111011101001011110010 float_exponent = 127-127 = fp8_e5m2_t_exp - 15 fp8_e5m2_t_exp = 15 = 0b01111 CAST_RINT float_mantissa = 00111011101001011110010 The discarded precision is greater than the discarded precision midpoint, and rounding is performed. Therefore, the result is as follows: fp8_e5m2_t_mantissa = 01 Therefore, the binary format of fp8_e5m2_t is as follows: sign:0, exponent:01111, mantissa: 01 The decimal value computed using the formula is as follows: fp8_e5m2_t=1.25 |
|
bfloat16_t |
fp4x2_e2m1_t |
The binary rule of bfloat16 is as follows: sign:1bit,exponent:8bit,mantissa:7bit The binary rule of fp4x2_e2m1_t is as follows: sign:1bit,exponent:2bit,mantissa:1bit The mantissa difference is 6 bits. When bfloat16_exponent = exponent – 127 < 0: Example 1: When exponent is 124 and bfloat16_exponent is exponent – 127 = –3 < 0, the exponent must be increased by 3 to be equal to float4_e2m1_exponent because the minimum value of float4_e2m1_exponent (exponent – 1) is 0 and cannot represent –3. In addition, the mantissa needs to be divided by 2 to the power of 3 because the bf16 computation formula is as follows: s × (2^(e – 127)) × (man) = s × (2^(e – 127 + 3)) × (man * 2^(–3)). By multiplying the exponent and dividing the mantissa by the same factor, the final value remains unchanged. Assume that bfloat16_mantissa = 0b1011011. The bfloat16 mantissa is computed as follows: 1 + man/128. The binary representation is as follows: 0b1.1011011. When the exponent bit is multiplied by 2 to the power of 3, the mantissa must be divided by 2 to the power of 3, and the decimal point is moved three places to the left. Therefore, bfloat16_mantissa is 0b0.0011011011. Because float4_e2m1 has only one mantissa bit, the nine least significant bits need to be discarded in the following CAST modes, and whether to round is determined based on the rounding mode. In the current example, the discarded precision midpoint is 0b100000000. CAST_RINT: rounding to the nearest even number when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: bfloat16_mantissa = 0b0.0000110xxx 000110xxx < Discarded precision midpoint. Output: float4_e2m1_mantissa = 0b0.0 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: bfloat16_mantissa = 0b0.0100110xxx 100110xxx > Discarded precision midpoint. Output: float4_e2m1_mantissa = 0b0.1 (3) When the discarded precision is equal to the discarded precision midpoint and the first bit is an even number, no rounding is performed. Example: bfloat16_mantissa = 0b0.0100000xxx 0 % 2 == 0. Output: float4_e2m1_mantissa = 0b0.0 (4) When the discarded precision is equal to the discarded precision midpoint and the first bit is an odd number, rounding is performed. Example: bfloat16_mantissa = 0b0.1100000xxx 1 % 2 == 1. Output: float4_e2m1_mantissa = 0b0.1 CAST_ROUND: rounding away from zero when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: bfloat16_mantissa = 0b0.0000110xxx 000110xxx < Discarded precision midpoint. Output: float4_e2m1_mantissa = 0b0.0 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: bfloat16_mantissa = 0b0.0100110xxx 100110xxx > Discarded precision midpoint. Output: float4_e2m1_mantissa = 0b0.1 (3) When the discarded precision is equal to the discarded precision midpoint, rounding away from zero is used. Therefore, rounding is performed. Example: bfloat16_mantissa = 0b0.0100000xxx Output: float4_e2m1_mantissa = 0b0.1 CAST_FLOOR: rounding toward negative infinity. (1) If the input is positive, no rounding is performed. Example: bfloat16_mantissa = 0b0.0000110xxx Output: float4_e2m1_mantissa = 0b0.0 (2) If the input is negative, rounding is performed. Example: bfloat16_mantissa = 0b0.0100110xxx Output: float4_e2m1_mantissa = 0b0.1 CAST_CEIL: rounding toward positive infinity. (1) If the input is positive, rounding is performed. Example: bfloat16_mantissa = 0b0.0000110xxx Output: float4_e2m1_mantissa = 0b0.1 (2) If the input is negative, no rounding is performed. Example: bfloat16_mantissa = 0b0.0100110xxx Output: float4_e2m1_mantissa = 0b0.0 CAST_TRUNC: rounding toward zero. (1) The extra precision is directly discarded, and no rounding is performed. Example: bfloat16_mantissa = 0b0.0100110xxx Output: float4_e2m1_mantissa = 0b0.0 Complete example: Input the bfloat16 value 0.761719, represented in binary as follows: sign:0, exponent:01111110, mantissa:1000011 bfloat16_exponent = 126 – 127 = –1 < 0. The minimum value of float16_exponent is 0. Therefore, bfloat16_exponent is incremented by 1, and the decimal point of bfloat16_mantissa is shifted leftward. 1 digit, 1.1000011 -> 0.11000011 CAST_RINT The discarded precision 1000011 is greater than the discarded precision midpoint 1000000. Therefore, rounding is performed. float4_e2m1_mantissa = 0.1 The final binary value of float4_e2m1 is as follows: sign:0, exponent: 00, mantissa = 1 The decimal value computed using the formula is as follows: float4_e2m1=0.5 |
|
bfloat16_t |
fp4x2_e1m2_t |
The binary rule of bfloat16 is as follows: sign:1bit,exponent:8bit,mantissa:7bit The binary rule of fp4x2_e1m2_t is as follows: sign:1bit,exponent:1bit,mantissa:2bit The mantissa bit difference is 5 bits. When bfloat16_exponent = exponent – 127 < 0, bfloat16_mantissa needs to be shifted. Example 1: When exponent is 124 and bfloat16_exponent is exponent – 127 = –3 < 0, the exponent must be increased by 3 to be equal to float4_e2m1_exponent because the minimum value of float4_e1m2_exponent (exponent – 1) is 0 and cannot represent –3. In addition, the mantissa needs to be divided by 2 to the power of 3 because the bf16 computation formula is as follows: s × (2^(e – 127)) × (man) = s × (2^(e – 127 + 3)) × (man * 2^(–3)). By multiplying the exponent and dividing the mantissa by the same factor, the final value remains unchanged. Assume that bfloat16_mantissa = 0b1011011. The bfloat16 mantissa is computed as follows: 1 + man/128. The binary representation is as follows: 0b1.1011011. When the exponent bit is multiplied by 2 to the power of 3, the mantissa must be divided by 2 to the power of 3, and the decimal point is moved three places to the left. Therefore, bfloat16_mantissa is 0b0.0011011011. Because float4_e2m1 has only 2-bit mantissa, the eight least significant bits need to be discarded in the following CAST modes, and whether to round is determined based on the rounding mode. In the current example, the discarded precision midpoint is 0b10000000. CAST_RINT: rounding to the nearest even number when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: bfloat16_mantissa = 0b0.0000011xxx 00011xxx < Discarded precision midpoint. Output: float4_e1m2_mantissa = 0b0.00 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: bfloat16_mantissa = 0b0.0010011xxx 10011xxx > Discarded precision midpoint. Output: float4_e1m2_mantissa = 0b0.01 (3) When the discarded precision is equal to the discarded precision midpoint and the second digit is an even number, no rounding is performed. Example: bfloat16_mantissa = 0b0.0010000xxx 0 % 2 == 0. Output: float4_e1m2_mantissa = 0b0.00 (4) If the discarded precision is equal to the discarded precision midpoint and the second digit is an odd number, rounding is performed. Example: bfloat16_mantissa = 0b0.0110000xxx 1 % 2 == 1. Output: float4_e1m2_mantissa = 0b0.10 CAST_ROUND: rounding away from zero when a number is halfway between two others. (1) When the discarded precision is less than the discarded precision midpoint, no rounding is performed. Example: bfloat16_mantissa = 0b0.0000110xxx 00110xxx < Discarded precision midpoint. Output: float4_e1m2_mantissa = 0b0.00 (2) When the discarded precision is greater than the discarded precision midpoint, rounding is performed. Example: bfloat16_mantissa = 0b0.0010110xxx 10110xxx > Discarded precision midpoint. Output: float4_e1m2_mantissa = 0b0.01 (3) When the discarded precision is equal to the discarded precision midpoint, rounding away from zero is used. Therefore, rounding is performed. Example: bfloat16_mantissa = 0b0.0010000xxx Output: float4_e1m2_mantissa = 0b0.01 CAST_FLOOR: rounding toward negative infinity. (1) If the input is positive, no rounding is performed. Example: bfloat16_mantissa = 0b0.0000110xxx Output: float4_e1m2_mantissa = 0b0.00 (2) If the input is negative, rounding is performed. Example: bfloat16_mantissa = 0b0.00100110xxx Output: float4_e1m2_mantissa = 0b0.01 CAST_CEIL: rounding toward positive infinity. (1) If the input is positive, rounding is performed. Example: bfloat16_mantissa = 0b0.0000110xxx Output: float4_e1m2_mantissa = 0b0.01 (2) If the input is negative, no rounding is performed. Example: bfloat16_mantissa = 0b0.0010110xxx Output: float4_e1m2_mantissa = 0b0.00 CAST_TRUNC: rounding toward zero. (1) The extra precision is directly discarded, and no rounding is performed. Example: bfloat16_mantissa = 0b0.0010110xxx Output: float4_e1m2_mantissa = 0b0.00 Complete example: Input the bfloat16 value 0.761719, represented in binary as follows: sign:0, exponent:01111110, mantissa:1000011 bfloat16_exponent = 126 – 127 = –1 < 0. The minimum value of float16_exponent is 0. Therefore, bfloat16_exponent is incremented by 1, and the decimal point of bfloat16_mantissa is shifted leftward. 1 digit, 1.1000011 -> 0.11000011 CAST_RINT The discarded precision 000011 is less than the discarded precision midpoint 100000. Therefore, no rounding is performed. float4_e2m1_mantissa = 0.11 The final binary value of float4_e2m1 is as follows: sign:0, exponent: 0, mantissa = 11 The decimal value computed using the formula is as follows: float4_e2m1=0.75 |
|
float |
hifloat8_t |
See Table 9. |
|
VCVTFF:F322HiF8 |
|
|---|---|
|
tmp2[31 : 0] = f32_src_data[i][31 : 0]; Ev = tmp2[30 : 23] - 8'b01111111, thr = tmp2[13 : 0]; if (Ev == 128 && tmp2[22 : 0] != 23'b0) then tmp3[7 : 0] = HiF8NAN(8'b10000000); else if ((Ev == 128 && tmp2[22 : 0] == 23'b0) || (Ev > 15)) then tmp3[7 : 0] = (tmp2[31] == 1'b0) ? HiF8+INF (8'b01101111) : HiF8-INF (8'b11101111); else if (Ev < -23) then tmp3[7 : 0] = HiF8ZERO (8'b00000000); else if (Ev == -23) then if ((Half To Away Round) || (Hybrid Round && {1'b1, tmp2[22 : 10]} >= thr)) then tmp3[7 : 0] = (tmp2[31] == 1'b0) ? 8'b00000001 : 8'b10000001; // min subnormal else tmp3[7 : 0] = HiF8ZERO (8'b00000000); end if else if (Ev == 0) then M = tmp2[22 : 20], T A_bit = tmp2[19], frac = tmp2[19 : 6]; else if (Ev == ±1) then M = tmp2[22 : 20], T A_bit = tmp2[19], frac = tmp2[19 : 6]; else if (Ev == ±[2, 3]) then M = tmp2[22 : 20], T A_bit = tmp2[19], frac = tmp2[19:6]; else if (Ev == ±[4, 7]) then M = tmp2[22 : 21], T A_bit = tmp2[20], frac = tmp2[20 : 7]; else if (Ev == ±[8, 15]) then M = tmp2[22], T A_bit = tmp2[21], frac = tmp2[21 : 8]; else if (Ev == [-16, -22]) then M = Ev + 23, T A_bit = tmp2[22], frac = tmp2[22 : 9]; // subnormal end if if (Ev == ±[0, 3]) then if (T A_bit == 1'b1) then M_tmp = M + 1, Ev = Ev + carry of M_tmp, M = (carry of M_tmp) ? 0 : M_tmp; end if else if (Ev == ±[4, 15]) then if (HALF To Away Round && T A_bit == 1'b1) || (Hybrid Round && frac >= thr) then M_tmp = M + 1, Ev = Ev + carry of M_tmp, M = (carry of M_tmp) ? 0 : M_tmp; end if else if (Ev == [-16, -22]) then if ((Half To Away Round) && T A_bit == 1'b1) || ((Hybrid Round && frac >= thr) then M_tmp = Ev + 23, Ev = Ev + 1, M = (Ev == -15) ? 0 : M_tmp; end if end if encode {tmp3[31], Ev, M} to tmp3[7 : 0] following HiF encoding rule; end if result[i][7 : 0] = saturation(tmp3[7 : 0]) according to control bit; |
|
VCVTFF: F162HiF8 |
|---|
|
tmp2[15 : 0] = f16_src_data[i][15 : 0]; Ev = tmp2[14 : 10] - 5'b01111, thr = {tmp2[0], 1'b1}; if (Ev == 16 && tmp2[9 : 0] != 10'b0) then tmp3[7 : 0] = HiF8NAN(8'b10000000); else if (Ev == 16 && tmp2[9:0] == 10'b0) && (Ev > 15) then tmp3[7 : 0] = (tmp2[31] == 1'b0) ? HiF8+INF(8'b01101111) : HiF8-INF(8'b11101111); else if (Ev < -23) then tmp3[7 : 0] = HiF8ZERO(8'b00000000); else if (Ev == -23) then if ((Half To Away Round) || (Hybrid Round && {1'b1, tmp2[9]} >= thr)) then tmp3[7 : 0] = (tmp2[31] == 1'b0) ? 8'b00000001 : 8'b10000001; // min subnormal else tmp3[7 : 0] = HiF8ZERO(8'b00000000); end if else if (Ev == 0) then M = tmp2[9 : 7], T A_bit = tmp2[6], frac = tmp2[6 : 5]; else if (Ev == ±1) then M = tmp2[9 : 7], T A_bit = tmp2[6], frac = tmp2[6 : 5]; else if (Ev == ±[2, 3]) then M = tmp2[9 : 7], T A_bit = tmp2[6], frac = tmp2[6 : 5]; else if (Ev == ±[4, 7]) then M = tmp2[9 : 8], T A_bit = tmp2[7], frac = tmp2[7 : 6]; else if (Ev == ±[8, 15]) then M = tmp2[9], T A_bit = tmp2[8], frac = tmp2[8 : 7]; else if (Ev == [-16, -22]) then M = Ev + 23, T A_bit = tmp2[9], frac = tmp2[9 : 8]; // subnormal end if if (Ev == ±[0, 3]) then if (T A_bit == 1'b1) then M_tmp = M + 1, Ev = Ev + carry of M_tmp, M = (carry of M_tmp) ? 0 : M_tmp; end if else if (Ev == ±[4, 15]) then if (HALF To Away Round && T A_bit == 1'b1) || (Hybrid Round && frac >= thr) then M_tmp = M + 1, Ev = Ev + carry of M_tmp, M = (carry of M_tmp) ? 0 : M_tmp; end if else if (Ev == [-16, -22]) then if ((Half To Away Round) && T A_bit == 1'b1) || ((Hybrid Round && frac >= thr) then M_tmp = Ev + 23, Ev = Ev + 1, M = (Ev == -15) ? 0 : M_tmp; end if end if encode {tmp3[31], Ev, M} to tmp3[7 : 0] following HiF encoding rule; end if result[i][7 : 0] = saturation(tmp3[7 : 0]) according to control bit; |
Returns
None
Constraints
- This instruction must be used together with the SetCtrlSpr(ISASI) instruction (SetCtrlSpr(ISASI)). You can set the register value to control the saturation and non-saturation modes of Cast.
- Float to integer:
- When the input is out of range of the output type, the result is truncated to fit the target data width. For example, if the input is the half-precision value 257, the output will be 1 when cast to uint8_t. If the input is +/–inf, the output will be the corresponding maximum or minimum value of the output type. If the input is nan, the output will be 0.
- Saturation mode: When the input is out of range of the output type, the output will be the maximum or minimum value of the output type. For example, if the input is the half-precision value 257, the output will be 255 when cast to uint8_t. If the input is the half-precision value –inf, the output will be 0 when cast to uint8_t. If the input is nan, the output will be 0.
- Float to float:
- Currently, float-to-float conversion supports both the saturation and non-saturation modes. In non-saturation mode, if the input is nan, the output will be nan. If the input is +/–inf, the output will be +/-inf. In saturation mode, if the input is nan, the output will be 0. If the input is out of range of the output type, the output will be the maximum value of the output type.
- When the output type is float32, only the non-saturation mode is supported.
- When the output type is fp8_e4m3fn_t, the output is nan because fp8_e4m3fn_t does not have the inf representation format.
- When the output type is fp8_e5m2_t/fp8_e4m3fn_t and the input is nan, the default output is 0.
- For the conversion from bfloat16 to float4, if the input is inf of the bfloat16 type or is out of range of the fp4x2_e2m1_t or fp4x2_e1m2_t type, the output will be the maximum or minimum value of the fp4x2_e2m1_t or fp4x2_e1m2_t type with the corresponding sign. If the input is nan, the output of the fp4x2_e2m1_t or fp4x2_e1m2_t type is 0.
- For the conversion from bfloat16_t to fp4x2_e2m1_t or fp4x2_e1m2_t, the instruction reads and writes every two elements as a pair. The valid bits of mask are even-numbered bits. For example, 10 00 00 00 10 10 00 10 is equivalent to 11 11 00 00 10 10 00 11.

- For the fp8_e8m0_t type:
If the input is bfloat16_t +/–inf or the absolute value exceeds the maximum value of the fp8_e8m0_t type, the maximum value will be 0b11111110 of the fp8_e8m0_t type.
If the input is nan of the bfloat16_t type, the output will be fp8_e8m0_t nan = 0b11111111.
- Integer to integer
Unsaturated mode: The input is truncated to the target data format. For example, if the input int32_t value is 256, the output uint8_t value will be 0.
Saturation mode: If the input is out of the target data range, it will be saturated to the maximum or minimum value of the target data type.
For the conversion from a narrow data type (such as int16_t, 2 bytes) to a wide data type (such as uint32_t, 4 bytes), only the saturation mode is supported. A negative input value will be saturated to 0.
Example
__simd_vf__ inline void CastVF(__ubuf__ int16_t* dstAddr, __ubuf__ float* srcAddr, uint32_t count, uint32_t srcRepeatSize, uint32_t dstRepeatSize, uint16_t repeatTimes)
{
// Add static to castTrait variables.
static constexpr AscendC::Reg::CastTrait castTrait =
{AscendC::Reg::RegLayout::ZERO, AscendC::Reg::SatMode::NO_SAT,AscendC::Reg::MaskMergeMode::ZEROING,AscendC::RoundMode::CAST_RINT};
AscendC::Reg::RegTensor<float> srcReg;
AscendC::Reg::RegTensor<int16_t> dstReg;
AscendC::Reg::MaskReg mask;
for (uint16_t i = 0; i < repeatTimes; i++) {
AscendC::Reg::LoadAlign(srcReg, srcAddr + i * srcRepeatSize);
mask = AscendC::Reg::UpdateMask<float>(count);
AscendC::Reg::Cast<int16_t, float, castTrait>(dstReg, srcReg, mask);
AscendC::Reg::StoreAlign(dstAddr + i * dstRepeatSize, dstReg, mask);
}
}