98 lines
3.7 KiB
Python
98 lines
3.7 KiB
Python
import pytest
|
|
from numpy.core._simd import targets
|
|
"""
|
|
This testing unit only for checking the sanity of common functionality,
|
|
therefore all we need is just to take one submodule that represents any
|
|
of enabled SIMD extensions to run the test on it and the second submodule
|
|
required to run only one check related to the possibility of mixing
|
|
the data types among each submodule.
|
|
"""
|
|
npyvs = [npyv_mod for npyv_mod in targets.values() if npyv_mod and npyv_mod.simd]
|
|
npyv, npyv2 = (npyvs + [None, None])[:2]
|
|
|
|
unsigned_sfx = ["u8", "u16", "u32", "u64"]
|
|
signed_sfx = ["s8", "s16", "s32", "s64"]
|
|
fp_sfx = ["f32"]
|
|
if npyv and npyv.simd_f64:
|
|
fp_sfx.append("f64")
|
|
|
|
int_sfx = unsigned_sfx + signed_sfx
|
|
all_sfx = unsigned_sfx + int_sfx
|
|
|
|
@pytest.mark.skipif(not npyv, reason="could not find any SIMD extension with NPYV support")
|
|
class Test_SIMD_MODULE:
|
|
|
|
@pytest.mark.parametrize('sfx', all_sfx)
|
|
def test_num_lanes(self, sfx):
|
|
nlanes = getattr(npyv, "nlanes_" + sfx)
|
|
vector = getattr(npyv, "setall_" + sfx)(1)
|
|
assert len(vector) == nlanes
|
|
|
|
@pytest.mark.parametrize('sfx', all_sfx)
|
|
def test_type_name(self, sfx):
|
|
vector = getattr(npyv, "setall_" + sfx)(1)
|
|
assert vector.__name__ == "npyv_" + sfx
|
|
|
|
def test_raises(self):
|
|
a, b = [npyv.setall_u32(1)]*2
|
|
for sfx in all_sfx:
|
|
vcb = lambda intrin: getattr(npyv, f"{intrin}_{sfx}")
|
|
pytest.raises(TypeError, vcb("add"), a)
|
|
pytest.raises(TypeError, vcb("add"), a, b, a)
|
|
pytest.raises(TypeError, vcb("setall"))
|
|
pytest.raises(TypeError, vcb("setall"), [1])
|
|
pytest.raises(TypeError, vcb("load"), 1)
|
|
pytest.raises(ValueError, vcb("load"), [1])
|
|
pytest.raises(ValueError, vcb("store"), [1], getattr(npyv, f"reinterpret_{sfx}_u32")(a))
|
|
|
|
@pytest.mark.skipif(not npyv2, reason=(
|
|
"could not find a second SIMD extension with NPYV support"
|
|
))
|
|
def test_nomix(self):
|
|
# mix among submodules isn't allowed
|
|
a = npyv.setall_u32(1)
|
|
a2 = npyv2.setall_u32(1)
|
|
pytest.raises(TypeError, npyv.add_u32, a2, a2)
|
|
pytest.raises(TypeError, npyv2.add_u32, a, a)
|
|
|
|
@pytest.mark.parametrize('sfx', unsigned_sfx)
|
|
def test_unsigned_overflow(self, sfx):
|
|
nlanes = getattr(npyv, "nlanes_" + sfx)
|
|
maxu = (1 << int(sfx[1:])) - 1
|
|
maxu_72 = (1 << 72) - 1
|
|
lane = getattr(npyv, "setall_" + sfx)(maxu_72)[0]
|
|
assert lane == maxu
|
|
lanes = getattr(npyv, "load_" + sfx)([maxu_72] * nlanes)
|
|
assert lanes == [maxu] * nlanes
|
|
lane = getattr(npyv, "setall_" + sfx)(-1)[0]
|
|
assert lane == maxu
|
|
lanes = getattr(npyv, "load_" + sfx)([-1] * nlanes)
|
|
assert lanes == [maxu] * nlanes
|
|
|
|
@pytest.mark.parametrize('sfx', signed_sfx)
|
|
def test_signed_overflow(self, sfx):
|
|
nlanes = getattr(npyv, "nlanes_" + sfx)
|
|
maxs_72 = (1 << 71) - 1
|
|
lane = getattr(npyv, "setall_" + sfx)(maxs_72)[0]
|
|
assert lane == -1
|
|
lanes = getattr(npyv, "load_" + sfx)([maxs_72] * nlanes)
|
|
assert lanes == [-1] * nlanes
|
|
mins_72 = -1 << 71
|
|
lane = getattr(npyv, "setall_" + sfx)(mins_72)[0]
|
|
assert lane == 0
|
|
lanes = getattr(npyv, "load_" + sfx)([mins_72] * nlanes)
|
|
assert lanes == [0] * nlanes
|
|
|
|
def test_truncate_f32(self):
|
|
f32 = npyv.setall_f32(0.1)[0]
|
|
assert f32 != 0.1
|
|
assert round(f32, 1) == 0.1
|
|
|
|
def test_compare(self):
|
|
data_range = range(0, npyv.nlanes_u32)
|
|
vdata = npyv.load_u32(data_range)
|
|
assert vdata == list(data_range)
|
|
assert vdata == tuple(data_range)
|
|
for i in data_range:
|
|
assert vdata[i] == data_range[i]
|