Skip to content

Commit 7f4fc14

Browse files
authored
implement dpnp.pad (#2093)
* implement dpnp.pad * fix directory name * fix failed test cases * skip tests for numpy<2.0 * address comments * add test_arraypad.py to TEST_SCOPE * add an assert * add support for mode median * update sycl_queue and usm_type tests * suppress warning * fast path improvement * minor updates
1 parent 543d76e commit 7f4fc14

File tree

9 files changed

+2034
-2
lines changed

9 files changed

+2034
-2
lines changed

.github/workflows/conda-package.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ env:
2525
test_arithmetic.py
2626
test_arraycreation.py
2727
test_arraymanipulation.py
28+
test_arraypad.py
2829
test_bitwise.py
2930
test_copy.py
3031
test_counting.py
@@ -60,6 +61,7 @@ env:
6061
third_party/cupy/logic_tests
6162
third_party/cupy/manipulation_tests
6263
third_party/cupy/math_tests
64+
third_party/cupy/padding_tests
6365
third_party/cupy/sorting_tests
6466
third_party/cupy/statistics_tests/test_histogram.py
6567
third_party/cupy/statistics_tests/test_meanvar.py

dpnp/dpnp_iface_manipulation.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import dpnp
5050

5151
from .dpnp_array import dpnp_array
52+
from .dpnp_utils.dpnp_utils_pad import dpnp_pad
5253

5354
__all__ = [
5455
"append",
@@ -76,6 +77,7 @@
7677
"matrix_transpose",
7778
"moveaxis",
7879
"ndim",
80+
"pad",
7981
"permute_dims",
8082
"ravel",
8183
"repeat",
@@ -1894,6 +1896,207 @@ def ndim(a):
18941896
return numpy.ndim(a)
18951897

18961898

1899+
def pad(array, pad_width, mode="constant", **kwargs):
1900+
"""
1901+
Pad an array.
1902+
1903+
For full documentation refer to :obj:`numpy.pad`.
1904+
1905+
Parameters
1906+
----------
1907+
array : {dpnp.ndarray, usm_ndarray}
1908+
The array of rank ``N`` to pad.
1909+
pad_width : {sequence, array_like, int}
1910+
Number of values padded to the edges of each axis.
1911+
``((before_1, after_1), ... (before_N, after_N))`` unique pad widths
1912+
for each axis.
1913+
``(before, after)`` or ``((before, after),)`` yields same before
1914+
and after pad for each axis.
1915+
``(pad,)`` or ``int`` is a shortcut for ``before = after = pad`` width
1916+
for all axes.
1917+
mode : {str, function}, optional
1918+
One of the following string values or a user supplied function.
1919+
1920+
"constant"
1921+
Pads with a constant value.
1922+
"edge"
1923+
Pads with the edge values of array.
1924+
"linear_ramp"
1925+
Pads with the linear ramp between `end_value` and the
1926+
array edge value.
1927+
"maximum"
1928+
Pads with the maximum value of all or part of the
1929+
vector along each axis.
1930+
"mean"
1931+
Pads with the mean value of all or part of the
1932+
vector along each axis.
1933+
"median"
1934+
Pads with the median value of all or part of the
1935+
vector along each axis.
1936+
"minimum"
1937+
Pads with the minimum value of all or part of the
1938+
vector along each axis.
1939+
"reflect"
1940+
Pads with the reflection of the vector mirrored on
1941+
the first and last values of the vector along each
1942+
axis.
1943+
"symmetric"
1944+
Pads with the reflection of the vector mirrored
1945+
along the edge of the array.
1946+
"wrap"
1947+
Pads with the wrap of the vector along the axis.
1948+
The first values are used to pad the end and the
1949+
end values are used to pad the beginning.
1950+
"empty"
1951+
Pads with undefined values.
1952+
<function>
1953+
Padding function, see Notes.
1954+
Default: ``"constant"``.
1955+
stat_length : {None, int, sequence of ints}, optional
1956+
Used in ``"maximum"``, ``"mean"``, ``"median"``, and ``"minimum"``.
1957+
Number of values at edge of each axis used to calculate the statistic
1958+
value. ``((before_1, after_1), ... (before_N, after_N))`` unique
1959+
statistic lengths for each axis.
1960+
``(before, after)`` or ``((before, after),)`` yields same before
1961+
and after statistic lengths for each axis.
1962+
``(stat_length,)`` or ``int`` is a shortcut for
1963+
``before = after = statistic`` length for all axes.
1964+
Default: ``None``, to use the entire axis.
1965+
constant_values : {sequence, scalar}, optional
1966+
Used in ``"constant"``. The values to set the padded values for each
1967+
axis.
1968+
``((before_1, after_1), ... (before_N, after_N))`` unique pad constants
1969+
for each axis.
1970+
``(before, after)`` or ``((before, after),)`` yields same before
1971+
and after constants for each axis.
1972+
``(constant,)`` or ``constant`` is a shortcut for
1973+
``before = after = constant`` for all axes.
1974+
Default: ``0``.
1975+
end_values : {sequence, scalar}, optional
1976+
Used in ``"linear_ramp"``. The values used for the ending value of the
1977+
linear_ramp and that will form the edge of the padded array.
1978+
``((before_1, after_1), ... (before_N, after_N))`` unique end values
1979+
for each axis.
1980+
``(before, after)`` or ``((before, after),)`` yields same before
1981+
and after end values for each axis.
1982+
``(constant,)`` or ``constant`` is a shortcut for
1983+
``before = after = constant`` for all axes.
1984+
Default: ``0``.
1985+
reflect_type : {"even", "odd"}, optional
1986+
Used in ``"reflect"``, and ``"symmetric"``. The ``"even"`` style is the
1987+
default with an unaltered reflection around the edge value. For
1988+
the ``"odd"`` style, the extended part of the array is created by
1989+
subtracting the reflected values from two times the edge value.
1990+
Default: ``"even"``.
1991+
1992+
Returns
1993+
-------
1994+
padded array : dpnp.ndarray
1995+
Padded array of rank equal to `array` with shape increased
1996+
according to `pad_width`.
1997+
1998+
Notes
1999+
-----
2000+
For an array with rank greater than 1, some of the padding of later
2001+
axes is calculated from padding of previous axes. This is easiest to
2002+
think about with a rank 2 array where the corners of the padded array
2003+
are calculated by using padded values from the first axis.
2004+
2005+
The padding function, if used, should modify a rank 1 array in-place. It
2006+
has the following signature::
2007+
2008+
padding_func(vector, iaxis_pad_width, iaxis, kwargs)
2009+
2010+
where
2011+
2012+
vector : dpnp.ndarray
2013+
A rank 1 array already padded with zeros. Padded values are
2014+
vector[:iaxis_pad_width[0]] and vector[-iaxis_pad_width[1]:].
2015+
iaxis_pad_width : tuple
2016+
A 2-tuple of ints, iaxis_pad_width[0] represents the number of
2017+
values padded at the beginning of vector where
2018+
iaxis_pad_width[1] represents the number of values padded at
2019+
the end of vector.
2020+
iaxis : int
2021+
The axis currently being calculated.
2022+
kwargs : dict
2023+
Any keyword arguments the function requires.
2024+
2025+
Examples
2026+
--------
2027+
>>> import dpnp as np
2028+
>>> a = np.array([1, 2, 3, 4, 5])
2029+
>>> np.pad(a, (2, 3), 'constant', constant_values=(4, 6))
2030+
array([4, 4, 1, 2, 3, 4, 5, 6, 6, 6])
2031+
2032+
>>> np.pad(a, (2, 3), 'edge')
2033+
array([1, 1, 1, 2, 3, 4, 5, 5, 5, 5])
2034+
2035+
>>> np.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4))
2036+
array([ 5, 3, 1, 2, 3, 4, 5, 2, -1, -4])
2037+
2038+
>>> np.pad(a, (2,), 'maximum')
2039+
array([5, 5, 1, 2, 3, 4, 5, 5, 5])
2040+
2041+
>>> np.pad(a, (2,), 'mean')
2042+
array([3, 3, 1, 2, 3, 4, 5, 3, 3])
2043+
2044+
>>> np.pad(a, (2,), 'median')
2045+
array([3, 3, 1, 2, 3, 4, 5, 3, 3])
2046+
2047+
>>> a = np.array([[1, 2], [3, 4]])
2048+
>>> np.pad(a, ((3, 2), (2, 3)), 'minimum')
2049+
array([[1, 1, 1, 2, 1, 1, 1],
2050+
[1, 1, 1, 2, 1, 1, 1],
2051+
[1, 1, 1, 2, 1, 1, 1],
2052+
[1, 1, 1, 2, 1, 1, 1],
2053+
[3, 3, 3, 4, 3, 3, 3],
2054+
[1, 1, 1, 2, 1, 1, 1],
2055+
[1, 1, 1, 2, 1, 1, 1]])
2056+
2057+
>>> a = np.array([1, 2, 3, 4, 5])
2058+
>>> np.pad(a, (2, 3), 'reflect')
2059+
array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2])
2060+
2061+
>>> np.pad(a, (2, 3), 'reflect', reflect_type='odd')
2062+
array([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8])
2063+
2064+
>>> np.pad(a, (2, 3), 'symmetric')
2065+
array([2, 1, 1, 2, 3, 4, 5, 5, 4, 3])
2066+
2067+
>>> np.pad(a, (2, 3), 'symmetric', reflect_type='odd')
2068+
array([0, 1, 1, 2, 3, 4, 5, 5, 6, 7])
2069+
2070+
>>> np.pad(a, (2, 3), 'wrap')
2071+
array([4, 5, 1, 2, 3, 4, 5, 1, 2, 3])
2072+
2073+
>>> def pad_width(vector, pad_width, iaxis, kwargs):
2074+
... pad_value = kwargs.get('padder', 10)
2075+
... vector[:pad_width[0]] = pad_value
2076+
... vector[-pad_width[1]:] = pad_value
2077+
>>> a = np.arange(6)
2078+
>>> a = a.reshape((2, 3))
2079+
>>> np.pad(a, 2, pad_width)
2080+
array([[10, 10, 10, 10, 10, 10, 10],
2081+
[10, 10, 10, 10, 10, 10, 10],
2082+
[10, 10, 0, 1, 2, 10, 10],
2083+
[10, 10, 3, 4, 5, 10, 10],
2084+
[10, 10, 10, 10, 10, 10, 10],
2085+
[10, 10, 10, 10, 10, 10, 10]])
2086+
>>> np.pad(a, 2, pad_width, padder=100)
2087+
array([[100, 100, 100, 100, 100, 100, 100],
2088+
[100, 100, 100, 100, 100, 100, 100],
2089+
[100, 100, 0, 1, 2, 100, 100],
2090+
[100, 100, 3, 4, 5, 100, 100],
2091+
[100, 100, 100, 100, 100, 100, 100],
2092+
[100, 100, 100, 100, 100, 100, 100]])
2093+
2094+
"""
2095+
2096+
dpnp.check_supported_arrays_type(array)
2097+
return dpnp_pad(array, pad_width, mode=mode, **kwargs)
2098+
2099+
18972100
def ravel(a, order="C"):
18982101
"""
18992102
Return a contiguous flattened array.

0 commit comments

Comments
 (0)