已合并
docs: Add description of NaN/Inf handling behavior for aclFloat16ToFloat/aclFloatToFloat16 (#790) #4102
rui创建于 18 天前
docs: Add description of NaN/Inf handling behavior for aclFloat16ToFloat/aclFloatToFloat16 (#790) #4102
已合并
共 5 个文件变更+19-1
| @@ -181,6 +181,8 @@ float aclFloat16ToFloat(aclFloat16 value) | |||
| 181 | 181 | ||
| 182 | 将[aclFloat16](25-05_Typedefs.md#aclFloat16)类型的数据转换为float(指float32)类型的数据。 | 182 | 将[aclFloat16](25-05_Typedefs.md#aclFloat16)类型的数据转换为float(指float32)类型的数据。 |
| 183 | 183 | ||
| 184 | +对于NaN和Inf等特殊值,本接口不会保留其语义,转换结果为普通有限数值:FP16 +Inf(0x7C00)转换为65536.0,FP16 -Inf(0xFC00)转换为-65536.0,FP16 NaN(0x7E00)转换为98304.0。该行为固定不变,不随Device的浮点计算结果输出模式(可通过[aclrtGetDeviceSatMode](04_device_management.md#aclrtGetDeviceSatMode)查询,模式说明请参见[aclrtFloatOverflowMode](25-02_Enumerations.md#aclrtFloatOverflowMode))而变化,适用于所有形态。如需保留NaN/Inf语义进行精度调试,建议直接在算子计算中产生NaN/Inf,不要通过本接口构造。 | ||
王 | |||
| 185 | + | ||
| 184 | ### 参数说明 | 186 | ### 参数说明 |
| 185 | 187 | ||
| 186 | | 参数名 | 输入/输出 | 说明 | | 188 | | 参数名 | 输入/输出 | 说明 | |
| @@ -232,6 +234,8 @@ aclFloat16 aclFloatToFloat16(float value) | |||
| 232 | 234 | ||
| 233 | 将float(指float32)类型的数据转换为[aclFloat16](25-05_Typedefs.md#aclFloat16)类型的数据。 | 235 | 将float(指float32)类型的数据转换为[aclFloat16](25-05_Typedefs.md#aclFloat16)类型的数据。 |
| 234 | 236 | ||
| 237 | +对于NaN和Inf等特殊值,本接口按照饱和模式处理:NaN和Inf均转换为FP16最大值65504.0(0x7BFF),负Inf转换为-65504.0(0xFBFF)。该行为固定不变,不随Device的浮点计算结果输出模式(可通过[aclrtGetDeviceSatMode](04_device_management.md#aclrtGetDeviceSatMode)查询,模式说明请参见[aclrtFloatOverflowMode](25-02_Enumerations.md#aclrtFloatOverflowMode))而变化,适用于所有形态。如需保留NaN/Inf语义进行精度调试,建议直接在算子计算中产生NaN/Inf,不要通过本接口构造。 | ||
| 238 | + | ||
| 235 | ### 参数说明 | 239 | ### 参数说明 |
| 236 | 240 | ||
| 237 | | 参数名 | 输入/输出 | 说明 | | 241 | | 参数名 | 输入/输出 | 说明 | |
| @@ -228,6 +228,10 @@ typedef enum { | |||
| 228 | * @param value [IN] Data to be converted | 228 | * @param value [IN] Data to be converted |
| 229 | * | 229 | * |
| 230 | * @retval Transformed data | 230 | * @retval Transformed data |
| 231 | + * | ||
| 232 | + * @note 不保留NaN/Inf语义,转换结果为普通有限数值:FP16 +Inf转为65536.0,-Inf转为-65536.0,NaN转为98304.0。 | ||
| 233 | + * 该行为兼容仅支持饱和模式的芯片,适用于所有形态。 | ||
| 234 | + * 如需保留NaN/Inf语义,建议直接在算子计算中产生,不要通过本接口构造。 | ||
| 231 | */ | 235 | */ |
| 232 | ACL_FUNC_VISIBILITY float aclFloat16ToFloat(aclFloat16 value); | 236 | ACL_FUNC_VISIBILITY float aclFloat16ToFloat(aclFloat16 value); |
| 233 | 237 | ||
| @@ -238,6 +242,10 @@ ACL_FUNC_VISIBILITY float aclFloat16ToFloat(aclFloat16 value); | |||
| 238 | * @param value [IN] Data to be converted | 242 | * @param value [IN] Data to be converted |
| 239 | * | 243 | * |
| 240 | * @retval Transformed data | 244 | * @retval Transformed data |
| 245 | + * | ||
| 246 | + * @note 按饱和模式处理:NaN和Inf均转为FP16最大值65504.0(0x7BFF),负Inf转为-65504.0(0xFBFF)。 | ||
| 247 | + * 该行为兼容仅支持饱和模式的芯片,适用于所有形态。 | ||
| 248 | + * 如需保留NaN/Inf语义,建议直接在算子计算中产生,不要通过本接口构造。 | ||
| 241 | */ | 249 | */ |
| 242 | ACL_FUNC_VISIBILITY aclFloat16 aclFloatToFloat16(float value); | 250 | ACL_FUNC_VISIBILITY aclFloat16 aclFloatToFloat16(float value); |
| 243 | 251 | ||
| @@ -16,8 +16,10 @@ | |||
| 16 | extern "C" { | 16 | extern "C" { |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | +// 不保留NaN/Inf语义,+Inf转65536.0,-Inf转-65536.0,NaN转98304.0,适用于所有形态 | ||
| 19 | float aclFloat16ToFloatImpl(aclFloat16 value) { return acl::Fp16ToFloat(value); } | 20 | float aclFloat16ToFloatImpl(aclFloat16 value) { return acl::Fp16ToFloat(value); } |
| 20 | 21 | ||
| 22 | +// 按饱和模式处理,NaN和Inf转65504.0(0x7BFF),负Inf转-65504.0(0xFBFF),适用于所有形态 | ||
| 21 | aclFloat16 aclFloatToFloat16Impl(float value) { return acl::FloatToFp16(value); } | 23 | aclFloat16 aclFloatToFloat16Impl(float value) { return acl::FloatToFp16(value); } |
| 22 | 24 | ||
| 23 | } | 25 | } |
| @@ -78,6 +78,7 @@ static void Fp16Normalize(uint16_t& expVal, uint16_t& man) | |||
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | +// FP16转FP32:不保留NaN/Inf语义,+Inf转65536.0,-Inf转-65536.0,NaN转98304.0,适用于所有形态 | ||
| 81 | float32_t Fp16ToFloat(const uint16_t val) | 82 | float32_t Fp16ToFloat(const uint16_t val) |
| 82 | { | 83 | { |
| 83 | uint16_t hfSign; | 84 | uint16_t hfSign; |
| @@ -108,6 +109,7 @@ float32_t Fp16ToFloat(const uint16_t val) | |||
| 108 | return ret; | 109 | return ret; |
| 109 | } | 110 | } |
| 110 | 111 | ||
| 112 | +// FP32转FP16:按饱和模式处理,NaN和Inf转65504.0(0x7BFF),负Inf转-65504.0(0xFBFF),适用于所有形态 | ||
| 111 | uint16_t FloatToFp16(const float32_t val) | 113 | uint16_t FloatToFp16(const float32_t val) |
| 112 | { | 114 | { |
| 113 | TypeUnion u; | 115 | TypeUnion u; |
| @@ -119,7 +121,7 @@ uint16_t FloatToFp16(const float32_t val) | |||
| 119 | 121 | ||
| 120 | uint16_t mRet; | 122 | uint16_t mRet; |
| 121 | uint16_t eRet; | 123 | uint16_t eRet; |
| 122 | - // Exponent overflow/NaN converts to signed inf/NaN | 124 | + // 指数溢出/NaN/Inf按饱和模式处理,转换为有符号MAX |
| 123 | if (eF > 0x8FU) { // 0x8Fu:142=127+15 | 125 | if (eF > 0x8FU) { // 0x8Fu:142=127+15 |
| 124 | eRet = FP16_MAX_EXP - 1U; | 126 | eRet = FP16_MAX_EXP - 1U; |
| 125 | mRet = FP16_MAX_MAN; | 127 | mRet = FP16_MAX_MAN; |
| @@ -96,8 +96,10 @@ static constexpr uint32_t FP32_MAN_LEN = 23U; | |||
| 96 | */ | 96 | */ |
| 97 | static constexpr uint32_t FP32_MAX_MAN = 0x7FFFFFU; | 97 | static constexpr uint32_t FP32_MAX_MAN = 0x7FFFFFU; |
| 98 | 98 | ||
| 99 | +// FP32转FP16:按饱和模式处理,NaN和Inf转65504.0(0x7BFF),负Inf转-65504.0(0xFBFF),适用于所有形态 | ||
| 99 | uint16_t FloatToFp16(const float32_t val); | 100 | uint16_t FloatToFp16(const float32_t val); |
| 100 | 101 | ||
| 102 | +// FP16转FP32:不保留NaN/Inf语义,+Inf转65536.0,-Inf转-65536.0,NaN转98304.0,适用于所有形态 | ||
| 101 | float32_t Fp16ToFloat(const uint16_t val); | 103 | float32_t Fp16ToFloat(const uint16_t val); |
| 102 | } // namespace acl | 104 | } // namespace acl |
| 103 | /** | 105 | /** |
和饱和模式是一个意思吗?