diff --git a/install_spack_env.sh b/install_spack_env.sh index 536696f8a4fa342bad3f9975bc2ff57f96d62add..86e62145c8eeaac083ac175428d7fa3f3d018846 100644 --- a/install_spack_env.sh +++ b/install_spack_env.sh @@ -76,7 +76,7 @@ cp /tmp/spack.yaml $SPACK_ROOT/var/spack/environments/$EBRAINS_SPACK_ENV/ rm $SPACK_ROOT/var/spack/environments/$EBRAINS_SPACK_ENV/spack.lock || echo "No spack.lock file" # activate environment -spack env activate $EBRAINS_SPACK_ENV +spack env activate --without-view $EBRAINS_SPACK_ENV # fetch all sources spack concretize --fresh --test root diff --git a/packages/build-brainscales/package.py b/packages/build-brainscales/package.py new file mode 100644 index 0000000000000000000000000000000000000000..a162821d8753e6cb8c9dd17e8e5cea7713ea1c03 --- /dev/null +++ b/packages/build-brainscales/package.py @@ -0,0 +1,136 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) +import os +import unittest.mock +import xml.etree.ElementTree as ET + +from spack import * +from spack.util.environment import EnvironmentModifications +import spack.build_environment + + +class BuildBrainscales(WafPackage): + """Common stuff for BrainScaleS packages...""" + + def do_fetch(self, mirror_only=False): + """Setup the project.""" + + self.stage.create() + self.stage.fetch(mirror_only) + + # if fetcher didn't do anything, it's cached already + if not os.path.exists(self.stage.source_path): + return + + with working_dir(self.stage.source_path): + python = which('python3') + if self.spec.satisfies('@:7'): + python('./waf', 'setup', '--repo-db-url=https://github.com/electronicvisions/projects', + '--clone-depth=2', + '--without-munge', + '--without-hxcomm-hostarq', + '--without-hxcomm-extoll', + '--project=' + str(self.spec.name), + '--release-branch=ebrains-' + str(self.spec.version) + ) + else: + python('./waf', 'setup', '--repo-db-url=https://github.com/electronicvisions/projects', + '--clone-depth=2', + '--without-munge', + '--without-hxcomm-hostarq', + '--project=' + str(self.spec.name), + '--release-branch=ebrains-' + str(self.spec.version) + ) + + + # in the configure step, we need access to all archived .git folders + def custom_archive(self, destination): + super(spack.fetch_strategy.GitFetchStrategy, self).archive(destination) + with unittest.mock.patch('spack.fetch_strategy.GitFetchStrategy.archive', new=custom_archive): + self.stage.cache_local() + + def _setup_common_env(self, env): + # grenade needs to find some libraries for the JIT-compilation of + # programs for BrainScaleS-2's embedded processor. + ppu_include_dirs = [] + ppu_dep_names = ['bitsery', 'boost', 'cereal'] + for ppu_dep_name in ppu_dep_names: + dep = self.spec[ppu_dep_name] + dep_include_dirs = set(dep.headers.directories) + ppu_include_dirs.extend(list(dep_include_dirs)) + for dir in reversed(ppu_include_dirs): + env.prepend_path("C_INCLUDE_PATH", dir) + env.prepend_path("CPLUS_INCLUDE_PATH", dir) + + def setup_build_environment(self, env): + my_envmod = EnvironmentModifications(env) + spack.build_environment.set_wrapper_variables(self, my_envmod) + my_env = {} + my_envmod.apply_modifications(my_env) + + def get_path(env, name): + path = env.get(name, "").strip() + if path: + return path.split(os.pathsep) + return [] + + # spack tries to find headers and libraries by itself (i.e. it's not + # relying on the compiler to find it); we explicitly expose the + # spack-provided env vars that contain include and library paths + if 'SPACK_INCLUDE_DIRS' in my_env: + for dir in reversed(get_path(my_env, "SPACK_INCLUDE_DIRS")): + env.prepend_path("C_INCLUDE_PATH", dir) + env.prepend_path("CPLUS_INCLUDE_PATH", dir) + if 'SPACK_LINK_DIRS' in my_env: + for dir in reversed(get_path(my_env, "SPACK_LINK_DIRS")): + env.prepend_path("LIBRARY_PATH", dir) + env.prepend_path("LD_LIBRARY_PATH", dir) + for dir in reversed(self.compiler.implicit_rpaths()): + env.prepend_path("LIBRARY_PATH", dir) + # technically this is probably not needed for the non-configure steps + env.prepend_path("LD_LIBRARY_PATH", dir) + + def setup_dependent_build_environment(self, env, dependent_spec): + self._setup_common_env(env) + + def setup_run_environment(self, env): + self._setup_common_env(env) + + def setup_dependent_run_environment(self, env, dependent_spec): + self._setup_common_env(env) + + # override configure step as we perform a project setup first + def configure(self, spec, prefix): + """Configure the project.""" + + args = ['--prefix={0}'.format(self.prefix)] + args += self.configure_args() + self.waf('configure', '--build-profile=release', '--disable-doxygen', *args) + + def build_args(self): + args = ['--keep', '--test-execnone', '-v'] + return args + + def build_test(self): + self.builder.waf('build', '--test-execall') + copy_tree('build/test_results', join_path(self.prefix, '.build')) + copy_tree('build/test_results', join_path(self.stage.path, ".install_time_tests")) + # propagate failures from junit output to spack + tree = ET.parse('build/test_results/summary.xml') + for testsuite in tree.getroot(): + for testcase in testsuite: + if (testcase.get('name').startswith("pycodestyle") or + testcase.get('name').startswith("pylint")): + continue + for elem in testcase: + if (elem.tag == 'failure') and not ( + elem.get('message').startswith("pylint:") or + elem.get('message').startswith("pycodestyle:") or + ("OK" in elem.get('message') and "Segmentation fault" in elem.get('message'))): + raise RuntimeError("Failed test found: {}".format(testcase.get('name'))) + + def install_args(self): + args = ['--test-execnone'] + return args diff --git a/packages/hxtorch/package.py b/packages/hxtorch/package.py index bff7e733e9fa3226d760decfc0cd2280718ce3ec..f9751d98611bb07b3afb9313834ac6a8680ae5d3 100644 --- a/packages/hxtorch/package.py +++ b/packages/hxtorch/package.py @@ -1,18 +1,20 @@ -# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os import unittest.mock -import sys import xml.etree.ElementTree as ET from spack import * from spack.util.environment import EnvironmentModifications import spack.build_environment +import importlib +build_brainscales = importlib.import_module("spack.pkg.ebrains-spack-builds.build_brainscales") -class Hxtorch(WafPackage): + +class Hxtorch(build_brainscales.BuildBrainscales): """hxtorch --- a PyTorch-based toplevel for the BrainScaleS-2 neuromorphic hardware systems""" homepage = "https://github.com/electronicvisions/hxtorch" @@ -77,123 +79,6 @@ class Hxtorch(WafPackage): depends_on('yaml-cpp+shared', type=('build', 'link', 'run')) extends('python') - def do_fetch(self, mirror_only=False): - """Setup the project.""" - - self.stage.create() - self.stage.fetch(mirror_only) - - # if fetcher didn't do anything, it's cached already - if not os.path.exists(self.stage.source_path): - return - - with working_dir(self.stage.source_path): - python = which('python3') - if self.spec.satisfies('@:7'): - python('./waf', 'setup', '--repo-db-url=https://github.com/electronicvisions/projects', - '--clone-depth=2', - '--without-munge', - '--without-hxcomm-hostarq', - '--without-hxcomm-extoll', - '--project=hxtorch', - '--release-branch=ebrains-' + str(self.spec.version) - ) - else: - python('./waf', 'setup', '--repo-db-url=https://github.com/electronicvisions/projects', - '--clone-depth=2', - '--without-munge', - '--without-hxcomm-hostarq', - '--project=hxtorch', - '--release-branch=ebrains-' + str(self.spec.version) - ) - - # in the configure step, we need access to all archived .git folders - def custom_archive(self, destination): - super(spack.fetch_strategy.GitFetchStrategy, self).archive(destination) - with unittest.mock.patch('spack.fetch_strategy.GitFetchStrategy.archive', new=custom_archive): - self.stage.cache_local() - - def _setup_common_env(self, env): - # grenade needs to find some libraries for the JIT-compilation of - # programs for BrainScaleS-2's embedded processor. - ppu_include_dirs = [] - ppu_dep_names = ['bitsery', 'boost', 'cereal'] - for ppu_dep_name in ppu_dep_names: - dep = self.spec[ppu_dep_name] - dep_include_dirs = set(dep.headers.directories) - ppu_include_dirs.extend(list(dep_include_dirs)) - for dir in reversed(ppu_include_dirs): - env.prepend_path("C_INCLUDE_PATH", dir) - env.prepend_path("CPLUS_INCLUDE_PATH", dir) - - def setup_build_environment(self, env): - my_envmod = EnvironmentModifications(env) - spack.build_environment.set_wrapper_variables(self, my_envmod) - my_env = {} - my_envmod.apply_modifications(my_env) - - def get_path(env, name): - path = env.get(name, "").strip() - if path: - return path.split(os.pathsep) - return [] - - # spack tries to find headers and libraries by itself (i.e. it's not - # relying on the compiler to find it); we explicitly expose the - # spack-provided env vars that contain include and library paths - if 'SPACK_INCLUDE_DIRS' in my_env: - for dir in reversed(get_path(my_env, "SPACK_INCLUDE_DIRS")): - env.prepend_path("C_INCLUDE_PATH", dir) - env.prepend_path("CPLUS_INCLUDE_PATH", dir) - if 'SPACK_LINK_DIRS' in my_env: - for dir in reversed(get_path(my_env, "SPACK_LINK_DIRS")): - env.prepend_path("LIBRARY_PATH", dir) - env.prepend_path("LD_LIBRARY_PATH", dir) - for dir in reversed(self.compiler.implicit_rpaths()): - env.prepend_path("LIBRARY_PATH", dir) - # technically this is probably not needed for the non-configure steps - env.prepend_path("LD_LIBRARY_PATH", dir) - - def setup_dependent_build_environment(self, env, dependent_spec): - self._setup_common_env(env) - - def setup_run_environment(self, env): - self._setup_common_env(env) - - def setup_dependent_run_environment(self, env, dependent_spec): - self._setup_common_env(env) - - # override configure step as we perform a project setup first - def configure(self, spec, prefix): - """Configure the project.""" - - args = ['--prefix={0}'.format(self.prefix)] - args += self.configure_args() - self.waf('configure', '--build-profile=release', '--disable-doxygen', *args) - - def build_args(self): - args = ['--keep', '--test-execnone', '-v'] - return args - - def build_test(self): - self.builder.waf('build', '--test-execall') - copy_tree('build/test_results', join_path(self.prefix, ".build")) - copy_tree('build/test_results', join_path(self.stage.path, ".install_time_tests")) - # propagate failures from junit output to spack - tree = ET.parse('build/test_results/summary.xml') - for testsuite in tree.getroot(): - for testcase in testsuite: - for elem in testcase: - if (elem.tag == 'failure') and not ( - elem.get('message').startswith("pylint:") or - elem.get('message').startswith("pycodestyle:") or - ("OK" in elem.get('message') and "Segmentation fault" in elem.get('message'))): - raise RuntimeError("Failed test found: {}".format(testcase.get('name'))) - - def install_args(self): - args = ['--test-execnone'] - return args - def install_test(self): with working_dir('spack-test', create=True): old_pythonpath = os.environ.get('PYTHONPATH', '') diff --git a/packages/jaxsnn/package.py b/packages/jaxsnn/package.py new file mode 100644 index 0000000000000000000000000000000000000000..cd66a37746f6c30760e1818e278a51e751fc2709 --- /dev/null +++ b/packages/jaxsnn/package.py @@ -0,0 +1,50 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) +import os +import unittest.mock +import xml.etree.ElementTree as ET + +from spack import * +from spack.util.environment import EnvironmentModifications +import spack.build_environment + +import importlib +build_brainscales = importlib.import_module("spack.pkg.ebrains-spack-builds.build_brainscales") + + +class Jaxsnn(build_brainscales.BuildBrainscales): + """jaxsnn is an event-based approach to machine-learning-inspired training + and simulation of SNNs, including support for the BrainScaleS-2 + neuromorphic backend.""" + + homepage = "https://github.com/electronicvisions/jaxsnn" + # This repo provides a custom waf binary used for the build below + git = "https://github.com/electronicvisions/pynn-brainscales.git" + + maintainers = ['emuller'] + + version('8.0-a3', tag='jaxsnn-8.0-a3') + version('8.0-a2', tag='jaxsnn-8.0-a2') + version('8.0-a1', tag='jaxsnn-8.0-a1') + + # for now, this is still "on top" of hxtorch… + depends_on('hxtorch@8.0-a3', when='@8.0-a3', type=('build', 'link', 'run', 'test')) + depends_on('hxtorch@8.0-a2', when='@8.0-a2', type=('build', 'link', 'run', 'test')) + depends_on('hxtorch@8.0-a1', when='@8.0-a1', type=('build', 'link', 'run', 'test')) + + # main dependencies w/o hxtorch.core dependencies (those come via hxtorch above) + depends_on('py-jax@0.4.13:', type=('build', 'link', 'run')) + depends_on('py-matplotlib', type=('build', 'link', 'run')) + depends_on('py-optax', type=('build', 'link', 'run')) + depends_on('py-tree-math', type=('build', 'link', 'run')) + extends('python') + + def install_test(self): + with working_dir('spack-test', create=True): + old_pythonpath = os.environ.get('PYTHONPATH', '') + os.environ['PYTHONPATH'] = ':'.join([str(self.prefix.lib), old_pythonpath]) + bash = which("bash") + # ignore segfaults for now (exit code 139) + bash('-c', '(python -c "import jaxsnn; print(jaxsnn.__file__)" || ( test $? -eq 139 && echo "segfault")) || exit $?') diff --git a/packages/nest/package.py b/packages/nest/package.py index f88e8f3ef172e99f4c8a290ccfcb698e4b4e9a86..e1593d4bfcbbad9b8566fdda5a2aada527b6e8ce 100644 --- a/packages/nest/package.py +++ b/packages/nest/package.py @@ -28,6 +28,7 @@ class Nest(CMakePackage): maintainers = ['terhorst'] version('master', branch='master') + version('3.7_rc1', sha256='6f5948ac717d4b66c84ed53ba5c9b0e44e4e9cc3c1f3d15d8d8f21024313061e') version('3.6', sha256='68d6b11791e1284dc94fef35d84c08dd7a11322c0f1e1fc9b39c5e6882284922') patch('nest-simulator-3.6-p1-CxxRealPath.patch', when='@3.6') version('3.5', sha256='3cdf5720854a4d8a7d359f9de9d2fb3619a0be2e36932028d6940360741547bd') @@ -93,7 +94,8 @@ class Nest(CMakePackage): depends_on('boost', when="@2.16:+boost", type='build') depends_on('py-setuptools@:44.99.99', when='@:2.15.99+python', type='build') depends_on('py-h5py', when='@3.4.99:+sonata', type=('test', 'build', 'run')) - depends_on('hdf5+cxx', when='@3.4.99:+sonata', type=('build', 'link', 'run')) + depends_on('hdf5+cxx+mpi', when='@3.4.99:+sonata+mpi', type=('build', 'run')) + depends_on('hdf5+cxx~mpi', when='@3.4.99:+sonata~mpi', type=('build', 'run')) depends_on('py-pandas', when='@3.4.99:+sonata', type=('build', 'run')) depends_on('py-nose', when='@:2.99.99+python+testsuite', type='test') diff --git a/packages/py-chex/package.py b/packages/py-chex/package.py new file mode 100644 index 0000000000000000000000000000000000000000..7e41890f4588105fc58e040d90b9f4a1fa84540c --- /dev/null +++ b/packages/py-chex/package.py @@ -0,0 +1,36 @@ +# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + + +from spack.package import * + + +# EBRAINS: based on spack/0.21.2 +class PyChex(PythonPackage): + """Chex is a library of utilities for helping to write reliable JAX code.""" + + homepage = "https://github.com/deepmind/chex" + pypi = "chex/chex-0.1.0.tar.gz" + + # begin EBRAINS (added): bring upstream + version("0.1.7", sha256="74ed49799ac4d229881456d468136f1b19a9f9839e3de72b058824e2a4f4dedd") + version("0.1.5", sha256="686858320f8f220c82a6c7eeb54dcdcaa4f3d7f66690dacd13a24baa1ee8299e") + # end EBRAINS + version("0.1.0", sha256="9e032058f5fed2fc1d5e9bf8e12ece5910cf6a478c12d402b6d30984695f2161") + + depends_on("python@3.7:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-absl-py@0.9.0:", type=("build", "run")) + # begin EBRAINS (added): bring upstream + depends_on("py-typing-extensions@4.2.0:", when="@0.1.6: ^python@:3.10", type=("build", "run")) + # end EBRAINS + depends_on("py-dm-tree@0.1.5:", type=("build", "run")) + depends_on("py-jax@0.1.55:", type=("build", "run")) + # begin EBRAINS (added): bring upstream + depends_on("py-jax@0.4.6:", when="@0.1.7:", type=("build", "run")) + # end EBRAINS + depends_on("py-jaxlib@0.1.37:", type=("build", "run")) + depends_on("py-numpy@1.18.0:", type=("build", "run")) + depends_on("py-toolz@0.9.0:", type=("build", "run")) diff --git a/packages/py-jax/package.py b/packages/py-jax/package.py new file mode 100644 index 0000000000000000000000000000000000000000..233de5b59b40af38d3d4e604477eb91e2b683b3a --- /dev/null +++ b/packages/py-jax/package.py @@ -0,0 +1,72 @@ +# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + + +from spack.package import * + + +# EBRAINS: based on spack/0.21.2 +class PyJax(PythonPackage): + """JAX is Autograd and XLA, brought together for high-performance + machine learning research. With its updated version of Autograd, + JAX can automatically differentiate native Python and NumPy + functions. It can differentiate through loops, branches, + recursion, and closures, and it can take derivatives of + derivatives of derivatives. It supports reverse-mode + differentiation (a.k.a. backpropagation) via grad as well as + forward-mode differentiation, and the two can be composed + arbitrarily to any order.""" + + homepage = "https://github.com/google/jax" + pypi = "jax/jax-0.2.25.tar.gz" + + # begin EBRAINS (added): bring upstream + version("0.4.13", sha256="03bfe6749dfe647f16f15f6616638adae6c4a7ca7167c75c21961ecfd3a3baaa") + # end EBRAINS + version("0.4.3", sha256="d43f08f940aa30eb339965cfb3d6bee2296537b0dc2f0c65ccae3009279529ae") + version("0.3.23", sha256="bff436e15552a82c0ebdef32737043b799e1e10124423c57a6ae6118c3a7b6cd") + version("0.2.25", sha256="822e8d1e06257eaa0fdc4c0a0686c4556e9f33647fa2a766755f984786ae7446") + + # begin EBRAINS (modified): bring upstream + depends_on("python@3.7:", type=("build", "run")) + depends_on("python@3.8:", when="@0.4:", type=("build", "run")) + depends_on("python@3.9:", when="@0.4.14:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-numpy@1.22:", when="@0.4.14:", type=("build", "run")) + depends_on("py-numpy@1.21:", when="@0.4.9:", type=("build", "run")) + depends_on("py-numpy@1.20:", when="@0.3:", type=("build", "run")) + depends_on("py-numpy@1.18:", type=("build", "run")) + depends_on("py-opt-einsum", type=("build", "run")) + depends_on("py-scipy@1.2.1:", type=("build", "run")) + depends_on("py-scipy@1.5:", when="@0.3:", type=("build", "run")) + depends_on("py-scipy@1.7:", when="@0.4.7:", type=("build", "run")) + depends_on("py-ml-dtypes@0.2.0:", when="@0.4.14:", type=("build", "run")) + depends_on("py-ml-dtypes@0.1.0:", when="@0.4.9:", type=("build", "run")) + depends_on("py-ml-dtypes@0.0.3:", when="@0.4.7:", type=("build", "run")) + depends_on("py-importlib-metadata@4.6:", when="@0.4.11: ^python@:3.9", type="run") + # end EBRAINS + + # See _minimum_jaxlib_version in jax/version.py + # begin EBRAINS (modified): bring upstream + jax_to_jaxlib = { + "0.4.14": "0.4.14", + "0.4.13": "0.4.13", + "0.4.3": "0.4.2", + "0.3.23": "0.3.15", + "0.2.25": "0.1.69", + } + # end EBRAINS + + for jax, jaxlib in jax_to_jaxlib.items(): + # begin EBRAINS (modified): bring upstream + depends_on(f"py-jaxlib@{jaxlib}", when=f"@{jax}", type=("build", "run")) + # end EBRAINS + + # Historical dependencies + depends_on("py-absl-py", when="@:0.3", type=("build", "run")) + depends_on("py-typing-extensions", when="@:0.3", type=("build", "run")) + # begin EBRAINS (deleted): + # depends_on("py-etils+epath", when="@0.3", type=("build", "run")) + # end EBRAINS diff --git a/packages/py-jaxlib/package.py b/packages/py-jaxlib/package.py new file mode 100644 index 0000000000000000000000000000000000000000..af04f737eceb3cfa00f7538da14dd8d5043df7cb --- /dev/null +++ b/packages/py-jaxlib/package.py @@ -0,0 +1,109 @@ +# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import tempfile + +from spack.package import * + + +# EBRAINS: based on spack/0.21.2 +class PyJaxlib(PythonPackage, CudaPackage): + """XLA library for Jax""" + + homepage = "https://github.com/google/jax" + url = "https://github.com/google/jax/archive/refs/tags/jaxlib-v0.1.74.tar.gz" + + tmp_path = "" + buildtmp = "" + + # begin EBRAINS (added): bring upstream + version("0.4.13", sha256="45766238b57b992851763c64bc943858aebafe4cad7b3df6cde844690bc34293") + # end EBRAINS + version("0.4.3", sha256="2104735dc22be2b105e5517bd5bc6ae97f40e8e9e54928cac1585c6112a3d910") + version("0.3.22", sha256="680a6f5265ba26d5515617a95ae47244005366f879a5c321782fde60f34e6d0d") + version("0.1.74", sha256="bbc78c7a4927012dcb1b7cd135c7521f782d7dad516a2401b56d3190f81afe35") + + # begin EBRAINS (deleted): Variant with default=False is provided by CudaPackage + # variant("cuda", default=True, description="Build with CUDA") + # end EBRAINS + + # jaxlib/setup.py + # begin EBRAINS (modified): bring upstream + depends_on("python@3.9:", when="@0.4.14:", type=("build", "run")) + depends_on("python@3.8:", when="@0.4:", type=("build", "run")) + depends_on("python@3.7:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-numpy@1.22:", when="@0.4.14:", type=("build", "run")) + depends_on("py-numpy@1.21:", when="@0.4.9:", type=("build", "run")) + depends_on("py-numpy@1.20:", when="@0.3:", type=("build", "run")) + depends_on("py-numpy@1.18:", type=("build", "run")) + depends_on("py-scipy@1.5:", type=("build", "run")) + depends_on("py-scipy@1.7:", when="@0.4.7:", type=("build", "run")) + depends_on("py-ml-dtypes@0.2.0:", when="@0.4.14:", type=("build", "run")) + depends_on("py-ml-dtypes@0.1.0:", when="@0.4.9:", type=("build", "run")) + depends_on("py-ml-dtypes@0.0.3:", when="@0.4.7:", type=("build", "run")) + # end EBRAINS + + # .bazelversion + depends_on("bazel@5.1.1:5.9", when="@0.3:", type="build") + # https://github.com/google/jax/issues/8440 + depends_on("bazel@4.1:4", when="@0.1", type="build") + + # README.md + # begin EBRAINS (added): bring upstream + depends_on("cuda@11.8:", when="@0.4.8:+cuda") + # end EBRAINS + depends_on("cuda@11.4:", when="@0.4:+cuda") + depends_on("cuda@11.1:", when="@0.3+cuda") + # https://github.com/google/jax/issues/12614 + depends_on("cuda@11.1:11.7.0", when="@0.1+cuda") + depends_on("cudnn@8.2:", when="@0.4:+cuda") + depends_on("cudnn@8.0.5:", when="+cuda") + + # Historical dependencies + depends_on("py-absl-py", when="@:0.3", type=("build", "run")) + depends_on("py-flatbuffers@1.12:2", when="@0.1", type=("build", "run")) + + def patch(self): + self.tmp_path = tempfile.mkdtemp(prefix="spack") + self.buildtmp = tempfile.mkdtemp(prefix="spack") + filter_file( + 'f"--output_path={output_path}",', + 'f"--output_path={output_path}",' + f' "--sources_path={self.tmp_path}",' + ' "--nohome_rc",' + ' "--nosystem_rc",' + f' "--jobs={make_jobs}",', + "build/build.py", + string=True, + ) + filter_file( + "args = parser.parse_args()", + "args, junk = parser.parse_known_args()", + "build/build_wheel.py", + string=True, + ) + + def install(self, spec, prefix): + args = [] + args.append("build/build.py") + if "+cuda" in spec: + args.append("--enable_cuda") + args.append("--cuda_path={0}".format(self.spec["cuda"].prefix)) + args.append("--cudnn_path={0}".format(self.spec["cudnn"].prefix)) + capabilities = ",".join( + "{0:.1f}".format(float(i) / 10.0) for i in spec.variants["cuda_arch"].value + ) + args.append("--cuda_compute_capabilities={0}".format(capabilities)) + args.append( + "--bazel_startup_options=" + "--output_user_root={0}".format(self.wrapped_package_object.buildtmp) + ) + python(*args) + with working_dir(self.wrapped_package_object.tmp_path): + args = std_pip_args + ["--prefix=" + self.prefix, "."] + pip(*args) + remove_linked_tree(self.wrapped_package_object.tmp_path) + remove_linked_tree(self.wrapped_package_object.buildtmp) diff --git a/packages/py-optax/package.py b/packages/py-optax/package.py new file mode 100644 index 0000000000000000000000000000000000000000..c5cf8840ec3e0fb1add31267cbba8879b1521d89 --- /dev/null +++ b/packages/py-optax/package.py @@ -0,0 +1,24 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack import * + + +class PyOptax(PythonPackage): + """A gradient processing and optimization library in JAX.""" + + homepage = "https://github.com/deepmind/optax" + pypi = "optax/optax-0.1.4.tar.gz" + + version("0.1.4", sha256="fb7a0550d57a6636164a3de25986a8a19be8ff6431fcdf1225b4e05175810f22") + + depends_on("python@3.8:", type=("build", "run")) + depends_on("py-setuptools", type="build") + + depends_on("py-absl-py@0.7.1:", type=("build", "run")) + depends_on("py-chex@0.1.5:", type=("build", "run")) + depends_on("py-jax@0.1.55:", type=("build", "run")) + depends_on("py-jaxlib@0.1.37:", type=("build", "run")) + depends_on("py-numpy@1.18:", type=("build", "run")) diff --git a/packages/pynn-brainscales/package.py b/packages/pynn-brainscales/package.py index e61b7b61fde63c2b60d7a1a0b6d4dec6b06294d3..39f07d8129ee0c8d0b8f151cceb746d0dd762dc1 100644 --- a/packages/pynn-brainscales/package.py +++ b/packages/pynn-brainscales/package.py @@ -1,18 +1,20 @@ -# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os import unittest.mock -import sys import xml.etree.ElementTree as ET from spack import * from spack.util.environment import EnvironmentModifications import spack.build_environment +import importlib +build_brainscales = importlib.import_module("spack.pkg.ebrains-spack-builds.build_brainscales") -class PynnBrainscales(WafPackage): + +class PynnBrainscales(build_brainscales.BuildBrainscales): """PyNN toplevel for the BrainScaleS-2 neuromorphic hardware systems""" homepage = "https://github.com/electronicvisions/pynn-brainscales" @@ -74,124 +76,6 @@ class PynnBrainscales(WafPackage): depends_on('yaml-cpp+shared', type=('build', 'link', 'run')) extends('python') - def do_fetch(self, mirror_only=False): - """Setup the project.""" - - self.stage.create() - self.stage.fetch(mirror_only) - - # if fetcher didn't do anything, it's cached already - if not os.path.exists(self.stage.source_path): - return - - with working_dir(self.stage.source_path): - python = which('python3') - if self.spec.satisfies('@:7'): - python('./waf', 'setup', '--repo-db-url=https://github.com/electronicvisions/projects', - '--clone-depth=2', - '--without-munge', - '--without-hxcomm-hostarq', - '--without-hxcomm-extoll', - '--project=pynn-brainscales', - '--release-branch=ebrains-' + str(self.spec.version) - ) - else: - python('./waf', 'setup', '--repo-db-url=https://github.com/electronicvisions/projects', - '--clone-depth=2', - '--without-munge', - '--without-hxcomm-hostarq', - '--project=pynn-brainscales', - '--release-branch=ebrains-' + str(self.spec.version) - ) - - - # in the configure step, we need access to all archived .git folders - def custom_archive(self, destination): - super(spack.fetch_strategy.GitFetchStrategy, self).archive(destination) - with unittest.mock.patch('spack.fetch_strategy.GitFetchStrategy.archive', new=custom_archive): - self.stage.cache_local() - - def _setup_common_env(self, env): - # grenade needs to find some libraries for the JIT-compilation of - # programs for BrainScaleS-2's embedded processor. - ppu_include_dirs = [] - ppu_dep_names = ['bitsery', 'boost', 'cereal'] - for ppu_dep_name in ppu_dep_names: - dep = self.spec[ppu_dep_name] - dep_include_dirs = set(dep.headers.directories) - ppu_include_dirs.extend(list(dep_include_dirs)) - for dir in reversed(ppu_include_dirs): - env.prepend_path("C_INCLUDE_PATH", dir) - env.prepend_path("CPLUS_INCLUDE_PATH", dir) - - def setup_build_environment(self, env): - my_envmod = EnvironmentModifications(env) - spack.build_environment.set_wrapper_variables(self, my_envmod) - my_env = {} - my_envmod.apply_modifications(my_env) - - def get_path(env, name): - path = env.get(name, "").strip() - if path: - return path.split(os.pathsep) - return [] - - # spack tries to find headers and libraries by itself (i.e. it's not - # relying on the compiler to find it); we explicitly expose the - # spack-provided env vars that contain include and library paths - if 'SPACK_INCLUDE_DIRS' in my_env: - for dir in reversed(get_path(my_env, "SPACK_INCLUDE_DIRS")): - env.prepend_path("C_INCLUDE_PATH", dir) - env.prepend_path("CPLUS_INCLUDE_PATH", dir) - if 'SPACK_LINK_DIRS' in my_env: - for dir in reversed(get_path(my_env, "SPACK_LINK_DIRS")): - env.prepend_path("LIBRARY_PATH", dir) - env.prepend_path("LD_LIBRARY_PATH", dir) - for dir in reversed(self.compiler.implicit_rpaths()): - env.prepend_path("LIBRARY_PATH", dir) - # technically this is probably not needed for the non-configure steps - env.prepend_path("LD_LIBRARY_PATH", dir) - - def setup_dependent_build_environment(self, env, dependent_spec): - self._setup_common_env(env) - - def setup_run_environment(self, env): - self._setup_common_env(env) - - def setup_dependent_run_environment(self, env, dependent_spec): - self._setup_common_env(env) - - # override configure step as we perform a project setup first - def configure(self, spec, prefix): - """Configure the project.""" - - args = ['--prefix={0}'.format(self.prefix)] - args += self.configure_args() - self.waf('configure', '--build-profile=release', '--disable-doxygen', *args) - - def build_args(self): - args = ['--keep', '--test-execnone', '-v'] - return args - - def build_test(self): - self.builder.waf('build', '--test-execall') - copy_tree('build/test_results', join_path(self.prefix, ".build")) - copy_tree('build/test_results', join_path(self.stage.path, ".install_time_tests")) - # propagate failures from junit output to spack - tree = ET.parse('build/test_results/summary.xml') - for testsuite in tree.getroot(): - for testcase in testsuite: - for elem in testcase: - if (elem.tag == 'failure') and not ( - elem.get('message').startswith("pylint:") or - elem.get('message').startswith("pycodestyle:") or - ("OK" in elem.get('message') and "Segmentation fault" in elem.get('message'))): - raise RuntimeError("Failed test found: {}".format(testcase.get('name'))) - - def install_args(self): - args = ['--test-execnone'] - return args - def install_test(self): with working_dir('spack-test', create=True): old_pythonpath = os.environ.get('PYTHONPATH', '') diff --git a/packages/wf-multi-area-model/package.py b/packages/wf-multi-area-model/package.py index 76db0cf2097ab9dab37df5f290378ba74535d8d3..bdfc5a549feab284b2d5b671b99ea5fde3739373 100644 --- a/packages/wf-multi-area-model/package.py +++ b/packages/wf-multi-area-model/package.py @@ -28,6 +28,7 @@ class WfMultiAreaModel(Package): depends_on("py-elephant", type=("run", "test")) depends_on("r-aod", type=("run", "test")) depends_on("py-notebook", type=("run", "test")) + depends_on("py-python-louvain", type=("run", "test")) def install(self, spec, prefix): install_tree(".", join_path(prefix, "notebooks")) diff --git a/spack.yaml b/spack.yaml index 726a38bc6b4b43582c064fcba2078aecbf370e34..9fc9e2c3f6737948b11f1ce1e7bfa127eb2be5f5 100644 --- a/spack.yaml +++ b/spack.yaml @@ -13,8 +13,9 @@ spack: - biobb-structure-checking@3.12.1 - biobb-structure-utils@4.0.0 - hxtorch@8.0-a3 - - nest@3.6 +sonata + - nest@3.7_rc1 +sonata - neuron@8.2.3 +mpi + - jaxsnn@8.0-a3 - py-bluepyefe@2.2.18 - py-bluepymm@0.7.65 - py-bluepyopt@1.13.86