code: def tile(cls, op):
      a = op.input
      combine_size = options.combine_size
      k = op.k
      axis = op.axis
  
      if len(a.chunks) == 1:
          return cls._tile_one_chunk(op)
  
      parallel_kind = op.parallel_kind.lower()
  
      if parallel_kind == "auto":
          nsplit = a.nsplits[axis]
          max_chunk_size = max(nsplit)
          if np.isnan(max_chunk_size):
              # has unknown chunk shape and k > 100 just choose 'psrs'
              parallel_kind = "psrs" if k > 100 else "tree"
          else:
              if combine_size * k <= max_chunk_size:
                  # each chunk will have k elements on specified axis,
                  # if combined chunk which generated in the tree reduction
                  # is less than max chunk size, parallel kind `tree` will be adopted
                  parallel_kind = "tree"
              else:
                  parallel_kind = "psrs"
  
      if parallel_kind == "tree":
          op._parallel_kind = "tree"
          return cls._tile_via_tree(op)
      else:
          assert parallel_kind == "psrs"
          op._parallel_kind = "psrs"
          return (yield from cls._tile_via_psrs(op))
  
imports: import itertools
  import numpy
  from ...None import opcodes
  from ...config import options
  from ...core import ExecutableTuple, recursive_tile
  from ...core.operand import OperandStage
  from ...serialization.serializables import FieldTypes, KeyField, Int64Field, Int32Field, BoolField, StringField, ListField
  from ...utils import ceildiv, flatten
  from ..array_utils import as_same_device, device
  from ..core import TensorOrder
  from ..datasource import tensor
  from ..operands import TensorOperand, TensorOperandMixin
  from ..utils import validate_axis, validate_order
  from .sort import _validate_sort_psrs_kinds
label_desc: Use image node_id 21 for calling the TensorTopk obj's underlying member method code with example usage: obj.tile(cls, op) and returns: cls, cls, unknown