def _ufunc_dispatch(ufunc, method, i, inputs, **kwargs):
<EOL>if '<STR_LIT>' in kwargs and kwargs['<STR_LIT>'] is not None:<EOL><INDENT>raise Error('<STR_LIT>')<EOL><DEDENT>nin = <NUM_LIT:2> if ufunc is np.dot else ufunc.nin<EOL>if nin is <NUM_LIT:1> and method == '<STR_LIT>':<EOL><INDENT>return vectorize(ufunc.__call__)(inputs[<NUM_LIT:0>], **kwargs)<EOL><DEDENT>elif nin is <NUM_LIT:2> and method == '<STR_LIT>':<EOL><INDENT>from distob import engine<EOL>here = engine.eid<EOL>locs, weights = zip(*[_engine_affinity(a) for a in inputs])<EOL>bshape = _broadcast_shape(*inputs)<EOL>locs = list(locs)<EOL>for i, loc in enumerate(locs):<EOL><INDENT>if isinstance(loc, _TupleType):<EOL><INDENT>num_new_axes = len(bshape) - inputs[i].ndim<EOL>if num_new_axes > <NUM_LIT:0>:<EOL><INDENT>locs[i] = (locs[i][<NUM_LIT:0>], locs[i][<NUM_LIT:1>] + num_new_axes)<EOL><DEDENT><DEDENT><DEDENT>if ufunc is np.dot:<EOL><INDENT>locs = [here if isinstance(m, _TupleType) else m for m in locs]<EOL><DEDENT>if locs[<NUM_LIT:0>] == locs[<NUM_LIT:1>]:<EOL><INDENT>location = locs[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>smallest = <NUM_LIT:0> if weights[<NUM_LIT:0>] <= weights[<NUM_LIT:1>] else <NUM_LIT:1><EOL>largest = <NUM_LIT:1> - smallest<EOL>if locs[<NUM_LIT:0>] is here or locs[<NUM_LIT:1>] is here:<EOL><INDENT>location = here if weights[<NUM_LIT:0>] == weights[<NUM_LIT:1>] else locs[largest]<EOL><DEDENT>else:<EOL><INDENT>if weights[smallest]*<NUM_LIT:2> < weights[largest] + weights[smallest]:<EOL><INDENT>location = locs[largest]<EOL><DEDENT>else:<EOL><INDENT>location = here<EOL><DEDENT><DEDENT><DEDENT>inputs = [_ufunc_move_input(a, location, bshape) for a in inputs]<EOL>if location is here:<EOL><INDENT>return ufunc.__call__(inputs[<NUM_LIT:0>], inputs[<NUM_LIT:1>], **kwargs)<EOL><DEDENT>else:<EOL><INDENT>if isinstance(location, numbers.Integral):<EOL><INDENT>return call(ufunc.__call__, inputs[<NUM_LIT:0>], inputs[<NUM_LIT:1>], **kwargs)<EOL><DEDENT>else:<EOL><INDENT>engine_ids, distaxis = location<EOL>n = len(engine_ids)<EOL>is_dist = tuple(isinstance(a, DistArray) for a in inputs)<EOL>assert(is_dist[<NUM_LIT:0>] or is_dist[<NUM_LIT:1>])<EOL>for i in <NUM_LIT:0>, <NUM_LIT:1>:<EOL><INDENT>if is_dist[i]:<EOL><INDENT>ndim = inputs[i].ndim<EOL>assert(inputs[i]._distaxis == distaxis)<EOL>assert(inputs[i]._n == n)<EOL><DEDENT><DEDENT>def _remote_ucall(inputs, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>return ufunc.__call__(inputs[<NUM_LIT:0>], inputs[<NUM_LIT:1>], **kwargs)<EOL><DEDENT>results = []<EOL>kwargs = kwargs.copy()<EOL>kwargs['<STR_LIT>'] = False<EOL>kwargs['<STR_LIT>'] = False<EOL>for j in range(n):<EOL><INDENT>subinputs = tuple(inputs[i]._subarrays[j] if <EOL>is_dist[i] else inputs[i] for i in (<NUM_LIT:0>, <NUM_LIT:1>))<EOL>results.append(call(_remote_ucall, subinputs, **kwargs))<EOL><DEDENT>results = [convert_result(ar) for ar in results]<EOL>return DistArray(results, distaxis)<EOL><DEDENT><DEDENT><DEDENT>elif ufunc.nin > <NUM_LIT:2>:<EOL><INDENT>raise Error(u'<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>raise Error(u'<STR_LIT>' % method)<EOL><DEDENT>
Route ufunc execution intelligently to local host or remote engine(s)
    depending on where the inputs are, to minimize the need to move data.
    Args:
      see numpy documentation for __numpy_ufunc__