From 72e5b1fb1af36b35201f7378caaa18c9e2f76c3e Mon Sep 17 00:00:00 2001 From: Python Infra CI Date: Mon, 19 Oct 2026 03:46:50 +0000 Subject: [PATCH 1/2] perf: hoist the `randint` dtype-bounds table out of the per-call hot pat --- mkl_random/mklrand.pyx | 43 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/mkl_random/mklrand.pyx b/mkl_random/mklrand.pyx index 7f55da6..ea04dae 100644 --- a/mkl_random/mklrand.pyx +++ b/mkl_random/mklrand.pyx @@ -1793,6 +1793,23 @@ def _brng_id_to_name(int brng_id): return brng_name +# Bounds for `_choose_randint_type`, keyed by dtype(...).name: the largest +# half open interval `[low, high)` representable by that dtype. Built once +# at import time rather than per call, since `randint` calls into this on +# every invocation, including the scalar fast path. +_randint_bounds = { + "bool": (0, 2), + "int8": (-2**7, 2**7), + "int16": (-2**15, 2**15), + "int32": (-2**31, 2**31), + "int64": (-2**63, 2**63), + "uint8": (0, 2**8), + "uint16": (0, 2**16), + "uint32": (0, 2**32), + "uint64": (0, 2**64), +} + + cdef class _MKLRandomState: cdef irk_state *internal_state cdef object lock @@ -2142,30 +2159,12 @@ cdef class _MKLRandomState: self.internal_state, irk_double_vec, size, self.lock ) - # Set up dictionary of integer types and relevant functions. - # - # The dictionary is keyed by dtype(...).name and the values - # are a tuple (low, high, function), where low and high are - # the bounds of the largest half open interval `[low, high)` - # and the function is the relevant function to call for - # that precision. - # - # The functions are all the same except for changed types in - # a few places. It would be easy to template them. + # Resolves dtype to its `_randint_bounds` entry and the matching + # `_rand_*`/`_rand_*_broadcast` methods below. The functions are all the + # same except for changed types in a few places. It would be easy to + # template them. def _choose_randint_type(self, dtype): - _randint_bounds = { - "bool": (0, 2), - "int8": (-2**7, 2**7), - "int16": (-2**15, 2**15), - "int32": (-2**31, 2**31), - "int64": (-2**63, 2**63), - "uint8": (0, 2**8), - "uint16": (0, 2**16), - "uint32": (0, 2**32), - "uint64": (0, 2**64), - } - key = np.dtype(dtype).name if key not in _randint_bounds: raise TypeError(f'Unsupported dtype "{key}" for randint') From 88c3bc51570f565e4796bda67832d2326eafd1b4 Mon Sep 17 00:00:00 2001 From: Vladislav Perevezentsev Date: Mon, 19 Oct 2026 06:53:08 -0700 Subject: [PATCH 2/2] Key randint bounds table by np.dtype --- mkl_random/mklrand.pyx | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/mkl_random/mklrand.pyx b/mkl_random/mklrand.pyx index 7bad619..e302da3 100644 --- a/mkl_random/mklrand.pyx +++ b/mkl_random/mklrand.pyx @@ -1794,20 +1794,19 @@ def _brng_id_to_name(int brng_id): return brng_name -# Bounds for `_choose_randint_type`, keyed by dtype(...).name: the largest -# half open interval `[low, high)` representable by that dtype. Built once -# at import time rather than per call, since `randint` calls into this on -# every invocation, including the scalar fast path. +# Largest half-open interval [low, high) per randint dtype. _randint_bounds = { - "bool": (0, 2), - "int8": (-2**7, 2**7), - "int16": (-2**15, 2**15), - "int32": (-2**31, 2**31), - "int64": (-2**63, 2**63), - "uint8": (0, 2**8), - "uint16": (0, 2**16), - "uint32": (0, 2**32), - "uint64": (0, 2**64), + np.dtype(name): (name, low, high) for name, low, high in ( + ("bool", 0, 2), + ("int8", -2**7, 2**7), + ("int16", -2**15, 2**15), + ("int32", -2**31, 2**31), + ("int64", -2**63, 2**63), + ("uint8", 0, 2**8), + ("uint16", 0, 2**16), + ("uint32", 0, 2**32), + ("uint64", 0, 2**64), + ) } @@ -2160,17 +2159,18 @@ cdef class _MKLRandomState: self.internal_state, irk_double_vec, size, self.lock ) - # Resolves dtype to its `_randint_bounds` entry and the matching - # `_rand_*`/`_rand_*_broadcast` methods below. The functions are all the - # same except for changed types in a few places. It would be easy to - # template them. + # Returns randint bounds and the matching `_rand_*`/`_rand_*_broadcast` + # methods for dtype. def _choose_randint_type(self, dtype): - key = np.dtype(dtype).name - if key not in _randint_bounds: - raise TypeError(f'Unsupported dtype "{key}" for randint') + _dtype = np.dtype(dtype) + try: + key, lowbnd, highbnd = _randint_bounds[_dtype] + except KeyError: + raise TypeError( + f'Unsupported dtype "{_dtype.name}" for randint' + ) from None - lowbnd, highbnd = _randint_bounds[key] return (lowbnd, highbnd, getattr(self, f"_rand_{key}"), getattr(self, f"_rand_{key}_broadcast"))