Skip to content

Commit

Permalink
add patch for numpy 1.26.4 that fixes RISC-V test failures
Browse files Browse the repository at this point in the history
  • Loading branch information
bedroge committed Jun 18, 2024
1 parent baa9b83 commit 63e7936
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ use_pip = True
# order is important!
exts_list = [
('numpy', '1.26.4', {
'patches': ['numpy-1.22.3_disable-broken-override-test.patch'],
'patches': [
'numpy-1.22.3_disable-broken-override-test.patch',
'numpy-1.26.4_fix-riscv64-test-failures.patch',
],
'checksums': [
{'numpy-1.26.4.tar.gz': '2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010'},
{'numpy-1.22.3_disable-broken-override-test.patch':
'9c589bb073b28b25ff45eb3c63c57966aa508dd8b318d0b885b6295271e4983c'},
{'numpy-1.26.4_fix-riscv64-test-failures.patch':
'81bd487dbca6da8285971a16a2c7b488718a051d3cd66450277bed6ff21741de'},
],
}),
('ply', '3.11', {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
From d9e88e32302b3842785a33d90cf22f8c1405cd05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bob=20Dr=C3=B6ge?= <b.e.droge@rug.nl>
Date: Tue, 18 Jun 2024 13:28:35 +0200
Subject: [PATCH 1/2] TST: Fix fp_noncontiguous and fpclass on riscv64

Modify fp_noncontiguous and fpclass so that they pass on riscv64.
The subtests that verify that the signs of negative NaNs are preserved
do not pass on riscv64 builds and are disabled. Many RISC-V
instructions that produce NaNs return a canonical NaN, as defined by
the RISC-V specification. The canonical NaNs are always positive. See
section 11.3 NaN Generation and Propagation of the RISC-V Unprivileged
ISA for more details.
---
numpy/core/tests/test_umath.py | 44 +++++++++++++++++++++++++++++-----
1 file changed, 38 insertions(+), 6 deletions(-)

diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 963e740d8dcb..8444893c80c3 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -1852,8 +1852,22 @@ def test_fpclass(self, stride):
assert_equal(np.isnan(arr_f64[::stride]), nan[::stride])
assert_equal(np.isinf(arr_f32[::stride]), inf[::stride])
assert_equal(np.isinf(arr_f64[::stride]), inf[::stride])
- assert_equal(np.signbit(arr_f32[::stride]), sign[::stride])
- assert_equal(np.signbit(arr_f64[::stride]), sign[::stride])
+ if platform.processor() == 'riscv64':
+ # On RISC-V, many operations that produce NaNs, such as converting
+ # a -NaN from f64 to f32, return a canonical NaN. The canonical
+ # NaNs are always positive. See section 11.3 NaN Generation and
+ # Propagation of the RISC-V Unprivileged ISA for more details.
+ # We disable the sign test on riscv64 for -np.nan as we
+ # cannot assume that its sign will be honoured in these tests.
+ arr_f64_rv = np.copy(arr_f64)
+ arr_f32_rv = np.copy(arr_f32)
+ arr_f64_rv[1] = -1.0
+ arr_f32_rv[1] = -1.0
+ assert_equal(np.signbit(arr_f32_rv[::stride]), sign[::stride])
+ assert_equal(np.signbit(arr_f64_rv[::stride]), sign[::stride])
+ else:
+ assert_equal(np.signbit(arr_f32[::stride]), sign[::stride])
+ assert_equal(np.signbit(arr_f64[::stride]), sign[::stride])
assert_equal(np.isfinite(arr_f32[::stride]), finite[::stride])
assert_equal(np.isfinite(arr_f64[::stride]), finite[::stride])

@@ -1874,23 +1888,37 @@ def test_fp_noncontiguous(self, dtype):
ncontig_in = data[1::3]
ncontig_out = out[1::3]
contig_in = np.array(ncontig_in)
+
+ if platform.processor() == 'riscv64':
+ # Disable the -np.nan signbit tests on riscv64. See comments in
+ # test_fpclass for more details.
+ data_rv = np.copy(data)
+ data_rv[1] = -1.0
+ ncontig_sign_in = data_rv[1::3]
+ contig_sign_in = np.array(ncontig_sign_in)
+ else:
+ ncontig_sign_in = ncontig_in
+ contig_sign_in = contig_in
+
assert_equal(ncontig_in.flags.c_contiguous, False)
assert_equal(ncontig_out.flags.c_contiguous, False)
assert_equal(contig_in.flags.c_contiguous, True)
+ assert_equal(ncontig_sign_in.flags.c_contiguous, False)
+ assert_equal(contig_sign_in.flags.c_contiguous, True)
# ncontig in, ncontig out
assert_equal(np.isnan(ncontig_in, out=ncontig_out), nan[1::3])
assert_equal(np.isinf(ncontig_in, out=ncontig_out), inf[1::3])
- assert_equal(np.signbit(ncontig_in, out=ncontig_out), sign[1::3])
+ assert_equal(np.signbit(ncontig_sign_in, out=ncontig_out), sign[1::3])
assert_equal(np.isfinite(ncontig_in, out=ncontig_out), finite[1::3])
# contig in, ncontig out
assert_equal(np.isnan(contig_in, out=ncontig_out), nan[1::3])
assert_equal(np.isinf(contig_in, out=ncontig_out), inf[1::3])
- assert_equal(np.signbit(contig_in, out=ncontig_out), sign[1::3])
+ assert_equal(np.signbit(contig_sign_in, out=ncontig_out), sign[1::3])
assert_equal(np.isfinite(contig_in, out=ncontig_out), finite[1::3])
# ncontig in, contig out
assert_equal(np.isnan(ncontig_in), nan[1::3])
assert_equal(np.isinf(ncontig_in), inf[1::3])
- assert_equal(np.signbit(ncontig_in), sign[1::3])
+ assert_equal(np.signbit(ncontig_sign_in), sign[1::3])
assert_equal(np.isfinite(ncontig_in), finite[1::3])
# contig in, contig out, nd stride
data_split = np.array(np.array_split(data, 2))
@@ -1900,7 +1928,11 @@ def test_fp_noncontiguous(self, dtype):
finite_split = np.array(np.array_split(finite, 2))
assert_equal(np.isnan(data_split), nan_split)
assert_equal(np.isinf(data_split), inf_split)
- assert_equal(np.signbit(data_split), sign_split)
+ if platform.processor() == 'riscv64':
+ data_split_rv = np.array(np.array_split(data_rv, 2))
+ assert_equal(np.signbit(data_split_rv), sign_split)
+ else:
+ assert_equal(np.signbit(data_split), sign_split)
assert_equal(np.isfinite(data_split), finite_split)

class TestLDExp:

From ccb1d4adc01b49c7e900e5f532dc6361eac1362a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bob=20Dr=C3=B6ge?= <b.e.droge@rug.nl>
Date: Tue, 18 Jun 2024 13:30:00 +0200
Subject: [PATCH 2/2] TST: Use platform.machine() for improved portability on
riscv64

Replace `platform.processor()` with `platform.machine()` considering the latter is more portable. More specifically, `platform.processor()` returns empty string on Arch Linux, and this PR fixes the corresponding test failure.
---
numpy/core/tests/test_numeric.py | 2 +-
numpy/core/tests/test_umath.py | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py
index e5edd3efce5a..ce5917a9b09f 100644
--- a/numpy/core/tests/test_numeric.py
+++ b/numpy/core/tests/test_numeric.py
@@ -483,7 +483,7 @@ def setup_method(self):
# Propagation of the RISC-V Unprivileged ISA for more details.
# We disable the float32 sign test on riscv64 for -np.nan as the sign
# of the NaN will be lost when it's converted to a float32.
- if platform.processor() != 'riscv64':
+ if platform.machine() != 'riscv64':
self.signf[3::6][self.ef[3::6]] = -np.nan
self.signd[3::6][self.ed[3::6]] = -np.nan
self.signf[4::6][self.ef[4::6]] = -0.
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 8444893c80c3..c5a3e2c81f83 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -1852,7 +1852,7 @@ def test_fpclass(self, stride):
assert_equal(np.isnan(arr_f64[::stride]), nan[::stride])
assert_equal(np.isinf(arr_f32[::stride]), inf[::stride])
assert_equal(np.isinf(arr_f64[::stride]), inf[::stride])
- if platform.processor() == 'riscv64':
+ if platform.machine() == 'riscv64':
# On RISC-V, many operations that produce NaNs, such as converting
# a -NaN from f64 to f32, return a canonical NaN. The canonical
# NaNs are always positive. See section 11.3 NaN Generation and
@@ -1889,7 +1889,7 @@ def test_fp_noncontiguous(self, dtype):
ncontig_out = out[1::3]
contig_in = np.array(ncontig_in)

- if platform.processor() == 'riscv64':
+ if platform.machine() == 'riscv64':
# Disable the -np.nan signbit tests on riscv64. See comments in
# test_fpclass for more details.
data_rv = np.copy(data)
@@ -1928,7 +1928,7 @@ def test_fp_noncontiguous(self, dtype):
finite_split = np.array(np.array_split(finite, 2))
assert_equal(np.isnan(data_split), nan_split)
assert_equal(np.isinf(data_split), inf_split)
- if platform.processor() == 'riscv64':
+ if platform.machine() == 'riscv64':
data_split_rv = np.array(np.array_split(data_rv, 2))
assert_equal(np.signbit(data_split_rv), sign_split)
else:

0 comments on commit 63e7936

Please sign in to comment.