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

        if isinstance(op, six.string_types):
            func = getattr(xp, op)
        else:
            func = op

        with device(device_id):
            kw = {"casting": chunk.op.casting} if chunk.op.out else {}

            if chunk.op.out and chunk.op.where:
                inputs, kw["out"], kw["where"] = (
                    inputs[:-2],
                    inputs[-2].copy(),
                    inputs[-1],
                )
            elif chunk.op.out:
                inputs, kw["out"] = inputs[:-1], inputs[-1].copy()

            with np.errstate(**chunk.op.err):
                if len(inputs) == 1:
                    try:
                        ctx[chunk.key] = _handle_out_dtype(
                            func(inputs[0], **kw), chunk.op.dtype
                        )
                    except TypeError:
                        if kw.get("where") is None:
                            raise
                        out, where = kw.pop("out"), kw.pop("where")
                        ctx[chunk.key] = _handle_out_dtype(
                            xp.where(where, func(inputs[0]), out), chunk.op.dtype
                        )
                else:
                    try:
                        if is_sparse_module(xp):
                            ctx[chunk.key] = _handle_out_dtype(
                                reduce(lambda a, b: func(a, b, **kw), inputs),
                                chunk.op.dtype,
                            )
                        else:
                            if "out" not in kw:
                                dest_value = xp.empty(chunk.shape, chunk.dtype)
                                kw["out"] = dest_value
                            ctx[chunk.key] = _handle_out_dtype(
                                reduce(lambda a, b: func(a, b, **kw), inputs),
                                chunk.op.dtype,
                            )
                    except TypeError:
                        if kw.get("where") is None:
                            raise
                        out, where = kw.pop("out"), kw.pop("where")
                        ctx[chunk.key] = _handle_out_dtype(
                            xp.where(
                                where, reduce(lambda a, b: func(a, b), inputs), out
                            ),
                            chunk.op.dtype,
                        )

    return _handle


# Traceback (ValueError)
In [1]: import numpy as np

In [2]: import mars.tensor as mt

In [3]: a = np.array([[0, -2, -1], [-3, 0, 0]])

In [4]: mt.absolute(a, where=a > -2).execute()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-f56bac3cbb7e> in <module>
----> 1 mt.absolute(a, where=a > -2).execute()

~/Workspace/mars/mars/tensor/core.py in execute(self, session, **kw)
362
363     def execute(self, session=None, **kw):
--> 364         return self._data.execute(session, **kw)
365
366

~/Workspace/mars/mars/tensor/core.py in execute(self, session, **kw)
168         if session is None:
169             session = Session.default_or_local()
--> 170         return session.run(self, **kw)
171
172     def fetch(self, session=None, **kw):

~/Workspace/mars/mars/session.py in run(self, *tensors, **kw)
107
108         tensors = tuple(mt.tensor(t) for t in tensors)
--> 109         result = self._sess.run(*tensors, **kw)
110
111         for t in tensors:

~/Workspace/mars/mars/session.py in run(self, *tensors, **kw)
49         if 'n_parallel' not in kw:
50             kw['n_parallel'] = cpu_count()
---> 51         res = self._executor.execute_tensors(tensors, **kw)
52         return res
53

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
352     def _wrapped(*args, **kwargs):
353         _kernel_mode.eager = False
--> 354         return_value = func(*args, **kwargs)
355         _kernel_mode.eager = None
356         return return_value

~/Workspace/mars/mars/executor.py in execute_tensors(self, tensors, fetch, n_parallel, n_thread, print_progress, mock, sparse_mock_percent)
513         self.execute_graph(graph, result_keys, n_parallel=n_parallel or n_thread,
514                            print_progress=print_progress, mock=mock,
--> 515                            sparse_mock_percent=sparse_mock_percent)
516
517         results = self._chunk_result

~/Workspace/mars/mars/executor.py in execute_graph(self, graph, keys, n_parallel, print_progress, mock, sparse_mock_percent)
447                                          print_progress=print_progress, mock=mock,
448                                          sparse_mock_percent=sparse_mock_percent)
--> 449         res = graph_execution.execute(True)
450         if mock:
451             self._chunk_result.clear()

~/Workspace/mars/mars/executor.py in execute(self, retval)
369         # wait until all the futures completed
370         for future in executed_futures:
--> 371             future.result()
372
373         if retval:

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

~/Workspace/mars/mars/executor.py in _execute_operand(self, op)
260             # so we pass the first operand's first output to Executor.handle
261             first_op = ops[0]
--> 262             Executor.handle(first_op.outputs[0], results, self._mock)
263             executed_chunk_keys.update([c.key for c in first_op.outputs])
264             op_keys.add(first_op.key)

~/Workspace/mars/mars/executor.py in handle(cls, chunk, results, mock)
433     def handle(cls, chunk, results, mock=False):
434         if not mock:
--> 435             return cls._get_op_runner(chunk, cls._op_runners)(results, chunk)
436         else:
437             return cls._get_op_runner(chunk, cls._op_size_estimators)(results, chunk)

~/Workspace/mars/mars/tensor/execution/arithmetic.py in _handle(ctx, chunk)
169                                 dest_value = xp.empty(chunk.shape, chunk.dtype)
170                                 kw['out'] = dest_value
--> 171                             ctx[chunk.key] = _handle_out_dtype(reduce(lambda a, b: func(a, b, **kw), inputs),
172                                                                chunk.op.dtype)
173                     except TypeError:

~/Workspace/mars/mars/tensor/execution/arithmetic.py in <lambda>(a, b)
169                                 dest_value = xp.empty(chunk.shape, chunk.dtype)
170                                 kw['out'] = dest_value
--> 171                             ctx[chunk.key] = _handle_out_dtype(reduce(lambda a, b: func(a, b, **kw), inputs),
172                                                                chunk.op.dtype)
173                     except TypeError:

ValueError: cannot specify 'out' as both a positional and keyword argument

# Fixed code
def _build_elementwise(op):
    def _handle(ctx, chunk):
        inputs, device_id, xp = as_same_device(
            [ctx[c.key] for c in chunk.inputs], device=chunk.device, ret_extra=True
        )

        if isinstance(op, six.string_types):
            func = getattr(xp, op)
        else:
            func = op

        with device(device_id):
            kw = {"casting": chunk.op.casting} if chunk.op.out else {}

            if chunk.op.out and chunk.op.where:
                inputs, kw["out"], kw["where"] = (
                    inputs[:-2],
                    inputs[-2].copy(),
                    inputs[-1],
                )
            elif chunk.op.out:
                inputs, kw["out"] = inputs[:-1], inputs[-1].copy()
            elif chunk.op.where:
                inputs, kw["where"] = inputs[:-1], inputs[-1]

            with np.errstate(**chunk.op.err):
                if len(inputs) == 1:
                    try:
                        ctx[chunk.key] = _handle_out_dtype(
                            func(inputs[0], **kw), chunk.op.dtype
                        )
                    except TypeError:
                        if kw.get("where") is None:
                            raise
                        out, where = kw.pop("out"), kw.pop("where")
                        ctx[chunk.key] = _handle_out_dtype(
                            xp.where(where, func(inputs[0]), out), chunk.op.dtype
                        )
                else:
                    try:
                        if is_sparse_module(xp):
                            ctx[chunk.key] = _handle_out_dtype(
                                reduce(lambda a, b: func(a, b, **kw), inputs),
                                chunk.op.dtype,
                            )
                        else:
                            if "out" not in kw:
                                dest_value = xp.empty(chunk.shape, chunk.dtype)
                                kw["out"] = dest_value
                            ctx[chunk.key] = _handle_out_dtype(
                                reduce(lambda a, b: func(a, b, **kw), inputs),
                                chunk.op.dtype,
                            )
                    except TypeError:
                        if kw.get("where") is None:
                            raise
                        out, where = kw.pop("out"), kw.pop("where")
                        ctx[chunk.key] = _handle_out_dtype(
                            xp.where(
                                where, reduce(lambda a, b: func(a, b), inputs), out
                            ),
                            chunk.op.dtype,
                        )

    return _handle