diff --git a/.github/workflows/ciwheel.yml b/.github/workflows/ciwheel.yml index 77f094fbcbf7add4b20a973498353388dcaf53ae..fc20275873d47fc563897cb4f5ecac5d5ddaf92e 100644 --- a/.github/workflows/ciwheel.yml +++ b/.github/workflows/ciwheel.yml @@ -24,38 +24,10 @@ jobs: with: fetch-depth: 0 submodules: recursive - - name: Update pip - run: python -m pip install --upgrade pip - - - name: Build wheels Linux - if: ${{ startsWith(matrix.os, 'ubuntu') }} - uses: pypa/cibuildwheel@v2.3.0 - with: - output-dir: dist - env: - CIBW_BEFORE_ALL: yum -y install libxml2-devel - CIBW_BEFORE_BUILD: python -m pip install numpy setuptools scikit-build ninja cmake - CIBW_BUILD: "cp3*-manylinux_x86_64" - CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 - CIBW_ARCHS_LINUX: x86_64 - CIBW_REPAIR_WHEEL_COMMAND: 'auditwheel repair -w {dest_dir} {wheel} && python /project/scripts/patchwheel.py {dest_dir}' - CIBW_TEST_COMMAND: python -m unittest discover -v -s {project}/python - - - name: Build wheels macos - if: ${{ startsWith(matrix.os, 'macos') }} - uses: pypa/cibuildwheel@v2.3.0 - with: - output-dir: dist - env: - MACOSX_DEPLOYMENT_TARGET: "10.15" #needed to undo some CIBW settings - CIBW_BEFORE_BUILD: python -m pip install numpy setuptools scikit-build ninja cmake - CIBW_BUILD: "cp3*-macosx_x86_64" - CIBW_ARCHS_MACOS: x86_64 universal2 - CIBW_TEST_COMMAND: python -m unittest discover -v -s {project}/python - - # this action runs auditwheel automatically with the following args: - # https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command - + - name: Install cibuildwheel + run: python3 -m pip install cibuildwheel + - name: Build wheels + run: python3 -m cibuildwheel --output-dir dist - uses: actions/upload-artifact@v2 with: name: dist @@ -68,18 +40,16 @@ jobs: steps: - name: Set up Python uses: actions/setup-python@v2 - - name: Update pip - run: python -m pip install --upgrade pip - name: Get packages - run: python -m pip install numpy setuptools scikit-build ninja cmake + run: python3 -m pip install build - uses: actions/checkout@v2 with: fetch-depth: 0 submodules: recursive - name: Make sdist - run: python setup.py sdist + run: python3 -m build -s - name: Install sdist - run: python -m pip install dist/arbor*.tar.gz + run: python3 -m pip install dist/arbor*.tar.gz - name: Run Python tests run: python3 -m unittest discover -v -s python - name: Run Python examples diff --git a/.github/workflows/test-everything.yml b/.github/workflows/test-everything.yml index d540ee525605118675c9cfaf15519f28e95a8a6f..21c7d6063595642257c237ba0793ab839cabb300 100644 --- a/.github/workflows/test-everything.yml +++ b/.github/workflows/test-everything.yml @@ -18,7 +18,7 @@ jobs: os: "ubuntu-18.04", cc: "gcc-8", cxx: "g++-8", - py: "3.6", + py: "3.7", cmake: "3.18.x", mpi: "ON", simd: "OFF" @@ -28,7 +28,7 @@ jobs: os: "ubuntu-18.04", cc: "clang-8", cxx: "clang++-8", - py: "3.6", + py: "3.7", cmake: "3.18.x", mpi: "ON", simd: "OFF" @@ -38,7 +38,7 @@ jobs: os: "macos-10.15", cc: "clang", cxx: "clang++", - py: "3.6", + py: "3.7", cmake: "3.18.x", mpi: "ON", simd: "OFF" @@ -48,7 +48,7 @@ jobs: os: "ubuntu-20.04", cc: "gcc-10", cxx: "g++-10", - py: "3.9", + py: "3.10", cmake: "3.22.x", mpi: "ON", simd: "OFF" @@ -58,7 +58,7 @@ jobs: os: "ubuntu-20.04", cc: "gcc-10", cxx: "g++-10", - py: "3.9", + py: "3.10", cmake: "3.22.x", mpi: "OFF", simd: "ON" @@ -68,7 +68,7 @@ jobs: os: "ubuntu-20.04", cc: "clang-10", cxx: "clang++-10", - py: "3.9", + py: "3.10", cmake: "3.22.x", mpi: "ON", simd: "OFF" @@ -78,7 +78,7 @@ jobs: os: "macos-11", cc: "clang", cxx: "clang++", - py: "3.9", + py: "3.10", cmake: "3.22.x", mpi: "ON", simd: "OFF" @@ -202,16 +202,12 @@ jobs: name: "Pip build test + Python examples test" runs-on: ubuntu-latest steps: - - name: Update pip - run: python -m pip install --upgrade pip - - name: Install Python packages - run: pip install numpy setuptools scikit-build ninja cmake - name: Clone w/ submodules uses: actions/checkout@v2 with: submodules: recursive - name: Build and install Arbor using pip + build flags - run: python3 -m pip install --verbose --install-option="-DARB_VECTORIZE=ON" --install-option="-DARB_ARCH=native" . + run: CMAKE_ARGS="-DARB_VECTORIZE=ON -DARB_ARCH=native" python3 -m pip install . - name: Check that build flags match run: | python3 -c "import arbor; print(arbor.config())" | grep -q "'arch': 'native'" diff --git a/CMakeLists.txt b/CMakeLists.txt index 48acc89b8d20808bb25ae986d0df45edb74731c6..69c18331746ed3afa08df83e028c1d42d38a5c92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,7 +302,7 @@ endif() #---------------------------------------------------------- # The minimum version of Python supported by Arbor. -set(arb_py_version 3.6.0) +set(arb_py_version 3.7.0) if(DEFINED PYTHON_EXECUTABLE) set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) @@ -311,7 +311,7 @@ endif() if(ARB_WITH_PYTHON) cmake_dependent_option(ARB_USE_BUNDLED_PYBIND11 "Use bundled pybind11" ON "ARB_WITH_PYTHON;ARB_USE_BUNDLED_LIBS" OFF) - if(DEFINED ENV{CIBUILDWHEEL}) + if(DEFINED ENV{CIBUILDWHEEL} AND (UNIX AND NOT APPLE)) find_package(Python3 ${arb_py_version} COMPONENTS Interpreter Development.Module REQUIRED) else() find_package(Python3 ${arb_py_version} COMPONENTS Interpreter Development REQUIRED) diff --git a/doc/dependencies.csv b/doc/dependencies.csv index 8cbc63c4bc747b683c8c864c5d68ba121e9732e9..f11919b43e305e9e530c15f88f7672ca862b8deb 100644 --- a/doc/dependencies.csv +++ b/doc/dependencies.csv @@ -19,7 +19,7 @@ bench,Google-benchmark,,submodule ``ext/google-benchmark``, --,fmt,,submodule ``ext/fmt``, --,tinyopt,,source copy ``ext/tinyopt``, ARB_WITH_PYTHON,pybind11,,submodule ``python/pybind11``, -ARB_WITH_PYTHON,Python,3.6,Python compatiblity is the range between the latest officially released point version and the minimum here specified.,"* it is not more advanced than the version specified by NEP 29. +ARB_WITH_PYTHON,Python,3.7,Python compatiblity is the range between the latest officially released point version and the minimum here specified.,"* it is not more advanced than the version specified by NEP 29. * it is available as a cray-python version on Piz Daint * it is available on labs.ebrains.eu diff --git a/doc/install/build_install.rst b/doc/install/build_install.rst index de6f6edec7b98eb55fbe99d92392478543431fb0..de3d12dee9ccbe43c37dfd748b8bc33fbc8404f9 100644 --- a/doc/install/build_install.rst +++ b/doc/install/build_install.rst @@ -135,7 +135,7 @@ More information on building with MPI is in the `HPC cluster section <cluster_>` Python ~~~~~~ -Arbor has a Python frontend, for which a minimum of Python 3.6 is required. +Arbor has a Python frontend, for which a minimum of Python 3.7 is required. In addition, `numpy` is a runtime requirement for the Python package. In order to use MPI in combination with the python frontend the `mpi4py <https://mpi4py.readthedocs.io/en/stable/install.html#>`_ diff --git a/doc/install/python.rst b/doc/install/python.rst index c4f7ab46893a3a349f6f80f144243ad015687c0c..78fbf6cc7cbe6720a1a16c7e73d436ae3df7d15f 100644 --- a/doc/install/python.rst +++ b/doc/install/python.rst @@ -6,7 +6,7 @@ Python Installation Arbor's Python API will be the most convenient interface for most users. .. note:: - Arbor requires Python version 3.6 and later. It is advised that you update ``pip`` as well. + Arbor requires Python version 3.7 and later. It is advised that you update ``pip`` as well. We strongly encourage using ``pip`` to install Arbor. To get help in case of problems installing with pip, run pip with the ``--verbose`` flag, and attach the output @@ -42,15 +42,11 @@ You are now ready to use Arbor! You can continue reading these documentation pag for any other platforms than listed above, ``pip`` will attempt a build from source and thus require these packages as well. - * Ubuntu/Debian: `git cmake gcc python3-dev python3-pip libxml2-dev` - * Fedora/CentOS/OpenSuse: `git cmake gcc-c++ python3-devel python3-pip libxml2-devel` - * MacOS: get `brew` `here <https://brew.sh>`_ and run `brew install cmake clang python3 libxml2` + * Ubuntu/Debian: ``git cmake gcc python3-dev python3-pip libxml2-dev`` + * Fedora/CentOS/OpenSuse: ``git cmake gcc-c++ python3-devel python3-pip libxml2-devel`` + * MacOS: get ``brew`` `here <https://brew.sh>`_ and run ``brew install cmake clang python3 libxml2`` * Windows: the simplest way is to use `WSL <https://docs.microsoft.com/en-us/windows/wsl/install-win10>`_ and then follow the instructions for Ubuntu. - In addition, you'll need a few Python packages present: - - ``pip3 install ninja scikit-build wheel setuptools numpy`` - .. _in_python_custom: Customising Arbor @@ -79,12 +75,11 @@ Every time you make changes to the code, you'll have to repeat the second step. Advanced options ^^^^^^^^^^^^^^^^ -By default Arbor is installed with multi-threading enabled. To enable more -advanced forms of parallelism and other features, Arbor comes with a few -compilation options. These are of the form ``-D<KEY>=<VALUE>``, must be appended -to the ``pip`` invocation via ``--install-option="-D<...>" --install-option="-D<...>" ...`` and can -be used on both local (``pip3 install ./arbor``) and remote (``pip3 install -arbor``) copies of Arbor. See the examples below. +Arbor comes with a few compilation options, some of them related to advanced forms of parallelism and other features. +The options and flags are the same :ref:`as documented for the CMAKE build <quickstart>`, but they are passed differently. +To enable more, they must be placed in the ``CMAKE_ARGS`` environment variable. +The simplest way to do this is by prepending the ``pip`` command with ``CMAKE_ARGS=""``, +where you place the arguments separated by space inside the quotes. .. Note:: @@ -92,9 +87,6 @@ arbor``) copies of Arbor. See the examples below. to remove the ``_skbuild`` directory. If you had Arbor installed already, you may need to remove it first before you can (re)compile it with the flags you need. - Also, make sure to pass each option individually via - ``--install-option="..."``. - The following flags can be used to configure the installation: * ``ARB_WITH_NEUROML=<ON|OFF>``: Enable support for NeuroML2 morphologies, @@ -119,6 +111,14 @@ The following flags can be used to configure the installation: and ``CMake`` under the hood, so all flags and options valid in ``CMake`` can be used in this fashion. + Allthough the + `scikit-build documentation <https://scikit-build.readthedocs.io/en/latest/usage.html#environment-variable-configuration>`_ + mentions that you can also pass the build options with ``--install-option=""``, + this will cause ``pip`` to build all dependencies, including all build-dependencies, + instead of downloading them from PyPI. + ``CMAKE_ARGS=""`` saves you the build time, and also downloading and setting up the dependencies they in turn require to be present. + Setting ``CMAKE_ARGS=""`` is in addition compatible with build front-ends like `build <https://pypa-build.readthedocs.io>`_. + Detailed instructions on how to install using CMake are in the :ref:`Python configuration <install-python>` section of the :ref:`installation guide <in_build_install>`. CMake is recommended if you need more control over @@ -138,33 +138,33 @@ In the examples below we assume you are installing from a local copy. .. code-block:: bash - pip3 install ./arbor --install-option="-DARB_WITH_MPI=ON" + CMAKE_ARGS="-DARB_WITH_MPI=ON" pip3 install ./arbor **Compile with** :ref:`vectorization <install-vectorize>` on a system with a SkyLake :ref:`architecture <install-architecture>`: .. code-block:: bash - pip3 install ./arbor --install-option="-DARB_VECTORIZE=ON" --install-option="-DARB_ARCH=skylake" - + CMAKE_ARGS="-DARB_VECTORIZE=ON -DARB_ARCH=skylake" pip3 install ./arbor + **Enable NVIDIA GPUs (compiled with nvcc)**. This requires the :ref:`CUDA toolkit <install-gpu>`: .. code-block:: bash - pip3 install ./arbor --install-option="-DARB_GPU=cuda" + CMAKE_ARGS="-DARB_GPU=cuda" pip3 install ./arbor **Enable NVIDIA GPUs (compiled with clang)**. This also requires the :ref:`CUDA toolkit <install-gpu>`: .. code-block:: bash - pip3 install ./arbor --install-option="-DARB_GPU=cuda-clang" + CMAKE_ARGS="-DARB_GPU=cuda-clang" pip3 install ./arbor **Enable AMD GPUs (compiled with hipcc)**. This requires setting the ``CC`` and ``CXX`` -:ref:`environment variables <install-gpu>` +:ref:`environment variables <install-gpu>`: .. code-block:: bash - pip3 install ./arbor --install-option="-DARB_GPU=hip" + CC=clang CXX=hipcc CMAKE_ARGS="-DARB_GPU=hip" pip3 install ./arbor Note on performance ------------------- diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..745f74710d7b01a838aece2d6350d092704554c5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,72 @@ +[project] +name = "arbor" +dynamic = ["version", "readme"] +license = {file = "LICENSE"} +description = "High performance simulation of networks of multicompartment neurons." +requires-python = ">=3.7" +keywords = ["simulator", "neuroscience", "morphological detail", "HPC", "GPU", "C++"] +authors = [ + {name = "Arbor Dev Team", email = "contact@arbor-sim.org"} +] +maintainers = [ + {name = "Arbor Dev Team", email = "contact@arbor-sim.org"} +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: C++" +] +dependencies = [ + "numpy" +] + +[tool.setuptools] +py-modules = ["arbor"] + +[tool.setuptools.dynamic] +version = {file = ["VERSION"]} +readme = {file = ["python/readme.md"]} + +[project.urls] +homepage = "https://arbor-sim.org" +documentation = "https://docs.arbor-sim.org" +repository = "https://github.com/arbor-sim/arbor" +changelog = "https://github.com/arbor-sim/arbor/releases" + +[build-system] +requires = [ + "setuptools", + "wheel", + "scikit-build", + "cmake>=3.18", + "ninja", +] +build-backend = "setuptools.build_meta" + +[tool.cibuildwheel] +build-frontend = "build" +build = ["cp3*-manylinux_x86_64","cp3*-macosx_universal2"]#,"cp3*-musllinux_x86_64","cp3*-musllinux_aarch64"] +skip = "cp36-*" +test-command = "python3 -m unittest discover -v -s {project}/python" + +[tool.cibuildwheel.macos] +archs = ["x86_64", "universal2", "arm64"] + +[tool.cibuildwheel.macos.environment] +MACOSX_DEPLOYMENT_TARGET = "10.15" + +[tool.cibuildwheel.linux] +archs = ["x86_64"] +manylinux-x86_64-image = "manylinux2014" +before-all = "yum -y install libxml2-devel" +repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} && python3 /project/scripts/patchwheel.py {dest_dir}" + +[[tool.cibuildwheel.overrides]] +select = "*-musllinux*" +before-all = "apk add libxml2-dev" diff --git a/python/example/single_cell_allen.py b/python/example/single_cell_allen.py index eac24649175f0d8d0f8b7e6f66066a4663357e6a..359b62e245174ff3d6f461d1a645c3dacd7c9691 100644 --- a/python/example/single_cell_allen.py +++ b/python/example/single_cell_allen.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from collections import defaultdict +from dataclasses import dataclass import json import arbor import seaborn @@ -15,13 +16,12 @@ def load_allen_fit(fit): fit = json.load(fd) # cable parameters convenience class + @dataclass class parameters: - def __init__(self, **kwargs): - self.cm = None - self.tempK = None - self.Vm = None - self.rL = None - self.__dict__.update(kwargs) + cm: float = None + tempK: float = None + Vm: float = None + rL: float = None param = defaultdict(parameters) mechs = defaultdict(dict) diff --git a/scripts/build-wheels.sh b/scripts/build-wheels.sh index 0b881c71b09dfe9fa288056b4270da65dc23be32..4b6412da948b8ce2191980cc375f977870b35194 100755 --- a/scripts/build-wheels.sh +++ b/scripts/build-wheels.sh @@ -14,14 +14,14 @@ set -e -u -x yum -y install libxml2-devel -/opt/python/cp310-cp310/bin/pip install ninja cmake rm -rf /src_dir/arbor/_skbuild +rm -rf /opt/python/cp36-cp36m # Python build toolchain does not work on Py3.6 export CIBUILDWHEEL=1 #Set condition for cmake -for PYBIN in /opt/python/cp*/bin; do - "${PYBIN}/python" -m pip install wheel scikit-build auditwheel +for PYBIN in /opt/python/cp3*/bin; do + "${PYBIN}/python" -m pip install pip auditwheel -U export PATH="${PYBIN}":$PATH "${PYBIN}/python" -m pip wheel --wheel-dir="/src_dir/builtwheel${PYBIN}/" /src_dir/arbor "${PYBIN}/python" -m auditwheel repair /src_dir/builtwheel${PYBIN}/arbor*.whl -w /src_dir/wheelhouse diff --git a/setup.py b/setup.py index 7511cd70a39c603025b58be2661f849b74003b78..30f9ed589d923cfb63b839faa9aff9ffd2484cc5 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -from pathlib import Path from sys import executable as python from skbuild import setup @@ -13,23 +12,7 @@ with_nml = True use_libs = True build_type = "Release" # this is ok even for debugging, as we always produce info -# Find our dir; *should* be the arbor checkout -here = Path(__file__).resolve().parent -# Read version file -with open(here / "VERSION") as fd: - arbor_version = fd.read().strip() -# Get the contents of the readme -with open(here / "python" / "readme.md", encoding="utf-8") as fd: - long_description = fd.read() - setup( - name="arbor", - version=arbor_version, - python_requires=">=3.6", - install_requires=["numpy"], - setup_requires=[], - zip_safe=False, - packages=["arbor"], cmake_args=[ "-DARB_WITH_PYTHON=on", f"-DPYTHON_EXECUTABLE={python}", @@ -41,25 +24,4 @@ setup( f"-DARB_USE_BUNDLED_LIBS={use_libs}", f"-DCMAKE_BUILD_TYPE={build_type}", ], - author="The Arbor dev team.", - url="https://arbor-sim.org", - description="High performance simulation of networks of multicompartment neurons.", - long_description=long_description, - long_description_content_type="text/markdown", - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: BSD License", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: C++", - ], - project_urls={ - "Source": "https://github.com/arbor-sim/arbor", - "Documentation": "https://docs.arbor-sim.org", - "Bug Reports": "https://github.com/arbor-sim/arbor/issues", - }, ) diff --git a/spack/package.py b/spack/package.py index 016265041e30243c1169edbcf6c83588a6b80512..c5028e59f0eff89e7151f1151cc5fdfe22e872ad 100644 --- a/spack/package.py +++ b/spack/package.py @@ -69,14 +69,14 @@ class Arbor(CMakePackage, CudaPackage): # python (bindings) extends("python", when="+python") - depends_on("python@3.6:", when="+python", type=("build", "run")) + depends_on("python@3.7:", when="+python", type=("build", "run")) depends_on("py-numpy", when="+python", type=("build", "run")) with when("+python"): - depends_on("py-pybind11@2.6:", type=("build", "run")) - depends_on("py-pybind11@2.8.1:", when="@0.5.3:", type=("build", "run")) + depends_on("py-pybind11@2.6:", type=("build")) + depends_on("py-pybind11@2.8.1:", when="@0.5.3:", type=("build")) # sphinx based documentation - depends_on("python@3.6:", when="+doc", type="build") + depends_on("python@3.7:", when="+doc", type="build") depends_on("py-sphinx", when="+doc", type="build") depends_on("py-svgwrite", when="+doc", type="build")