LCOV - code coverage report
Current view: top level - include - kernel_fp16.h (source / functions) Coverage Total Hit
Test: coverage.info_filtered Lines: 60.7 % 56 34
Test Date: 2026-07-27 14:41:20 Functions: 78.9 % 19 15

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : /*!
      12              :  * \file kernel_fp16.h
      13              :  * \brief
      14              :  */
      15              : #ifndef ASCENDC_FP16_H
      16              : #define ASCENDC_FP16_H
      17              : #include <algorithm>
      18              : #include <cmath>
      19              : #include <cstdint>
      20              : 
      21              : enum class DimIndex {
      22              :     K_DIM0 = 0,
      23              :     K_DIM1,
      24              :     K_DIM2,
      25              :     K_DIM3,
      26              :     K_DIM4,
      27              :     K_DIM5,
      28              :     K_DIM6,
      29              :     K_DIM7,
      30              :     K_DIM8,
      31              :     K_DIM9,
      32              :     K_DIM10,
      33              :     K_DIM11,
      34              :     K_DIM12,
      35              :     K_DIM13,
      36              :     K_DIM14,
      37              :     K_DIM15,
      38              :     K_DIM16,
      39              : };
      40              : 
      41              : enum class BitShift {
      42              :     K_BIT_SHIFT2 = 2,
      43              :     K_BIT_SHIFT3 = 3,
      44              :     K_BIT_SHIFT4 = 4,
      45              :     K_BIT_SHIFT5 = 5,
      46              :     K_BIT_SHIFT6 = 6,
      47              :     K_BIT_SHIFT7 = 7,
      48              :     K_BIT_SHIFT8 = 8,
      49              :     K_BIT_SHIFT9 = 9,
      50              :     K_BIT_SHIFT10 = 10,
      51              :     K_BIT_SHIFT11 = 11,
      52              :     K_BIT_SHIFT12 = 12,
      53              :     K_BIT_SHIFT13 = 13,
      54              :     K_BIT_SHIFT14 = 14,
      55              :     K_BIT_SHIFT15 = 15,
      56              :     K_BIT_SHIFT16 = 16,
      57              :     K_BIT_SHIFT20 = 20,
      58              :     K_BIT_SHIFT24 = 24,
      59              :     K_BIT_SHIFT27 = 27,
      60              :     K_BIT_SHIFT28 = 28,
      61              :     K_BIT_SHIFT31 = 31,
      62              :     K_BIT_SHIFT32 = 32,
      63              :     K_BIT_SHIFT36 = 36,
      64              :     K_BIT_SHIFT40 = 40,
      65              :     K_BIT_SHIFT44 = 44,
      66              :     K_BIT_SHIFT48 = 48,
      67              :     K_BIT_SHIFT52 = 52,
      68              :     K_BIT_SHIFT56 = 56,
      69              :     K_BIT_SHIFT59 = 59,
      70              :     K_BIT_SHIFT60 = 60,
      71              :     K_BIT_SHIFT63 = 63,
      72              :     K_BIT_SHIFT64 = 64,
      73              :     K_BIT_SHIFT128 = 128,
      74              :     K_BIT_SHIFT255 = 255,
      75              :     K_BIT_SHIFT256 = 256,
      76              :     K_BIT_SHIFT512 = 512,
      77              :     K_BIT_SHIFT768 = 768,
      78              :     K_BIT_SHIFT784 = 784,
      79              :     K_BIT_SHIFT1020 = 1020,
      80              :     K_BIT_SHIFT1024 = 1024,
      81              :     K_BIT_SHIFT3136 = 3136,
      82              :     K_BIT_SHIFT4096 = 4096,
      83              :     K_BIT_SHIFT6144 = 6144,
      84              :     K_BIT_SHIFT10240 = 10240,
      85              :     K_BIT_SHIFT65536 = 65536
      86              : };
      87              : 
      88              : enum class Fp16BasicParam {
      89              :     K_FP16_EXP_BIAS = 15,          // fp16 exponent bias
      90              :     K_FP16_EXP_LEN = 5,            // the exponent bit length of fp16 is 5
      91              :     K_FP16_MAN_LEN = 10,           // the mantissa bit length of fp16 is 10
      92              :     K_FP16_SIGN_INDEX = 15,        // bit index of sign in fp16
      93              :     K_FP16_SIGN_MASK = 0x8000,     // sign mask of fp16         (1 00000 00000 00000)
      94              :     K_FP16_EXP_MASK = 0x7C00,      // exponent mask of fp16 (  11111 00000 00000)
      95              :     K_FP16_MAN_MASK = 0x03FF,      // mantissa mask of fp16 (        11111 11111)
      96              :     K_FP16_MAN_HIDE_BIT = 0x0400,  // hide_bit of mantissa of fp16(   1 00000 00000)
      97              :     K_FP16_MAX = 0x7BFF,           // maximum value (0111 1011 1111 1111)
      98              :     K_FP16_MIN = 0xFBFF,           // minimum value            (1111 1011 1111 1111)
      99              :     K_FP16_ABS_MAX = 0x7FFF,       // absolute maximum value   (0111 1111 1111 1111)
     100              :     K_FP16_MAX_EXP = 0x001F,       // maximum exponent value of fp16 is 15(11111)
     101              :     K_FP16_MAX_VALID_EXP = 0x001E, // maximum valid exponent value of fp16 is 14(11110)
     102              :     K_FP16_MAX_MAN = 0x03FF,       // maximum mantissa value of fp16(11111 11111)
     103              : };
     104              : 
     105              : // / @ingroup fp16 basic operator
     106              : // / @brief   get sign of fp16
     107           70 : inline uint16_t FP16_EXTRAC_SIGN(uint16_t x)
     108              : {
     109           70 :     return (((x) >> static_cast<uint16_t>(Fp16BasicParam::K_FP16_SIGN_INDEX)) & 1);
     110              : }
     111              : // / @ingroup fp16 basic operator
     112              : // / @brief   get exponent of fp16
     113           70 : inline int16_t FP16_EXTRAC_EXP(uint16_t x)
     114              : {
     115              :     return (
     116           70 :         ((x) >> static_cast<uint16_t>(Fp16BasicParam::K_FP16_MAN_LEN)) &
     117           70 :         static_cast<uint16_t>(Fp16BasicParam::K_FP16_MAX_EXP));
     118              : }
     119              : // / @ingroup fp16 basic operator
     120              : // / @brief   get mantissa of fp16
     121           70 : inline uint16_t FP16_EXTRAC_MAN(uint16_t x)
     122              : {
     123              :     return (
     124           70 :         (((x) >> 0) & 0x3FF) |
     125          140 :         (((((x) >> static_cast<uint16_t>(Fp16BasicParam::K_FP16_MAN_LEN)) & 0x1F) > 0 ? 1 : 0) * 0x400));
     126              : }
     127              : // / @ingroup fp16 basic operator
     128              : // / @brief   constructor of fp16 from sign exponent and mantissa
     129           62 : inline uint16_t FP16_CONSTRUCTOR(uint16_t s, uint16_t e, uint16_t m)
     130              : {
     131              :     return (
     132           62 :         ((s) << (static_cast<uint16_t>(Fp16BasicParam::K_FP16_SIGN_INDEX))) |
     133           62 :         ((e) << static_cast<uint16_t>(Fp16BasicParam::K_FP16_MAN_LEN)) |
     134           62 :         ((m) & (static_cast<uint16_t>(Fp16BasicParam::K_FP16_MAX_MAN))));
     135              : }
     136              : // / @ingroup fp16 special value judgment
     137              : // / @brief   whether a fp16 is zero
     138            8 : inline bool FP16_IS_ZERO(uint16_t x) { return (x & (static_cast<uint16_t>(Fp16BasicParam::K_FP16_ABS_MAX))) == 0; }
     139              : // / @ingroup fp16 special value judgment
     140              : // / @brief   whether a fp16 is a denormalized value
     141           22 : inline bool FP16_IS_DENORM(uint16_t x) { return (x & (static_cast<uint16_t>(Fp16BasicParam::K_FP16_EXP_MASK))) == 0; }
     142              : // / @ingroup fp16 special value judgment
     143              : // / @brief   whether a fp16 is invalid
     144           52 : inline bool FP16_IS_INVALID(uint16_t x)
     145              : {
     146              :     return (
     147           52 :         (x & static_cast<uint16_t>(Fp16BasicParam::K_FP16_EXP_MASK)) ==
     148           52 :         static_cast<uint16_t>(Fp16BasicParam::K_FP16_EXP_MASK));
     149              : }
     150              : 
     151              : enum class Fp32BasicParam : uint32_t {
     152              :     K_FP32_EXP_BIAS = 127,             // fp32 exponent bias
     153              :     K_FP32_EXP_LEN = 8,                // the exponent bit length of float/fp32 is 8
     154              :     K_FP32_MAN_LEN = 23,               // the mantissa bit length of float/fp32 is 23
     155              :     K_FP32_SIGN_INDEX = 31,            // bit index of sign in float/fp32
     156              :     K_FP32_SIGN_MASK = 0x80000000u,    // sign mask of fp32 (1 0000 0000  0000 0000 0000 0000 000)
     157              :     K_FP32_EXP_MASK = 0x7F800000u,     // exponent mask of fp32 (  1111 1111  0000 0000 0000 0000 000)
     158              :     K_FP32_MAN_MASK = 0x007FFFFFu,     // mantissa mask of fp32 (1111 1111 1111 1111 111)
     159              :     K_FP32_MAN_HIDE_BIT = 0x00800000u, // hide_bit of mantissa of fp32 (  1  0000 0000 0000 0000 000)
     160              :     K_FP32_ABS_MAX = 0x7FFFFFFFu,      // absolute maximum value (0 1111 1111  1111 1111 1111 1111 111)
     161              :     K_FP32_MAX_EXP = 0xFF,             // maximum exponent value of fp32 is 255(1111 1111)
     162              :     K_FP32_MAX_MAN = 0x7FFFFF          // maximum mantissa value of fp32 (1111 1111 1111 1111 1111 111)
     163              : };
     164              : 
     165              : // / @ingroup fp32 basic operator
     166              : // / @brief   constructor of fp32 from sign exponent and mantissa
     167           18 : inline uint32_t FP32_CONSTRUCTOR(uint32_t s, uint32_t e, uint32_t m)
     168              : {
     169              :     return (
     170           18 :         ((s) << static_cast<uint16_t>(Fp32BasicParam::K_FP32_SIGN_INDEX)) |
     171           18 :         ((e) << static_cast<uint16_t>(Fp32BasicParam::K_FP32_MAN_LEN)) |
     172           18 :         ((m) & static_cast<uint32_t>(Fp32BasicParam::K_FP32_MAX_MAN)));
     173              : }
     174              : 
     175              : enum class Fp64BasicParam : uint64_t {
     176              :     K_FP64_EXP_BIAS = 1023,                      // fp64 exponent bias
     177              :     K_FP64_EXP_LEN = 11,                         // the exponent bit length of double/fp64 is 11
     178              :     K_FP64_MAN_LEN = 52,                         // the mantissa bit length of double/fp64 is 52
     179              :     K_FP64_SIGN_INDEX = 63,                      // bit index of sign in double/fp64 is 63
     180              :     K_FP64_SIGN_MASK = 0x8000000000000000LLu,    // sign mask of fp64 (1 000 (total 63bits 0))
     181              :     K_FP64_EXP_MASK = 0x7FF0000000000000LLu,     // exponent mask of fp64 (0 1 11111 11111  0000?-?-(total 52bits 0))
     182              :     K_FP64_MAN_MASK = 0x000FFFFFFFFFFFFFLLu,     // mantissa mask of fp64 ( 1111?-?-(total 52bits 1))
     183              :     K_FP64_MAN_HIDE_BIT = 0x0010000000000000LLu, // hide_bit of mantissa of fp64 ( 1 0000?-?-(total 52bits 0))
     184              :     K_FP64_ABS_MAX = 0x7FFFFFFFFFFFFFFFLLu,      // absolute maximum value (0 111?-?-(total 63bits 1))
     185              :     K_FP64_MAX_EXP = 0x07FF,                     // maximum exponent value of fp64 is 2047(1 11111 11111)
     186              :     K_FP64_MAX_MAN = 0xFFFFFFFFFFFLLu            // maximum mantissa value of fp64  (111?-?-(total 52bits 1))
     187              : };
     188              : 
     189              : enum class NumBitMax : uint64_t {
     190              :     K_INT8_MAX = 0x7F,         // maximum positive value of int8_t (0111 1111)
     191              :     K_BIT_LEN8_MAX = 0xFF,     // maximum value of a data with 8 bits length  (1111 111)
     192              :     K_INT16_MAX = 0x7FFF,      // maximum positive value of int16_t (0111 1111 1111 1111)
     193              :     K_BIT_LEN16_MAX = 0xFFFF,  // maximum value of a data with 16 bits length (1111 1111 1111 1111)
     194              :     K_INT32_MAX = 0x7FFFFFFFu, // maximum positive value of int32_t (0111 1111 1111 1111 1111 1111 1111 1111)
     195              :     // maximum value of uint32_t(1111 1111 1111 1111 1111 1111 1111 1111)
     196              :     K_BIT_LEN32_MAX = 0xFFFFFFFFu,
     197              :     // maximum value of int64_t  (0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111)
     198              :     K_INT64_MAX = 0x7FFFFFFFFFFFFFFFu,
     199              :     // maximum value of uint64_t (1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111)
     200              :     K_BIT_LEN64_MAX = 0xFFFFFFFFFFFFFFFFu
     201              : };
     202              : 
     203              : // / @ingroup half enum
     204              : // / @brief   round mode of last valid digital
     205              : enum class TagFp16RoundMode {
     206              :     K_ROUND_TO_NEAREST = 0, // < round to nearest even
     207              :     K_ROUND_BY_TRUNCATED,   // < round by truncated
     208              :     K_ROUND_MODE_RESERVED,
     209              : };
     210              : 
     211              : #ifndef __TIK_CC
     212              : #define __ai_core__
     213              : #define __ai_host__
     214              : #endif
     215              : 
     216              : /**
     217              :  * @ingroup half
     218              :  * @brief   Half precision float
     219              :  * bit15:       1 bit SIGN      +---+-----+------------+
     220              :  * bit14-10:    5 bit EXP       | S |EEEEE|MM MMMM MMMM|
     221              :  * bit0-9:      10bit MAN       +---+-----+------------+
     222              :  */
     223              : #define TIK_ALIGN(n) alignas(n)
     224              : struct half {
     225              :     uint16_t val;
     226              : 
     227              : public:
     228              :     /* *
     229              :      * @ingroup half constructor
     230              :      * @brief   Default constructor
     231              :      */
     232              :     __ai_host__ __ai_core__ half() = default;
     233              :     /* *
     234              :      * @ingroup half copy constructor
     235              :      * @brief   Constructor with a half object(copy constructor)
     236              :      */
     237           20 :     __ai_host__ __ai_core__ half(const half& fp) : val(fp.val) {}
     238              :     /* *
     239              :      * @ingroup half constructor
     240              :      * @brief   Constructor with an float value
     241              :      */
     242           16 :     __ai_host__ __ai_core__ half(const float& fVal) : val(FloatToFp16(fVal)) {}
     243              :     /* *
     244              :      * @ingroup half constructor
     245              :      * @brief   Constructor with an double value
     246              :      */
     247            4 :     __ai_host__ __ai_core__ half(const double& dVal) : val(DoubleToFp16(dVal)) {}
     248              :     /* *
     249              :      * @ingroup half constructor
     250              :      * @brief   Constructor with an int8_t value
     251              :      */
     252              :     __ai_host__ __ai_core__ half(const int8_t& iVal) : val(Int8ToFp16(iVal)) {}
     253              :     /* *
     254              :      * @ingroup half constructor
     255              :      * @brief   Constructor with an uint8_t value
     256              :      */
     257              :     __ai_host__ __ai_core__ half(const uint8_t& uiVal) : val(UInt8ToFp16(uiVal)) {}
     258              :     /* *
     259              :      * @ingroup half constructor
     260              :      * @brief   Constructor with an int16_t value
     261              :      */
     262              :     __ai_host__ __ai_core__ half(const int16_t& iVal) : val(Int16ToFp16(iVal)) {}
     263              :     /* *
     264              :      * @ingroup half constructor
     265              :      * @brief   Constructor with an uint16_t value
     266              :      */
     267           40 :     __ai_host__ __ai_core__ half(const uint16_t& uiVal) : val(UInt16ToFp16(uiVal)) {}
     268              :     /* *
     269              :      * @ingroup half constructor
     270              :      * @brief   Constructor with an int32_t value
     271              :      */
     272              :     __ai_host__ __ai_core__ half(const int32_t& iVal) : val(Int32ToFp16(iVal)) {}
     273              :     /* *
     274              :      * @ingroup half constructor
     275              :      * @brief   Constructor with an uint32_t value
     276              :      */
     277              :     __ai_host__ __ai_core__ half(const uint32_t& uiVal) : val(UInt32ToFp16(uiVal)) {}
     278              : 
     279              :     uint16_t FloatToFp16(const float& fVal) const;
     280              :     uint16_t DoubleToFp16(const double& dVal);
     281              :     uint16_t Int8ToFp16(const int8_t& iVal) const;
     282              :     uint16_t UInt8ToFp16(const uint8_t& uiVal) const;
     283              :     uint16_t Int16ToFp16(const int16_t& iVal) const;
     284              :     uint16_t UInt16ToFp16(const uint16_t& uiVal);
     285              :     uint16_t Int32ToFp16(const int32_t& iVal) const;
     286              :     uint16_t UInt32ToFp16(const uint32_t& uiVal) const;
     287              : 
     288              :     /* *
     289              :      * @ingroup half math operator
     290              :      * @param [in] fp half object to be added
     291              :      * @brief   Override addition operator to performing half addition
     292              :      * @return  Return half result of adding this and fp
     293              :      */
     294              :     half operator+(const half fp) const;
     295              :     /* *
     296              :      * @ingroup half math operator
     297              :      * @param [in] fp half object to be subtracted
     298              :      * @brief   Override addition operator to performing half subtraction
     299              :      * @return  Return half result of subtraction fp from this
     300              :      */
     301              :     half operator-(const half fp) const;
     302              :     /* *
     303              :      * @ingroup half math operator
     304              :      * @param [in] fp half object to be multiplied
     305              :      * @brief   Override multiplication operator to performing half
     306              :      * multiplication
     307              :      * @return  Return half result of multiplying this and fp
     308              :      */
     309              :     half operator*(const half fp) const;
     310              :     /* *
     311              :      * @ingroup half math operator divided
     312              :      * @param [in] fp half object to be divided
     313              :      * @brief   Override division operator to performing half division
     314              :      * @return  Return half result of division this by fp
     315              :      */
     316              :     half operator/(const half fp) const;
     317              :     /* *
     318              :      * @ingroup half math operator
     319              :      * @param [in] fp half object to be added
     320              :      * @brief   Override addition operator to performing half addition
     321              :      * @return  Return half result of adding this and fp
     322              :      */
     323              :     half operator+=(const half fp);
     324              :     /* *
     325              :      * @ingroup half math operator
     326              :      * @param [in] fp half object to be subtracted
     327              :      * @brief   Override addition operator to performing half subtraction
     328              :      * @return  Return half result of subtraction fp from this
     329              :      */
     330              :     half operator-=(const half fp);
     331              :     /* *
     332              :      * @ingroup half math operator
     333              :      * @param [in] fp half object to be multiplied
     334              :      * @brief   Override multiplication operator to performing half
     335              :      * multiplication
     336              :      * @return  Return half result of multiplying this and fp
     337              :      */
     338              :     half operator*=(const half fp);
     339              :     /* *
     340              :      * @ingroup half math operator divided
     341              :      * @param [in] fp half object to be divided
     342              :      * @brief   Override division operator to performing half division
     343              :      * @return  Return half result of division this by fp
     344              :      */
     345              :     half operator/=(const half fp);
     346              :     /*
     347              :      * @ingroup half math operator auto-increment
     348              :      * @param [in] fp half object to be Front auto-increment
     349              :      * @brief   Override Front auto-increment operator to performing half Front auto-increment
     350              :      * @return  Return half result of Front auto-increment this and fp
     351              :      */
     352              :     half operator++();
     353              :     /*
     354              :      * @ingroup half math operator auto-increment
     355              :      * @param [in] fp half object to be Back auto-increment
     356              :      * @brief   Override Front Back auto-increment operator to performing half Back auto-increment
     357              :      * @return  Return half result of Back auto-increment this and fp
     358              :      */
     359              :     half operator++(int);
     360              :     /*
     361              :      * @ingroup half math operator auto-decrement
     362              :      * @param [in] fp half object to be Front auto-decrement
     363              :      * @brief   Override Front auto-decrement operator to performing half Front auto-decrement
     364              :      * @return  Return half result of Front auto-decrement this and fp
     365              :      */
     366              :     half operator--();
     367              :     /*
     368              :      * @ingroup half math operator auto-decrement
     369              :      * @param [in] fp half object to be Back auto-decrement
     370              :      * @brief   Override Back auto-decrement operator to performing half Back auto-decrement
     371              :      * @return  Return half result of Back auto-decrement this and fp
     372              :      */
     373              :     half operator--(int);
     374              :     /*
     375              :      * @ingroup half math operator AND
     376              :      * @param [in] fp half object to be AND
     377              :      * @brief   Override AND operator to performing half Front AND
     378              :      * @return  Return half result of AND this and fp
     379              :      */
     380              :     bool operator&&(const half fp) const;
     381              :     /*
     382              :      * @ingroup half math operator OR
     383              :      * @param [in] fp half object to be OR
     384              :      * @brief   Override OR operator to performing half OR
     385              :      * @return  Return half result of OR this and fp
     386              :      */
     387              :     bool operator||(const half fp) const;
     388              : 
     389              :     /* *
     390              :      * @ingroup half math compare operator
     391              :      * @param [in] fp half object to be compared
     392              :      * @brief   Override basic comparison operator to performing half if-equal
     393              :      * comparison
     394              :      * @return  Return boolean result of if-equal comparison of this and fp.
     395              :      */
     396              :     bool operator==(const half& fp) const;
     397              :     /* *
     398              :      * @ingroup half math compare operator
     399              :      * @param [in] fp half object to be compared
     400              :      * @brief   Override basic comparison operator to performing half not-equal
     401              :      * comparison
     402              :      * @return  Return boolean result of not-equal comparison of this and fp.
     403              :      */
     404              :     bool operator!=(const half& fp) const;
     405              :     /* *
     406              :      * @ingroup half math compare operator
     407              :      * @param [in] fp half object to be compared
     408              :      * @brief   Override basic comparison operator to performing half
     409              :      * greater-than comparison
     410              :      * @return  Return boolean result of greater-than comparison of this and fp.
     411              :      */
     412              :     bool operator>(const half& fp) const;
     413              :     /* *
     414              :      * @ingroup half math compare operator
     415              :      * @param [in] fp half object to be compared
     416              :      * @brief   Override basic comparison operator to performing half
     417              :      * greater-equal comparison
     418              :      * @return  Return boolean result of greater-equal comparison of this and fp.
     419              :      */
     420              :     bool operator>=(const half& fp) const;
     421              :     /* *
     422              :      * @ingroup half math compare operator
     423              :      * @param [in] fp half object to be compared
     424              :      * @brief   Override basic comparison operator to performing half less-than
     425              :      * comparison
     426              :      * @return  Return boolean result of less-than comparison of this and fp.
     427              :      */
     428              :     bool operator<(const half& fp) const;
     429              :     /* *
     430              :      * @ingroup half math compare operator
     431              :      * @param [in] fp half object to be compared
     432              :      * @brief   Override basic comparison operator to performing half less-equal
     433              :      * comparison
     434              :      * @return  Return boolean result of less-equal comparison of this and fp.
     435              :      */
     436              :     bool operator<=(const half& fp) const;
     437              : 
     438              :     /* *
     439              :      * @ingroup half math evaluation operator
     440              :      * @param [in] fp half object to be copy to half
     441              :      * @brief   Override basic evaluation operator to copy half to a new half
     442              :      * @return  Return half result from fp
     443              :      */
     444              :     half& operator=(const half& fp);
     445              : 
     446              :     /* *
     447              :      * @ingroup half math evaluation operator
     448              :      * @param [in] fVal float object to be converted to half
     449              :      * @brief   Override basic evaluation operator to convert float to half
     450              :      * @return  Return half result from fVal
     451              :      */
     452              :     half& operator=(const float& fVal);
     453              :     /* *
     454              :      * @ingroup half math evaluation operator
     455              :      * @param [in] dVal double object to be converted to half
     456              :      * @brief   Override basic evaluation operator to convert double to half
     457              :      * @return  Return half result from dVal
     458              :      */
     459              :     half& operator=(const double& dVal);
     460              :     /* *
     461              :      * @ingroup half math evaluation operator
     462              :      * @param [in] iVal float object to be converted to half
     463              :      * @brief   Override basic evaluation operator to convert float to half
     464              :      * @return  Return half result from iVal
     465              :      */
     466              :     half& operator=(const int8_t& iVal);
     467              :     /* *
     468              :      * @ingroup half math evaluation operator
     469              :      * @param [in] uiVal uint8_t object to be converted to half
     470              :      * @brief   Override basic evaluation operator to convert uint8_t to half
     471              :      * @return  Return half result from uiVal
     472              :      */
     473              :     half& operator=(const uint8_t& uiVal);
     474              :     /* *
     475              :      * @ingroup half math evaluation operator
     476              :      * @param [in] iVal int16_t object to be converted to half
     477              :      * @brief   Override basic evaluation operator to convert int16_t to half
     478              :      * @return  Return half result from iVal
     479              :      */
     480              :     half& operator=(const int16_t& iVal);
     481              :     /* *
     482              :      * @ingroup half math evaluation operator
     483              :      * @param [in] uiVal uint16_t object to be converted to half
     484              :      * @brief   Override basic evaluation operator to convert uint16_t to half
     485              :      * @return  Return half result from uiVal
     486              :      */
     487              :     half& operator=(const uint16_t& uiVal);
     488              :     /* *
     489              :      * @ingroup half math evaluation operator
     490              :      * @param [in] iVal int32_t object to be converted to half
     491              :      * @brief   Override basic evaluation operator to convert int32_t to half
     492              :      * @return  Return half result from iVal
     493              :      */
     494              :     half& operator=(const int32_t& iVal);
     495              :     /* *
     496              :      * @ingroup half math evaluation operator
     497              :      * @param [in] uiVal uint32_t object to be converted to half
     498              :      * @brief   Override basic evaluation operator to convert uint32_t to half
     499              :      * @return  Return half result from uiVal
     500              :      */
     501              :     half& operator=(const uint32_t& uiVal);
     502              :     /* *
     503              :      * @ingroup half math conversion
     504              :      * @brief   Override convert operator to convert half to float/fp32
     505              :      * @return  Return float/fp32 value of half
     506              :      */
     507              :     operator float() const;
     508              :     /* *
     509              :      * @ingroup half math conversion
     510              :      * @brief   Override convert operator to convert half to double/fp64
     511              :      * @return  Return double/fp64 value of half
     512              :      */
     513              :     operator double() const;
     514              :     /* *
     515              :      * @ingroup half math conversion
     516              :      * @brief   Override convert operator to convert half to int8_t
     517              :      * @return  Return int8_t value of half
     518              :      */
     519              :     operator int8_t() const;
     520              :     /* *
     521              :      * @ingroup half math conversion
     522              :      * @brief   Override convert operator to convert half to uint8_t
     523              :      * @return  Return uint8_t value of half
     524              :      */
     525              :     operator uint8_t() const;
     526              :     /* *
     527              :      * @ingroup half conversion
     528              :      * @brief   Override convert operator to convert half to int16_t
     529              :      * @return  Return int16_t value of half
     530              :      */
     531              :     operator int16_t() const;
     532              :     /* *
     533              :      * @ingroup half math conversion
     534              :      * @brief   Override convert operator to convert half to uint16_t
     535              :      * @return  Return uint16_t value of half
     536              :      */
     537              :     operator uint16_t() const;
     538              :     /* *
     539              :      * @ingroup half math conversion
     540              :      * @brief   Override convert operator to convert half to int32_t
     541              :      * @return  Return int32_t value of half
     542              :      */
     543              :     operator int32_t() const;
     544              :     /* *
     545              :      * @ingroup half math conversion
     546              :      * @brief   Override convert operator to convert half to int64_t
     547              :      * @return  Return int64_t value of half
     548              :      */
     549              :     operator uint32_t() const;
     550              :     /* *
     551              :      * @ingroup half judgment method
     552              :      * @param [in] fp half object to be judgement
     553              :      * @brief   whether a half is inifinite
     554              :      * @return  Returns 1:+INF -1:-INF 0:not INF
     555              :      */
     556              :     int32_t IsInf() const;
     557              :     /* *
     558              :      * @ingroup half math conversion
     559              :      * @brief   Convert half to float/fp32
     560              :      * @return  Return float/fp32 value of half
     561              :      */
     562              :     float ToFloat() const;
     563              :     /* *
     564              :      * @ingroup half math conversion
     565              :      * @brief   Convert half to double/fp64
     566              :      * @return  Return double/fp64 value of half
     567              :      */
     568              :     double ToDouble() const;
     569              :     /* *
     570              :      * @ingroup half math conversion
     571              :      * @brief   Convert half to int8_t
     572              :      * @return  Return int8_t value of half
     573              :      */
     574              :     int8_t ToInt8() const;
     575              :     /* *
     576              :      * @ingroup half math conversion
     577              :      * @brief   Convert half to uint8_t
     578              :      * @return  Return uint8_t value of half
     579              :      */
     580              :     uint8_t ToUInt8() const;
     581              :     /* *
     582              :      * @ingroup half conversion
     583              :      * @brief   Convert half to int16_t
     584              :      * @return  Return int16_t value of half
     585              :      */
     586              :     int16_t ToInt16() const;
     587              :     /* *
     588              :      * @ingroup half math conversion
     589              :      * @brief   Convert half to uint16_t
     590              :      * @return  Return uint16_t value of half
     591              :      */
     592              :     uint16_t ToUInt16() const;
     593              :     /* *
     594              :      * @ingroup half math conversion
     595              :      * @brief   Convert half to int32_t
     596              :      * @return  Return int32_t value of half
     597              :      */
     598              :     int32_t ToInt32() const;
     599              :     /* *
     600              :      * @ingroup half math conversion
     601              :      * @brief   Convert half to int64_t
     602              :      * @return  Return int64_t value of half
     603              :      */
     604              :     uint32_t ToUInt32() const;
     605              : };
     606              : 
     607              : /**
     608              :  * @ingroup half public method
     609              :  * @param [in]     val signature is negative
     610              :  * @param [in|out] s   sign of half object
     611              :  * @param [in|out] e   exponent of half object
     612              :  * @param [in|out] m   mantissa of half object
     613              :  * @brief   Extract the sign, exponent and mantissa of a half object
     614              :  */
     615              : void ExtractFp16(const uint16_t& val, uint16_t& s, int16_t& e, uint16_t& m);
     616              : /**
     617              :  * @ingroup half public method
     618              :  * @param [in]     negative sign is negative
     619              :  * @param [in|out] man      mantissa to be reverse
     620              :  * @brief   Calculate a mantissa's complement (add ont to it's radix-minus-one
     621              :  * complement)
     622              :  * @return  Return complement of man
     623              :  */
     624              : template <typename T>
     625            0 : void ReverseMan(bool negative, T& man)
     626              : {
     627            0 :     if (negative) {
     628            0 :         man = (~(man)) + 1;
     629              :     }
     630            0 : }
     631              : /**
     632              :  * @ingroup half public method
     633              :  * @param [in] ea exponent of one half/float number
     634              :  * @param [in] ma mantissa of one half/float number
     635              :  * @param [in] eb exponent of another half/float number
     636              :  * @param [in] mb mantissa of another half/float number
     637              :  * @brief   choose mantissa to be shift right whoes exponent is less than another
     638              :  * one
     639              :  * @return  Return mantissawhoes exponent is less than another one
     640              :  */
     641              : template <typename T>
     642              : T MinMan(const int16_t& ea, T& ma, const int16_t& eb, T& mb)
     643              : {
     644              :     return (ea > eb) ? mb : ma;
     645              : }
     646              : 
     647              : /**
     648              :  * @ingroup half public method
     649              :  * @param [in] man   mantissa to be operate
     650              :  * @param [in] shift right shift bits
     651              :  * @brief   right shift a mantissa
     652              :  * @return  Return right-shift mantissa
     653              :  */
     654              : template <typename T>
     655            0 : T RightShift(T man, int16_t shift)
     656              : {
     657            0 :     int32_t bits = sizeof(T) * 8; // one byte have 8 bits
     658            0 :     T mask = ((static_cast<T>(1u)) << (static_cast<uint32_t>(bits - 1)));
     659            0 :     for (int32_t i = 0; i < shift; i++) {
     660            0 :         man = ((man & mask) | (man >> 1));
     661              :     }
     662            0 :     return man;
     663              : }
     664              : 
     665              : /**
     666              :  * @ingroup half public method
     667              :  * @param [in] ea exponent of one temp half number
     668              :  * @param [in] ma mantissa of one temp half number
     669              :  * @param [in] eb exponent of another temp half number
     670              :  * @param [in] mb mantissa of another temp half number
     671              :  * @brief   Get mantissa sum of two temp half numbers, T support types:
     672              :  * uint16_t/uint32_t/uint64_t
     673              :  * @return  Return mantissa sum
     674              :  */
     675              : template <typename T>
     676            0 : T GetManSum(int16_t ea, const T& ma, int16_t eb, const T& mb)
     677              : {
     678              :     T sum;
     679            0 :     if (ea != eb) {
     680              :         T mTmp;
     681            0 :         int16_t eTmp = static_cast<int16_t>(std::abs(ea - eb));
     682            0 :         if (ea > eb) {
     683            0 :             mTmp = mb;
     684            0 :             mTmp = RightShift(mTmp, eTmp);
     685            0 :             sum = ma + mTmp;
     686              :         } else {
     687            0 :             mTmp = ma;
     688            0 :             mTmp = RightShift(mTmp, eTmp);
     689            0 :             sum = mTmp + mb;
     690              :         }
     691              :     } else {
     692            0 :         sum = mb + ma;
     693              :     }
     694            0 :     return sum;
     695              : }
     696              : 
     697              : /**
     698              :  * @ingroup half public method
     699              :  * @param [in] bit0    whether the last preserved bit is 1 before round
     700              :  * @param [in] bit1    whether the abbreviation's highest bit is 1
     701              :  * @param [in] bitLeft whether the abbreviation's bits which not contain highest
     702              :  * bit grater than 0
     703              :  * @param [in] man     mantissa of a half or float number, support types:
     704              :  * uint16_t/uint32_t/uint64_t
     705              :  * @param [in] shift   abbreviation bits
     706              :  * @brief    Round half or float mantissa to nearest value
     707              :  * @return   Returns true if round 1,otherwise false;
     708              :  */
     709              : template <typename T>
     710           26 : T ManRoundToNearest(bool bit0, bool bit1, bool bitLeft, T man, uint16_t shift = 0)
     711              : {
     712           26 :     man = ((bit1 && (bit0 || bitLeft)) ? 1 : 0) + (man >> shift);
     713           26 :     return man;
     714              : }
     715              : 
     716              : /**
     717              :  * @ingroup half public method
     718              :  * @param [in] man    mantissa of a float number, support types: uint16_t/uint32_t/uint64_t
     719              :  * @brief   Get bit length of a uint32_t number
     720              :  * @return  Return bit length of man
     721              :  */
     722              : template <typename T>
     723           36 : int16_t GetManBitLength(T man)
     724              : {
     725           36 :     int16_t lenRet = 0;
     726          450 :     while (man) {
     727          414 :         lenRet++;
     728          414 :         man >>= 1;
     729              :     }
     730           36 :     return lenRet;
     731              : }
     732              : 
     733              : /**
     734              :  * \brief half datatype
     735              :  *
     736              :  * \details This structure implements the datatype for storing half-precision floating-point numbers.
     737              :  * The structure implements assignment operators and type conversions.
     738              :  * 16 bits are being used in total: 1 sign bit, 5 bits for the exponent, and the significand is
     739              :  * being stored in 10 bits.
     740              :  * The total precision is 11 bits. There are 15361 representable numbers within theinterval [0.0, 1.0],
     741              :  * endpoints included.
     742              :  * On average we have log10(2**11) ≈ 3.311 decimal digits.
     743              :  */
     744              : namespace float16 {
     745              : using Fp16T = half;
     746              : } // namespace float16
     747              : #endif // ASCENDC_FP16_H
        

Generated by: LCOV version 2.0-1