Skip to content

Commit 33ccbfe

Browse files
bashtageSheppard, Kevin
authored andcommitted
CLN: Improve variable size definitions
Improve array initialization to improve performance Switch while to for loops to avoid function calls Improve variable type definitions
1 parent 489c615 commit 33ccbfe

File tree

1 file changed

+64
-37
lines changed

1 file changed

+64
-37
lines changed

randomstate/array_utilities.pxi

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ ctypedef int64_t (* random_int_2_i)(aug_state* state, int64_t a, int64_t b) nogi
1818

1919
ctypedef void (* random_double_fill)(aug_state* state, np.npy_intp count, double *out) nogil
2020

21-
cdef Py_ssize_t compute_numel(size):
22-
cdef Py_ssize_t i, n = 1
21+
cdef np.npy_intp compute_numel(size):
22+
cdef np.npy_intp i, n = 1
2323
if isinstance(size, tuple):
2424
for i in range(len(size)):
2525
n *= size[i]
@@ -153,8 +153,8 @@ cdef object cont_broadcast_2(aug_state* state, void* func, object size, object l
153153
else:
154154
it = np.PyArray_MultiIterNew2(a_arr, b_arr)
155155
randoms = <np.ndarray>np.empty(it.shape, np.double)
156-
#randoms = np.PyArray_SimpleNew(it.nd, np.PyArray_DIMS(it), np.NPY_DOUBLE)
157-
# TODO: These are needed when using a for loop
156+
# randoms = np.PyArray_SimpleNew(it.nd, np.PyArray_DIMS(it), np.NPY_DOUBLE)
157+
158158

159159
randoms_data = <double *>np.PyArray_DATA(randoms)
160160
n = np.PyArray_SIZE(randoms)
@@ -175,8 +175,10 @@ cdef object cont_broadcast_3(aug_state* state, void* func, object size, object l
175175
object b, object b_name, constraint_type b_constraint,
176176
object c, object c_name, constraint_type c_constraint):
177177
cdef np.ndarray a_arr, b_arr, c_arr, randoms
178+
cdef double *randoms_data
178179
cdef np.broadcast it
179180
cdef random_double_3 f = (<random_double_3>func)
181+
cdef np.npy_intp i, n
180182

181183
a_arr = <np.ndarray>np.PyArray_FROM_OTF(a, np.NPY_DOUBLE, np.NPY_ALIGNED)
182184
if a_constraint != CONS_NONE:
@@ -191,20 +193,22 @@ cdef object cont_broadcast_3(aug_state* state, void* func, object size, object l
191193
check_array_constraint(c_arr, c_name, c_constraint)
192194

193195
if size is not None:
194-
randoms = np.empty(size, np.double)
196+
randoms = <np.ndarray>np.empty(size, np.double)
195197
else:
196198
it = np.PyArray_MultiIterNew3(a_arr, b_arr, c_arr)
197199
#randoms = np.PyArray_SimpleNew(it.nd, np.PyArray_DIMS(it), np.NPY_DOUBLE)
198-
randoms = np.empty(it.shape, np.double)
200+
randoms = <np.ndarray>np.empty(it.shape, np.double)
199201

200-
it = it = np.PyArray_MultiIterNew4(randoms, a_arr, b_arr, c_arr)
201-
# np.broadcast(randoms, a_arr, b_arr, c_arr)
202+
randoms_data = <double *>np.PyArray_DATA(randoms)
203+
n = np.PyArray_SIZE(randoms)
204+
205+
it = np.PyArray_MultiIterNew4(randoms, a_arr, b_arr, c_arr)
202206
with lock, nogil:
203-
while np.PyArray_MultiIter_NOTDONE(it):
207+
for i in range(n):
204208
a_val = (<double*>np.PyArray_MultiIter_DATA(it, 1))[0]
205209
b_val = (<double*>np.PyArray_MultiIter_DATA(it, 2))[0]
206210
c_val = (<double*>np.PyArray_MultiIter_DATA(it, 3))[0]
207-
(<double*>np.PyArray_MultiIter_DATA(it, 0))[0] = f(state, a_val, b_val, c_val)
211+
randoms_data[i] = f(state, a_val, b_val, c_val)
208212

209213
np.PyArray_MultiIter_NEXT(it)
210214

@@ -263,8 +267,9 @@ cdef object cont(aug_state* state, void* func, object size, object lock, int nar
263267
elif narg == 3:
264268
return (<random_double_3>func)(state, _a, _b, _c)
265269

266-
cdef Py_ssize_t i, n = compute_numel(size)
267-
cdef double [::1] randoms = np.empty(n, np.double)
270+
cdef np.npy_intp i, n = compute_numel(size)
271+
cdef np.ndarray randoms = np.empty(n, np.double)
272+
cdef double *randoms_data = <double *>np.PyArray_DATA(randoms)
268273
cdef random_double_0 f0;
269274
cdef random_double_1 f1;
270275
cdef random_double_2 f2;
@@ -274,28 +279,30 @@ cdef object cont(aug_state* state, void* func, object size, object lock, int nar
274279
if narg == 0:
275280
f0 = (<random_double_0>func)
276281
for i in range(n):
277-
randoms[i] = f0(state)
282+
randoms_data[i] = f0(state)
278283
elif narg == 1:
279284
f1 = (<random_double_1>func)
280285
for i in range(n):
281-
randoms[i] = f1(state, _a)
286+
randoms_data[i] = f1(state, _a)
282287
elif narg == 2:
283288
f2 = (<random_double_2>func)
284289
for i in range(n):
285-
randoms[i] = f2(state, _a, _b)
290+
randoms_data[i] = f2(state, _a, _b)
286291
elif narg == 3:
287292
f3 = (<random_double_3>func)
288293
for i in range(n):
289-
randoms[i] = f3(state, _a, _b, _c)
294+
randoms_data[i] = f3(state, _a, _b, _c)
290295

291296
return np.asarray(randoms).reshape(size)
292297

293298
cdef object discrete_broadcast_d(aug_state* state, void* func, object size, object lock,
294299
object a, object a_name, constraint_type a_constraint):
295300

296301
cdef np.ndarray a_arr, randoms
302+
cdef long *randoms_data
297303
cdef np.broadcast it
298304
cdef random_uint_d f = (<random_uint_d>func)
305+
cdef np.npy_intp i, n
299306

300307
a_arr = <np.ndarray>np.PyArray_FROM_OTF(a, np.NPY_DOUBLE, np.NPY_ALIGNED)
301308
if a_constraint != CONS_NONE:
@@ -307,11 +314,14 @@ cdef object discrete_broadcast_d(aug_state* state, void* func, object size, obje
307314
#randoms = np.empty(np.shape(a_arr), np.double)
308315
randoms = np.PyArray_SimpleNew(np.PyArray_NDIM(a_arr), np.PyArray_DIMS(a_arr), np.NPY_LONG)
309316

317+
randoms_data = <long *>np.PyArray_DATA(randoms)
318+
n = np.PyArray_SIZE(randoms)
319+
310320
it = np.broadcast(randoms, a_arr)
311321
with lock, nogil:
312-
while np.PyArray_MultiIter_NOTDONE(it):
322+
for i in range(n):
313323
a_val = (<double*>np.PyArray_MultiIter_DATA(it, 1))[0]
314-
(<long*>np.PyArray_MultiIter_DATA(it, 0))[0] = f(state, a_val)
324+
randoms_data[i] = f(state, a_val)
315325

316326
np.PyArray_MultiIter_NEXT(it)
317327

@@ -321,8 +331,10 @@ cdef object discrete_broadcast_dd(aug_state* state, void* func, object size, obj
321331
object a, object a_name, constraint_type a_constraint,
322332
object b, object b_name, constraint_type b_constraint):
323333
cdef np.ndarray a_arr, b_arr, randoms
334+
cdef long *randoms_data
324335
cdef np.broadcast it
325336
cdef random_uint_dd f = (<random_uint_dd>func)
337+
cdef np.npy_intp i, n
326338

327339
a_arr = <np.ndarray>np.PyArray_FROM_OTF(a, np.NPY_DOUBLE, np.NPY_ALIGNED)
328340
if a_constraint != CONS_NONE:
@@ -332,19 +344,21 @@ cdef object discrete_broadcast_dd(aug_state* state, void* func, object size, obj
332344
check_array_constraint(b_arr, b_name, b_constraint)
333345

334346
if size is not None:
335-
randoms = np.empty(size, np.int)
347+
randoms = <np.ndarray>np.empty(size, np.int)
336348
else:
337349
it = np.PyArray_MultiIterNew2(a_arr, b_arr)
338-
randoms = np.empty(it.shape, np.int)
350+
randoms = <np.ndarray>np.empty(it.shape, np.int)
339351
# randoms = np.PyArray_SimpleNew(it.nd, np.PyArray_DIMS(it), np.NPY_LONG)
340352

353+
randoms_data = <long *>np.PyArray_DATA(randoms)
354+
n = np.PyArray_SIZE(randoms)
355+
341356
it = np.PyArray_MultiIterNew3(randoms, a_arr, b_arr)
342357
with lock, nogil:
343-
while np.PyArray_MultiIter_NOTDONE(it):
358+
for i in range(n):
344359
a_val = (<double*>np.PyArray_MultiIter_DATA(it, 1))[0]
345360
b_val = (<double*>np.PyArray_MultiIter_DATA(it, 2))[0]
346-
347-
(<long*>np.PyArray_MultiIter_DATA(it, 0))[0] = f(state, a_val, b_val)
361+
randoms_data[i] = f(state, a_val, b_val)
348362

349363
np.PyArray_MultiIter_NEXT(it)
350364

@@ -354,8 +368,11 @@ cdef object discrete_broadcast_di(aug_state* state, void* func, object size, obj
354368
object a, object a_name, constraint_type a_constraint,
355369
object b, object b_name, constraint_type b_constraint):
356370
cdef np.ndarray a_arr, b_arr, randoms
371+
cdef long *randoms_data
357372
cdef np.broadcast it
358373
cdef random_uint_di f = (<random_uint_di>func)
374+
cdef np.npy_intp i, n
375+
359376

360377
a_arr = <np.ndarray>np.PyArray_FROM_OTF(a, np.NPY_DOUBLE, np.NPY_ALIGNED)
361378
if a_constraint != CONS_NONE:
@@ -366,15 +383,17 @@ cdef object discrete_broadcast_di(aug_state* state, void* func, object size, obj
366383
check_array_constraint(b_arr, b_name, b_constraint)
367384

368385
if size is not None:
369-
randoms = np.empty(size, np.int)
386+
randoms = <np.ndarray>np.empty(size, np.int)
370387
else:
371388
it = np.PyArray_MultiIterNew2(a_arr, b_arr)
372-
randoms = np.empty(it.shape, np.int)
373-
#randoms = np.PyArray_SimpleNew(it.nd, np.PyArray_DIMS(it), np.NPY_LONG)
389+
randoms = <np.ndarray>np.empty(it.shape, np.int)
390+
391+
randoms_data = <long *>np.PyArray_DATA(randoms)
392+
n = np.PyArray_SIZE(randoms)
374393

375394
it = np.PyArray_MultiIterNew3(randoms, a_arr, b_arr)
376395
with lock, nogil:
377-
while np.PyArray_MultiIter_NOTDONE(it):
396+
for i in range(n):
378397
a_val = (<double*>np.PyArray_MultiIter_DATA(it, 1))[0]
379398
b_val = (<long*>np.PyArray_MultiIter_DATA(it, 2))[0]
380399
(<long*>np.PyArray_MultiIter_DATA(it, 0))[0] = f(state, a_val, b_val)
@@ -388,8 +407,10 @@ cdef object discrete_broadcast_iii(aug_state* state, void* func, object size, ob
388407
object b, object b_name, constraint_type b_constraint,
389408
object c, object c_name, constraint_type c_constraint):
390409
cdef np.ndarray a_arr, b_arr, c_arr, randoms
410+
cdef long *randoms_data
391411
cdef np.broadcast it
392412
cdef random_uint_iii f = (<random_uint_iii>func)
413+
cdef np.npy_intp i, n
393414

394415
a_arr = <np.ndarray>np.PyArray_FROM_OTF(a, np.NPY_LONG, np.NPY_ALIGNED)
395416
if a_constraint != CONS_NONE:
@@ -404,19 +425,21 @@ cdef object discrete_broadcast_iii(aug_state* state, void* func, object size, ob
404425
check_array_constraint(c_arr, c_name, c_constraint)
405426

406427
if size is not None:
407-
randoms = np.empty(size, np.int)
428+
randoms = <np.ndarray>np.empty(size, np.int)
408429
else:
409430
it = np.PyArray_MultiIterNew3(a_arr, b_arr, c_arr)
410-
randoms = np.empty(it.shape, np.int)
411-
#randoms = np.PyArray_SimpleNew(it.nd, np.PyArray_DIMS(it), np.NPY_LONG)
431+
randoms = <np.ndarray>np.empty(it.shape, np.int)
432+
433+
randoms_data = <long *>np.PyArray_DATA(randoms)
434+
n = np.PyArray_SIZE(randoms)
412435

413436
it = np.PyArray_MultiIterNew4(randoms, a_arr, b_arr, c_arr)
414437
with lock, nogil:
415-
while np.PyArray_MultiIter_NOTDONE(it):
438+
for i in range(n):
416439
a_val = (<long*>np.PyArray_MultiIter_DATA(it, 1))[0]
417440
b_val = (<long*>np.PyArray_MultiIter_DATA(it, 2))[0]
418441
c_val = (<long*>np.PyArray_MultiIter_DATA(it, 3))[0]
419-
(<long*>np.PyArray_MultiIter_DATA(it, 0))[0] = f(state, a_val, b_val, c_val)
442+
randoms_data[i] = f(state, a_val, b_val, c_val)
420443

421444
np.PyArray_MultiIter_NEXT(it)
422445

@@ -425,24 +448,28 @@ cdef object discrete_broadcast_iii(aug_state* state, void* func, object size, ob
425448
cdef object discrete_broadcast_i(aug_state* state, void* func, object size, object lock,
426449
object a, object a_name, constraint_type a_constraint):
427450
cdef np.ndarray a_arr, randoms
451+
cdef long *randoms_data
428452
cdef np.broadcast it
429453
cdef random_uint_i f = (<random_uint_i>func)
454+
cdef np.npy_intp i, n
430455

431456
a_arr = <np.ndarray>np.PyArray_FROM_OTF(a, np.NPY_LONG, np.NPY_ALIGNED)
432457
if a_constraint != CONS_NONE:
433458
check_array_constraint(a_arr, a_name, a_constraint)
434459

435460
if size is not None:
436-
randoms = np.empty(size, np.int)
461+
randoms = <np.ndarray>np.empty(size, np.int)
437462
else:
438-
#randoms = np.empty(np.shape(a_arr), np.double)
439463
randoms = np.PyArray_SimpleNew(np.PyArray_NDIM(a_arr), np.PyArray_DIMS(a_arr), np.NPY_LONG)
440464

465+
randoms_data = <long *>np.PyArray_DATA(randoms)
466+
n = np.PyArray_SIZE(randoms)
467+
441468
it = np.broadcast(randoms, a_arr)
442469
with lock, nogil:
443-
while np.PyArray_MultiIter_NOTDONE(it):
470+
for i in range(n):
444471
a_val = (<long*>np.PyArray_MultiIter_DATA(it, 1))[0]
445-
(<long*>np.PyArray_MultiIter_DATA(it, 0))[0] = f(state, a_val)
472+
randoms_data[i] = f(state, a_val)
446473

447474
np.PyArray_MultiIter_NEXT(it)
448475

@@ -540,7 +567,7 @@ cdef object disc(aug_state* state, void* func, object size, object lock,
540567
else:
541568
return (<random_uint_iii>func)(state, _ia, _ib, _ic)
542569

543-
cdef Py_ssize_t i, n = compute_numel(size)
570+
cdef np.npy_intp i, n = compute_numel(size)
544571
cdef np.int_t [::1] randoms = np.empty(n, np.int)
545572
cdef random_uint_0 f0;
546573
cdef random_uint_d fd;

0 commit comments

Comments
 (0)