Skip to content

Commit 1cdc7af

Browse files
committed
Add cumulative_sum and cumulative_prod (Array API)
1 parent fce2d66 commit 1cdc7af

1 file changed

Lines changed: 127 additions & 0 deletions

File tree

dpnp/tests/third_party/cupy/math_tests/test_sumprod.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,3 +1357,130 @@ def test_trapz_1dim_with_x_and_dx(self, xp, dtype):
13571357
a = testing.shaped_arange((5,), xp, dtype)
13581358
x = testing.shaped_arange((5,), xp, dtype)
13591359
return xp.trapezoid(a, x=x, dx=0.1)
1360+
1361+
1362+
@testing.with_requires("numpy>=2.1")
1363+
@pytest.mark.parametrize("func", ["cumulative_sum", "cumulative_prod"])
1364+
class TestCumulativeSumProd:
1365+
1366+
@testing.for_all_dtypes()
1367+
@testing.numpy_cupy_allclose(rtol=1e-6)
1368+
def test_1d(self, xp, dtype, func):
1369+
a = testing.shaped_arange((5,), xp, dtype)
1370+
return getattr(xp, func)(a)
1371+
1372+
@testing.for_all_dtypes()
1373+
@testing.numpy_cupy_allclose(rtol=1e-6, contiguous_check=False)
1374+
def test_axis(self, xp, dtype, func):
1375+
a = testing.shaped_arange((3, 4, 5), xp, dtype)
1376+
return getattr(xp, func)(a, axis=1)
1377+
1378+
@testing.for_all_dtypes()
1379+
@testing.numpy_cupy_allclose(rtol=1e-6)
1380+
def test_negative_axis(self, xp, dtype, func):
1381+
a = testing.shaped_arange((3, 4, 5), xp, dtype)
1382+
return getattr(xp, func)(a, axis=-1)
1383+
1384+
@testing.for_all_dtypes(no_bool=True)
1385+
@testing.numpy_cupy_allclose(rtol=1e-6)
1386+
def test_dtype(self, xp, dtype, func):
1387+
a = testing.shaped_arange((5,), xp, numpy.int16)
1388+
return getattr(xp, func)(a, dtype=dtype)
1389+
1390+
@testing.for_all_dtypes()
1391+
@testing.numpy_cupy_allclose(rtol=1e-6)
1392+
def test_1d_include_initial(self, xp, dtype, func):
1393+
a = testing.shaped_arange((5,), xp, dtype)
1394+
return getattr(xp, func)(a, include_initial=True)
1395+
1396+
@testing.for_all_dtypes()
1397+
@testing.numpy_cupy_allclose(rtol=1e-6, contiguous_check=False)
1398+
def test_axis_include_initial(self, xp, dtype, func):
1399+
a = testing.shaped_arange((3, 4, 5), xp, dtype)
1400+
return getattr(xp, func)(a, axis=1, include_initial=True)
1401+
1402+
@testing.for_all_dtypes()
1403+
@testing.numpy_cupy_allclose(rtol=1e-6)
1404+
def test_negative_axis_include_initial(self, xp, dtype, func):
1405+
a = testing.shaped_arange((3, 4, 5), xp, dtype)
1406+
return getattr(xp, func)(a, axis=-1, include_initial=True)
1407+
1408+
@testing.for_all_dtypes()
1409+
@testing.numpy_cupy_allclose(rtol=1e-6)
1410+
def test_out(self, xp, dtype, func):
1411+
a = testing.shaped_arange((3, 4, 5), xp, dtype)
1412+
out = xp.zeros((3, 4, 5), dtype=dtype)
1413+
getattr(xp, func)(a, axis=1, out=out)
1414+
return out
1415+
1416+
@testing.for_all_dtypes()
1417+
@testing.numpy_cupy_allclose(rtol=1e-6)
1418+
def test_out_include_initial(self, xp, dtype, func):
1419+
a = testing.shaped_arange((3, 4, 5), xp, dtype)
1420+
out = xp.zeros((3, 5, 5), dtype=dtype)
1421+
getattr(xp, func)(a, axis=1, out=out, include_initial=True)
1422+
return out
1423+
1424+
@testing.for_all_dtypes()
1425+
def test_axis_none_requires_1d(self, dtype, func):
1426+
for xp in (numpy, cupy):
1427+
a = testing.shaped_arange((3, 4), xp, dtype)
1428+
with pytest.raises(ValueError):
1429+
getattr(xp, func)(a)
1430+
1431+
@testing.for_all_dtypes()
1432+
def test_invalid_axis(self, dtype, func):
1433+
for xp in (numpy, cupy):
1434+
a = testing.shaped_arange((3, 4), xp, dtype)
1435+
with pytest.raises(AxisError):
1436+
getattr(xp, func)(a, axis=3)
1437+
1438+
def test_out_shape_mismatch(self, func):
1439+
a = testing.shaped_arange((3, 4), cupy, numpy.float32)
1440+
out = cupy.zeros((3, 5), dtype=numpy.float32)
1441+
with pytest.raises(ValueError):
1442+
getattr(cupy, func)(a, axis=1, out=out)
1443+
1444+
@pytest.mark.skip("implementation-defined acc to Python array API")
1445+
@testing.for_all_dtypes()
1446+
@testing.numpy_cupy_allclose(rtol=1e-6)
1447+
def test_0d(self, xp, dtype, func):
1448+
# numpy accepts 0-D input; cupy matches via atleast_1d.
1449+
a = xp.asarray(3, dtype=dtype)
1450+
return getattr(xp, func)(a)
1451+
1452+
@testing.for_all_dtypes()
1453+
@testing.numpy_cupy_allclose(rtol=1e-6)
1454+
def test_0d_include_initial(self, xp, dtype, func):
1455+
a = xp.asarray(3, dtype=dtype)
1456+
return getattr(xp, func)(a, include_initial=True)
1457+
1458+
@testing.for_all_dtypes()
1459+
@testing.numpy_cupy_allclose(rtol=1e-6)
1460+
def test_empty_axis(self, xp, dtype, func):
1461+
a = xp.empty((3, 0, 4), dtype=dtype)
1462+
return getattr(xp, func)(a, axis=1)
1463+
1464+
@testing.for_all_dtypes()
1465+
@testing.numpy_cupy_allclose(rtol=1e-6)
1466+
def test_empty_axis_include_initial(self, xp, dtype, func):
1467+
a = xp.empty((3, 0, 4), dtype=dtype)
1468+
return getattr(xp, func)(a, axis=1, include_initial=True)
1469+
1470+
@pytest.mark.parametrize("in_dtype", [numpy.int8, numpy.uint16])
1471+
@testing.numpy_cupy_array_equal()
1472+
def test_narrow_int_promotion_include_initial(self, xp, in_dtype, func):
1473+
# Narrow integer inputs must promote to int64 / uint64 (matches
1474+
# numpy's default-platform-integer rule) even when include_initial
1475+
# takes the internal-allocation path.
1476+
a = testing.shaped_arange((5,), xp, in_dtype)
1477+
return getattr(xp, func)(a, include_initial=True)
1478+
1479+
@testing.for_all_dtypes(no_bool=True)
1480+
@testing.numpy_cupy_allclose(rtol=1e-6)
1481+
def test_out_dtype_cast(self, xp, dtype, func):
1482+
# out has a different dtype than x -- result must be cast.
1483+
a = testing.shaped_arange((3, 4, 5), xp, numpy.int16)
1484+
out = xp.zeros((3, 4, 5), dtype=dtype)
1485+
getattr(xp, func)(a, axis=1, out=out)
1486+
return out

0 commit comments

Comments
 (0)