# Buggy code
def execute(cls, ctx, op):
    inputs, device_id, xp = as_same_device(
        [ctx[c.key] for c in op.inputs], device=op.device, ret_extra=True
    )

    with device(device_id):
        a = xp.concatenate(inputs, axis=op.axis)
        p = len(inputs)
        assert a.shape[op.axis] == p**2

        if op.kind is not None:
            # sort
            _sort(a, op, xp, inplace=True)
        else:
            # prepare for sampling via `partition`
            kth = xp.linspace(
                p - 1, a.shape[op.axis] - 1, num=p - 1, endpoint=False
            ).astype(int)
            a.partition(kth, axis=op.axis)

        select = xp.linspace(
            p - 1, a.shape[op.axis] - 1, num=p - 1, endpoint=False
        ).astype(int)
        slc = (slice(None),) * op.axis + (select,)
        ctx[op.outputs[0].key] = result = a[slc]
        assert result.shape[op.axis] == p - 1


# Traceback (IndexError)
In [59]: a = mt.random.randint(0, 2, size=(1000,), chunk_size=300)

In [60]: mt.sort(mt.sort(a)).execute()
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-60-6c95dab88665> in <module>
----> 1 mt.sort(mt.sort(a)).execute()

~/Documents/mars_dev/mars/mars/core.py in execute(self, session, **kw)
644
645         if wait:
--> 646             return run()
647         else:
648             thread_executor = ThreadPoolExecutor(1)

~/Documents/mars_dev/mars/mars/core.py in run()
640
641         def run():
--> 642             self.data.execute(session, **kw)
643             return self
644

~/Documents/mars_dev/mars/mars/core.py in execute(self, session, **kw)
377
378         if wait:
--> 379             return run()
380         else:
381             # leverage ThreadPoolExecutor to submit task,

~/Documents/mars_dev/mars/mars/core.py in run()
372         def run():
373             # no more fetch, thus just fire run
--> 374             session.run(self, **kw)
375             # return Tileable or ExecutableTuple itself
376             return self

~/Documents/mars_dev/mars/mars/session.py in run(self, *tileables, **kw)
503         tileables = tuple(mt.tensor(t) if not isinstance(t, (Entity, Base)) else t
504                           for t in tileables)
--> 505         result = self._sess.run(*tileables, **kw)
506
507         for t in tileables:

~/Documents/mars_dev/mars/mars/session.py in run(self, *tileables, **kw)
109             # set number of running cores
110             self.context.set_ncores(kw['n_parallel'])
--> 111             res = self._executor.execute_tileables(tileables, **kw)
112             return res
113

~/Documents/mars_dev/mars/mars/utils.py in _inner(*args, **kwargs)
456         def _inner(*args, **kwargs):
457             with self:
--> 458                 return func(*args, **kwargs)
459
460         return _inner

~/Documents/mars_dev/mars/mars/executor.py in execute_tileables(self, tileables, fetch, n_parallel, n_thread, print_progress, mock, compose, name)
884                                    n_parallel=n_parallel or n_thread,
885                                    print_progress=print_progress, mock=mock,
--> 886                                    chunk_result=chunk_result)
887
888                 # update shape of tileable and its chunks whatever it's successful or not

~/Documents/mars_dev/mars/mars/executor.py in execute_graph(self, graph, keys, n_parallel, print_progress, mock, no_intermediate, compose, retval, chunk_result)
696             print_progress=print_progress, mock=mock, mock_max_memory=self._mock_max_memory,
697             fetch_keys=fetch_keys, no_intermediate=no_intermediate)
--> 698         res = graph_execution.execute(retval)
699         self._mock_max_memory = max(self._mock_max_memory, graph_execution._mock_max_memory)
700         if mock:

~/Documents/mars_dev/mars/mars/executor.py in execute(self, retval)
577         # wait until all the futures completed
578         for future in executed_futures:
--> 579             future.result()
580
581         if retval:

~/miniconda3/envs/py3.7.2/lib/python3.7/concurrent/futures/_base.py in result(self, timeout)
423                 raise CancelledError()
424             elif self._state == FINISHED:
--> 425                 return self.__get_result()
426
427             self._condition.wait(timeout)

~/miniconda3/envs/py3.7.2/lib/python3.7/concurrent/futures/_base.py in __get_result(self)
382     def __get_result(self):
383         if self._exception:
--> 384             raise self._exception
385         else:
386             return self._result

~/miniconda3/envs/py3.7.2/lib/python3.7/concurrent/futures/thread.py in run(self)
55
56         try:
---> 57             result = self.fn(*self.args, **self.kwargs)
58         except BaseException as exc:
59             self.future.set_exception(exc)

~/Documents/mars_dev/mars/mars/utils.py in _inner(*args, **kwargs)
456         def _inner(*args, **kwargs):
457             with self:
--> 458                 return func(*args, **kwargs)
459
460         return _inner

~/Documents/mars_dev/mars/mars/executor.py in _execute_operand(self, op)
444             # so we pass the first operand's first output to Executor.handle
445             first_op = ops[0]
--> 446             self.handle_op(first_op, results, self._mock)
447
448             # update maximal memory usage during execution

~/Documents/mars_dev/mars/mars/executor.py in handle_op(self, *args, **kw)
376
377     def handle_op(self, *args, **kw):
--> 378         return Executor.handle(*args, **kw)
379
380     def _order_starts(self):

~/Documents/mars_dev/mars/mars/executor.py in handle(cls, op, results, mock)
647                 # The `UFuncTypeError` was introduced by numpy#12593 since v1.17.0.
648                 try:
--> 649                     return runner(results, op)
650                 except UFuncTypeError as e:
651                     raise TypeError(str(e)).with_traceback(sys.exc_info()[2]) from None

~/Documents/mars_dev/mars/mars/tensor/base/psrs.py in execute(cls, ctx, op)
426                               num=n, endpoint=False).astype(int)
427             slc = (slice(None),) * op.axis + (slc,)
--> 428             ctx[op.outputs[-1].key] = res[slc]
429
430

IndexError: index 0 is out of bounds for axis 0 with size 0

# Fixed code
def execute(cls, ctx, op):
    inputs, device_id, xp = as_same_device(
        [ctx[c.key] for c in op.inputs if len(ctx[c.key]) > 0],
        device=op.device,
        ret_extra=True,
    )

    with device(device_id):
        a = xp.concatenate(inputs, axis=op.axis)
        p = len(inputs)
        assert a.shape[op.axis] == p * len(op.inputs)

        if op.kind is not None:
            # sort
            _sort(a, op, xp, inplace=True)
        else:
            # prepare for sampling via `partition`
            kth = xp.linspace(
                p - 1, a.shape[op.axis] - 1, num=p - 1, endpoint=False
            ).astype(int)
            a.partition(kth, axis=op.axis)

        select = xp.linspace(
            p - 1, a.shape[op.axis] - 1, num=len(op.inputs) - 1, endpoint=False
        ).astype(int)
        slc = (slice(None),) * op.axis + (select,)
        ctx[op.outputs[0].key] = a[slc]