Skip to content

Commit

Permalink
Merge pull request #390 from bashtage/test-cov-final
Browse files Browse the repository at this point in the history
TST: Add more corner case coverage and remove unreachable
  • Loading branch information
bashtage authored Oct 4, 2024
2 parents aeae819 + 8805fa5 commit abacda9
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 55 deletions.
1 change: 0 additions & 1 deletion randomgen/broadcasting.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ cdef int check_constraint(double val, object name, constraint_type cons) except
cdef int check_array_constraint(
np.ndarray val, object name, constraint_type cons
) except -1
cdef validate_output_shape(iter_shape, np.ndarray output)
cdef check_output(object out, object dtype, object size, bint require_c_array)

ctypedef double (*random_double_fill)(
Expand Down
21 changes: 0 additions & 21 deletions randomgen/broadcasting.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,6 @@ cdef int check_constraint(double val, object name, constraint_type cons) except

return 0

cdef validate_output_shape(iter_shape, np.ndarray output):
cdef np.npy_intp *dims
cdef np.npy_intp ndim, i
dims = np.PyArray_DIMS(output)
ndim = np.PyArray_NDIM(output)
output_shape = tuple((dims[i] for i in range(ndim)))
if iter_shape != output_shape:
raise ValueError(
f"Output size {output_shape} is not compatible with broadcast "
f"dimensions of inputs {iter_shape}."
)

cdef check_output(object out, object dtype, object size, bint require_c_array):
"""
Check user-supplied output array properties and shape
Expand Down Expand Up @@ -222,7 +210,6 @@ cdef object cont_broadcast_1(void *func, void *state, object size, object lock,
randoms_data = <double *>np.PyArray_DATA(randoms)
n = np.PyArray_SIZE(randoms)
it = np.PyArray_MultiIterNew2(randoms, a_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -260,7 +247,6 @@ cdef object cont_broadcast_2(void *func, void *state, object size, object lock,
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew3(randoms, a_arr, b_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -303,7 +289,6 @@ cdef object cont_broadcast_3(void *func, void *state, object size, object lock,
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew4(randoms, a_arr, b_arr, c_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -434,7 +419,6 @@ cdef object discrete_broadcast_d(void *func, void *state, object size, object lo
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew2(randoms, a_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -470,7 +454,6 @@ cdef object discrete_broadcast_dd(void *func, void *state, object size, object l
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew3(randoms, a_arr, b_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -507,7 +490,6 @@ cdef object discrete_broadcast_di(void *func, void *state, object size, object l
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew3(randoms, a_arr, b_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -548,7 +530,6 @@ cdef object discrete_broadcast_iii(void *func, void *state, object size, object
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew4(randoms, a_arr, b_arr, c_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -581,7 +562,6 @@ cdef object discrete_broadcast_i(void *func, void *state, object size, object lo
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew2(randoms, a_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down Expand Up @@ -761,7 +741,6 @@ cdef object cont_broadcast_1_f(void *func, bitgen_t *state, object size, object
randoms_data = <float *>np.PyArray_DATA(randoms)
n = np.PyArray_SIZE(randoms)
it = np.PyArray_MultiIterNew2(randoms, a_arr)
validate_output_shape(it.shape, randoms)

with lock, nogil:
for i in range(n):
Expand Down
2 changes: 0 additions & 2 deletions randomgen/common.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,6 @@ cpdef object object_to_int(object val, object bits, object name, int default_bit
if val.ndim != 1 or val.size == 0:
raise ValueError("{0} must be 1-d and non-empty".format(name))
power = 32 if val.dtype == np.uint32 else 64
if val.ndim == 0:
return int(val.item())
out = sum([int(val[i]) * 2**(power * i) for i in range(len(val))])
if out < 0 or (bits is not None and out >= (int(2)**bits)):
raise ValueError("{0} is out-of-range for "
Expand Down
8 changes: 1 addition & 7 deletions randomgen/generator.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@ from numpy.random.c_distributions cimport (
)

from randomgen cimport api
from randomgen.broadcasting cimport (
check_output,
double_fill,
float_fill,
validate_output_shape,
)
from randomgen.broadcasting cimport check_output, double_fill, float_fill
from randomgen.common cimport compute_complex
from randomgen.distributions cimport (
random_double_fill,
Expand Down Expand Up @@ -705,7 +700,6 @@ cdef class ExtendedGenerator:
n = np.PyArray_SIZE(randoms)

it = np.PyArray_MultiIterNew5(randoms, oloc, v_real, v_imag, rho)
validate_output_shape(it.shape, randoms)
with self.lock, nogil:
n2 = 2 * n # Avoid compiler noise for cast
for i in range(n2):
Expand Down
4 changes: 2 additions & 2 deletions randomgen/speck128.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ cdef class SPECK128(BitGenerator):
ValueError
If SSE 4.1 is not supported
"""
return RANDOMGEN_USE_SSE41
return bool(RANDOMGEN_USE_SSE41)

@use_sse41.setter
def use_sse41(self, value):
capable = speck_sse41_capable()
if value and not capable:
raise ValueError("CPU does not support SSE41")
speck_use_sse41(value)
speck_use_sse41(int(value))

@property
def state(self):
Expand Down
23 changes: 23 additions & 0 deletions randomgen/tests/test_broadcasting.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,30 @@ def test_constraint_violations():
legacy_poisson_lam_max = np.iinfo("l").max - np.sqrt(np.iinfo("l").max) * 10
with pytest.raises(ValueError):
generator.cont_3_alt_cons(1.5, poisson_lam_max + 10000, 1)
with pytest.raises(ValueError):
generator.cont_3_alt_cons(1.5, np.nan, 1)
with pytest.raises(ValueError):
generator.cont_3_alt_cons(1.5, -0.01, 1)
with pytest.raises(ValueError):
generator.cont_3_alt_cons(1.5, 1, legacy_poisson_lam_max + 10000)
with pytest.raises(ValueError):
generator.cont_3_alt_cons(1.5, 1, np.nan)
with pytest.raises(ValueError):
generator.cont_3_alt_cons(1.5, 1, -1)
with pytest.raises(ValueError):
generator.cont_3_alt_cons([1.5, 0.5], [1], [1])
with pytest.raises(ValueError):
generator.cont_3_alt_cons([1.5], [1, poisson_lam_max + 10000], [1])
with pytest.raises(ValueError):
generator.cont_3_alt_cons([1.5], [1, np.nan], [1])
with pytest.raises(ValueError):
generator.cont_3_alt_cons([1.5], [1, -1], [1])
with pytest.raises(ValueError):
generator.cont_3_alt_cons([1.5], [1], [1, legacy_poisson_lam_max + 10000])
with pytest.raises(ValueError):
generator.cont_3_alt_cons([1.5], [1], [1, -1])
with pytest.raises(ValueError):
generator.cont_3_alt_cons([1.5], [1], [1, np.nan])

with pytest.raises(ValueError):
generator.cont_1_float(-2.0)
Expand Down Expand Up @@ -350,3 +366,10 @@ def test_float_fill():
res = generator.cont_f_fill(size=out.shape, out=out)
assert_allclose(res, np.full_like(res, 3.141592))
assert res is out


def test_validate_output():
with pytest.raises(ValueError):
generator.cont_1(np.array([0.1, 0.2, 0.3]), out=np.empty((7, 5)))
with pytest.raises(ValueError):
generator.cont_1(np.array([0.1, 0.2, 0.3]), size=(7, 11))
10 changes: 8 additions & 2 deletions randomgen/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,14 @@ def test_object_to_int_errors():
"test",
allowed_sizes=(32, 64),
)

# res = object_to_int_shim(1, 32, "test", allowed_sizes=(32, 64))
with pytest.raises(ValueError):
object_to_int_shim(
[sum(2**i for i in range(63))],
128,
"test",
default_bits=32,
allowed_sizes=(32, 64),
)


def test_uncupported_mode():
Expand Down
41 changes: 26 additions & 15 deletions randomgen/tests/test_direct.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,6 @@ def test_str(self):

def test_generator(self):
bit_generator = self.setup_bitgenerator(self.data1["seed"])
if "generator" not in dir(bit_generator):
pytest.skip("generator attribute has been removed")
with pytest.raises(NotImplementedError):
bit_generator.generator

Expand Down Expand Up @@ -451,10 +449,7 @@ def test_uinteger_reset_jump(self):
new_bg = bg.jumped()
jumped = np.random.Generator(new_bg)
new_seed_seq = new_bg._get_seed_seq()
if seed_seq is None:
assert new_seed_seq is None
else:
assert_equal(seed_seq.entropy, new_seed_seq.entropy)
assert_equal(seed_seq.entropy, new_seed_seq.entropy)

if "has_uint32" in jumped.bit_generator.state:
assert jumped.bit_generator.state["has_uint32"] == 0
Expand All @@ -471,12 +466,9 @@ def test_jumped_seed_seq_clone(self):
seed_seq = bg._get_seed_seq()
new_bg = bg.jumped()
new_seed_seq = new_bg._get_seed_seq()
if seed_seq is None:
assert new_seed_seq is None
else:
assert_equal(seed_seq.entropy, new_seed_seq.entropy)
assert seed_seq.spawn_key == new_seed_seq.spawn_key
assert seed_seq.n_children_spawned == new_seed_seq.n_children_spawned
assert_equal(seed_seq.entropy, new_seed_seq.entropy)
assert seed_seq.spawn_key == new_seed_seq.spawn_key
assert seed_seq.n_children_spawned == new_seed_seq.n_children_spawned
assert not np.all(new_bg.random_raw(10) == bg.random_raw(10))

def test_uinteger_reset_advance(self):
Expand Down Expand Up @@ -867,9 +859,6 @@ def test_large_advance(self):
bg = self.setup_bitgenerator([0], inc=1)
state = bg.state["state"]
assert state["state"] == self.large_advance_initial
bg.advance(sum(2**i for i in range(96)))
state = bg.state["state"]
assert state["state"] == self.large_advance_final


class TestPhilox(Random123):
Expand Down Expand Up @@ -2163,3 +2152,25 @@ def test_bitgen_ctor():
assert isinstance(p.__bit_generator_ctor(b"LXM"), LXM)
with pytest.raises(ValueError):
p.__bit_generator_ctor("NewFangledBG")


def test_speck_sse41():
s = SPECK128(0)
if not s.use_sse41:
pytest.skip("Can only test if SSE41 is available")
assert isinstance(s.use_sse41, bool)
orig = s.use_sse41
s.use_sse41 = not orig
assert s.use_sse41 != orig
s.use_sse41 = orig


def test_pcg64_errors():
with pytest.raises(TypeError):
PCG64(0, variant=("dxsm-128",))
p_np = PCG64(0, numpy_seed=True)
with pytest.raises(ValueError):
p_np.seed(seed=0, inc=3)
p = PCG64(0)
with pytest.raises(TypeError):
p.seed(seed=0, inc=[3, 4])
5 changes: 0 additions & 5 deletions randomgen/tests/test_extended_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ def extended_gen():
return ExtendedGenerator(pcg)


@pytest.fixture(scope="function")
def extended_gen_legacy():
return ExtendedGenerator(MT19937())


_mt19937 = MT19937(SEED)
random = ExtendedGenerator(_mt19937)

Expand Down

0 comments on commit abacda9

Please sign in to comment.