code: def take(outname, inname, chunks, index, itemsize, axis=0):
      """Index array with an iterable of index
  
      Handles a single index by a single list
  
      Mimics ``np.take``
  
      >>> from pprint import pprint
      >>> chunks, dsk = take('y', 'x', [(20, 20, 20, 20)], [5, 1, 47, 3], 8, axis=0)
      >>> chunks
      ((2, 1, 1),)
      >>> pprint(dsk)   # doctest: +ELLIPSIS
      {('y', 0): (<function getitem at ...>, ('x', 0), (array([5, 1]),)),
       ('y', 1): (<function getitem at ...>, ('x', 2), (array([7]),)),
       ('y', 2): (<function getitem at ...>, ('x', 0), (array([3]),))}
  
      When list is sorted we retain original block structure
  
      >>> chunks, dsk = take('y', 'x', [(20, 20, 20, 20)], [1, 3, 5, 47], 8, axis=0)
      >>> chunks
      ((3, 1),)
      >>> pprint(dsk)     # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
      {('y', 0): (<function getitem at ...>,
                  ('x', 0),
                  (array([1, 3, 5]),)),
       ('y', 1): (<function getitem at ...>, ('x', 2), (array([7]),))}
  
      When any indexed blocks would otherwise grow larger than
      dask.config.array.chunk-size, we might split them,
      depending on the value of ``dask.config.slicing.split-large-chunks``.
  
      >>> import dask
      >>> with dask.config.set({"array.slicing.split-large-chunks": True}):
      ...      chunks, dsk = take('y', 'x', [(1, 1, 1), (2000, 2000), (2000, 2000)],
      ...                        [0] + [1] * 6 + [2], axis=0, itemsize=8)
      >>> chunks
      ((1, 3, 3, 1), (2000, 2000), (2000, 2000))
      """
      from dask.array.core import PerformanceWarning
  
      plan = slicing_plan(chunks[axis], index)
      if len(plan) >= len(chunks[axis]) * 10:
          factor = math.ceil(len(plan) / len(chunks[axis]))
  
          warnings.warn(
              "Slicing with an out-of-order index is generating %d "
              "times more chunks" % factor,
              PerformanceWarning,
              stacklevel=6,
          )
      if not is_arraylike(index):
          index = np.asarray(index)
  
      # Check for chunks from the plan that would violate the user's
      # configured chunk size.
      nbytes = utils.parse_bytes(config.get("array.chunk-size"))
      other_chunks = [
          chunks[i] for i in range(len(chunks)) if i != axis
      ]
      other_numel = math.prod(max(x) for x in other_chunks)
  
      if math.isnan(other_numel) or other_numel == 0:
          warnsize = maxsize = math.inf
      else:
          maxsize = math.ceil(nbytes / (other_numel * itemsize))
          warnsize = maxsize * 5
  
      split = config.get("array.slicing.split-large-chunks", None)
  
      # Warn only when the default is not specified.
      warned = split is not None
  
      for _, index_list in plan:
          if not warned and len(index_list) > warnsize:
              msg = (
                  "Slicing is producing a large chunk. To accept the large\n"
                  "chunk and silence this warning, set the option\n"
                  "    >>> with dask.config.set(**{'array.slicing.split_large_chunks': False}):\n"
                  "    ...     array[indexer]\n\n"
                  "To avoid creating the large chunks, set the option\n"
                  "    >>> with dask.config.set(**{'array.slicing.split_large_chunks': True}):\n"
                  "    ...     array[indexer]"
              )
              warnings.warn(msg, PerformanceWarning, stacklevel=6)
              warned = True
  
      where_index = []
      index_lists = []
      for where_idx, index_list in plan:
          index_length = len(index_list)
          if split and index_length > maxsize:
              index_sublist = np.array_split(
                  index_list, math.ceil(index_length / maxsize)
              )
              index_lists.extend(index_sublist)
              where_index.extend([where_idx] * len(index_sublist))
          else:
              if not is_arraylike(index_list):
                  index_list = np.array(index_list)
              index_lists.append(index_list)
              where_index.append(where_idx)
  
      dims = [range(len(bd)) for bd in chunks]
  
      indims = list(dims)
      indims[axis] = list(range(len(where_index)))
      keys = list(product([outname], *indims))
  
      outdims = list(dims)
      outdims[axis] = where_index
      slices = [[colon] * len(bd) for bd in chunks]
      slices[axis] = index_lists
      slices = list(product(*slices))
      inkeys = list(product([inname], *outdims))
      values = [
          (getitem, inkey, slc) for inkey, slc in zip(inkeys, slices)
      ]
  
      chunks2 = list(chunks)
      chunks2[axis] = tuple(map(len, index_lists))
      dsk = dict(zip(keys, values))
  
      return tuple(chunks2), dsk
  
imports: from __future__ import annotations
  import bisect
  import functools
  import math
  import warnings
  from itertools import product
  from numbers import Integral, Number
  from operator import itemgetter
  import numpy
  from tlz import concat, memoize, merge, pluck
  from dask import config, core, utils
  from dask.array.chunk import getitem
  from dask.base import is_dask_collection, tokenize
  from dask.highlevelgraph import HighLevelGraph
  from dask.utils import cached_cumsum, is_arraylike
label_desc: Use image node_id 11 for calling a global function with example usage: take(outname, inname, chunks, index, itemsize, axis) and returns: tuple,  dsk