class_docstr: This transform does the following, for each op that supports int16:
  - For each input of dtype int32 which actually supports int16, inject a "cast" op to change it
    to int16 dtype.
  - For each output of dtype int16, inject a "cast" op to change it back to int32.
  It's mainly for int16 op ANE residency.
class_docstr_tok: ["This","transform","does","the","following",",","for","each","op","that","supports","int16",":","-","For","each","input","of","dtype","int32","which","actually","supports","int16",",","inject","a","``","cast","''","op","to","change","it","to","int16","dtype",".","-","For","each","output","of","dtype","int16",",","inject","a","``","cast","''","op","to","change","it","back","to","int32",".","It","'s","mainly","for","int16","op","ANE","residency","."]
docstr: Determines if any of the op's input will overflow when represented by int16. Constants with
  values more than np.iinfo(np.int16).max or less than np.iinfo(np.int16).min overflows in int16.
docstr_tok: ["Determines","if","any","of","the","op","'s","input","will","overflow","when","represented","by","int16",".","Constants","with","values","more","than","np.iinfo","(","np.int16",")",".max","or","less","than","np.iinfo","(","np.int16",")",".min","overflows","in","int16","."]
code: def int16_overflow(op: Operation) -> bool:
      """
      Determines if any of the op's input will overflow when represented by int16. Constants with
      values more than np.iinfo(np.int16).max or less than np.iinfo(np.int16).min overflows in int16.
      """
      _INT16_MAX = np.iinfo(np.int16).max
      _INT16_MIN = np.iinfo(np.int16).min
      for _, inputs in op.inputs.items():
          is_list_input = isinstance(inputs, (list, tuple))
          if not is_list_input:
              inputs = [inputs]
          for var in inputs:
              if var.val is not None and var.is_tensor_or_scalar_of(
                  dtype="int32"
              ):
                  if np.any(var.val > _INT16_MAX) or np.any(
                      var.val < _INT16_MIN
                  ):
                      return True
  
      # In `gather` and `gather_along_axis`, if the dim size of x is larger than int16 upperbound,
      # the dynamic indices could overflow.
      if (
          op.op_type in {"gather", "gather_along_axis"}
          and op.indices.val is None
          and op.x.shape is not None
      ):
          dim_size = op.x.shape[op.axis.val]
          if not is_symbolic(dim_size) and dim_size > _INT16_MAX:
              return True
  
      return False
  
imports: from abc import abstractmethod
  from enum import Enum
  from typing import Set, Text
  import numpy
  from coremltools.converters.mil._deployment_compatibility import AvailableTarget
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import Operation, types
  from coremltools.converters.mil.mil.block import is_current_opset_version_compatible_with
  from coremltools.converters.mil.mil.ops.registry import SSAOpRegistry
  from coremltools.converters.mil.mil.passes.graph_pass import AbstractGraphPass
  from coremltools.converters.mil.mil.passes.helper import block_context_manager
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
  from coremltools.converters.mil.mil.program import Program
  from coremltools.converters.mil.mil.types.symbolic import is_symbolic
label_desc: Use image node_id 4 for calling the add_int16_cast obj's underlying member method code with example usage: obj.int16_overflow(op) and returns: False, True, True