def create_math_ufunc(math_name, nargs, name, doc): assert 1 <= nargs <= 2 if nargs == 1: return elementwise.create_ufunc(name, ('e->e', 'f->f', 'd->d'), 'out0 = %s(in0)' % math_name, doc=doc) else: return elementwise.create_ufunc(name, ('ee->e', 'ff->f', 'dd->d'), 'out0 = %s(in0, in1)' % math_name, doc=doc)
def create_math_ufunc(math_name, nargs, name, doc): assert 1 <= nargs <= 2 if nargs == 1: return elementwise.create_ufunc( name, ['e->e', 'f->f', 'd->d'], 'out0 = %s(in0)' % math_name, doc=doc) else: return elementwise.create_ufunc( name, ['ee->e', 'ff->f', 'dd->d'], 'out0 = %s(in0, in1)' % math_name, doc=doc)
def create_comparison(name, op, doc=''): return elementwise.create_ufunc( 'cupy_' + name, ['??->?', 'bb->?', 'BB->?', 'hh->?', 'HH->?', 'ii->?', 'II->?', 'll->?', 'LL->?', 'qq->?', 'QQ->?', 'ee->?', 'ff->?', 'dd->?'], 'out0 = in0 %s in1' % op, doc=doc)
def create_comparison(name, op, doc=''): return elementwise.create_ufunc('cupy_' + name, [ '??->?', 'bb->?', 'BB->?', 'hh->?', 'HH->?', 'ii->?', 'II->?', 'll->?', 'LL->?', 'qq->?', 'QQ->?', 'ee->?', 'ff->?', 'dd->?' ], 'out0 = in0 %s in1' % op, doc=doc)
def create_arithmetic(name, op, boolop, doc): return elementwise.create_ufunc( 'cupy_' + name, (('??->?', 'out0 = in0 %s in1' % boolop), 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 'QQ->Q', 'ee->e', 'ff->f', 'dd->d'), 'out0 = in0 %s in1' % op, doc=doc)
def _create_bit_op(name, op, no_bool, doc=''): types = () if no_bool else ('??->?',) return elementwise.create_ufunc( 'cupy_' + name, types + ('bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 'QQ->Q'), 'out0 = in0 %s in1' % op, doc=doc)
def create_arithmetic(name, op, boolop, doc): return elementwise.create_ufunc( 'cupy_' + name, [('??->?', 'out0 = in0 %s in1' % boolop), 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 'QQ->Q', 'ee->e', 'ff->f', 'dd->d'], 'out0 = in0 %s in1' % op, doc=doc)
def _create_bit_op(name, op, no_bool, doc=''): types = () if no_bool else ('??->?', ) return elementwise.create_ufunc( 'cupy_' + name, types + ('bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 'QQ->Q'), 'out0 = in0 %s in1' % op, doc=doc)
def _create_float_test_ufunc(name, doc): return elementwise.create_ufunc( 'cupy_' + name, ['e->?', 'f->?', 'd->?'], 'out0 = %s(in0)' % name, doc=doc)
'bitwise_xor', '^', False, '''Computes the bitwise XOR of two arrays elementwise. Only integer and boolean arrays are handled. .. seealso:: :data:`numpy.bitwise_xor` ''') invert = elementwise.create_ufunc( 'cupy_invert', (('?->?', 'out0 = !in0'), 'b->b', 'B->B', 'h->h', 'H->H', 'i->i', 'I->I', 'l->l', 'L->L', 'q->q', 'Q->Q'), 'out0 = ~in0', doc='''Computes the bitwise NOT of an array elementwise. Only integer and boolean arrays are handled. .. seealso:: :data:`numpy.invert` ''') left_shift = _create_bit_op( 'left_shift', '<<', True, '''Shifts the bits of each integer element to the left. Only integer arrays are handled. .. seealso:: :data:`numpy.left_shift`
""", ) reciprocal = elementwise.create_ufunc( "cupy_reciprocal", ( "b", "B", "h", "H", "i", "I", "l", "L", "q", "Q", ("e", "out0 = 1 / in0"), ("f", "out0 = 1 / in0"), ("d", "out0 = 1 / in0"), ), "out0 = in0 == 0 ? 0 : (1 / in0)", doc="""Computes ``1 / x`` elementwise. .. seealso:: :data:`numpy.reciprocal` """, ) negative = elementwise.create_ufunc( "cupy_negative",
.. seealso:: :data:`numpy.exp` ''') expm1 = ufunc.create_math_ufunc( 'expm1', 1, 'cupy_expm1', '''Computes ``exp(x) - 1`` elementwise. .. seealso:: :data:`numpy.expm1` ''') exp2 = elementwise.create_ufunc('cupy_exp2', ('e->e', 'f->f', ('d->d', 'out0 = pow(2., in0)')), 'out0 = powf(2.f, in0)', doc='''Elementwise exponentiation with base 2. .. seealso:: :data:`numpy.exp2` ''') log = ufunc.create_math_ufunc( 'log', 1, 'cupy_log', '''Elementwise natural logarithm function. .. seealso:: :data:`numpy.log` ''') log10 = ufunc.create_math_ufunc( 'log10', 1, 'cupy_log10', '''Elementwise common logarithm function. .. seealso:: :data:`numpy.log10`
``condition`` is ``True``, otherwise elements of ``y``. """ missing = (x is None, y is None).count(True) if missing == 1: raise ValueError("Must provide both 'x' and 'y' or neither.") if missing == 2: # TODO(unno): return nonzero(cond) return NotImplementedError() return _where_ufunc(condition.astype('?'), x, y) _where_ufunc = elementwise.create_ufunc( 'cupy_where', ('???->?', '?bb->b', '?BB->B', '?hh->h', '?HH->H', '?ii->i', '?II->I', '?ll->l', '?LL->L', '?qq->q', '?QQ->Q', '?ee->e', '?ff->f', # On CUDA 6.5 these combinations don't work correctly (on CUDA >=7.0, it # works). # See issue #551. '?hd->d', '?Hd->d', '?dd->d'), 'out0 = in0 ? in1 : in2') # TODO(okuta): Implement searchsorted # TODO(okuta): Implement extract
bitwise_xor = _create_bit_op( 'bitwise_xor', '^', False, '''Computes the bitwise XOR of two arrays elementwise. Only integer and boolean arrays are handled. .. seealso:: :data:`numpy.bitwise_xor` ''') invert = elementwise.create_ufunc( 'cupy_invert', (('?->?', 'out0 = !in0'), 'b->b', 'B->B', 'h->h', 'H->H', 'i->i', 'I->I', 'l->l', 'L->L', 'q->q', 'Q->Q'), 'out0 = ~in0', doc='''Computes the bitwise NOT of an array elementwise. Only integer and boolean arrays are handled. .. seealso:: :data:`numpy.invert` ''') left_shift = _create_bit_op( 'left_shift', '<<', True, '''Shifts the bits of each integer element to the left. Only integer arrays are handled. .. seealso:: :data:`numpy.left_shift` ''')
.. seealso:: :data:`numpy.logical_and` ''') logical_or = ufunc.create_comparison( 'logical_or', '||', '''Computes the logical OR of two arrays. .. seealso:: :data:`numpy.logical_or` ''') logical_not = elementwise.create_ufunc( 'cupy_logical_not', ('?->?', 'b->?', 'B->?', 'h->?', 'H->?', 'i->?', 'I->?', 'l->?', 'L->?', 'q->?', 'Q->?', 'e->?', 'f->?', 'd->?'), 'out0 = !in0', doc='''Computes the logical NOT of an array. .. seealso:: :data:`numpy.logical_not` ''') logical_xor = elementwise.create_ufunc( 'cupy_logical_xor', ('??->?', 'bb->?', 'BB->?', 'hh->?', 'HH->?', 'ii->?', 'II->?', 'll->?', 'LL->?', 'qq->?', 'QQ->?', 'ee->?', 'ff->?', 'dd->?'), 'out0 = !in0 != !in1', doc='''Computes the logical XOR of two arrays. .. seealso:: :data:`numpy.logical_xor` ''')
logical_or = ufunc.create_comparison( 'logical_or', '||', '''Computes the logical OR of two arrays. .. seealso:: :data:`numpy.logical_or` ''') logical_not = elementwise.create_ufunc( 'cupy_logical_not', ('?->?', 'b->?', 'B->?', 'h->?', 'H->?', 'i->?', 'I->?', 'l->?', 'L->?', 'q->?', 'Q->?', 'e->?', 'f->?', 'd->?'), 'out0 = !in0', doc='''Computes the logical NOT of an array. .. seealso:: :data:`numpy.logical_not` ''') logical_xor = elementwise.create_ufunc( 'cupy_logical_xor', ('??->?', 'bb->?', 'BB->?', 'hh->?', 'HH->?', 'ii->?', 'II->?', 'll->?', 'LL->?', 'qq->?', 'QQ->?', 'ee->?', 'ff->?', 'dd->?'), 'out0 = !in0 != !in1', doc='''Computes the logical XOR of two arrays. .. seealso:: :data:`numpy.logical_xor`
from cupy import elementwise _id = 'out0 = in0' # TODO(okuta): Implement convolve _clip = elementwise.create_ufunc( 'cupy_clip', ('???->?', 'bbb->b', 'BBB->B', 'hhh->h', 'HHH->H', 'iii->i', 'III->I', 'lll->l', 'LLL->L', 'qqq->q', 'QQQ->Q', 'eee->e', 'fff->f', 'ddd->d'), 'out0 = min(in2, max(in1, in0))') def clip(a, a_min, a_max, out=None): '''Clips the values of an array to a given interval. This is equivalent to ``maximum(minimum(a, a_max), a_min)``, while this function is more efficient. Args: a (cupy.ndarray): The source array. a_min (scalar or cupy.ndarray): The left side of the interval. a_max (scalar or cupy.ndarray): The right side of the interval. out (cupy.ndarray): Output array. Returns: cupy.ndarray: Clipped array. .. seealso:: :func:`numpy.clip` '''
def _create_float_test_ufunc(name, doc): return elementwise.create_ufunc('cupy_' + name, ('e->?', 'f->?', 'd->?'), 'out0 = %s(in0)' % name, doc=doc)
arctan2 = ufunc.create_math_ufunc( 'atan2', 2, 'cupy_arctan2', '''Elementwise inverse-tangent of the ratio of two arrays. .. seealso:: :data:`numpy.arctan2` ''') deg2rad = elementwise.create_ufunc( 'cupy_deg2rad', ('e->e', 'f->f', 'd->d'), 'out0 = in0 * (out0_type)(M_PI / 180)', doc='''Converts angles from degrees to radians elementwise. .. seealso:: :data:`numpy.deg2rad`, :data:`numpy.radians` ''') rad2deg = elementwise.create_ufunc( 'cupy_rad2deg', ('e->e', 'f->f', 'd->d'), 'out0 = in0 * (out0_type)(180 / M_PI)', doc='''Converts angles from radians to degrees elementwise. .. seealso:: :data:`numpy.rad2deg`, :data:`numpy.degrees` ''')
from cupy import elementwise _id = 'out0 = in0' def convolve(a, v, mode='full'): # TODO(beam2d): Implement it raise NotImplementedError _clip = elementwise.create_ufunc( 'cupy_clip', ['bbb->b', 'BBB->B', 'hhh->h', 'HHH->H', 'iii->i', 'III->I', 'lll->l', 'LLL->L', 'qqq->q', 'QQQ->Q', 'eee->e', 'fff->f', 'ddd->d'], 'out0 = min(in2, max(in1, in0))') def clip(a, a_min, a_max, out=None): '''Clips the values of an array to a given interval. This is equivalent to ``max(min(a, a_max), a_min)``, while this function is more efficient. Args: a (cupy.ndarray): The source array. a_min (scalar or cupy.ndarray): The left side of the interval. a_max (scalar or cupy.ndarray): The right side of the interval. out (cupy.ndarray): Output array. Returns: cupy.ndarray: Clipped array.
return _where_ufunc(condition.astype('?'), x, y) _where_ufunc = elementwise.create_ufunc( 'cupy_where', ( '???->?', '?bb->b', '?BB->B', '?hh->h', '?HH->H', '?ii->i', '?II->I', '?ll->l', '?LL->L', '?qq->q', '?QQ->Q', '?ee->e', '?ff->f', # On CUDA 6.5 these combinations don't work correctly (on CUDA >=7.0, it # works). # See issue #551. '?hd->d', '?Hd->d', '?dd->d'), 'out0 = in0 ? in1 : in2') # TODO(okuta): Implement searchsorted # TODO(okuta): Implement extract
from cupy import elementwise from cupy.math import ufunc add = ufunc.create_arithmetic( 'add', '+', '|', '''Adds two arrays elementwise. .. seealso:: :data:`numpy.add` ''') reciprocal = elementwise.create_ufunc( 'cupy_reciprocal', ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', ('e', 'out0 = 1 / in0'), ('f', 'out0 = 1 / in0'), ('d', 'out0 = 1 / in0')), 'out0 = in0 == 0 ? 0 : (1 / in0)', doc='''Computes ``1 / x`` elementwise. .. seealso:: :data:`numpy.reciprocal` ''') negative = elementwise.create_ufunc( 'cupy_negative', (('?->?', 'out0 = !in0'), 'b->b', 'B->B', 'h->h', 'H->H', 'i->i', 'I->I', 'l->l', 'L->L', 'q->q', 'Q->Q', 'e->e', 'f->f', 'd->d'), 'out0 = -in0', doc='''Takes numerical negative elementwise. .. seealso:: :data:`numpy.negative` ''')
add = ufunc.create_arithmetic( 'add', '+', '|', '''Adds two arrays elementwise. .. seealso:: :data:`numpy.add` ''') reciprocal = elementwise.create_ufunc( 'cupy_reciprocal', ('b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', ('e', 'out0 = 1 / in0'), ('f', 'out0 = 1 / in0'), ('d', 'out0 = 1 / in0')), 'out0 = in0 == 0 ? 0 : (1 / in0)', doc='''Computes ``1 / x`` elementwise. .. seealso:: :data:`numpy.reciprocal` ''') negative = elementwise.create_ufunc( 'cupy_negative', (('?->?', 'out0 = !in0'), 'b->b', 'B->B', 'h->h', 'H->H', 'i->i', 'I->I', 'l->l', 'L->L', 'q->q', 'Q->Q', 'e->e', 'f->f', 'd->d'), 'out0 = -in0', doc='''Takes numerical negative elementwise.
else: return ret def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None): # TODO(beam2d): Implement these raise NotImplementedError def meshgrid(*xi, **kwargs): # TODO(beam2d): Implement these raise NotImplementedError # TODO(beam2d): Implement these # mgrid # ogrid _arange_ufunc = elementwise.create_ufunc('cupy_arange', [ 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 'QQ->Q', 'ee->e', 'ff->f', 'dd->d' ], 'out0 = in0 + i * in1') _float_linspace = 'out0 = in0 + i * in1 / in2' _linspace_ufunc = elementwise.create_ufunc( 'cupy_linspace', [ 'bbb->b', 'Bbb->B', 'hhh->h', 'Hhh->H', 'iii->i', 'Iii->I', 'lll->l', 'Lll->L', 'qqq->q', 'Qqq->Q', ('eel->e', _float_linspace), ('ffl->f', _float_linspace), ('ddl->d', _float_linspace) ], 'out0 = (in0_type)(in0 + _floor_divide(in1_type(i * in1), in2))')
x (cupy.ndarray): Values from which to choose on ``True``. y (cupy.ndarray): Values from which to choose on ``False``. Returns: cupy.ndarray: Each element of output contains elements of ``x`` when ``condition`` is ``True``, otherwise elements of ``y``. """ missing = (x is None, y is None).count(True) if missing == 1: raise ValueError("Must provide both 'x' and 'y' or neither.") if missing == 2: # TODO(unno): return nonzero(cond) return NotImplementedError() return _where_ufunc(condition.astype('?'), x, y) _where_ufunc = elementwise.create_ufunc( 'cupy_where', ('???->?', '?bb->b', '?BB->B', '?hh->h', '?HH->H', '?ii->i', '?II->I', '?ll->l', '?LL->L', '?qq->q', '?QQ->Q', '?ee->e', '?ff->f', '?dd->d'), 'out0 = in0 ? in1 : in2') # TODO(okuta): Implement searchsorted # TODO(okuta): Implement extract
from cupy import elementwise from cupy.math import ufunc signbit = elementwise.create_ufunc( 'cupy_signbit', ['e->?', 'f->?', 'd->?'], 'out0 = signbit(in0)', doc='''Tests elementwise if the sign bit is set (i.e. less than zero). .. seealso:: :data:`numpy.signbit` ''') copysign = ufunc.create_math_ufunc( 'copysign', 2, 'cupy_copysign', '''Returns the first arugment with the sign bit of the second elementwise. .. seealso:: :data:`numpy.copysign` ''') ldexp = elementwise.create_ufunc( 'cupy_ldexp', ['ei->e', 'fi->f', 'el->e', 'fl->f', 'di->d', 'dl->d'], 'out0 = ldexp(in0, in1)', doc='''Computes ``x1 * 2 ** x2`` elementwise. .. seealso:: :data:`numpy.ldexp`
if retstep: return ret, step else: return ret # TODO(okuta): Implement logspace # TODO(okuta): Implement meshgrid # mgrid # ogrid _arange_ufunc = elementwise.create_ufunc( 'cupy_arange', ('bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 'QQ->Q', 'ee->e', 'ff->f', 'dd->d'), 'out0 = in0 + i * in1') _float_linspace = 'out0 = in0 + i * in1 / in2' _linspace_ufunc = elementwise.create_ufunc( 'cupy_linspace', ('bbb->b', 'Bbb->B', 'hhh->h', 'Hhh->H', 'iii->i', 'Iii->I', 'lll->l', 'Lll->L', 'qqq->q', 'Qqq->Q', ('eel->e', _float_linspace), ('ffl->f', _float_linspace), ('ddl->d', _float_linspace)), 'out0 = (in0_type)(in0 + _floor_divide(in1_type(i * in1), in2))')
expm1 = ufunc.create_math_ufunc( 'expm1', 1, 'cupy_expm1', '''Computes ``exp(x) - 1`` elementwise. .. seealso:: :data:`numpy.expm1` ''') exp2 = elementwise.create_ufunc( 'cupy_exp2', ['e->e', 'f->f', ('d->d', 'out0 = pow(2., in0)')], 'out0 = powf(2.f, in0)', doc='''Elementwise exponentiation with base 2. .. seealso:: :data:`numpy.exp2` ''') log = ufunc.create_math_ufunc( 'log', 1, 'cupy_log', '''Elementwise natural logarithm function. .. seealso:: :data:`numpy.log` ''')