class_docstr: Scatter ``updates`` to ``data`` at locations ``indices`` at dimension ``axis``
  by operation ``mode``.
  
  Example: ``mode == update``.
  
  * For ``i`` in ``[0, len(indices)]``:
  
  .. math::
     output[p_0, ..., p_{axis-1}, indice[i], p_{axis+1}, ..., p_D] =
  .. math::
     updates[p_0, ..., p_{axis-1}, i, p_{axis+1}, ..., p_D]
  
  * For ``j != i``:
  
  .. math::
     output[p_0, ..., p_{axis-1}, j, p_{axis+1}, ..., p_D] =
  .. math::
     data[p_0, ..., p_{axis-1}, j, p_{axis+1}, ..., p_D]
  
  Example: ``mode == add``.
  
  * For ``i`` in ``[0, len(indices)]``:
  
  .. math::
     output[p_0, ..., p_{axis-1}, indice[i], p_{axis+1}, ..., p_D] =
  .. math::
     updates[p_0, ..., p_{axis-1}, i, p_{axis+1}, ..., p_D] +
  .. math::
     x[p_0, ..., p_{axis-1}, indice[i], p_{axis+1}, ..., p_D]
  
  * For ``j != i``:
  
  .. math::
     output[p_0, ..., p_{axis-1}, j, p_{axis+1}, ..., p_D] =
  .. math::
     data[p_0, ..., p_{axis-1}, j, p_{axis+1}, ..., p_D]
  
  Parameters
  ----------
  data: tensor<\*D, T> (Required)
  indices: tensor<[C], i32> (Required)
      * 1-D tensor.
  updates: tensor<\*K, T> (Required)
      * ``K = data.shape[:axis] + [len(indices)] + data.shape[axis+1:]``.
  axis: const i32 (Optional)
      * Default to ``0``.
  mode: const string (Optional)
      * Can be the following modes: ``update``, ``add``, ``sub``, ``mul``,
        ``div``, ``max``, ``min``.
      * Default value is ``update``.
  
  Returns
  -------
  tensor<\*D, T>
      * With the same type and shape as input ``x``.
  
  Attributes
  ----------
  T: fp16, fp32, i32
  
  For example:
      data = [[1, 2, 3], [4, 5, 6]]
      indices = [1, 0]
      updates = [[5, 6, 7], [8, 9, 10]]
      axis = 0
      mode = "update"
  
  produces:
     [[9, 11, 13], [9, 11, 13]]
class_docstr_tok: ["Scatter","``","updates","``","to","``","data","``","at","locations","``","indices","``","at","dimension","``","axis","``","by","operation","``","mode","``",".","Example",":","``","mode","==","update","``",".","*","For","``","i","``","in","``","[","0",",","len","(","indices",")","]","``",":","..","math",":",":","output","[","p_0",",","...",",","p_","{","axis-1","}",",","indice","[","i","]",",","p_","{","axis+1","}",",","...",",","p_D","]","=","..","math",":",":","updates","[","p_0",",","...",",","p_","{","axis-1","}",",","i",",","p_","{","axis+1","}",",","...",",","p_D","]","*","For","``","j","!","=","i","``",":","..","math",":",":","output","[","p_0",",","...",",","p_","{","axis-1","}",",","j",",","p_","{","axis+1","}",",","...",",","p_D","]","=","..","math",":",":","data","[","p_0",",","...",",","p_","{","axis-1","}",",","j",",","p_","{","axis+1","}",",","...",",","p_D","]","Example",":","``","mode","==","add","``",".","*","For","``","i","``","in","``","[","0",",","len","(","indices",")","]","``",":","..","math",":",":","output","[","p_0",",","...",",","p_","{","axis-1","}",",","indice","[","i","]",",","p_","{","axis+1","}",",","...",",","p_D","]","=","..","math",":",":","updates","[","p_0",",","...",",","p_","{","axis-1","}",",","i",",","p_","{","axis+1","}",",","...",",","p_D","]","+","..","math",":",":","x","[","p_0",",","...",",","p_","{","axis-1","}",",","indice","[","i","]",",","p_","{","axis+1","}",",","...",",","p_D","]","*","For","``","j","!","=","i","``",":","..","math",":",":","output","[","p_0",",","...",",","p_","{","axis-1","}",",","j",",","p_","{","axis+1","}",",","...",",","p_D","]","=","..","math",":",":","data","[","p_0",",","...",",","p_","{","axis-1","}",",","j",",","p_","{","axis+1","}",",","...",",","p_D","]","Parameters","--","--","--","--","--","data",":","tensor","<","\\","*","D",",","T",">","(","Required",")","indices",":","tensor","<","[","C","]",",","i32",">","(","Required",")","*","1-D","tensor",".","updates",":","tensor","<","\\","*","K",",","T",">","(","Required",")","*","``","K","=","data.shape","[",":","axis","]","+","[","len","(","indices",")","]","+","data.shape","[","axis+1",":","]","``",".","axis",":","const","i32","(","Optional",")","*","Default","to","``","0","``",".","mode",":","const","string","(","Optional",")","*","Can","be","the","following","modes",":","``","update","``",",","``","add","``",",","``","sub","``",",","``","mul","``",",","``","div","``",",","``","max","``",",","``","min","``",".","*","Default","value","is","``","update","``",".","Returns","--","--","--","-","tensor","<","\\","*","D",",","T",">","*","With","the","same","type","and","shape","as","input","``","x","``",".","Attributes","--","--","--","--","--","T",":","fp16",",","fp32",",","i32","For","example",":","data","=","[","[","1",",","2",",","3","]",",","[","4",",","5",",","6","]","]","indices","=","[","1",",","0","]","updates","=","[","[","5",",","6",",","7","]",",","[","8",",","9",",","10","]","]","axis","=","0","mode","=","``","update","''","produces",":","[","[","9",",","11",",","13","]",",","[","9",",","11",",","13","]","]"]
code: def type_inference(self):
      if (
          self.axis.val < -self.data.rank
          or self.axis.val >= self.data.rank
      ):
          raise IndexError(
              "Axis value {} is out of bounds for {} node {}".format(
                  self.axis.val, self.op_type, self.name
              )
          )
  
      axis = self.axis.val
      axis = axis if axis >= 0 else axis + self.data.rank
      expected_updates_shape = (
          self.data.shape[:axis]
          + self.indices.shape
          + self.data.shape[axis + 1 :]
      )
  
      err = "Updates shape {} is incorrect. It should be {}.".format(
          self.updates.shape, expected_updates_shape
      )
      assert is_compatible_symbolic_vector(
          self.updates.shape, tuple(expected_updates_shape)
      ), err
  
      return self.data.sym_type
  
imports: import numpy
  from coremltools.converters.mil.mil import Operation, types
  from coremltools.converters.mil.mil.input_type import DefaultInputs, InputSpec, TensorInputType
  from coremltools.converters.mil.mil.operation import SYMBOL, VALUE, precondition
  from coremltools.converters.mil.mil.ops.defs._op_reqs import register_op
  from coremltools.converters.mil.mil.ops.defs._utils import compute_gather
  from coremltools.converters.mil.mil.types.symbolic import is_compatible_symbolic_vector
label_desc: Use image node_id 2 for calling the scatter obj's underlying member method code with example usage: obj.type_inference() and returns: self