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 index d1d7f5ebe3a010fddf40fbb71bbc8b2c91acb00b..cd66a37746f6c30760e1818e278a51e751fc2709 100644 --- a/packages/jaxsnn/package.py +++ b/packages/jaxsnn/package.py @@ -1,4 +1,4 @@ -# 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) @@ -10,8 +10,11 @@ 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(WafPackage): + +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.""" @@ -38,116 +41,6 @@ class Jaxsnn(WafPackage): depends_on('py-tree-math', 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') - python('./waf', 'setup', '--repo-db-url=https://github.com/electronicvisions/projects', - '--clone-depth=2', - '--without-munge', - '--without-hxcomm-hostarq', - '--project=jaxsnn', - '--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 - def install_test(self): with working_dir('spack-test', create=True): old_pythonpath = os.environ.get('PYTHONPATH', '') 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', '')