diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index af35efd..4831132 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -1,4 +1,5 @@ name: Build mkl_random documentation + on: pull_request: push: @@ -34,13 +35,13 @@ jobs: if: ${{ !github.event.pull_request || github.event.action != 'closed' }} uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: "3.12" architecture: x64 - name: Install sphinx dependencies if: ${{ !github.event.pull_request || github.event.action != 'closed' }} shell: bash -l {0} run: | - pip install numpy cython setuptools scikit-build cmake sphinx sphinx_rtd_theme furo pydot graphviz sphinxcontrib-programoutput sphinxcontrib-googleanalytics sphinx_design + pip install numpy cython setuptools">=77" scikit-build cmake sphinx sphinx_rtd_theme furo pydot graphviz sphinxcontrib-programoutput sphinxcontrib-googleanalytics sphinx_design - name: Checkout repo uses: actions/checkout@v4.1.1 with: @@ -52,7 +53,7 @@ jobs: run: | # Ensure that SYCL libraries are on LD_LIBRARY_PATH source /opt/intel/oneapi/setvars.sh - python setup.py develop + pip install --no-deps --no-build-isolation -e . --verbose python -c "import mkl_random; print(mkl_random.__version__)" || exit 1 sphinx-build -M html docs/source docs/build mkdir -p ~/rendered_docs diff --git a/.github/workflows/build-with-clang.yml b/.github/workflows/build-with-clang.yml index 3bde36b..af79694 100644 --- a/.github/workflows/build-with-clang.yml +++ b/.github/workflows/build-with-clang.yml @@ -13,8 +13,7 @@ jobs: strategy: matrix: python: ["3.9", "3.10", "3.11", "3.12"] - numpy_build_version: ["numpy'<2'", "numpy'>=2'"] - + numpy_version: ["numpy'<2'", "numpy'>=2'"] env: ONEAPI_ROOT: /opt/intel/oneapi @@ -55,8 +54,8 @@ jobs: - name: Install mkl_random dependencies run: | - pip install cython setuptools pytest pytest-cov - pip install ${{ matrix.numpy_build_version }} + pip install cython setuptools">=77" + pip install ${{ matrix.numpy_version }} - name: List oneAPI folder content run: ls ${{ env.ONEAPI_ROOT }}/compiler @@ -68,11 +67,10 @@ jobs: export CC=$CMPLR_ROOT/bin/icx export CXX=$CMPLR_ROOT/bin/icpx export CFLAGS="${CFLAGS} -fno-fast-math -O2" - python setup.py develop + pip install -e . --no-build-isolation --no-deps --verbose - name: Run mkl_random tests run: | source ${{ env.ONEAPI_ROOT }}/setvars.sh - # Test with NumPy<2 for now - pip install numpy"<2" + pip install pytest pytest -s -v --pyargs mkl_random diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 364ac5f..33c8ce5 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -1,6 +1,9 @@ name: Conda package using conda-forge -on: push +on: + pull_request: + push: + branches: [master] permissions: read-all @@ -44,7 +47,7 @@ jobs: - name: Build conda package run: | CHANNELS="-c conda-forge --override-channels" - VERSIONS="--python ${{ matrix.python }} --numpy 2" + VERSIONS="--python ${{ matrix.python }} --numpy 2.0" TEST="--no-test" conda build \ @@ -56,7 +59,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - path: /usr/share/miniconda/conda-bld/linux-64/${{ env.PACKAGE_NAME }}-*.tar.bz2 + path: /usr/share/miniconda/conda-bld/linux-64/${{ env.PACKAGE_NAME }}-*.conda build_windows: runs-on: windows-2019 @@ -72,6 +75,7 @@ jobs: fetch-depth: 0 - uses: conda-incubator/setup-miniconda@v3 with: + conda-remove-defaults: true auto-activate-base: true activate-environment: "" @@ -89,12 +93,12 @@ jobs: - name: Install conda-build run: conda install conda-build - name: Build conda package - run: conda build --no-test --python ${{ matrix.python }} --numpy 2 -c conda-forge --override-channels conda-recipe-cf + run: conda build --no-test --python ${{ matrix.python }} --numpy 2.0 -c conda-forge --override-channels conda-recipe-cf - name: Upload artifact uses: actions/upload-artifact@v4 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - path: ${{ env.conda-bld }}${{ env.PACKAGE_NAME }}-*.tar.bz2 + path: ${{ env.conda-bld }}${{ env.PACKAGE_NAME }}-*.conda test_linux: needs: build_linux @@ -123,7 +127,7 @@ jobs: run: | mkdir -p $GITHUB_WORKSPACE/channel/linux-64 conda index $GITHUB_WORKSPACE/channel || exit 1 - mv ${PACKAGE_NAME}-*.tar.bz2 $GITHUB_WORKSPACE/channel/linux-64 || exit 1 + mv ${PACKAGE_NAME}-*.conda $GITHUB_WORKSPACE/channel/linux-64 || exit 1 conda index $GITHUB_WORKSPACE/channel || exit 1 # Test channel conda search $PACKAGE_NAME -c $GITHUB_WORKSPACE/channel --override-channels --info --json > $GITHUB_WORKSPACE/ver.json @@ -185,6 +189,7 @@ jobs: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - uses: conda-incubator/setup-miniconda@v3 with: + conda-remove-defaults: true auto-activate-base: true activate-environment: "" - name: Install conda-build @@ -193,7 +198,7 @@ jobs: - name: Create conda channel run: | mkdir ${{ env.GITHUB_WORKSPACE }}\channel\win-64 - move ${{ env.PACKAGE_NAME }}-*.tar.bz2 ${{ env.GITHUB_WORKSPACE }}\channel\win-64 + move ${{ env.PACKAGE_NAME }}-*.conda ${{ env.GITHUB_WORKSPACE }}\channel\win-64 conda index ${{ env.GITHUB_WORKSPACE }}/channel # Test channel conda search ${{ env.PACKAGE_NAME }} -c ${{ env.GITHUB_WORKSPACE }}/channel --override-channels --info --json > ${{ env.GITHUB_WORKSPACE }}\ver.json diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 11f119b..355c629 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -1,6 +1,9 @@ name: Conda package -on: push +on: + pull_request: + push: + branches: [master] permissions: read-all @@ -16,7 +19,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: ["3.9", "3.10"] + python: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 with: @@ -56,14 +59,14 @@ jobs: uses: actions/upload-artifact@v4 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - path: /usr/share/miniconda/conda-bld/linux-64/${{ env.PACKAGE_NAME }}-*.tar.bz2 + path: /usr/share/miniconda/conda-bld/linux-64/${{ env.PACKAGE_NAME }}-*.conda build_windows: runs-on: windows-2019 strategy: matrix: - python: ['3.9', '3.10'] + python: ["3.9", "3.10", "3.11", "3.12"] env: conda-bld: C:\Miniconda\conda-bld\win-64\ steps: @@ -72,6 +75,7 @@ jobs: fetch-depth: 0 - uses: conda-incubator/setup-miniconda@v3 with: + conda-remove-defaults: true auto-activate-base: true activate-environment: "" @@ -94,7 +98,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - path: ${{ env.conda-bld }}${{ env.PACKAGE_NAME }}-*.tar.bz2 + path: ${{ env.conda-bld }}${{ env.PACKAGE_NAME }}-*.conda test_linux: needs: build_linux @@ -102,7 +106,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10'] + python: ["3.9", "3.10", "3.11", "3.12"] numpy: ['1.26*'] experimental: [false] runner: [ubuntu-latest] @@ -123,7 +127,7 @@ jobs: run: | mkdir -p $GITHUB_WORKSPACE/channel/linux-64 conda index $GITHUB_WORKSPACE/channel || exit 1 - mv ${PACKAGE_NAME}-*.tar.bz2 $GITHUB_WORKSPACE/channel/linux-64 || exit 1 + mv ${PACKAGE_NAME}-*.conda $GITHUB_WORKSPACE/channel/linux-64 || exit 1 conda index $GITHUB_WORKSPACE/channel || exit 1 # Test channel conda search $PACKAGE_NAME -c $GITHUB_WORKSPACE/channel --override-channels --info --json > $GITHUB_WORKSPACE/ver.json @@ -170,7 +174,7 @@ jobs: strategy: matrix: - python: ['3.9', '3.10'] + python: ["3.9", "3.10", "3.11", "3.12"] numpy: ['1.26*'] experimental: [false] runner: [windows-2019] @@ -185,6 +189,7 @@ jobs: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - uses: conda-incubator/setup-miniconda@v3 with: + conda-remove-defaults: true auto-activate-base: true activate-environment: "" - name: Install conda-build @@ -193,7 +198,7 @@ jobs: - name: Create conda channel run: | mkdir ${{ env.GITHUB_WORKSPACE }}\channel\win-64 - move ${{ env.PACKAGE_NAME }}-*.tar.bz2 ${{ env.GITHUB_WORKSPACE }}\channel\win-64 + move ${{ env.PACKAGE_NAME }}-*.conda ${{ env.GITHUB_WORKSPACE }}\channel\win-64 conda index ${{ env.GITHUB_WORKSPACE }}/channel # Test channel conda search ${{ env.PACKAGE_NAME }} -c ${{ env.GITHUB_WORKSPACE }}/channel --override-channels --info --json > ${{ env.GITHUB_WORKSPACE }}\ver.json @@ -220,6 +225,9 @@ jobs: restore-keys: | ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + + # add intel-openmp as an explicit dependency + # to avoid it being missed when package version is specified exactly - name: Install mkl_random shell: cmd run: | @@ -229,7 +237,8 @@ jobs: FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( SET PACKAGE_VERSION=%%F ) - conda create -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% pytest python=${{ matrix.python }} numpy=${{ matrix.numpy }} -c ${{ env.GITHUB_WORKSPACE }}/channel ${{ env.CHANNELS }} + SET "WORKAROUND_DEPENDENCIES=intel-openmp" + conda create -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %WORKAROUND_DEPENDENCIES% pytest python=${{ matrix.python }} numpy=${{ matrix.numpy }} -c ${{ env.GITHUB_WORKSPACE }}/channel ${{ env.CHANNELS }} # Test installed packages conda list - name: Run tests diff --git a/README.md b/README.md index 52b4ef5..82acffc 100644 --- a/README.md +++ b/README.md @@ -65,3 +65,10 @@ The list of supported by `mkl_random.RandomState` constructor `brng` keywords is * 'PHILOX4X32X10' * 'NONDETERM' * 'ARS5' + +--- + +To build `mkl_random` from sources on Linux: + - install a recent version of MKL, if necessary; + - execute `source /path_to_oneapi/mkl/latest/env/vars.sh`; + - execute `python -m pip install .` diff --git a/conda-recipe-cf/bld.bat b/conda-recipe-cf/bld.bat index 1b04207..5d64fa2 100644 --- a/conda-recipe-cf/bld.bat +++ b/conda-recipe-cf/bld.bat @@ -1,5 +1,5 @@ @rem Remember to source the compiler set MKLROOT=%CONDA_PREFIX% -%PYTHON% setup.py install +%PYTHON% -m pip install --no-build-isolation --no-deps . if errorlevel 1 exit 1 diff --git a/conda-recipe-cf/build.sh b/conda-recipe-cf/build.sh index 34241cc..55964cb 100644 --- a/conda-recipe-cf/build.sh +++ b/conda-recipe-cf/build.sh @@ -2,4 +2,4 @@ export CFLAGS="-I$PREFIX/include $CFLAGS" export MKLROOT=$CONDA_PREFIX -$PYTHON setup.py install +$PYTHON -m pip install --no-build-isolation --no-deps . diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index fbe587d..00bc9b1 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -19,7 +19,7 @@ requirements: - {{ compiler('cxx') }} host: - python - - setuptools + - setuptools >=77 - mkl-devel - cython - numpy @@ -34,8 +34,6 @@ test: - pytest --pyargs mkl_random requires: - pytest - - mkl-service - - numpy imports: - mkl_random - mkl_random.mklrand @@ -43,6 +41,5 @@ test: about: home: http://github.com/IntelPython/mkl_random license: BSD-3-Clause - license_family: BSD license_file: LICENSE.txt summary: NumPy-based implementation of random number generation sampling using Intel (R) Math Kernel Library, mirroring numpy.random, but exposing all choices of sampling algorithms available in MKL. diff --git a/conda-recipe/bld.bat b/conda-recipe/bld.bat index 1b04207..5d64fa2 100644 --- a/conda-recipe/bld.bat +++ b/conda-recipe/bld.bat @@ -1,5 +1,5 @@ @rem Remember to source the compiler set MKLROOT=%CONDA_PREFIX% -%PYTHON% setup.py install +%PYTHON% -m pip install --no-build-isolation --no-deps . if errorlevel 1 exit 1 diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh index 34241cc..55964cb 100644 --- a/conda-recipe/build.sh +++ b/conda-recipe/build.sh @@ -2,4 +2,4 @@ export CFLAGS="-I$PREFIX/include $CFLAGS" export MKLROOT=$CONDA_PREFIX -$PYTHON setup.py install +$PYTHON -m pip install --no-build-isolation --no-deps . diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 3282337..00b41f1 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -19,7 +19,7 @@ requirements: - {{ compiler('cxx') }} host: - python - - setuptools + - setuptools >=77 - mkl-devel - cython - numpy-base @@ -34,8 +34,6 @@ test: - pytest --pyargs mkl_random requires: - pytest - - mkl-service - - numpy imports: - mkl_random - mkl_random.mklrand @@ -43,6 +41,5 @@ test: about: home: http://github.com/IntelPython/mkl_random license: BSD-3-Clause - license_family: BSD license_file: LICENSE.txt summary: NumPy-based implementation of random number generation sampling using Intel (R) Math Kernel Library, mirroring numpy.random, but exposing all choices of sampling algorithms available in MKL. diff --git a/docs/source/maintenance/index.rst b/docs/source/maintenance/index.rst index 2611957..d1b7b68 100644 --- a/docs/source/maintenance/index.rst +++ b/docs/source/maintenance/index.rst @@ -31,7 +31,7 @@ can be found. :caption: Building mkl_random $ export MKLROOT= - python setup.py develop + python -m pip install . To run test suite, install :mod:`pytest`, and run diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9896bc9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,78 @@ +# Copyright (c) 2017, Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[build-system] +build-backend = "setuptools.build_meta" +requires = ["setuptools>=77", "Cython", "numpy"] + +[project] +authors = [ + {name = "Intel Corporation", email = "scripting@intel.com"} +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "Intended Audience :: Developers", + "Programming Language :: C", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Software Development", + "Topic :: Scientific/Engineering", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Operating System :: Unix" +] +dependencies = ["numpy >=1.26.4", "mkl"] +description = "NumPy-based Python interface to Intel (R) MKL Random Number Generation functionality" +dynamic = ["version"] +keywords = ["MKL", "VSL", "true randomness", "pseudorandomness", + "Philox", "MT-19937", "SFMT-19937", "MT-2203", "ARS-5", + "R-250", "MCG-31"] +license = "BSD-3-Clause" +name = "mkl_random" +readme = {file = "README.md", content-type = "text/markdown"} +requires-python = ">=3.9,<3.13" + +[project.optional-dependencies] +test = ["pytest"] + +[project.urls] +Download = "http://github.com/IntelPython/mkl_random" +Homepage = "http://github.com/IntelPython/mkl_random" + +[tool.setuptools] +include-package-data = true +packages = ["mkl_random"] + +[tool.setuptools.package-data] +"mkl_random" = ["tests/*.py"] + +[tool.setuptools.dynamic] +version = {attr = "mkl_random._version.__version__"} diff --git a/setup.py b/setup.py index 130954a..b9d4002 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # Copyright (c) 2017, Intel Corporation # # Redistribution and use in source and binary forms, with or without @@ -26,44 +25,12 @@ import os import sys -import io -import re from os.path import join import Cython.Build from setuptools import setup, Extension import numpy as np -with io.open('mkl_random/_version.py', 'rt', encoding='utf8') as f: - version = re.search(r'__version__ = \'(.*?)\'', f.read()).group(1) - -with open("README.md", "r", encoding="utf-8") as file: - long_description = file.read() - -VERSION = version - -CLASSIFIERS = CLASSIFIERS = """\ -Development Status :: 5 - Production/Stable -Intended Audience :: Science/Research -Intended Audience :: Developers -License :: OSI Approved -Programming Language :: C -Programming Language :: Python -Programming Language :: Python :: 3 -Programming Language :: Python :: 3.9 -Programming Language :: Python :: 3.10 -Programming Language :: Python :: 3.11 -Programming Language :: Python :: 3.12 -Programming Language :: Python :: Implementation :: CPython -Topic :: Software Development -Topic :: Scientific/Engineering -Operating System :: Microsoft :: Windows -Operating System :: POSIX -Operating System :: Unix -Operating System :: MacOS -""" - - def extensions(): mkl_root = os.environ.get('MKLROOT', None) if mkl_root: @@ -73,10 +40,7 @@ def extensions(): 'libraries': ['mkl_rt'] } else: - try: - mkl_info = get_info('mkl') - except: - mkl_info = dict() + raise ValueError("MKLROOT environment variable not set.") mkl_include_dirs = mkl_info.get('include_dirs', []) mkl_library_dirs = mkl_info.get('library_dirs', []) @@ -101,23 +65,23 @@ def extensions(): exts = [ Extension( "mkl_random.mklrand", - [ - os.path.join("mkl_random", "mklrand.pyx"), - os.path.join("mkl_random", "src", "mkl_distributions.cpp"), - os.path.join("mkl_random", "src", "randomkit.cpp"), + sources = [ + join("mkl_random", "mklrand.pyx"), + join("mkl_random", "src", "mkl_distributions.cpp"), + join("mkl_random", "src", "randomkit.cpp"), ], depends = [ - os.path.join("mkl_random", "src", "mkl_distributions.hpp"), - os.path.join("mkl_random", "src", "randomkit.h"), - os.path.join("mkl_random", "src", "numpy_multiiter_workaround.h") + join("mkl_random", "src", "mkl_distributions.hpp"), + join("mkl_random", "src", "randomkit.h"), + join("mkl_random", "src", "numpy_multiiter_workaround.h") ], - include_dirs = [os.path.join("mkl_random", "src"), np.get_include()] + mkl_include_dirs, + include_dirs = [join("mkl_random", "src"), np.get_include()] + mkl_include_dirs, libraries = libs, library_dirs = lib_dirs, extra_compile_args = eca + [ # "-ggdb", "-O0", "-Wall", "-Wextra", ], - define_macros=defs + [("NDEBUG",None),], # [("DEBUG", None),] + define_macros=defs + [("NDEBUG", None)], # [("DEBUG", None),] language="c++" ) ] @@ -126,36 +90,7 @@ def extensions(): setup( - name = "mkl_random", - maintainer = "Intel Corp.", - maintainer_email = "scripting@intel.com", - description = "NumPy-based Python interface to Intel (R) MKL Random Number Generation functionality", - version = version, - include_package_data=True, - ext_modules=extensions(), cmdclass={'build_ext': Cython.Build.build_ext}, + ext_modules=extensions(), zip_safe=False, - long_description = long_description, - long_description_content_type="text/markdown", - url = "http://github.com/IntelPython/mkl_random", - author = "Intel Corporation", - download_url = "http://github.com/IntelPython/mkl_random", - license = "BSD", - classifiers = [_f for _f in CLASSIFIERS.split('\n') if _f], - platforms = ["Windows", "Linux", "Mac OS-X"], - test_suite = "pytest", - python_requires = '>=3.7', - setup_requires=["Cython",], - install_requires = ["numpy >=1.16"], - packages=[ - "mkl_random", - ], - package_data={ - "mkl_random" : [ - "tests/*.*", - ] - }, - keywords=["MKL", "VSL", "true randomness", "pseudorandomness", - "Philox", "MT-19937", "SFMT-19937", "MT-2203", "ARS-5", - "R-250", "MCG-31",], )