code: def _tile_tree_reduction(
      cls,
      op: "TensorSearchsorted",
      a: TileableType,
      v: Any,
      out: TileableType,
  ):
      from ..indexing import TensorSlice
      from ..merge import TensorConcatenate
      from ..reduction import TensorMax, TensorMin
  
      if has_unknown_shape(a):
          yield
  
      combine_size = op.combine_size or options.combine_size
      n_chunk = len(a.chunks)
      input_len = len(op.inputs)
      v_chunks = [v] if input_len == 1 else v.chunks
      cum_nsplits = [0] + np.cumsum(a.nsplits[0]).tolist()
  
      input_chunks = []
      offsets = []
      for i in range(n_chunk):
          offset = cum_nsplits[i]
          cur_chunk = a.chunks[i]
          chunk_size = a.shape[0]
          chunks = []
          if i > 0:
              last_chunk = a.chunks[i - 1]
              if last_chunk.shape[0] > 0:
                  slice_chunk_op = TensorSlice(
                      slices=[slice(-1, None)], dtype=cur_chunk.dtype
                  )
                  slice_chunk = slice_chunk_op.new_chunk(
                      [last_chunk], shape=(1,), order=out.order
                  )
                  chunks.append(slice_chunk)
                  chunk_size += 1
                  offset -= 1
          chunks.append(cur_chunk)
          if i < n_chunk - 1:
              next_chunk = a.chunks[i + 1]
              if next_chunk.shape[0] > 0:
                  slice_chunk_op = TensorSlice(
                      slices=[slice(1)], dtype=cur_chunk.dtype
                  )
                  slice_chunk = slice_chunk_op.new_chunk(
                      [next_chunk], shape=(1,), order=out.order
                  )
                  chunks.append(slice_chunk)
                  chunk_size += 1
  
          concat_op = TensorConcatenate(dtype=cur_chunk.dtype)
          concat_chunk = concat_op.new_chunk(
              chunks,
              shape=(chunk_size,),
              order=out.order,
              index=cur_chunk.index,
          )
          input_chunks.append(concat_chunk)
          offsets.append(offset)
  
      out_chunks = []
      for v_chunk in v_chunks:
          chunks = []
          v_shape = v_chunk.shape if hasattr(v_chunk, "shape") else ()
          v_index = v_chunk.index if hasattr(v_chunk, "index") else (0,)
          for inp_chunk, offset in zip(input_chunks, offsets):
              chunk_op = op.copy().reset_key()
              chunk_op.stage = OperandStage.map
              chunk_op.offset = offset
              chunk_op.n_chunk = n_chunk
              chunk_op.size = a.shape[0]
              chunk_inputs = [inp_chunk]
              if input_len > 1:
                  chunk_inputs.append(v_chunk)
              map_chunk = chunk_op.new_chunk(
                  chunk_inputs,
                  shape=v_shape,
                  index=inp_chunk.index,
                  order=out.order,
              )
              chunks.append(map_chunk)
  
          op_type = TensorMax if op.side == "right" else TensorMin
          while len(chunks) > combine_size:
              new_chunks = []
              it = itertools.count(0)
              while True:
                  j = next(it)
                  to_combine = chunks[
                      j * combine_size : (j + 1) * combine_size
                  ]
                  if len(to_combine) == 0:
                      break
  
                  new_chunks.append(
                      cls._combine_chunks(
                          to_combine,
                          op_type,
                          v_chunk,
                          OperandStage.combine,
                          (j,),
                      )
                  )
              chunks = new_chunks
  
          chunk = cls._combine_chunks(
              chunks, op_type, v_chunk, OperandStage.agg, v_index
          )
          out_chunks.append(chunk)
  
      new_op = op.copy().reset_key()
      nsplits = (
          ((s,) for s in out.shape)
          if len(op.inputs) == 1
          else v.nsplits
      )
      return new_op.new_tensors(
          op.inputs, out.shape, chunks=out_chunks, nsplits=nsplits
      )
  
imports: import itertools
  from typing import Any, List, Tuple, Type
  import numpy
  from ...None import opcodes
  from ...core import TILEABLE_TYPE
  from ...core.operand import OperandStage
  from ...serialization.serializables import StringField, AnyField, Int64Field, Int32Field
  from ...typing import TileableType, ChunkType
  from ...config import options
  from ...utils import has_unknown_shape
  from ..operands import TensorOperand, TensorOperandMixin
  from ..core import TENSOR_TYPE, TensorOrder
  from ..datasource.array import tensor
  from ..array_utils import as_same_device, device
label_desc: Use image node_id 5 for calling the TensorSearchsorted obj's underlying member method code with example usage: obj._tile_tree_reduction(cls, op, a, v, out) and returns: new_op