code: def float32_to_float8e4m3(  # noqa: PLR0911
      fval: float,
      scale: float = 1.0,
      fn: bool = True,
      uz: bool = False,
      saturate: bool = True,
  ) -> int:
      """Convert a float32 value to a float8, e4m3 (as int).
  
      See :ref:`onnx-detail-float8` for technical details.
  
      Args:
          fval: float to convert
          scale: scale, divide *fval* by *scale* before casting it
          fn: no infinite values
          uz: no negative zero
          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.
  
      Returns:
          converted float
      """
      if not fn:
          raise NotImplementedError(
              "float32_to_float8e4m3 not implemented with fn=False."
          )
      x = fval / scale
      b = int.from_bytes(struct.pack("<f", np.float32(x)), "little")
      ret = (b & 0x80000000) >> 24  # sign
      if uz:
          if (b & 0x7FC00000) == 0x7FC00000:  # noqa: PLR2004
              return 0x80
          if np.isinf(x):
              if saturate:
                  return ret | 127
              return 0x80
          e = (b & 0x7F800000) >> 23  # exponent
          m = b & 0x007FFFFF  # mantissa
  
          if e < 116:  # noqa: PLR2004
              ret = 0
          elif e < 120:  # noqa: PLR2004
              # denormalized number
              ex = e - 119
              if ex >= -2:  # noqa: PLR2004
                  ret |= 1 << (2 + ex)
                  ret |= m >> (21 - ex)
              elif m > 0:
                  ret |= 1
              else:
                  ret = 0
              mask = 1 << (20 - ex)
              if m & mask and (
                  ret & 1
                  or m & (mask - 1) > 0
                  or (
                      m & mask
                      and m & (mask << 1)
                      and m & (mask - 1) == 0
                  )
              ):
                  # rounding
                  ret += 1
          elif e < 135:  # noqa: PLR2004
              # normalized number
              ex = e - 119  # 127 - 8
              if ex == 0:
                  ret |= 0x4
                  ret |= m >> 21
              else:
                  ret |= ex << 3
                  ret |= m >> 20
              if m & 0x80000 and ((m & 0x100000) or (m & 0x7FFFF)):
                  if (ret & 0x7F) < 0x7F:  # noqa: PLR2004
                      # rounding
                      ret += 1
                  elif not saturate:
                      return 0x80
          elif saturate:
              ret |= 0x7F  # 01111110
          else:
              ret = 0x80
          return int(ret)
      else:
          if (b & 0x7FC00000) == 0x7FC00000:  # noqa: PLR2004
              return 0x7F | ret
          if np.isinf(x):
              if saturate:
                  return ret | 126
              return 0x7F | ret
          e = (b & 0x7F800000) >> 23  # exponent
          m = b & 0x007FFFFF  # mantissa
  
          if e != 0:
              if e < 117:  # noqa: PLR2004
                  pass
              elif e < 121:  # noqa: PLR2004
                  # denormalized number
                  ex = e - 120
                  if ex >= -2:  # noqa: PLR2004
                      ret |= 1 << (2 + ex)
                      ret |= m >> (21 - ex)
                  elif m > 0:
                      ret |= 1
                  mask = 1 << (20 - ex)
                  if m & mask and (
                      ret & 1
                      or m & (mask - 1) > 0
                      or (
                          m & mask
                          and m & (mask << 1)
                          and m & (mask - 1) == 0
                      )
                  ):
                      # rounding
                      ret += 1
              elif e < 136:  # noqa: PLR2004
                  # normalized number
                  ex = e - 120
                  if ex == 0:
                      ret |= 0x4
                      ret |= m >> 21
                  else:
                      ret |= ex << 3
                      ret |= m >> 20
                      if (ret & 0x7F) == 0x7F:  # noqa: PLR2004
                          ret &= 0xFE
                  if (m & 0x80000) and (
                      (m & 0x100000) or (m & 0x7FFFF)
                  ):
                      if (ret & 0x7F) < 0x7E:  # noqa: PLR2004
                          # rounding
                          ret += 1
                      elif not saturate:
                          ret |= 0x7F
              elif saturate:
                  ret |= 126  # 01111110
              else:
                  ret |= 0x7F
          return int(ret)
  
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, subbyte
label_desc: Use image node_id 13 for calling a global function with example usage: float32_to_float8e4m3(fval, scale, fn, uz, saturate) and returns: int, int, int, int, unknown, unknown, unknown, unknown, int