Skip to content

Commit f39cec6

Browse files
Merge remote-tracking branch 'origin/master' into add_dpnp_cli_options
2 parents fd4f6ba + 5865e82 commit f39cec6

3 files changed

Lines changed: 25 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525

2626
* Fixed incorrect in-place advanced indexing for 4D arrays when using `range` or `list` as index keys [#2872](https://github.com/IntelPython/dpnp/pull/2872)
2727
* Fixed `conda build` command syntax in GitHub workflows and documentation to use `conda-build` [#2888](https://github.com/IntelPython/dpnp/pull/2888)
28+
* Fixed incorrect `dpnp.tensor.acosh` result for `complex(±0, NaN)` special case to match the Python Array API specification [#2914](https://github.com/IntelPython/dpnp/pull/2914)
2829

2930
### Security
3031

dpnp/tensor/libtensor/include/kernels/elementwise_functions/acosh.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,6 @@ struct AcoshFunctor
150150
if (std::isnan(rx)) {
151151
return resT{sycl::fabs(ry), rx};
152152
}
153-
/* acosh(0 + I*NaN) = NaN + I*NaN */
154-
if (std::isnan(ry)) {
155-
return resT{ry, ry};
156-
}
157153
/* ordinary cases */
158154
const realT res_im = sycl::copysign(rx, std::imag(in));
159155
return resT{sycl::fabs(ry), res_im};

dpnp/tests/tensor/elementwise/test_hyperbolic.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
)
3939
from .utils import (
4040
_all_dtypes,
41+
_complex_fp_dtypes,
4142
_map_to_device_dtype,
43+
_real_fp_dtypes,
4244
)
4345

4446
_hyper_funcs = [(np.sinh, dpt.sinh), (np.cosh, dpt.cosh), (np.tanh, dpt.tanh)]
@@ -65,7 +67,7 @@ def test_hyper_out_type(np_call, dpt_call, dtype):
6567

6668

6769
@pytest.mark.parametrize("np_call, dpt_call", _all_funcs)
68-
@pytest.mark.parametrize("dtype", ["f2", "f4", "f8"])
70+
@pytest.mark.parametrize("dtype", _real_fp_dtypes)
6971
def test_hyper_real_contig(np_call, dpt_call, dtype):
7072
q = get_queue_or_skip()
7173
skip_if_dtype_not_supported(dtype, q)
@@ -96,7 +98,7 @@ def test_hyper_real_contig(np_call, dpt_call, dtype):
9698

9799

98100
@pytest.mark.parametrize("np_call, dpt_call", _all_funcs)
99-
@pytest.mark.parametrize("dtype", ["c8", "c16"])
101+
@pytest.mark.parametrize("dtype", _complex_fp_dtypes)
100102
def test_hyper_complex_contig(np_call, dpt_call, dtype):
101103
q = get_queue_or_skip()
102104
skip_if_dtype_not_supported(dtype, q)
@@ -123,7 +125,7 @@ def test_hyper_complex_contig(np_call, dpt_call, dtype):
123125

124126

125127
@pytest.mark.parametrize("np_call, dpt_call", _all_funcs)
126-
@pytest.mark.parametrize("dtype", ["f2", "f4", "f8"])
128+
@pytest.mark.parametrize("dtype", _real_fp_dtypes)
127129
def test_hyper_real_strided(np_call, dpt_call, dtype):
128130
q = get_queue_or_skip()
129131
skip_if_dtype_not_supported(dtype, q)
@@ -157,7 +159,7 @@ def test_hyper_real_strided(np_call, dpt_call, dtype):
157159

158160

159161
@pytest.mark.parametrize("np_call, dpt_call", _all_funcs)
160-
@pytest.mark.parametrize("dtype", ["c8", "c16"])
162+
@pytest.mark.parametrize("dtype", _complex_fp_dtypes)
161163
def test_hyper_complex_strided(np_call, dpt_call, dtype):
162164
q = get_queue_or_skip()
163165
skip_if_dtype_not_supported(dtype, q)
@@ -185,7 +187,7 @@ def test_hyper_complex_strided(np_call, dpt_call, dtype):
185187

186188

187189
@pytest.mark.parametrize("np_call, dpt_call", _all_funcs)
188-
@pytest.mark.parametrize("dtype", ["f2", "f4", "f8"])
190+
@pytest.mark.parametrize("dtype", _real_fp_dtypes)
189191
def test_hyper_real_special_cases(np_call, dpt_call, dtype):
190192
q = get_queue_or_skip()
191193
skip_if_dtype_not_supported(dtype, q)
@@ -200,3 +202,20 @@ def test_hyper_real_special_cases(np_call, dpt_call, dtype):
200202

201203
tol = 8 * dpt.finfo(dtype).resolution
202204
assert_allclose(dpt.asnumpy(dpt_call(yf)), Y_np, atol=tol, rtol=tol)
205+
206+
207+
@pytest.mark.parametrize("dtype", _complex_fp_dtypes)
208+
def test_acosh_zero_nan(dtype):
209+
# check acosh(±0 + NaN j) = NaN ± π/2 j (Array API spec)
210+
q = get_queue_or_skip()
211+
skip_if_dtype_not_supported(dtype, q)
212+
213+
x = [complex(+0.0, np.nan), complex(-0.0, np.nan)]
214+
215+
xf = np.array(x, dtype=dtype)
216+
yf = dpt.asarray(xf, dtype=dtype, sycl_queue=q)
217+
218+
Y_dpt = dpt.asnumpy(dpt.acosh(yf))
219+
220+
assert np.isnan(Y_dpt.real).all()
221+
assert_allclose(np.abs(Y_dpt.imag), np.pi / 2, atol=1e-6, strict=False)

0 commit comments

Comments
 (0)