summaryrefslogtreecommitdiff
path: root/benchmarks
diff options
context:
space:
mode:
authorSayed Adel <seiko@imavr.com>2023-02-17 19:06:48 +0200
committerSayed Adel <seiko@imavr.com>2023-02-20 05:34:00 +0200
commit2aa7fde3ace38bd19469e76a445f320d5916962d (patch)
tree01f2ba8d5bc137bafd287beaaedc5d2184c440ec /benchmarks
parent52ac8524b98c028fa68c205488bf953ab2a8a074 (diff)
downloadnumpy-2aa7fde3ace38bd19469e76a445f320d5916962d.tar.gz
BENCH: Add new data generator
for fairness and to stabilize the benchmark
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/benchmarks/common.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py
index 0c40e85b0..587fab343 100644
--- a/benchmarks/benchmarks/common.py
+++ b/benchmarks/benchmarks/common.py
@@ -1,5 +1,7 @@
import numpy
import random
+import os
+import functools
# Various pre-crafted datasets/variables for testing
# !!! Must not be changed -- only appended !!!
@@ -110,5 +112,112 @@ def get_indexes_rand_():
return indexes_rand_
+CACHE_ROOT = os.path.dirname(__file__)
+CACHE_ROOT = os.path.abspath(
+ os.path.join(CACHE_ROOT, '..', 'env', 'numpy_benchdata')
+)
+
+
+@functools.cache
+def get_data(size, dtype, ip_num=0, zeros=False, finite=True, denormal=False):
+ """
+ Generates a cached random array that covers several scenarios that
+ may affect the benchmark for fairness and to stabilize the benchmark.
+
+ Parameters
+ ----------
+ size: int
+ Array length.
+
+ dtype: dtype or dtype specifier
+
+ ip_num: int
+ Input number, to avoid memory overload
+ and to provide unique data for each operand.
+
+ zeros: bool
+ Spreading zeros along with generated data.
+
+ finite: bool
+ Avoid spreading fp special cases nan/inf.
+
+ denormal:
+ Spreading subnormal numbers along with generated data.
+ """
+ np = numpy
+ dtype = np.dtype(dtype)
+ dname = dtype.name
+ cache_name = f'{dname}_{size}_{ip_num}_{int(zeros)}'
+ if dtype.kind in 'fc':
+ cache_name += f'{int(finite)}{int(denormal)}'
+ cache_name += '.bin'
+ cache_path = os.path.join(CACHE_ROOT, cache_name)
+ if os.path.exists(cache_path):
+ return np.fromfile(cache_path, dtype)
+
+ array = np.ones(size, dtype)
+ rands = []
+ if dtype.kind == 'i':
+ dinfo = np.iinfo(dtype)
+ scale = 8
+ if zeros:
+ scale += 1
+ lsize = size // scale
+ for low, high in (
+ (-0x80, -1),
+ (1, 0x7f),
+ (-0x8000, -1),
+ (1, 0x7fff),
+ (-0x80000000, -1),
+ (1, 0x7fffffff),
+ (-0x8000000000000000, -1),
+ (1, 0x7fffffffffffffff),
+ ):
+ rands += [np.random.randint(
+ max(low, dinfo.min),
+ min(high, dinfo.max),
+ lsize, dtype
+ )]
+ elif dtype.kind == 'u':
+ dinfo = np.iinfo(dtype)
+ scale = 4
+ if zeros:
+ scale += 1
+ lsize = size // scale
+ for high in (0xff, 0xffff, 0xffffffff, 0xffffffffffffffff):
+ rands += [np.random.randint(1, min(high, dinfo.max), lsize, dtype)]
+ elif dtype.kind in 'fc':
+ scale = 1
+ if zeros:
+ scale += 1
+ if not finite:
+ scale += 2
+ if denormal:
+ scale += 1
+ dinfo = np.finfo(dtype)
+ lsize = size // scale
+ rands = [np.random.rand(lsize).astype(dtype)]
+ if not finite:
+ rands += [
+ np.empty(lsize, dtype=dtype), np.empty(lsize, dtype=dtype)
+ ]
+ rands[1].fill(float('nan'))
+ rands[2].fill(float('inf'))
+ if denormal:
+ rands += [np.empty(lsize, dtype=dtype)]
+ rands[-1].fill(dinfo.smallest_subnormal)
+
+ if rands:
+ if zeros:
+ rands += [np.zeros(lsize, dtype)]
+ stride = len(rands)
+ for start, r in enumerate(rands):
+ array[start:len(r)*stride:stride] = r
+
+ if not os.path.exists(CACHE_ROOT):
+ os.mkdir(CACHE_ROOT)
+ array.tofile(cache_path)
+ return array
+
class Benchmark:
pass