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

    with device(device_id):
        ctx[op.outputs[0].key] = xp.isclose(
            a, b, atol=op.atol, rtol=op.rtol, equal_nan=op.equal_nan
        )


# Traceback (ValueError)
In []: mt.isclose((0,0), (0,0)).execute()
Out[]: array([True, True])
In []: mt.isclose((0,0), (0,)).execute()
Out[]: arary([True, True])
In []: np.isclose((0,0), (0))
Out[]: array([True, True])
In []: mt.isclose((0,0), (0)).execute()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-a3e463eb7acf> in <module>
----> 1 mt.isclose((0,0), (0)).execute()

~/anaconda3/lib/python3.7/site-packages/mars/core.py in execute(self, session, **kw)
580
581     def execute(self, session=None, **kw):
--> 582         self._data.execute(session, **kw)
583         return self
584

~/anaconda3/lib/python3.7/site-packages/mars/core.py in execute(self, session, **kw)
368
369         # no more fetch, thus just fire run
--> 370         session.run(self, **kw)
371         # return Tileable or ExecutableTuple itself
372         return self

~/anaconda3/lib/python3.7/site-packages/mars/session.py in run(self, *tileables, **kw)
460         tileables = tuple(mt.tensor(t) if not isinstance(t, (Entity, Base)) else t
461                           for t in tileables)
--> 462         result = self._sess.run(*tileables, **kw)
463
464         for t in tileables:

~/anaconda3/lib/python3.7/site-packages/mars/session.py in run(self, *tileables, **kw)
105             # set number of running cores
106             self.context.set_ncores(kw['n_parallel'])
--> 107             res = self._executor.execute_tileables(tileables, **kw)
108             return res
109

~/anaconda3/lib/python3.7/site-packages/mars/utils.py in _wrapped(*args, **kwargs)
406                 _kernel_mode.eager = False
407             _kernel_mode.eager_count = enter_eager_count + 1
--> 408             return func(*args, **kwargs)
409         finally:
410             _kernel_mode.eager_count -= 1

~/anaconda3/lib/python3.7/site-packages/mars/utils.py in inner(*args, **kwargs)
500     def inner(*args, **kwargs):
501         with build_mode():
--> 502             return func(*args, **kwargs)
503     return inner
504

~/anaconda3/lib/python3.7/site-packages/mars/executor.py in execute_tileables(self, tileables, fetch, n_parallel, n_thread, print_progress, mock, compose, name)
878                                    n_parallel=n_parallel or n_thread,
879                                    print_progress=print_progress, mock=mock,
--> 880                                    chunk_result=chunk_result)
881
882                 # update shape of tileable and its chunks whatever it's successful or not

~/anaconda3/lib/python3.7/site-packages/mars/executor.py in execute_graph(self, graph, keys, n_parallel, print_progress, mock, no_intermediate, compose, retval, chunk_result)
688             print_progress=print_progress, mock=mock, mock_max_memory=self._mock_max_memory,
689             fetch_keys=fetch_keys, no_intermediate=no_intermediate)
--> 690         res = graph_execution.execute(retval)
691         self._mock_max_memory = max(self._mock_max_memory, graph_execution._mock_max_memory)
692         if mock:

~/anaconda3/lib/python3.7/site-packages/mars/executor.py in execute(self, retval)
569         # wait until all the futures completed
570         for future in executed_futures:
--> 571             future.result()
572
573         if retval:

~/anaconda3/lib/python3.7/concurrent/futures/_base.py in result(self, timeout)
426                 raise CancelledError()
427             elif self._state == FINISHED:
--> 428                 return self.__get_result()
429
430             self._condition.wait(timeout)

~/anaconda3/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

~/anaconda3/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)

~/anaconda3/lib/python3.7/site-packages/mars/executor.py in _execute_operand(self, op)
441             # so we pass the first operand's first output to Executor.handle
442             first_op = ops[0]
--> 443             Executor.handle(first_op, results, self._mock)
444
445             # update maximal memory usage during execution

~/anaconda3/lib/python3.7/site-packages/mars/executor.py in handle(cls, op, results, mock)
639                 # The `UFuncTypeError` was introduced by numpy#12593 since v1.17.0.
640                 try:
--> 641                     return runner(results, op)
642                 except UFuncTypeError as e:
643                     raise TypeError(str(e)).with_traceback(sys.exc_info()[2]) from None

~/anaconda3/lib/python3.7/site-packages/mars/tensor/arithmetic/isclose.py in execute(cls, ctx, op)
61     def execute(cls, ctx, op):
62         (a, b), device_id, xp = as_same_device(
---> 63             [ctx[c.key] for c in op.inputs], device=op.device, ret_extra=True)
64
65         with device(device_id):

ValueError: not enough values to unpack (expected 2, got 1)

# Fixed 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 = op.lhs if np.isscalar(op.lhs) else inputs[0]
        b = op.rhs if np.isscalar(op.rhs) else inputs[-1]

        ctx[op.outputs[0].key] = xp.isclose(
            a, b, atol=op.atol, rtol=op.rtol, equal_nan=op.equal_nan
        )