code: def upcast_float16_ufunc(fn):
      """Decorator that enforces computation is not done in float16 by NumPy.
  
      Some ufuncs in NumPy will compute float values on int8 and uint8
      in half-precision (float16), which is not enough, and not compatible
      with the C code.
  
      Parameters
      ----------
      fn
          A NumPy ufunc.
  
      Returns
      -------
      A function similar to `fn.__call__`, computing the same value with a minimum
      floating-point precision of float32
      """
  
      def ret(*args, **kwargs):
          out_dtype = np.find_common_type(
              [a.dtype for a in args], [np.float16]
          )
          if out_dtype == "float16":
              # Force everything to float32
              sig = "f" * fn.nin + "->" + "f" * fn.nout
              kwargs.update(sig=sig)
          return fn(*args, **kwargs)
  
      return ret
  
imports: import os
  from copy import copy
  from itertools import combinations
  from tempfile import mkstemp
  import numpy
  import pytest
  import pytensor
  from pytensor import function, shared
  from pytensor.compile.mode import get_default_mode
  from pytensor.configdefaults import config
  from pytensor.graph.utils import MethodNotDefined
  from pytensor.misc.safe_asarray import _asarray
  from pytensor.tensor.type import TensorType, complex_dtypes, discrete_dtypes, float_dtypes
  from tests import unittest_tools
label_desc: Use image node_id 7 for calling a global function with example usage: upcast_float16_ufunc(fn) and returns: ret, fn