# Buggy code
def execute_agg(cls, ctx, op):
    (input_chunk,), device_id, xp = as_same_device(
        [ctx[c.key] for c in op.inputs], device=op.device, ret_extra=True
    )
    axis = cls.get_axis(op.axis)
    func_name = getattr(cls, "_func_name", None)
    reduce_func = getattr(xp, func_name)
    out = op.outputs[0]
    with device(device_id):
        if "dtype" in inspect.getfullargspec(reduce_func).args:
            ret = reduce_func(
                input_chunk, axis=axis, dtype=op.dtype, keepdims=bool(op.keepdims)
            )
        else:
            ret = reduce_func(input_chunk, axis=axis, keepdims=bool(op.keepdims))

        if hasattr(ret, "astype"):
            # for non-object dtype
            ret = ret.astype(op.dtype, order=out.order.value, copy=False)
        ctx[out.key] = ret


# Traceback (ValueError)
Traceback (most recent call last):
File "miniconda3/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3417, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-26-c79b5d2b7d19>", line 1, in <module>
histogram(vt).execute()
File "Code/mars/mars/core.py", line 764, in execute
return super().execute(session=session, **kw)
File "Code/mars/mars/core.py", line 379, in execute
return run()
File "Code/mars/mars/core.py", line 374, in run
session.run(self, **kw)
File "Code/mars/mars/session.py", line 506, in run
result = self._sess.run(*tileables, **kw)
File "Code/mars/mars/session.py", line 111, in run
res = self._executor.execute_tileables(tileables, **kw)
File "Code/mars/mars/utils.py", line 459, in _inner
return func(*args, **kwargs)
File "Code/mars/mars/executor.py", line 883, in execute_tileables
self.execute_graph(chunk_graph, list(temp_result_keys),
File "Code/mars/mars/executor.py", line 698, in execute_graph
res = graph_execution.execute(retval)
File "Code/mars/mars/executor.py", line 579, in execute
future.result()
File "miniconda3/lib/python3.8/concurrent/futures/_base.py", line 432, in result
return self.__get_result()
File "miniconda3/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result
raise self._exception
File "miniconda3/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "Code/mars/mars/utils.py", line 459, in _inner
return func(*args, **kwargs)
File "Code/mars/mars/executor.py", line 446, in _execute_operand
self.handle_op(first_op, results, self._mock)
File "Code/mars/mars/executor.py", line 378, in handle_op
return Executor.handle(*args, **kw)
File "Code/mars/mars/executor.py", line 649, in handle
return runner(results, op)
File "Code/mars/mars/tensor/reduction/core.py", line 291, in execute
return cls.execute_agg(ctx, op)
File "Code/mars/mars/tensor/reduction/core.py", line 272, in execute_agg
ret = reduce_func(input_chunk, axis=axis,
File "<__array_function__ internals>", line 5, in amin
File "miniconda3/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 2830, in amin
return _wrapreduction(a, np.minimum, 'min', axis, None, out,
File "miniconda3/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 87, in _wrapreduction
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
ValueError: zero-size array to reduction operation minimum which has no identity

# Fixed code
def execute_agg(cls, ctx, op):
    (input_chunk,), device_id, xp = as_same_device(
        [ctx[c.key] for c in op.inputs], device=op.device, ret_extra=True
    )
    axis = cls.get_axis(op.axis)
    func_name = getattr(cls, "_func_name", None)
    reduce_func = getattr(xp, func_name)
    out = op.outputs[0]
    with device(device_id):
        if input_chunk.size == 0 and op.keepdims:
            # input chunk is empty, when keepdims is True, return itself
            ret = input_chunk
        elif "dtype" in inspect.getfullargspec(reduce_func).args:
            ret = reduce_func(
                input_chunk, axis=axis, dtype=op.dtype, keepdims=bool(op.keepdims)
            )
        else:
            ret = reduce_func(input_chunk, axis=axis, keepdims=bool(op.keepdims))

        if hasattr(ret, "astype"):
            # for non-object dtype
            ret = ret.astype(op.dtype, order=out.order.value, copy=False)
        ctx[out.key] = ret