docstr: Refer to http://csweb.cs.wfu.edu/bigiron/LittleFE-PSRS/build/html/PSRSalgorithm.html
  to see explanation of parallel sorting by regular sampling
docstr_tok: ["Refer","to","http",":","\/\/csweb.cs.wfu.edu\/bigiron\/LittleFE-PSRS\/build\/html\/PSRSalgorithm.html","to","see","explanation","of","parallel","sorting","by","regular","sampling"]
code: def _tile_psrs(cls, op):
      """
      Refer to http://csweb.cs.wfu.edu/bigiron/LittleFE-PSRS/build/html/PSRSalgorithm.html
      to see explanation of parallel sorting by regular sampling
      """
      out_tensor = op.outputs[0]
      (
          in_tensor,
          axis_chunk_shape,
          out_idxes,
          need_align,
      ) = yield from cls.preprocess(op)
      axis_offsets = [0] + np.cumsum(
          in_tensor.nsplits[op.axis]
      ).tolist()[:-1]
      return_value, return_indices = op.return_value, op.return_indices
  
      out_value_chunks, out_indices_chunks = [], []
      for out_idx in out_idxes:
          # stage 1: local sort and regular samples collected
          (
              sorted_chunks,
              indices_chunks,
              sampled_chunks,
          ) = cls.local_sort_and_regular_sample(
              op, in_tensor, axis_chunk_shape, axis_offsets, out_idx
          )
  
          # stage 2: gather and merge samples, choose and broadcast p-1 pivots
          concat_pivot_chunk = cls.concat_and_pivot(
              op,
              axis_chunk_shape,
              out_idx,
              sorted_chunks,
              sampled_chunks,
          )
  
          # stage 3: Local data is partitioned
          partition_chunks = cls.partition_local_data(
              op,
              axis_chunk_shape,
              sorted_chunks,
              indices_chunks,
              concat_pivot_chunk,
          )
  
          proxy_chunk = TensorShuffleProxy(
              dtype=partition_chunks[0].dtype
          ).new_chunk(partition_chunks, shape=())
  
          # stage 4: all *ith* classes are gathered and merged
          (
              partition_sort_chunks,
              partition_indices_chunks,
              sort_info_chunks,
          ) = cls.partition_merge_data(
              op, need_align, None, partition_chunks, proxy_chunk
          )
  
          if not need_align:
              if return_value:
                  out_value_chunks.extend(partition_sort_chunks)
              if return_indices:
                  out_indices_chunks.extend(partition_indices_chunks)
          else:
              (
                  align_reduce_value_chunks,
                  align_reduce_indices_chunks,
              ) = cls.align_partitions_data(
                  op,
                  out_idx,
                  in_tensor,
                  partition_sort_chunks,
                  partition_indices_chunks,
                  sort_info_chunks,
              )
              if return_value:
                  out_value_chunks.extend(align_reduce_value_chunks)
              if return_indices:
                  out_indices_chunks.extend(align_reduce_indices_chunks)
  
      new_op = op.copy()
      nsplits = list(in_tensor.nsplits)
      if not need_align:
          nsplits[op.axis] = (np.nan,) * axis_chunk_shape
      kws = []
      if return_value:
          kws.append(
              {
                  "shape": out_tensor.shape,
                  "order": out_tensor.order,
                  "chunks": out_value_chunks,
                  "nsplits": nsplits,
                  "dtype": out_tensor.dtype,
              }
          )
      if return_indices:
          kws.append(
              {
                  "shape": out_tensor.shape,
                  "order": TensorOrder.C_ORDER,
                  "chunks": out_indices_chunks,
                  "nsplits": nsplits,
                  "dtype": np.dtype(np.int64),
              }
          )
      return new_op.new_tensors(op.inputs, kws=kws)
  
imports: import numpy
  from ...None import opcodes
  from ...serialization.serializables import FieldTypes, Int32Field, StringField, ListField, BoolField
  from ...core import ExecutableTuple
  from ..array_utils import as_same_device, device
  from ..core import TensorOrder
  from ..datasource import tensor
  from ..operands import TensorOperand, TensorShuffleProxy
  from ..utils import validate_axis, validate_order
  from .psrs import TensorPSRSOperandMixin
label_desc: Use image node_id 12 for calling the TensorSort obj's underlying member method code with example usage: obj._tile_psrs(cls, op) and returns: new_op