class_docstr: A mapping from multi-dimensional indices to another set of multi-dimensional indices
  
  Parameters
  ----------
  initial_indices : List[Var]
      Variables representing the indices prior to remapping.
  final_indices : List[PrimExpr]
      Expressions defining the indices after remapping.
  inverse_index_map : Union[Callable, Optional[IndexMap]]
      The optional pre-defined inverse index map.
      When this is defined, IndexMap::Inverse will return the pre-defined inverse index map.
      Otherwise, the inverse index map will be computed on the fly.
      It is the user's responsibility to ensure the correctness of the pre-defined inverse
      index map.
class_docstr_tok: ["A","mapping","from","multi-dimensional","indices","to","another","set","of","multi-dimensional","indices","Parameters","--","--","--","--","--","initial_indices",":","List","[","Var","]","Variables","representing","the","indices","prior","to","remapping",".","final_indices",":","List","[","PrimExpr","]","Expressions","defining","the","indices","after","remapping",".","inverse_index_map",":","Union","[","Callable",",","Optional","[","IndexMap","]","]","The","optional","pre-defined","inverse","index","map",".","When","this","is","defined",",","IndexMap",":",":Inverse","will","return","the","pre-defined","inverse","index","map",".","Otherwise",",","the","inverse","index","map","will","be","computed","on","the","fly",".","It","is","the","user","'s","responsibility","to","ensure","the","correctness","of","the","pre-defined","inverse","index","map","."]
docstr: Create an index map from a function
  
  Parameters
  ----------
  mapping_function : Callable
  
      The function to map from source indices to target indices.
      The function should accept tir.Var parameters and return
      either a `tir.PrimExpr` or a list.  Each element of the
      returned list should be either a `tir.PrimExpr` or the
      object `IndexMap.AXIS_SEPARATOR`.  Returning a
      `tir.PrimExpr` is equivalent to returning a list of length
      1 containing that `tir.PrimExpr`.
  
  ndim: Optional[int]
  
      The dimensionality of the buffer to which this
      transformation should be applied.  If mapping_function uses
      variadic argument `*args`, ndim must be specified.  If
      mapping_function does not use variadic arguments, ndim is
      optional.
  
  inverse_index_map : Union[Callable, Optional[IndexMap]]
      The optional pre-defined inverse index map.
      When this is defined, IndexMap::Inverse will return the pre-defined inverse index map.
      Otherwise, the inverse index map will be computed on the fly.
      It is the user's responsibility to ensure the correctness of the pre-defined inverse
      index map.
  
  index_dtype : str
      The default index dtype to use for input iters in the mapping function.
  
  Returns
  -------
  ret: Tuple[IndexMap, List[int]]
  
      Returns a tuple whose first element is an IndexMap
      representing the `mapping_function`, and whose second index
      is a list of indices at which `IndexMap.AXIS_SEPARATOR`
      occurred.
docstr_tok: ["Create","an","index","map","from","a","function","Parameters","--","--","--","--","--","mapping_function",":","Callable","The","function","to","map","from","source","indices","to","target","indices",".","The","function","should","accept","tir.Var","parameters","and","return","either","a","`","tir.PrimExpr","`","or","a","list",".","Each","element","of","the","returned","list","should","be","either","a","`","tir.PrimExpr","`","or","the","object","`","IndexMap.AXIS_SEPARATOR","`",".","Returning","a","`","tir.PrimExpr","`","is","equivalent","to","returning","a","list","of","length","1","containing","that","`","tir.PrimExpr","`",".","ndim",":","Optional","[","int","]","The","dimensionality","of","the","buffer","to","which","this","transformation","should","be","applied",".","If","mapping_function","uses","variadic","argument","`","*","args","`",",","ndim","must","be","specified",".","If","mapping_function","does","not","use","variadic","arguments",",","ndim","is","optional",".","inverse_index_map",":","Union","[","Callable",",","Optional","[","IndexMap","]","]","The","optional","pre-defined","inverse","index","map",".","When","this","is","defined",",","IndexMap",":",":Inverse","will","return","the","pre-defined","inverse","index","map",".","Otherwise",",","the","inverse","index","map","will","be","computed","on","the","fly",".","It","is","the","user","'s","responsibility","to","ensure","the","correctness","of","the","pre-defined","inverse","index","map",".","index_dtype",":","str","The","default","index","dtype","to","use","for","input","iters","in","the","mapping","function",".","Returns","--","--","--","-","ret",":","Tuple","[","IndexMap",",","List","[","int","]","]","Returns","a","tuple","whose","first","element","is","an","IndexMap","representing","the","`","mapping_function","`",",","and","whose","second","index","is","a","list","of","indices","at","which","`","IndexMap.AXIS_SEPARATOR","`","occurred","."]
code: def from_func_with_separators(
      mapping_function: Callable,
      ndim: Optional[int] = None,
      inverse_index_map: Union[Callable, Optional["IndexMap"]] = None,
      *,
      index_dtype: str = "int64",
  ):
      """Create an index map from a function
  
      Parameters
      ----------
      mapping_function : Callable
  
          The function to map from source indices to target indices.
          The function should accept tir.Var parameters and return
          either a `tir.PrimExpr` or a list.  Each element of the
          returned list should be either a `tir.PrimExpr` or the
          object `IndexMap.AXIS_SEPARATOR`.  Returning a
          `tir.PrimExpr` is equivalent to returning a list of length
          1 containing that `tir.PrimExpr`.
  
      ndim: Optional[int]
  
          The dimensionality of the buffer to which this
          transformation should be applied.  If mapping_function uses
          variadic argument `*args`, ndim must be specified.  If
          mapping_function does not use variadic arguments, ndim is
          optional.
  
      inverse_index_map : Union[Callable, Optional[IndexMap]]
          The optional pre-defined inverse index map.
          When this is defined, IndexMap::Inverse will return the pre-defined inverse index map.
          Otherwise, the inverse index map will be computed on the fly.
          It is the user's responsibility to ensure the correctness of the pre-defined inverse
          index map.
  
      index_dtype : str
          The default index dtype to use for input iters in the mapping function.
  
      Returns
      -------
      ret: Tuple[IndexMap, List[int]]
  
          Returns a tuple whose first element is an IndexMap
          representing the `mapping_function`, and whose second index
          is a list of indices at which `IndexMap.AXIS_SEPARATOR`
          occurred.
  
      """
      params = inspect.signature(mapping_function).parameters
  
      args = []
      var_arg_name = None
      kwargs = collections.OrderedDict()
  
      for name, param in params.items():
          if param.kind in [
              inspect.Parameter.POSITIONAL_ONLY,
              inspect.Parameter.POSITIONAL_OR_KEYWORD,
          ]:
              args.append(tvm.tir.Var(name, index_dtype))
  
          elif param.kind == inspect.Parameter.VAR_POSITIONAL:
              var_arg_name = name
  
          elif param.kind == inspect.Parameter.KEYWORD_ONLY:
              kwargs[name] = tvm.tir.Var(name, index_dtype)
  
          else:
              raise ValueError(
                  "transform_layout mapping may not have *args"
              )
  
      # Now that all the named arguments have been collected,
      # everything that remains should go to the *args, if
      # specified.
      if var_arg_name is not None:
          assert (
              ndim is not None
          ), "ndim must be specified when *args is used"
          num_var_args = ndim - len(args) - len(kwargs)
          for i in range(num_var_args):
              args.append(
                  tvm.tir.Var(f"{var_arg_name}_{i}", index_dtype)
              )
  
      mapping = mapping_function(*args, **kwargs)
  
      initial_indices = args + list(kwargs.values())
  
      final_indices = []
      axis_separators = []
  
      try:
          iter(mapping)
          is_iterable = True
      except TypeError:
          is_iterable = False
  
      if is_iterable:
          for val in mapping:
              if isinstance(val, tvm.ir.PrimExpr):
                  final_indices.append(val)
              elif val is IndexMap.AXIS_SEPARATOR:
                  axis_separators.append(len(final_indices))
              else:
                  raise TypeError(
                      "Expected mapping function to return list of "
                      "either tvm.ir.PrimExpr or IndexMap.AXIS_SEPARATOR.  "
                      f"Instead received {val} of type {type(val)}."
                  )
      else:
          final_indices.append(mapping)
  
      return (
          IndexMap(initial_indices, final_indices, inverse_index_map),
          axis_separators,
      )
  
imports: import collections
  import inspect
  from typing import Callable, List, Mapping, Optional, Tuple, Union
  import tvm
  import tvm._ffi
  import tvm.runtime
  from tvm.ir import BaseFunc, Range
  from tvm.runtime import Object, Scriptable
  from ..runtime.ndarray import NDArray
  from .None import _ffi_api
  from .buffer import Buffer
  from .expr import PrimExpr, Var
label_desc: Use image node_id 3 for calling the IndexMap obj's underlying member method code with example usage: obj.from_func_with_separators(mapping_function, ndim, inverse_index_map) and returns: IndexMap,  axis_separators