• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Owner(s): ["module: dynamo"]
2
3import itertools
4from unittest import expectedFailure as xfail, skipIf as skipif
5
6import numpy
7import pytest
8from pytest import raises as assert_raises
9
10from torch.testing._internal.common_utils import (
11    instantiate_parametrized_tests,
12    parametrize,
13    run_tests,
14    skipIfTorchDynamo,
15    subtest,
16    TEST_WITH_TORCHDYNAMO,
17    TestCase,
18    xpassIfTorchDynamo,
19)
20
21
22if TEST_WITH_TORCHDYNAMO:
23    import numpy as np
24    from numpy.testing import assert_equal
25else:
26    import torch._numpy as np
27    from torch._numpy.testing import assert_equal
28
29
30class TestIndexing(TestCase):
31    @skipif(TEST_WITH_TORCHDYNAMO, reason=".tensor attr, type of a[0, 0]")
32    def test_indexing_simple(self):
33        a = np.array([[1, 2, 3], [4, 5, 6]])
34
35        assert isinstance(a[0, 0], np.ndarray)
36        assert isinstance(a[0, :], np.ndarray)
37        assert a[0, :].tensor._base is a.tensor
38
39    def test_setitem(self):
40        a = np.array([[1, 2, 3], [4, 5, 6]])
41        a[0, 0] = 8
42        assert isinstance(a, np.ndarray)
43        assert_equal(a, [[8, 2, 3], [4, 5, 6]])
44
45
46class TestReshape(TestCase):
47    @skipif(TEST_WITH_TORCHDYNAMO, reason=".tensor attribute")
48    def test_reshape_function(self):
49        arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
50        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
51        assert np.all(np.reshape(arr, (2, 6)) == tgt)
52
53        arr = np.asarray(arr)
54        assert np.transpose(arr, (1, 0)).tensor._base is arr.tensor
55
56    @skipif(TEST_WITH_TORCHDYNAMO, reason=".tensor attribute")
57    def test_reshape_method(self):
58        arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
59        arr_shape = arr.shape
60
61        tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
62
63        # reshape(*shape_tuple)
64        assert np.all(arr.reshape(2, 6) == tgt)
65        assert arr.reshape(2, 6).tensor._base is arr.tensor  # reshape keeps the base
66        assert arr.shape == arr_shape  # arr is intact
67
68        # XXX: move out to dedicated test(s)
69        assert arr.reshape(2, 6).tensor._base is arr.tensor
70
71        # reshape(shape_tuple)
72        assert np.all(arr.reshape((2, 6)) == tgt)
73        assert arr.reshape((2, 6)).tensor._base is arr.tensor
74        assert arr.shape == arr_shape
75
76        tgt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
77        assert np.all(arr.reshape(3, 4) == tgt)
78        assert arr.reshape(3, 4).tensor._base is arr.tensor
79        assert arr.shape == arr_shape
80
81        assert np.all(arr.reshape((3, 4)) == tgt)
82        assert arr.reshape((3, 4)).tensor._base is arr.tensor
83        assert arr.shape == arr_shape
84
85
86# XXX : order='C' / 'F'
87#        tgt = [[1, 4, 7, 10],
88#               [2, 5, 8, 11],
89#               [3, 6, 9, 12]]
90#        assert np.all(arr.T.reshape((3, 4), order='C') == tgt)
91#
92#        tgt = [[1, 10, 8, 6], [4, 2, 11, 9], [7, 5, 3, 12]]
93#        assert_equal(arr.reshape((3, 4), order='F'), tgt)
94#
95
96
97class TestTranspose(TestCase):
98    @skipif(TEST_WITH_TORCHDYNAMO, reason=".tensor attribute")
99    def test_transpose_function(self):
100        arr = [[1, 2], [3, 4], [5, 6]]
101        tgt = [[1, 3, 5], [2, 4, 6]]
102        assert_equal(np.transpose(arr, (1, 0)), tgt)
103
104        arr = np.asarray(arr)
105        assert np.transpose(arr, (1, 0)).tensor._base is arr.tensor
106
107    @skipif(TEST_WITH_TORCHDYNAMO, reason=".tensor attribute")
108    def test_transpose_method(self):
109        a = np.array([[1, 2], [3, 4]])
110        assert_equal(a.transpose(), [[1, 3], [2, 4]])
111        assert_equal(a.transpose(None), [[1, 3], [2, 4]])
112        assert_raises((RuntimeError, ValueError), lambda: a.transpose(0))
113        assert_raises((RuntimeError, ValueError), lambda: a.transpose(0, 0))
114        assert_raises((RuntimeError, ValueError), lambda: a.transpose(0, 1, 2))
115
116        assert a.transpose().tensor._base is a.tensor
117
118
119class TestRavel(TestCase):
120    @skipif(TEST_WITH_TORCHDYNAMO, reason=".tensor attribute")
121    def test_ravel_function(self):
122        a = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
123        tgt = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
124        assert_equal(np.ravel(a), tgt)
125
126        arr = np.asarray(a)
127        assert np.ravel(arr).tensor._base is arr.tensor
128
129    @skipif(TEST_WITH_TORCHDYNAMO, reason=".tensor attribute")
130    def test_ravel_method(self):
131        a = np.array([[0, 1], [2, 3]])
132        assert_equal(a.ravel(), [0, 1, 2, 3])
133
134        assert a.ravel().tensor._base is a.tensor
135
136
137class TestNonzero(TestCase):
138    def test_nonzero_trivial(self):
139        assert_equal(np.nonzero(np.array([])), ([],))
140        assert_equal(np.array([]).nonzero(), ([],))
141
142        assert_equal(np.nonzero(np.array([0])), ([],))
143        assert_equal(np.array([0]).nonzero(), ([],))
144
145        assert_equal(np.nonzero(np.array([1])), ([0],))
146        assert_equal(np.array([1]).nonzero(), ([0],))
147
148    def test_nonzero_onedim(self):
149        x = np.array([1, 0, 2, -1, 0, 0, 8])
150        assert_equal(np.nonzero(x), ([0, 2, 3, 6],))
151        assert_equal(x.nonzero(), ([0, 2, 3, 6],))
152
153    def test_nonzero_twodim(self):
154        x = np.array([[0, 1, 0], [2, 0, 3]])
155        assert_equal(np.nonzero(x), ([0, 1, 1], [1, 0, 2]))
156        assert_equal(x.nonzero(), ([0, 1, 1], [1, 0, 2]))
157
158        x = np.eye(3)
159        assert_equal(np.nonzero(x), ([0, 1, 2], [0, 1, 2]))
160        assert_equal(x.nonzero(), ([0, 1, 2], [0, 1, 2]))
161
162    def test_sparse(self):
163        # test special sparse condition boolean code path
164        for i in range(20):
165            c = np.zeros(200, dtype=bool)
166            c[i::20] = True
167            assert_equal(np.nonzero(c)[0], np.arange(i, 200 + i, 20))
168            assert_equal(c.nonzero()[0], np.arange(i, 200 + i, 20))
169
170            c = np.zeros(400, dtype=bool)
171            c[10 + i : 20 + i] = True
172            c[20 + i * 2] = True
173            assert_equal(
174                np.nonzero(c)[0],
175                np.concatenate((np.arange(10 + i, 20 + i), [20 + i * 2])),
176            )
177
178    def test_array_method(self):
179        # Tests that the array method
180        # call to nonzero works
181        m = np.array([[1, 0, 0], [4, 0, 6]])
182        tgt = [[0, 1, 1], [0, 0, 2]]
183
184        assert_equal(m.nonzero(), tgt)
185
186
187@instantiate_parametrized_tests
188class TestArgmaxArgminCommon(TestCase):
189    sizes = [
190        (),
191        (3,),
192        (3, 2),
193        (2, 3),
194        (3, 3),
195        (2, 3, 4),
196        (4, 3, 2),
197        (1, 2, 3, 4),
198        (2, 3, 4, 1),
199        (3, 4, 1, 2),
200        (4, 1, 2, 3),
201        (64,),
202        (128,),
203        (256,),
204    ]
205
206    @skipif(numpy.__version__ < "1.22", reason="NP_VER: fails on NumPy 1.21.x")
207    @parametrize(
208        "size, axis",
209        list(
210            itertools.chain(
211                *[
212                    [
213                        (size, axis)
214                        for axis in list(range(-len(size), len(size))) + [None]
215                    ]
216                    for size in sizes
217                ]
218            )
219        ),
220    )
221    @parametrize("method", [np.argmax, np.argmin])
222    def test_np_argmin_argmax_keepdims(self, size, axis, method):
223        # arr = np.random.normal(size=size)
224        arr = np.empty(shape=size)
225
226        # contiguous arrays
227        if axis is None:
228            new_shape = [1 for _ in range(len(size))]
229        else:
230            new_shape = list(size)
231            new_shape[axis] = 1
232        new_shape = tuple(new_shape)
233
234        _res_orig = method(arr, axis=axis)
235        res_orig = _res_orig.reshape(new_shape)
236        res = method(arr, axis=axis, keepdims=True)
237        assert_equal(res, res_orig)
238        assert res.shape == new_shape
239
240        outarray = np.empty(res.shape, dtype=res.dtype)
241        res1 = method(arr, axis=axis, out=outarray, keepdims=True)
242        assert res1 is outarray
243        assert_equal(res, outarray)
244
245        if len(size) > 0:
246            wrong_shape = list(new_shape)
247            if axis is not None:
248                wrong_shape[axis] = 2
249            else:
250                wrong_shape[0] = 2
251            wrong_outarray = np.empty(wrong_shape, dtype=res.dtype)
252            with pytest.raises(ValueError):
253                method(arr.T, axis=axis, out=wrong_outarray, keepdims=True)
254
255        # non-contiguous arrays
256        if axis is None:
257            new_shape = [1 for _ in range(len(size))]
258        else:
259            new_shape = list(size)[::-1]
260            new_shape[axis] = 1
261        new_shape = tuple(new_shape)
262
263        _res_orig = method(arr.T, axis=axis)
264        res_orig = _res_orig.reshape(new_shape)
265        res = method(arr.T, axis=axis, keepdims=True)
266        assert_equal(res, res_orig)
267        assert res.shape == new_shape
268        outarray = np.empty(new_shape[::-1], dtype=res.dtype)
269        outarray = outarray.T
270        res1 = method(arr.T, axis=axis, out=outarray, keepdims=True)
271        assert res1 is outarray
272        assert_equal(res, outarray)
273
274        if len(size) > 0:
275            # one dimension lesser for non-zero sized
276            # array should raise an error
277            with pytest.raises(ValueError):
278                method(arr[0], axis=axis, out=outarray, keepdims=True)
279
280        if len(size) > 0:
281            wrong_shape = list(new_shape)
282            if axis is not None:
283                wrong_shape[axis] = 2
284            else:
285                wrong_shape[0] = 2
286            wrong_outarray = np.empty(wrong_shape, dtype=res.dtype)
287            with pytest.raises(ValueError):
288                method(arr.T, axis=axis, out=wrong_outarray, keepdims=True)
289
290    @skipif(True, reason="XXX: need ndarray.chooses")
291    @parametrize("method", ["max", "min"])
292    def test_all(self, method):
293        # a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
294        a = np.arange(4 * 5 * 6 * 7 * 8).reshape((4, 5, 6, 7, 8))
295        arg_method = getattr(a, "arg" + method)
296        val_method = getattr(a, method)
297        for i in range(a.ndim):
298            a_maxmin = val_method(i)
299            aarg_maxmin = arg_method(i)
300            axes = list(range(a.ndim))
301            axes.remove(i)
302            assert np.all(a_maxmin == aarg_maxmin.choose(*a.transpose(i, *axes)))
303
304    @parametrize("method", ["argmax", "argmin"])
305    def test_output_shape(self, method):
306        # see also gh-616
307        a = np.ones((10, 5))
308        arg_method = getattr(a, method)
309
310        # Check some simple shape mismatches
311        out = np.ones(11, dtype=np.int_)
312
313        with assert_raises(ValueError):
314            arg_method(-1, out=out)
315
316        out = np.ones((2, 5), dtype=np.int_)
317        with assert_raises(ValueError):
318            arg_method(-1, out=out)
319
320        # these could be relaxed possibly (used to allow even the previous)
321        out = np.ones((1, 10), dtype=np.int_)
322        with assert_raises(ValueError):
323            arg_method(-1, out=out)
324
325        out = np.ones(10, dtype=np.int_)
326        arg_method(-1, out=out)
327        assert_equal(out, arg_method(-1))
328
329    @parametrize("ndim", [0, 1])
330    @parametrize("method", ["argmax", "argmin"])
331    def test_ret_is_out(self, ndim, method):
332        a = np.ones((4,) + (256,) * ndim)
333        arg_method = getattr(a, method)
334        out = np.empty((256,) * ndim, dtype=np.intp)
335        ret = arg_method(axis=0, out=out)
336        assert ret is out
337
338    @parametrize(
339        "arr_method, np_method", [("argmax", np.argmax), ("argmin", np.argmin)]
340    )
341    def test_np_vs_ndarray(self, arr_method, np_method):
342        # make sure both ndarray.argmax/argmin and
343        # numpy.argmax/argmin support out/axis args
344        # a = np.random.normal(size=(2, 3))
345        a = np.arange(6).reshape((2, 3))
346        arg_method = getattr(a, arr_method)
347
348        # check keyword args
349        out1 = np.zeros(3, dtype=int)
350        out2 = np.zeros(3, dtype=int)
351        assert_equal(arg_method(out=out1, axis=0), np_method(a, out=out2, axis=0))
352        assert_equal(out1, out2)
353
354    @parametrize(
355        "arr_method, np_method", [("argmax", np.argmax), ("argmin", np.argmin)]
356    )
357    def test_np_vs_ndarray_positional(self, arr_method, np_method):
358        a = np.arange(6).reshape((2, 3))
359        arg_method = getattr(a, arr_method)
360
361        # check positional args
362        out1 = np.zeros(2, dtype=int)
363        out2 = np.zeros(2, dtype=int)
364        assert_equal(arg_method(1, out1), np_method(a, 1, out2))
365        assert_equal(out1, out2)
366
367
368@instantiate_parametrized_tests
369class TestArgmax(TestCase):
370    usg_data = [
371        ([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 0),
372        ([3, 3, 3, 3, 2, 2, 2, 2], 0),
373        ([0, 1, 2, 3, 4, 5, 6, 7], 7),
374        ([7, 6, 5, 4, 3, 2, 1, 0], 0),
375    ]
376    sg_data = usg_data + [
377        ([1, 2, 3, 4, -4, -3, -2, -1], 3),
378        ([1, 2, 3, 4, -1, -2, -3, -4], 3),
379    ]
380    darr = [
381        (np.array(d[0], dtype=t), d[1])
382        for d, t in (itertools.product(usg_data, (np.uint8,)))
383    ]
384    darr += [
385        (np.array(d[0], dtype=t), d[1])
386        for d, t in (
387            itertools.product(
388                sg_data, (np.int8, np.int16, np.int32, np.int64, np.float32, np.float64)
389            )
390        )
391    ]
392    darr += [
393        (np.array(d[0], dtype=t), d[1])
394        for d, t in (
395            itertools.product(
396                (
397                    ([0, 1, 2, 3, np.nan], 4),
398                    ([0, 1, 2, np.nan, 3], 3),
399                    ([np.nan, 0, 1, 2, 3], 0),
400                    ([np.nan, 0, np.nan, 2, 3], 0),
401                    # To hit the tail of SIMD multi-level(x4, x1) inner loops
402                    # on variant SIMD widthes
403                    ([1] * (2 * 5 - 1) + [np.nan], 2 * 5 - 1),
404                    ([1] * (4 * 5 - 1) + [np.nan], 4 * 5 - 1),
405                    ([1] * (8 * 5 - 1) + [np.nan], 8 * 5 - 1),
406                    ([1] * (16 * 5 - 1) + [np.nan], 16 * 5 - 1),
407                    ([1] * (32 * 5 - 1) + [np.nan], 32 * 5 - 1),
408                ),
409                (np.float32, np.float64),
410            )
411        )
412    ]
413    nan_arr = darr + [
414        subtest(([0, 1, 2, 3, complex(0, np.nan)], 4), decorators=[xpassIfTorchDynamo]),
415        subtest(([0, 1, 2, 3, complex(np.nan, 0)], 4), decorators=[xpassIfTorchDynamo]),
416        subtest(([0, 1, 2, complex(np.nan, 0), 3], 3), decorators=[xpassIfTorchDynamo]),
417        subtest(([0, 1, 2, complex(0, np.nan), 3], 3), decorators=[xpassIfTorchDynamo]),
418        subtest(([complex(0, np.nan), 0, 1, 2, 3], 0), decorators=[xpassIfTorchDynamo]),
419        subtest(
420            ([complex(np.nan, np.nan), 0, 1, 2, 3], 0), decorators=[xpassIfTorchDynamo]
421        ),
422        subtest(
423            ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
424            decorators=[xpassIfTorchDynamo],
425        ),
426        subtest(
427            ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
428            decorators=[xpassIfTorchDynamo],
429        ),
430        subtest(
431            ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
432            decorators=[xpassIfTorchDynamo],
433        ),
434        subtest(
435            ([complex(0, 0), complex(0, 2), complex(0, 1)], 1),
436            decorators=[xpassIfTorchDynamo],
437        ),
438        subtest(
439            ([complex(1, 0), complex(0, 2), complex(0, 1)], 0),
440            decorators=[xpassIfTorchDynamo],
441        ),
442        subtest(
443            ([complex(1, 0), complex(0, 2), complex(1, 1)], 2),
444            decorators=[xpassIfTorchDynamo],
445        ),
446        ([False, False, False, False, True], 4),
447        ([False, False, False, True, False], 3),
448        ([True, False, False, False, False], 0),
449        ([True, False, True, False, False], 0),
450    ]
451
452    @parametrize("data", nan_arr)
453    def test_combinations(self, data):
454        arr, pos = data
455        #      with suppress_warnings() as sup:
456        #          sup.filter(RuntimeWarning,
457        #                      "invalid value encountered in reduce")
458        #        if np.asarray(arr).dtype.kind in "c":
459        #            pytest.xfail(reason="'max_values_cpu' not implemented for 'ComplexDouble'")
460
461        val = np.max(arr)
462
463        assert_equal(np.argmax(arr), pos)  # , err_msg="%r" % arr)
464        assert_equal(arr[np.argmax(arr)], val)  # , err_msg="%r" % arr)
465
466        # add padding to test SIMD loops
467        rarr = np.repeat(arr, 129)
468        rpos = pos * 129
469        assert_equal(np.argmax(rarr), rpos, err_msg=f"{rarr!r}")
470        assert_equal(rarr[np.argmax(rarr)], val, err_msg=f"{rarr!r}")
471
472        padd = np.repeat(np.min(arr), 513)
473        rarr = np.concatenate((arr, padd))
474        rpos = pos
475        assert_equal(np.argmax(rarr), rpos, err_msg=f"{rarr!r}")
476        assert_equal(rarr[np.argmax(rarr)], val, err_msg=f"{rarr!r}")
477
478    def test_maximum_signed_integers(self):
479        a = np.array([1, 2**7 - 1, -(2**7)], dtype=np.int8)
480        assert_equal(np.argmax(a), 1)
481
482        a = np.array([1, 2**15 - 1, -(2**15)], dtype=np.int16)
483        assert_equal(np.argmax(a), 1)
484
485        a = np.array([1, 2**31 - 1, -(2**31)], dtype=np.int32)
486        assert_equal(np.argmax(a), 1)
487
488        a = np.array([1, 2**63 - 1, -(2**63)], dtype=np.int64)
489        assert_equal(np.argmax(a), 1)
490
491
492@instantiate_parametrized_tests
493class TestArgmin(TestCase):
494    usg_data = [
495        ([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], 8),
496        ([3, 3, 3, 3, 2, 2, 2, 2], 4),
497        ([0, 1, 2, 3, 4, 5, 6, 7], 0),
498        ([7, 6, 5, 4, 3, 2, 1, 0], 7),
499    ]
500    sg_data = usg_data + [
501        ([1, 2, 3, 4, -4, -3, -2, -1], 4),
502        ([1, 2, 3, 4, -1, -2, -3, -4], 7),
503    ]
504    darr = [
505        (np.array(d[0], dtype=t), d[1])
506        for d, t in (itertools.product(usg_data, (np.uint8,)))
507    ]
508    darr += [
509        (np.array(d[0], dtype=t), d[1])
510        for d, t in (
511            itertools.product(
512                sg_data, (np.int8, np.int16, np.int32, np.int64, np.float32, np.float64)
513            )
514        )
515    ]
516    darr += [
517        (np.array(d[0], dtype=t), d[1])
518        for d, t in (
519            itertools.product(
520                (
521                    ([0, 1, 2, 3, np.nan], 4),
522                    ([0, 1, 2, np.nan, 3], 3),
523                    ([np.nan, 0, 1, 2, 3], 0),
524                    ([np.nan, 0, np.nan, 2, 3], 0),
525                    # To hit the tail of SIMD multi-level(x4, x1) inner loops
526                    # on variant SIMD widthes
527                    ([1] * (2 * 5 - 1) + [np.nan], 2 * 5 - 1),
528                    ([1] * (4 * 5 - 1) + [np.nan], 4 * 5 - 1),
529                    ([1] * (8 * 5 - 1) + [np.nan], 8 * 5 - 1),
530                    ([1] * (16 * 5 - 1) + [np.nan], 16 * 5 - 1),
531                    ([1] * (32 * 5 - 1) + [np.nan], 32 * 5 - 1),
532                ),
533                (np.float32, np.float64),
534            )
535        )
536    ]
537    nan_arr = darr + [
538        subtest(([0, 1, 2, 3, complex(0, np.nan)], 4), decorators=[xfail]),
539        subtest(([0, 1, 2, 3, complex(np.nan, 0)], 4), decorators=[xfail]),
540        subtest(([0, 1, 2, complex(np.nan, 0), 3], 3), decorators=[xfail]),
541        subtest(([0, 1, 2, complex(0, np.nan), 3], 3), decorators=[xfail]),
542        subtest(([complex(0, np.nan), 0, 1, 2, 3], 0), decorators=[xfail]),
543        subtest(([complex(np.nan, np.nan), 0, 1, 2, 3], 0), decorators=[xfail]),
544        subtest(
545            ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
546            decorators=[xfail],
547        ),
548        subtest(
549            ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
550            decorators=[xfail],
551        ),
552        subtest(
553            ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
554            decorators=[xfail],
555        ),
556        subtest(([complex(0, 0), complex(0, 2), complex(0, 1)], 0), decorators=[xfail]),
557        subtest(([complex(1, 0), complex(0, 2), complex(0, 1)], 2), decorators=[xfail]),
558        subtest(([complex(1, 0), complex(0, 2), complex(1, 1)], 1), decorators=[xfail]),
559        ([True, True, True, True, False], 4),
560        ([True, True, True, False, True], 3),
561        ([False, True, True, True, True], 0),
562        ([False, True, False, True, True], 0),
563    ]
564
565    @parametrize("data", nan_arr)
566    def test_combinations(self, data):
567        arr, pos = data
568
569        if np.asarray(arr).dtype.kind in "c":
570            pytest.xfail(reason="'min_values_cpu' not implemented for 'ComplexDouble'")
571
572        #        with suppress_warnings() as sup:
573        #            sup.filter(RuntimeWarning, "invalid value encountered in reduce")
574        min_val = np.min(arr)
575
576        assert_equal(np.argmin(arr), pos, err_msg=f"{arr!r}")
577        assert_equal(arr[np.argmin(arr)], min_val, err_msg=f"{arr!r}")
578
579        # add padding to test SIMD loops
580        rarr = np.repeat(arr, 129)
581        rpos = pos * 129
582        assert_equal(np.argmin(rarr), rpos, err_msg=f"{rarr!r}")
583        assert_equal(rarr[np.argmin(rarr)], min_val, err_msg=f"{rarr!r}")
584
585        padd = np.repeat(np.max(arr), 513)
586        rarr = np.concatenate((arr, padd))
587        rpos = pos
588        assert_equal(np.argmin(rarr), rpos, err_msg=f"{rarr!r}")
589        assert_equal(rarr[np.argmin(rarr)], min_val, err_msg=f"{rarr!r}")
590
591    def test_minimum_signed_integers(self):
592        a = np.array([1, -(2**7), -(2**7) + 1, 2**7 - 1], dtype=np.int8)
593        assert_equal(np.argmin(a), 1)
594
595        a = np.array([1, -(2**15), -(2**15) + 1, 2**15 - 1], dtype=np.int16)
596        assert_equal(np.argmin(a), 1)
597
598        a = np.array([1, -(2**31), -(2**31) + 1, 2**31 - 1], dtype=np.int32)
599        assert_equal(np.argmin(a), 1)
600
601        a = np.array([1, -(2**63), -(2**63) + 1, 2**63 - 1], dtype=np.int64)
602        assert_equal(np.argmin(a), 1)
603
604
605class TestAmax(TestCase):
606    def test_basic(self):
607        a = [3, 4, 5, 10, -3, -5, 6.0]
608        assert_equal(np.amax(a), 10.0)
609        b = [[3, 6.0, 9.0], [4, 10.0, 5.0], [8, 3.0, 2.0]]
610        assert_equal(np.amax(b, axis=0), [8.0, 10.0, 9.0])
611        assert_equal(np.amax(b, axis=1), [9.0, 10.0, 8.0])
612
613        arr = np.asarray(a)
614        assert_equal(np.amax(arr), arr.max())
615
616
617class TestAmin(TestCase):
618    def test_basic(self):
619        a = [3, 4, 5, 10, -3, -5, 6.0]
620        assert_equal(np.amin(a), -5.0)
621        b = [[3, 6.0, 9.0], [4, 10.0, 5.0], [8, 3.0, 2.0]]
622        assert_equal(np.amin(b, axis=0), [3.0, 3.0, 2.0])
623        assert_equal(np.amin(b, axis=1), [3.0, 4.0, 2.0])
624
625        arr = np.asarray(a)
626        assert_equal(np.amin(arr), arr.min())
627
628
629class TestContains(TestCase):
630    def test_contains(self):
631        a = np.arange(12).reshape(3, 4)
632        assert 2 in a
633        assert 42 not in a
634
635
636@instantiate_parametrized_tests
637class TestNoExtraMethods(TestCase):
638    # make sure ndarray does not carry extra methods/attributes
639    # >>> set(dir(a)) - set(dir(a.tensor.numpy()))
640    @parametrize("name", ["fn", "ivar", "method", "name", "plain", "rvar"])
641    def test_extra_methods(self, name):
642        a = np.ones(3)
643        with pytest.raises(AttributeError):
644            getattr(a, name)
645
646
647class TestIter(TestCase):
648    @skipIfTorchDynamo()
649    def test_iter_1d(self):
650        # numpy generates array scalars, we do 0D arrays
651        a = np.arange(5)
652        lst = list(a)
653        assert all(type(x) == np.ndarray for x in lst), f"{[type(x) for x in lst]}"
654        assert all(x.ndim == 0 for x in lst)
655
656    def test_iter_2d(self):
657        # numpy iterates over the 0th axis
658        a = np.arange(5)[None, :]
659        lst = list(a)
660        assert len(lst) == 1
661        assert type(lst[0]) == np.ndarray
662        assert_equal(lst[0], np.arange(5))
663
664
665if __name__ == "__main__":
666    run_tests()
667