Skip to content

Commit 1b37690

Browse files
committed
impl elementwise exp and sin
1 parent 0df49b6 commit 1b37690

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

dpctl/tests/elementwise/test_sin.py

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import itertools
2+
3+
import numpy as np
4+
import pytest
5+
from numpy.testing import assert_raises_regex
6+
7+
import dpctl
8+
import dpctl.tensor as dpt
9+
from dpctl.tests.helper import get_queue_or_skip, skip_if_dtype_not_supported
10+
11+
from .utils import _all_dtypes, _map_to_device_dtype
12+
13+
14+
@pytest.mark.parametrize("dtype", _all_dtypes)
15+
def test_sin_out_type(dtype):
16+
q = get_queue_or_skip()
17+
skip_if_dtype_not_supported(dtype, q)
18+
19+
X = dpt.asarray(0, dtype=dtype, sycl_queue=q)
20+
expected_dtype = np.sin(np.array(0, dtype=dtype)).dtype
21+
expected_dtype = _map_to_device_dtype(expected_dtype, q.sycl_device)
22+
assert dpt.sin(X).dtype == expected_dtype
23+
24+
X = dpt.asarray(0, dtype=dtype, sycl_queue=q)
25+
expected_dtype = np.sin(np.array(0, dtype=dtype)).dtype
26+
expected_dtype = _map_to_device_dtype(expected_dtype, q.sycl_device)
27+
Y = dpt.empty_like(X, dtype=expected_dtype)
28+
dpt.sin(X, out=Y)
29+
np.testing.assert_allclose(dpt.asnumpy(dpt.sin(X)), dpt.asnumpy(Y))
30+
31+
32+
@pytest.mark.parametrize("dtype", ["f2", "f4", "f8", "c8", "c16"])
33+
def test_sin_output(dtype):
34+
q = get_queue_or_skip()
35+
skip_if_dtype_not_supported(dtype, q)
36+
37+
n_seq = 100
38+
n_rep = 137
39+
40+
Xnp = np.linspace(-np.pi / 4, np.pi / 4, num=n_seq, dtype=dtype)
41+
X = dpt.asarray(np.repeat(Xnp, n_rep), dtype=dtype, sycl_queue=q)
42+
43+
Y = dpt.sin(X)
44+
tol = 8 * dpt.finfo(Y.dtype).resolution
45+
46+
np.testing.assert_allclose(
47+
dpt.asnumpy(Y), np.repeat(np.sin(Xnp), n_rep), atol=tol, rtol=tol
48+
)
49+
50+
Z = dpt.empty_like(X, dtype=dtype)
51+
dpt.sin(X, out=Z)
52+
53+
np.testing.assert_allclose(
54+
dpt.asnumpy(Z), np.repeat(np.sin(Xnp), n_rep), atol=tol, rtol=tol
55+
)
56+
57+
58+
@pytest.mark.parametrize("usm_type", ["device", "shared", "host"])
59+
def test_sin_usm_type(usm_type):
60+
q = get_queue_or_skip()
61+
62+
arg_dt = np.dtype("f4")
63+
input_shape = (10, 10, 10, 10)
64+
X = dpt.empty(input_shape, dtype=arg_dt, usm_type=usm_type, sycl_queue=q)
65+
X[..., 0::2] = np.pi / 6
66+
X[..., 1::2] = np.pi / 3
67+
68+
Y = dpt.sin(X)
69+
assert Y.usm_type == X.usm_type
70+
assert Y.sycl_queue == X.sycl_queue
71+
assert Y.flags.c_contiguous
72+
73+
expected_Y = np.empty(input_shape, dtype=arg_dt)
74+
expected_Y[..., 0::2] = np.sin(np.float32(np.pi / 6))
75+
expected_Y[..., 1::2] = np.sin(np.float32(np.pi / 3))
76+
tol = 8 * dpt.finfo(Y.dtype).resolution
77+
78+
np.testing.assert_allclose(dpt.asnumpy(Y), expected_Y, atol=tol, rtol=tol)
79+
80+
81+
@pytest.mark.parametrize("dtype", _all_dtypes)
82+
def test_sin_order(dtype):
83+
q = get_queue_or_skip()
84+
skip_if_dtype_not_supported(dtype, q)
85+
86+
arg_dt = np.dtype(dtype)
87+
input_shape = (10, 10, 10, 10)
88+
X = dpt.empty(input_shape, dtype=arg_dt, sycl_queue=q)
89+
X[..., 0::2] = np.pi / 6
90+
X[..., 1::2] = np.pi / 3
91+
92+
for ord in ["C", "F", "A", "K"]:
93+
for perms in itertools.permutations(range(4)):
94+
U = dpt.permute_dims(X[:, ::-1, ::-1, :], perms)
95+
Y = dpt.sin(U, order=ord)
96+
expected_Y = np.sin(dpt.asnumpy(U))
97+
tol = 8 * max(
98+
dpt.finfo(Y.dtype).resolution,
99+
np.finfo(expected_Y.dtype).resolution,
100+
)
101+
np.testing.assert_allclose(
102+
dpt.asnumpy(Y), expected_Y, atol=tol, rtol=tol
103+
)
104+
105+
106+
def test_sin_errors():
107+
get_queue_or_skip()
108+
try:
109+
gpu_queue = dpctl.SyclQueue("gpu")
110+
except dpctl.SyclQueueCreationError:
111+
pytest.skip("SyclQueue('gpu') failed, skipping")
112+
try:
113+
cpu_queue = dpctl.SyclQueue("cpu")
114+
except dpctl.SyclQueueCreationError:
115+
pytest.skip("SyclQueue('cpu') failed, skipping")
116+
117+
x = dpt.zeros(2, sycl_queue=gpu_queue)
118+
y = dpt.empty_like(x, sycl_queue=cpu_queue)
119+
assert_raises_regex(
120+
TypeError,
121+
"Input and output allocation queues are not compatible",
122+
dpt.sin,
123+
x,
124+
y,
125+
)
126+
127+
x = dpt.zeros(2)
128+
y = dpt.empty(3)
129+
assert_raises_regex(
130+
TypeError,
131+
"The shape of input and output arrays are inconsistent",
132+
dpt.sin,
133+
x,
134+
y,
135+
)
136+
137+
x = dpt.zeros(2)
138+
y = x
139+
assert_raises_regex(
140+
TypeError, "Input and output arrays have memory overlap", dpt.sin, x, y
141+
)
142+
143+
x = dpt.zeros(2, dtype="float32")
144+
y = np.empty_like(x)
145+
assert_raises_regex(
146+
TypeError, "output array must be of usm_ndarray type", dpt.sin, x, y
147+
)
148+
149+
150+
@pytest.mark.parametrize("dtype", _all_dtypes)
151+
def test_sin_error_dtype(dtype):
152+
q = get_queue_or_skip()
153+
skip_if_dtype_not_supported(dtype, q)
154+
155+
x = dpt.zeros(5, dtype=dtype)
156+
y = dpt.empty_like(x, dtype="int16")
157+
assert_raises_regex(
158+
TypeError, "Output array of type.*is needed", dpt.sin, x, y
159+
)
160+
161+
162+
@pytest.mark.parametrize(
163+
"np_call, dpt_call", [(np.sin, dpt.sin), (np.cos, dpt.cos)]
164+
)
165+
@pytest.mark.parametrize("dtype", ["f", "d"])
166+
@pytest.mark.parametrize("stride", [-1, 1, 2, 4, 5])
167+
def test_sincos_overlaps(np_call, dpt_call, dtype, stride):
168+
N = 100
169+
rng = np.random.default_rng(42)
170+
x = rng.standard_normal(N, dtype)
171+
y = np_call(x[::stride])
172+
z = dpt_call(dpt.asarray(x[::stride]))
173+
174+
tol = 8 * dpt.finfo(y.dtype).resolution
175+
np.testing.assert_allclose(y, dpt.asnumpy(z), atol=tol, rtol=tol)

0 commit comments

Comments
 (0)