code: def float32_to_float8e5m2(  # pylint: disable=too-many-statements
      fval: float,
      scale: float = 1.0,
      fn: bool = False,
      uz: bool = False,
      saturate: bool = True,
  ) -> int:
      """
      Convert a float32 value to a float8, e5m2 (as int).
  
      :param fval: float to convert
      :param scale: scale, divide *fval* by *scale* before casting it
      :param fn: no infinite values
      :param uz: no negative zero
      :param saturate: if True, any value out of range included inf becomes the maximum value,
          otherwise, it becomes NaN. The description of operator Cast fully describes the
          differences.
      :return: converted float
      """
      x = fval / scale
      b = int.from_bytes(struct.pack("<f", np.float32(x)), "little")
      ret = (b & 0x80000000) >> 24  # sign
  
      if fn and uz:
          if (b & 0x7FC00000) == 0x7FC00000:
              return 0x80
          if (b & 0x7FFFFFFF) == 0x7F800000:
              # inf
              if saturate:
                  return ret | 0x7F
              return 0x80
          e = (b & 0x7F800000) >> 23  # exponent
          m = b & 0x007FFFFF  # mantissa
  
          if e != 0:
              if e < 109:
                  pass
              elif e < 110:
                  ret |= 1
                  if (m >> 23) & 1:
                      # rounding
                      # may be unused
                      ret += 1
              elif e < 112:  # 127 - 16 + 1
                  d = 111 - e
                  ret |= 1 << (1 - d)
                  ret |= m >> (22 + d)
                  if (m >> (21 + d)) & 1:
                      # rounding
                      ret += 1
              elif e < 143:  # 127 + 15 + 1
                  ex = e - 111  # 127 - 16
                  ret |= ex << 2
                  ret |= m >> 21
                  if m & 0x100000:
                      if (ret & 0x7F) < 0x7F:
                          # rounding
                          ret += 1
                      elif not saturate:
                          ret = 0x80
              elif e == 255 and m == 0:  # inf
                  ret = 0x80
              elif saturate:
                  ret |= 0x7F  # last possible number
              else:
                  ret = 0x80
          elif m == 0:
              # -0
              ret = 0
          return int(ret)
      elif not fn and not uz:
          if (b & 0x7FC00000) == 0x7FC00000:
              return 0x7F | ret
          if np.isinf(x):
              if saturate:
                  return 0x7B | ret
              return 0x7C | ret
          e = (b & 0x7F800000) >> 23  # exponent
          m = b & 0x007FFFFF  # mantissa
  
          if e != 0:
              if e < 110:
                  pass
              elif e < 111:
                  ret |= 1
                  if (m >> 23) & 1:
                      # rounding
                      # may be unused
                      ret += 1
              elif e < 113:  # 127 - 15 + 1
                  d = 112 - e
                  ret |= 1 << (1 - d)
                  ret |= m >> (22 + d)
                  if (m >> (21 + d)) & 1:
                      # rounding
                      ret += 1
              elif e < 143:  # 127 + 15 + 1
                  ex = e - 112  # 127 - 15
                  ret |= ex << 2
                  ret |= m >> 21
                  if (m & 0x100000) and (
                      (m & 0xFFFFF) or (m & 0x200000)
                  ):  # round to nearest even
                      if (ret & 0x7F) < 0x7B:
                          # rounding
                          ret += 1
                      elif saturate:
                          ret |= 0x7B
                      else:
                          ret |= 0x7C
              elif saturate:
                  ret |= 0x7B
              else:
                  ret |= 0x7C
          return int(ret)
      else:
          raise NotImplementedError(
              "fn and uz must be both False or True."
          )
  
imports: import collections.abc
  import numbers
  import struct
  from cmath import isnan
  from typing import Any, Callable, Dict, KeysView, List, Optional, Sequence, Tuple, TypeVar, Union, cast
  import google.protobuf.message
  import numpy
  from onnx import IR_VERSION, AttributeProto, FunctionProto, GraphProto, MapProto, ModelProto, NodeProto, OperatorSetIdProto, OptionalProto, SequenceProto, SparseTensorProto, TensorProto, TensorShapeProto, TrainingInfoProto, TypeProto, ValueInfoProto, defs, mapping
label_desc: Use image node_id 14 for calling a global function with example usage: float32_to_float8e5m2(fval, scale, fn, uz, saturate) and returns: int, int, int, int, unknown, unknown, unknown, unknown