Skip to content

Commit 6d397d8

Browse files
committed
REF: Add aray fillers for multiple data types
Use template system to generate array fillers for doubles and floats Add array filler that fills 32-bit array using 64-bit RNGs
1 parent 805c3ef commit 6d397d8

File tree

2 files changed

+66
-41
lines changed

2 files changed

+66
-41
lines changed

randomstate/array_fillers.pxi.in

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
ctypedef void (* random_float_fill)(aug_state* state, np.npy_intp count, float *out) nogil
2+
ctypedef void (* random_double_fill)(aug_state* state, np.npy_intp count, double *out) nogil
3+
4+
{{
5+
py:
6+
ctypes = (('float64', 'double'),
7+
('float32', 'float'))
8+
}}
9+
{{for nptype, ctype in ctypes}}
10+
11+
12+
cdef object {{ctype}}_fill(aug_state* state, void *func, object size, object lock):
13+
cdef random_{{ctype}}_fill f = <random_{{ctype}}_fill>func
14+
cdef {{ctype}} out
15+
cdef {{ctype}} *out_array_data
16+
cdef np.ndarray out_array
17+
cdef np.npy_intp n
18+
19+
if size is None:
20+
with lock:
21+
f(state, 1, &out)
22+
return out
23+
else:
24+
out_array = <np.ndarray>np.empty(size, np.{{nptype}})
25+
n = np.PyArray_SIZE(out_array)
26+
out_array_data = <{{ctype}} *>np.PyArray_DATA(out_array)
27+
with lock, nogil:
28+
f(state, n, out_array_data)
29+
return out_array
30+
31+
{{endfor}}
32+
33+
34+
cdef object float_fill_from_double(aug_state* state, void *func, object size, object lock):
35+
cdef random_double_fill f = <random_double_fill>func
36+
cdef double out
37+
cdef double* buffer
38+
cdef float *out_array_data
39+
cdef np.ndarray out_array
40+
cdef np.npy_intp i, n, buffer_size, remaining, total, fetch
41+
42+
if size is None:
43+
with lock:
44+
f(state, 1, &out)
45+
return <float>out
46+
else:
47+
out_array = <np.ndarray>np.empty(size, np.float32)
48+
n = np.PyArray_SIZE(out_array)
49+
buffer_size = 1000 if n > 1000 else n
50+
total = 0
51+
remaining = n
52+
buffer = <double *> malloc(buffer_size * sizeof(double))
53+
54+
out_array_data = <float *>np.PyArray_DATA(out_array)
55+
while remaining > 0:
56+
fetch = 1000 if remaining > 1000 else remaining
57+
with lock, nogil:
58+
f(state, fetch, buffer)
59+
for i in range(fetch):
60+
out_array_data[i + total] = <float> buffer[i]
61+
total += fetch
62+
remaining -= fetch
63+
64+
free(buffer)
65+
66+
return out_array

randomstate/array_utilities.pxi

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ ctypedef uint32_t (* random_uint_1_i_32)(aug_state* state, uint32_t a) nogil
1616
ctypedef int32_t (* random_int_2_i_32)(aug_state* state, int32_t a, int32_t b) nogil
1717
ctypedef int64_t (* random_int_2_i)(aug_state* state, int64_t a, int64_t b) nogil
1818

19-
ctypedef void (* random_float_fill)(aug_state* state, np.npy_intp count, float *out) nogil
20-
ctypedef void (* random_double_fill)(aug_state* state, np.npy_intp count, double *out) nogil
21-
22-
2319
cdef np.npy_intp compute_numel(size):
2420
cdef np.npy_intp i, n = 1
2521
if isinstance(size, tuple):
@@ -600,40 +596,3 @@ cdef object disc(aug_state* state, void* func, object size, object lock,
600596
return np.asarray(randoms).reshape(size)
601597

602598

603-
cdef object double_fill(aug_state* state, void *func, object size, object lock):
604-
cdef random_double_fill f = <random_double_fill>func
605-
cdef double out
606-
cdef double *out_array_data
607-
cdef np.ndarray out_array
608-
cdef np.npy_intp n
609-
610-
if size is None:
611-
with lock:
612-
f(state, 1, &out)
613-
return out
614-
else:
615-
out_array = <np.ndarray>np.empty(size, np.float64)
616-
n = np.PyArray_SIZE(out_array)
617-
out_array_data = <double *>np.PyArray_DATA(out_array)
618-
with lock, nogil:
619-
f(state, n, out_array_data)
620-
return out_array
621-
622-
cdef object float_fill(aug_state* state, void *func, object size, object lock):
623-
cdef random_float_fill f = <random_float_fill>func
624-
cdef float out
625-
cdef float *out_array_data
626-
cdef np.ndarray out_array
627-
cdef np.npy_intp n
628-
629-
if size is None:
630-
with lock:
631-
f(state, 1, &out)
632-
return out
633-
else:
634-
out_array = <np.ndarray>np.empty(size, np.float32)
635-
n = np.PyArray_SIZE(out_array)
636-
out_array_data = <float *>np.PyArray_DATA(out_array)
637-
with lock, nogil:
638-
f(state, n, out_array_data)
639-
return out_array

0 commit comments

Comments
 (0)