Skip to content

Commit

Permalink
Merge pull request #347 from cupy/revert-345-revert-281-support-numpy…
Browse files Browse the repository at this point in the history
…1-13

Support NumPy 1.13 again
  • Loading branch information
gwtnb committed Aug 10, 2017
2 parents 834625a + 211d364 commit 431afae
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 31 deletions.
25 changes: 19 additions & 6 deletions cupy/core/core.pyx
Expand Up @@ -36,6 +36,17 @@ cdef inline _should_use_rop(x, y):
return xp < yp and not isinstance(y, ndarray)


try:
_AxisError = numpy.AxisError
except AttributeError:
class IndexOrValueError(IndexError, ValueError):

def __init__(self, *args, **kwargs):
super(IndexOrValueError, self).__init__(*args, **kwargs)

_AxisError = IndexOrValueError


cdef class ndarray:

"""Multi-dimensional array on a CUDA device.
Expand Down Expand Up @@ -605,8 +616,9 @@ cdef class ndarray:
if _axis < 0:
_axis += ndim
if _axis < 0 or _axis >= ndim:
msg = "'axis' entry %d is out of bounds [-%d, %d)"
raise ValueError(msg % (axis_orig, ndim, ndim))
raise _AxisError(
"'axis' entry %d is out of bounds [-%d, %d)" %
(axis_orig, ndim, ndim))
if axis_flags[_axis] == 1:
raise ValueError("duplicate value in 'axis'")
axis_flags[_axis] = 1
Expand All @@ -621,8 +633,9 @@ cdef class ndarray:
pass
else:
if _axis < 0 or _axis >= ndim:
msg = "'axis' entry %d is out of bounds [-%d, %d)"
raise ValueError(msg % (axis_orig, ndim, ndim))
raise _AxisError(
"'axis' entry %d is out of bounds [-%d, %d)" %
(axis_orig, ndim, ndim))
axis_flags[_axis] = 1

# Verify that the axes requested are all of size one
Expand Down Expand Up @@ -2273,7 +2286,7 @@ cpdef ndarray concatenate_method(tup, int axis):
if axis < 0:
axis += ndim
if axis < 0 or axis >= ndim:
raise IndexError(
raise _AxisError(
'axis {} out of bounds [0, {})'.format(axis, ndim))
dtype = a.dtype
continue
Expand Down Expand Up @@ -2649,7 +2662,7 @@ cpdef ndarray _take(ndarray a, indices, li=None, ri=None, ndarray out=None):
index_range = a.size
else:
if not (-a.ndim <= li < a.ndim and -a.ndim <= ri < a.ndim):
raise ValueError('Axis overrun')
raise _AxisError('Axis overrun')
if a.ndim != 0:
li %= a.ndim
ri %= a.ndim
Expand Down
3 changes: 2 additions & 1 deletion cupy/manipulation/join.py
Expand Up @@ -128,5 +128,6 @@ def _get_positive_axis(ndim, axis):
if a < 0:
a += ndim
if a < 0 or a >= ndim:
raise IndexError('axis {} out of bounds [0, {})'.format(axis, ndim))
raise core.core._AxisError(
'axis {} out of bounds [0, {})'.format(axis, ndim))
return a
7 changes: 5 additions & 2 deletions cupy/manipulation/rearrange.py
@@ -1,4 +1,5 @@
import cupy
from cupy import core


def flip(a, axis):
Expand All @@ -23,7 +24,8 @@ def flip(a, axis):

axis = int(axis)
if not -a_ndim <= axis < a_ndim:
raise ValueError('axis must be >= %d and < %d' % (-a_ndim, a_ndim))
raise ValueError(
'axis must be >= %d and < %d' % (-a_ndim, a_ndim))

return _flip(a, axis)

Expand Down Expand Up @@ -99,7 +101,8 @@ def roll(a, shift, axis=None):
if axis < 0:
axis += a.ndim
if not 0 <= axis < a.ndim:
raise ValueError('axis must be >= %d and < %d' % (-a.ndim, a.ndim))
raise core.core._AxisError(
'axis must be >= %d and < %d' % (-a.ndim, a.ndim))
size = a.shape[axis]
if size == 0:
return a
Expand Down
4 changes: 2 additions & 2 deletions cupy/math/sumprod.py
Expand Up @@ -125,7 +125,7 @@ def cumsum(a, axis=None, dtype=None, out=None):
if axis is None:
out = out.ravel()
elif not (-a.ndim <= axis < a.ndim):
raise ValueError('axis(={}) out of bounds'.format(axis))
raise core.core._AxisError('axis(={}) out of bounds'.format(axis))
else:
return _proc_as_batch(_cumsum_batch, out, axis=axis)

Expand Down Expand Up @@ -203,7 +203,7 @@ def cumprod(a, axis=None, dtype=None, out=None):
if axis is None:
out = out.ravel()
elif not (-a.ndim <= axis < a.ndim):
raise ValueError('axis(={}) out of bounds'.format(axis))
raise core.core._AxisError('axis(={}) out of bounds'.format(axis))
else:
return _proc_as_batch(_cumprod_batch, out, axis=axis)

Expand Down
4 changes: 2 additions & 2 deletions cupy/statistics/histogram.py
Expand Up @@ -40,8 +40,8 @@ def bincount(x, weights=None, minlength=None):
raise ValueError('The weights and list don\'t have the same length.')
if minlength is not None:
minlength = int(minlength)
if minlength <= 0:
raise ValueError('minlength must be positive')
if minlength < 0:
raise ValueError('minlength must be non-negative')

size = int(cupy.max(x)) + 1
if minlength is not None:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/install.rst
Expand Up @@ -44,7 +44,7 @@ Before installing CuPy, we recommend to upgrade ``setuptools`` if you are using
The following Python packages are required to install CuPy.
The latest version of each package will automatically be installed if missing.

* `NumPy <http://www.numpy.org/>`_ 1.9, 1.10, 1.11, 1.12
* `NumPy <http://www.numpy.org/>`_ 1.9, 1.10, 1.11, 1.12, 1.13
* `Six <https://pythonhosted.org/six/>`_ 1.9+

CUDA support
Expand Down
2 changes: 1 addition & 1 deletion tests/cupy_tests/core_tests/test_fusion.py
Expand Up @@ -949,7 +949,7 @@ def g(x, y, z):

return g(a, b, c)

@testing.for_all_dtypes()
@testing.for_all_dtypes(no_bool=True)
@testing.numpy_cupy_array_equal()
def test_fuse3(self, xp, dtype):
a = xp.array([2, 2, 2, 2, 3, 3, 3, 3], dtype=dtype)
Expand Down
10 changes: 9 additions & 1 deletion tests/cupy_tests/core_tests/test_ndarray.py
Expand Up @@ -3,6 +3,7 @@

import numpy

import cupy
from cupy import core
from cupy import cuda
from cupy import get_array_module
Expand Down Expand Up @@ -217,11 +218,18 @@ def test_take(self, xp, dtype):
class TestNdarrayTakeErrorAxisOverRun(unittest.TestCase):

@testing.for_all_dtypes()
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_axis_overrun(self, xp, dtype):
def test_axis_overrun1(self, xp, dtype):
a = testing.shaped_arange(self.shape, xp, dtype)
wrap_take(a, self.indices, axis=self.axis)

@testing.for_all_dtypes()
def test_axis_overrun2(self, dtype):
a = testing.shaped_arange(self.shape, cupy, dtype)
with self.assertRaises(core.core._AxisError):
wrap_take(a, self.indices, axis=self.axis)


@testing.parameterize(
{"shape": (3, 4, 5), "indices": (2, 3), "out_shape": (2, 4)},
Expand Down
14 changes: 10 additions & 4 deletions tests/cupy_tests/core_tests/test_ndarray_unary_op.py
Expand Up @@ -51,8 +51,11 @@ def check_array_op(self, op, xp, dtype):
a = testing.shaped_arange((2, 3), xp, dtype)
return op(a)

def test_neg_array(self):
self.check_array_op(operator.neg)
@testing.for_all_dtypes(no_bool=True)
@testing.numpy_cupy_allclose()
def test_neg_array(self, xp, dtype):
a = testing.shaped_arange((2, 3), xp, dtype)
return operator.neg(a)

def test_pos_array(self):
self.check_array_op(operator.pos)
Expand All @@ -66,8 +69,11 @@ def check_zerodim_op(self, op, xp, dtype):
a = xp.array(-2, dtype)
return op(a)

def test_neg_zerodim(self):
self.check_zerodim_op(operator.neg)
@testing.for_all_dtypes(no_bool=True)
@testing.numpy_cupy_allclose()
def test_neg_zerodim(self, xp, dtype):
a = xp.array(-2, dtype)
return operator.neg(a)

def test_pos_zerodim(self):
self.check_zerodim_op(operator.pos)
Expand Down
26 changes: 25 additions & 1 deletion tests/cupy_tests/manipulation_tests/test_dims.py
Expand Up @@ -161,11 +161,17 @@ def test_squeze_int_axis2(self, xp):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), xp)
return a.squeeze(axis=-3)

@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_squeze_int_axis_failure(self, xp):
def test_squeze_int_axis_failure1(self, xp):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), xp)
a.squeeze(axis=-9)

def test_squeze_int_axis_failure2(self):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), cupy)
with self.assertRaises(cupy.core.core._AxisError):
a.squeeze(axis=-9)

@testing.numpy_cupy_array_equal()
def test_squeze_tuple_axis1(self, xp):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), xp)
Expand All @@ -186,6 +192,7 @@ def test_squeze_tuple_axis4(self, xp):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), xp)
return a.squeeze(axis=())

@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_squeze_tuple_axis_failure1(self, xp):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), xp)
Expand All @@ -196,6 +203,11 @@ def test_squeze_tuple_axis_failure2(self, xp):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), xp)
a.squeeze(axis=(2, 2))

def test_squeze_tuple_axis_failure3(self):
a = testing.shaped_arange((1, 2, 1, 3, 1, 1, 4, 1), cupy)
with self.assertRaises(cupy.core.core._AxisError):
a.squeeze(axis=(-9,))

@testing.numpy_cupy_array_equal()
def test_squeeze_scalar1(self, xp):
a = testing.shaped_arange((), xp)
Expand All @@ -206,16 +218,28 @@ def test_squeeze_scalar2(self, xp):
a = testing.shaped_arange((), xp)
return a.squeeze(axis=-1)

@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_squeeze_scalar_failure1(self, xp):
a = testing.shaped_arange((), xp)
a.squeeze(axis=-2)

@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_squeeze_scalar_failure2(self, xp):
a = testing.shaped_arange((), xp)
a.squeeze(axis=1)

def test_squeeze_scalar_failure3(self):
a = testing.shaped_arange((), cupy)
with self.assertRaises(cupy.core.core._AxisError):
a.squeeze(axis=-2)

def test_squeeze_scalar_failure4(self):
a = testing.shaped_arange((), cupy)
with self.assertRaises(cupy.core.core._AxisError):
a.squeeze(axis=1)

@testing.numpy_cupy_raises()
def test_squeeze_failure(self, xp):
a = testing.shaped_arange((2, 1, 3, 4), xp)
Expand Down
9 changes: 7 additions & 2 deletions tests/cupy_tests/manipulation_tests/test_join.py
Expand Up @@ -206,8 +206,13 @@ def test_stack_different_shape(self, xp):
b = testing.shaped_arange((2, 4), xp)
return xp.stack([a, b])

@testing.with_requires('numpy>=1.10')
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_stack_out_of_bounds(self, xp):
def test_stack_out_of_bounds1(self, xp):
a = testing.shaped_arange((2, 3), xp)
return xp.stack([a, a], axis=3)

def test_stack_out_of_bounds2(self):
a = testing.shaped_arange((2, 3), cupy)
with self.assertRaises(cupy.core.core._AxisError):
return cupy.stack([a, a], axis=3)
19 changes: 17 additions & 2 deletions tests/cupy_tests/manipulation_tests/test_rearrange.py
@@ -1,5 +1,6 @@
import unittest

import cupy
from cupy import testing


Expand Down Expand Up @@ -57,17 +58,31 @@ def test_roll_zero_array(self, xp, dtype):
return xp.roll(x, 5)

@testing.for_all_dtypes()
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_roll_invalid_axis(self, xp, dtype):
def test_roll_invalid_axis1(self, xp, dtype):
x = testing.shaped_arange((5, 2), xp, dtype)
return xp.roll(x, 1, axis=2)

@testing.for_all_dtypes()
def test_roll_invalid_axis2(self, dtype):
x = testing.shaped_arange((5, 2), cupy, dtype)
with self.assertRaises(cupy.core.core._AxisError):
return cupy.roll(x, 1, axis=2)

@testing.for_all_dtypes()
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_roll_invalid_negative_axis(self, xp, dtype):
def test_roll_invalid_negative_axis1(self, xp, dtype):
x = testing.shaped_arange((5, 2), xp, dtype)
return xp.roll(x, 1, axis=-3)

@testing.for_all_dtypes()
def test_roll_invalid_negative_axis2(self, dtype):
x = testing.shaped_arange((5, 2), cupy, dtype)
with self.assertRaises(cupy.core.core._AxisError):
return cupy.roll(x, 1, axis=-3)


@testing.gpu
class TestFliplr(unittest.TestCase):
Expand Down
36 changes: 32 additions & 4 deletions tests/cupy_tests/math_tests/test_sumprod.py
Expand Up @@ -188,17 +188,31 @@ def test_cumsum_axis(self, xp, dtype):
return xp.cumsum(a, axis=self.axis)

@testing.for_all_dtypes()
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_invalid_axis_lower(self, xp, dtype):
def test_invalid_axis_lower1(self, xp, dtype):
a = testing.shaped_arange((4, 5), xp, dtype)
return xp.cumsum(a, axis=-a.ndim - 1)

@testing.for_all_dtypes()
def test_invalid_axis_lower2(self, dtype):
a = testing.shaped_arange((4, 5), cupy, dtype)
with self.assertRaises(cupy.core.core._AxisError):
return cupy.cumsum(a, axis=-a.ndim - 1)

@testing.for_all_dtypes()
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_invalid_axis_upper(self, xp, dtype):
def test_invalid_axis_upper1(self, xp, dtype):
a = testing.shaped_arange((4, 5), xp, dtype)
return xp.cumsum(a, axis=a.ndim + 1)

@testing.for_all_dtypes()
def test_invalid_axis_upper2(self, dtype):
a = testing.shaped_arange((4, 5), cupy, dtype)
with self.assertRaises(cupy.core.core._AxisError):
return cupy.cumsum(a, axis=a.ndim + 1)


@testing.gpu
class TestCumprod(unittest.TestCase):
Expand Down Expand Up @@ -230,13 +244,27 @@ def test_cumprod_huge_array(self, xp):
return xp.cumprod(a)

@testing.for_all_dtypes()
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_invalid_axis_lower(self, xp, dtype):
def test_invalid_axis_lower1(self, xp, dtype):
a = testing.shaped_arange((4, 5), xp, dtype)
return xp.cumprod(a, axis=-a.ndim - 1)

@testing.for_all_dtypes()
def test_invalid_axis_lower2(self, dtype):
a = testing.shaped_arange((4, 5), cupy, dtype)
with self.assertRaises(cupy.core.core._AxisError):
return cupy.cumprod(a, axis=-a.ndim - 1)

@testing.for_all_dtypes()
@testing.with_requires('numpy>=1.13')
@testing.numpy_cupy_raises()
def test_invalid_axis_upper(self, xp, dtype):
def test_invalid_axis_upper1(self, xp, dtype):
a = testing.shaped_arange((4, 5), xp, dtype)
return xp.cumprod(a, axis=a.ndim)

@testing.for_all_dtypes()
def test_invalid_axis_upper2(self, dtype):
a = testing.shaped_arange((4, 5), cupy, dtype)
with self.assertRaises(cupy.core.core._AxisError):
return cupy.cumprod(a, axis=a.ndim)

0 comments on commit 431afae

Please sign in to comment.