Coverage for /opt/cloud/slavespace/usr1/096471637100f3de0fcfc01072822a80/dttest/api/python/ge/ge/graph/_numeric.py: 98%
41 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-27 10:03 +0800
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-27 10:03 +0800
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# -------------------------------------------------------------------
4# -----------------------------------------------------------------------------------------------------------
5# Copyright (c) 2025 Huawei Technologies Co., Ltd.
6# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
7# CANN Open Software License Agreement Version 2.0 (the "License").
8# Please refer to the License for details. You may not use this file except in compliance with the License.
9# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
10# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
11# See LICENSE in the root of the software repository for the full text of the License.
12# -----------------------------------------------------------------------------------------------------------
14"""Numeric module for numeric operations in GraphEngine."""
16import struct
17from typing import List
19__all__ = ["float_to_fp16_bits", "float_list_to_fp16_bits"]
22def float_to_fp16_bits(value: float) -> int:
23 """Convert float to fp16 bits."""
24 f32 = struct.unpack("<I", struct.pack("<f", float(value)))[0]
25 sign = (f32 >> 31) & 0x1
26 exponent = (f32 >> 23) & 0xFF
27 mantissa = f32 & 0x7FFFFF
29 if exponent == 255:
30 half_exp = 0x1F
31 half_mant = 0x200 if mantissa != 0 else 0
32 else:
33 exponent -= 127
34 if exponent > 15:
35 half_exp = 0x1F
36 half_mant = 0
37 elif exponent < -14:
38 if exponent < -24:
39 half_exp = 0
40 half_mant = 0
41 else:
42 mantissa |= 0x800000
43 shift = -exponent - 14
44 shifted = mantissa >> (shift + 13)
45 round_bit = (mantissa >> (shift + 12)) & 0x1
46 remainder = mantissa & ((1 << (shift + 12)) - 1)
47 if round_bit and ((shifted & 0x1) or remainder):
48 shifted += 1
49 half_exp = 0
50 half_mant = shifted
51 else:
52 half_exp = exponent + 15
53 half_mant = mantissa >> 13
54 round_bits = mantissa & 0x1FFF
55 if round_bits > 0x1000 or (round_bits == 0x1000 and (half_mant & 0x1)):
56 half_mant += 1
57 if half_mant == 0x400:
58 half_mant = 0
59 half_exp += 1
60 if half_exp == 0x1F:
61 half_mant = 0
62 return (sign << 15) | ((half_exp & 0x1F) << 10) | (half_mant & 0x3FF)
65def float_list_to_fp16_bits(values: List[float]) -> List[int]:
66 """Convert float list to fp16 bits list."""
67 return [float_to_fp16_bits(v) for v in values]