Skip to content

Commit 1810114

Browse files
authored
Merge 142b4fa into 0e50556
2 parents 0e50556 + 142b4fa commit 1810114

20 files changed

+1086
-772
lines changed

tests/skipped_tests.tbl

Lines changed: 0 additions & 214 deletions
Large diffs are not rendered by default.

tests/skipped_tests_gpu.tbl

Lines changed: 0 additions & 215 deletions
Large diffs are not rendered by default.

tests/skipped_tests_gpu_no_fp64.tbl

Lines changed: 0 additions & 171 deletions
Large diffs are not rendered by default.

tests/third_party/cupy/__init__.py

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import pytest
2+
3+
import dpnp as cupy
4+
5+
6+
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
7+
def test_bytes():
8+
out = cupy.random.bytes(10)
9+
assert isinstance(out, bytes)
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import unittest
2+
3+
import numpy
4+
import pytest
5+
6+
import dpnp as cupy
7+
from tests.helper import has_support_aspect64
8+
from tests.third_party.cupy import testing
9+
from tests.third_party.cupy.testing import _condition
10+
11+
12+
@testing.parameterize(
13+
{"seed": None},
14+
{"seed": 0},
15+
)
16+
@pytest.mark.skipif(not has_support_aspect64(), reason="fp64 is required")
17+
class TestPermutations(unittest.TestCase):
18+
19+
def _xp_random(self, xp):
20+
if self.seed is None:
21+
return xp.random
22+
else:
23+
pytest.skip("random.RandomState.permutation() is not supported yet")
24+
return xp.random.RandomState(seed=self.seed)
25+
26+
# Test ranks
27+
28+
# TODO(niboshi): Fix xfail
29+
@pytest.mark.xfail(reason="Explicit error types required")
30+
def test_permutation_zero_dim(self):
31+
for xp in (numpy, cupy):
32+
xp_random = self._xp_random(xp)
33+
a = testing.shaped_random((), xp)
34+
with pytest.raises(IndexError):
35+
xp_random.permutation(a)
36+
37+
# Test same values
38+
39+
@testing.for_all_dtypes(no_float16=True, no_bool=True, no_complex=True)
40+
def test_permutation_sort_1dim(self, dtype):
41+
cupy_random = self._xp_random(cupy)
42+
a = cupy.arange(10, dtype=dtype)
43+
b = cupy.copy(a)
44+
c = cupy_random.permutation(a)
45+
testing.assert_allclose(a, b)
46+
testing.assert_allclose(b, cupy.sort(c))
47+
48+
@testing.for_all_dtypes(no_float16=True, no_bool=True, no_complex=True)
49+
def test_permutation_sort_ndim(self, dtype):
50+
cupy_random = self._xp_random(cupy)
51+
a = cupy.arange(15, dtype=dtype).reshape(5, 3)
52+
b = cupy.copy(a)
53+
c = cupy_random.permutation(a)
54+
testing.assert_allclose(a, b)
55+
testing.assert_allclose(b, cupy.sort(c, axis=0))
56+
57+
# Test seed
58+
59+
@testing.for_all_dtypes()
60+
def test_permutation_seed1(self, dtype):
61+
a = testing.shaped_random((10,), cupy, dtype)
62+
b = cupy.copy(a)
63+
64+
cupy_random = self._xp_random(cupy)
65+
if self.seed is None:
66+
cupy_random.seed(0)
67+
pa = cupy_random.permutation(a)
68+
cupy_random = self._xp_random(cupy)
69+
if self.seed is None:
70+
cupy_random.seed(0)
71+
pb = cupy_random.permutation(b)
72+
73+
testing.assert_allclose(pa, pb)
74+
75+
76+
@pytest.mark.skipif(not has_support_aspect64(), reason="fp64 is required")
77+
class TestShuffle(unittest.TestCase):
78+
79+
# Test ranks
80+
81+
@pytest.mark.skip("no proper validation yet")
82+
def test_shuffle_zero_dim(self):
83+
for xp in (numpy, cupy):
84+
a = testing.shaped_random((), xp)
85+
with pytest.raises(TypeError):
86+
xp.random.shuffle(a)
87+
88+
# Test same values
89+
90+
@testing.for_all_dtypes(no_float16=True, no_bool=True, no_complex=True)
91+
def test_shuffle_sort_1dim(self, dtype):
92+
a = cupy.arange(10, dtype=dtype)
93+
b = cupy.copy(a)
94+
cupy.random.shuffle(a)
95+
testing.assert_allclose(cupy.sort(a), b)
96+
97+
@testing.for_all_dtypes(no_float16=True, no_bool=True, no_complex=True)
98+
def test_shuffle_sort_ndim(self, dtype):
99+
a = cupy.arange(15, dtype=dtype).reshape(5, 3)
100+
b = cupy.copy(a)
101+
cupy.random.shuffle(a)
102+
testing.assert_allclose(cupy.sort(a, axis=0), b)
103+
104+
# Test seed
105+
106+
@testing.for_all_dtypes()
107+
def test_shuffle_seed1(self, dtype):
108+
a = testing.shaped_random((10,), cupy, dtype)
109+
b = cupy.copy(a)
110+
cupy.random.seed(0)
111+
cupy.random.shuffle(a)
112+
cupy.random.seed(0)
113+
cupy.random.shuffle(b)
114+
testing.assert_allclose(a, b)
115+
116+
117+
@testing.parameterize(
118+
*(
119+
testing.product(
120+
{
121+
# 'num': [0, 1, 100, 1000, 10000, 100000],
122+
"num": [0, 1, 100], # dpnp.random.permutation() is slow
123+
}
124+
)
125+
)
126+
)
127+
@pytest.mark.skipif(not has_support_aspect64(), reason="fp64 is required")
128+
class TestPermutationSoundness(unittest.TestCase):
129+
130+
def setUp(self):
131+
a = cupy.random.permutation(self.num)
132+
self.a = a
133+
134+
# Test soundness
135+
136+
@_condition.repeat(3)
137+
def test_permutation_soundness(self):
138+
assert (numpy.sort(self.a) == numpy.arange(self.num)).all()
139+
140+
141+
@testing.parameterize(
142+
*(
143+
testing.product(
144+
{
145+
"offset": [0, 17, 34, 51],
146+
"gap": [1, 2, 3, 5, 7],
147+
"mask": [1, 2, 4, 8, 16, 32, 64, 128],
148+
}
149+
)
150+
)
151+
)
152+
class TestPermutationRandomness(unittest.TestCase):
153+
154+
num = 256
155+
156+
def setUp(self):
157+
a = cupy.random.permutation(self.num)
158+
self.a = a
159+
self.num_half = int(self.num / 2)
160+
161+
# Simple bit proportion test
162+
163+
# This test is to check kind of randomness of permutation.
164+
# An intuition behind this test is that, when you make a sub-array
165+
# by regularly extracting half elements from the permuted array,
166+
# the sub-array should also hold randomness and accordingly
167+
# frequency of appearance of 0 and 1 at each bit position of
168+
# whole elements in the sub-array should become similar
169+
# when elements count of original array is 2^N.
170+
# Note that this is not an established method to check randomness.
171+
# TODO(anaruse): implement randomness check using some established methods.
172+
@_condition.repeat_with_success_at_least(5, 3)
173+
@pytest.mark.skip("no support of index as numpy array")
174+
def test_permutation_randomness(self):
175+
if self.mask > self.num_half:
176+
return
177+
index = numpy.arange(self.num_half)
178+
index = (index * self.gap + self.offset) % self.num
179+
samples = self.a[index]
180+
ret = samples & self.mask > 0
181+
count = numpy.count_nonzero(ret) # expectation: self.num_half / 2
182+
if count > self.num_half - count:
183+
count = self.num_half - count
184+
prob_le_count = self._calc_probability(count)
185+
if prob_le_count < 0.001:
186+
raise
187+
188+
def _calc_probability(self, count):
189+
comb_all = self._comb(self.num, self.num_half)
190+
comb_le_count = 0
191+
for i in range(count + 1):
192+
tmp = self._comb(self.num_half, i)
193+
comb_i = tmp * tmp
194+
comb_le_count += comb_i
195+
prob = comb_le_count / comb_all
196+
return prob
197+
198+
def _comb(self, N, k):
199+
val = numpy.float64(1)
200+
for i in range(k):
201+
val *= (N - i) / (k - i)
202+
return val
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import unittest
2+
3+
import pytest
4+
5+
from dpnp import random
6+
from tests.third_party.cupy import testing
7+
8+
9+
@pytest.mark.skip("random.get_random_state() is not supported yet")
10+
class TestResetSeed(unittest.TestCase):
11+
12+
@testing.for_float_dtypes(no_float16=True)
13+
def test_reset_seed(self, dtype):
14+
rs = random.get_random_state()
15+
rs.seed(0)
16+
l1 = rs.rand(10, dtype=dtype)
17+
18+
rs = random.get_random_state()
19+
rs.seed(0)
20+
l2 = rs.rand(10, dtype=dtype)
21+
22+
testing.assert_array_equal(l1, l2)

0 commit comments

Comments
 (0)