From 8a0636dc3eec4447112123c31f743ac1674cd049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Thu, 5 Jun 2025 14:36:38 +0200 Subject: [PATCH 01/32] add blueline uenv for running ICON with ICON4Py dycore. --- recipes/blueline/dev/g200/README.md | 2 + recipes/blueline/dev/g200/compilers.yaml | 5 + recipes/blueline/dev/g200/config.yaml | 7 + recipes/blueline/dev/g200/environments.yaml | 11 + .../dev/g200/repo/packages/ghex/package.py | 87 +++++++ .../hwmalloc/cmake_install_path.patch | 27 +++ .../g200/repo/packages/hwmalloc/package.py | 52 +++++ .../dev/g200/repo/packages/icon4py/package.py | 113 +++++++++ .../repo/packages/oomph/install_0.2.patch | 102 ++++++++ .../repo/packages/oomph/install_0.3.patch | 57 +++++ .../dev/g200/repo/packages/oomph/package.py | 109 +++++++++ .../dev/g200/repo/packages/py-uv/package.py | 33 +++ .../repo/packages/rust-bootstrap/package.py | 179 +++++++++++++++ .../dev/g200/repo/packages/rust/package.py | 217 ++++++++++++++++++ 14 files changed, 1001 insertions(+) create mode 100644 recipes/blueline/dev/g200/README.md create mode 100644 recipes/blueline/dev/g200/compilers.yaml create mode 100644 recipes/blueline/dev/g200/config.yaml create mode 100644 recipes/blueline/dev/g200/environments.yaml create mode 100644 recipes/blueline/dev/g200/repo/packages/ghex/package.py create mode 100644 recipes/blueline/dev/g200/repo/packages/hwmalloc/cmake_install_path.patch create mode 100644 recipes/blueline/dev/g200/repo/packages/hwmalloc/package.py create mode 100644 recipes/blueline/dev/g200/repo/packages/icon4py/package.py create mode 100644 recipes/blueline/dev/g200/repo/packages/oomph/install_0.2.patch create mode 100644 recipes/blueline/dev/g200/repo/packages/oomph/install_0.3.patch create mode 100644 recipes/blueline/dev/g200/repo/packages/oomph/package.py create mode 100644 recipes/blueline/dev/g200/repo/packages/py-uv/package.py create mode 100644 recipes/blueline/dev/g200/repo/packages/rust-bootstrap/package.py create mode 100644 recipes/blueline/dev/g200/repo/packages/rust/package.py diff --git a/recipes/blueline/dev/g200/README.md b/recipes/blueline/dev/g200/README.md new file mode 100644 index 0000000..27c75be --- /dev/null +++ b/recipes/blueline/dev/g200/README.md @@ -0,0 +1,2 @@ +# blueline-uenv +Experimental ALPS user environment for running blueline icon-exclaim diff --git a/recipes/blueline/dev/g200/compilers.yaml b/recipes/blueline/dev/g200/compilers.yaml new file mode 100644 index 0000000..1a86a3d --- /dev/null +++ b/recipes/blueline/dev/g200/compilers.yaml @@ -0,0 +1,5 @@ +bootstrap: + spec: gcc@11 +gcc: + specs: + - gcc@11 diff --git a/recipes/blueline/dev/g200/config.yaml b/recipes/blueline/dev/g200/config.yaml new file mode 100644 index 0000000..1c26eca --- /dev/null +++ b/recipes/blueline/dev/g200/config.yaml @@ -0,0 +1,7 @@ +name: icon4pypoc +store: /user-environment +spack: + repo: https://github.com/spack/spack.git + commit: releases/v0.23 +modules: false +description: icon4py proof-of-concept diff --git a/recipes/blueline/dev/g200/environments.yaml b/recipes/blueline/dev/g200/environments.yaml new file mode 100644 index 0000000..b02e8fd --- /dev/null +++ b/recipes/blueline/dev/g200/environments.yaml @@ -0,0 +1,11 @@ +myenv: + compiler: + - toolchain: gcc + spec: gcc + specs: + - icon4py@icon_20250328 +distributed +cuda + - py-mpi4py + - python + unify: true + views: + default: diff --git a/recipes/blueline/dev/g200/repo/packages/ghex/package.py b/recipes/blueline/dev/g200/repo/packages/ghex/package.py new file mode 100644 index 0000000..fc03b88 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/ghex/package.py @@ -0,0 +1,87 @@ +from spack.package import * + + +class Ghex(CMakePackage, CudaPackage, ROCmPackage): + """GHEX is a generic halo-exchange library.""" + + homepage = "https://github.com/ghex-org/GHEX" + url = "https://github.com/ghex-org/GHEX/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/GHEX.git" + maintainers = ["boeschf"] + + version("0.4.1", tag="v0.4.1", submodules=True) + version("0.4.0", tag="v0.4.0", submodules=True) + version("0.3.0", tag="v0.3.0", submodules=True) + version("master", branch="master", submodules=True) + + depends_on("cxx", type="build") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", default="mpi", description="Transport backend", values=backends, multi=False + ) + variant("xpmem", default=False, description="Use xpmem shared memory") + variant("python", default=True, description="Build Python bindings") + + depends_on("cmake@3.21:", type="build") + depends_on("mpi") + depends_on("boost") + depends_on("xpmem", when="+xpmem", type=("build", "run")) + + depends_on("oomph") + for backend in backends: + depends_on(f"oomph backend={backend}", when=f"backend={backend}") + depends_on("oomph+cuda", when="+cuda") + depends_on("oomph+rocm", when="+rocm") + depends_on("oomph@0.3:", when="@0.3:") + + conflicts("+cuda+rocm") + + with when("+python"): + extends("python") + depends_on("python@3.7:", type="build") + depends_on("py-pip", type="build") + depends_on("py-pybind11", type="build") + depends_on("py-mpi4py", type=("build", "run")) + depends_on("py-numpy", type=("build", "run")) + + depends_on("py-pytest", when="+python", type=("test")) + + def cmake_args(self): + spec = self.spec + + args = [ + self.define("GHEX_USE_BUNDLED_LIBS", True), + self.define("GHEX_USE_BUNDLED_GRIDTOOLS", True), + self.define("GHEX_USE_BUNDLED_GTEST", self.run_tests), + self.define("GHEX_USE_BUNDLED_OOMPH", False), + self.define("GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper()), + self.define_from_variant("GHEX_USE_XPMEM", "xpmem"), + self.define_from_variant("GHEX_BUILD_PYTHON_BINDINGS", "python"), + self.define("GHEX_WITH_TESTING", self.run_tests), + ] + + if spec.satisfies("+python"): + args.append(self.define("GHEX_PYTHON_LIB_PATH", python_platlib)) + + if self.run_tests and spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if "+cuda" in spec and spec.variants["cuda_arch"].value != "none": + arch_str = ";".join(spec.variants["cuda_arch"].value) + args.append(self.define("CMAKE_CUDA_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "CUDA")) + + if "+rocm" in spec and spec.variants["amdgpu_target"].value != "none": + arch_str = ";".join(spec.variants["amdgpu_target"].value) + args.append(self.define("CMAKE_HIP_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "AMD")) + + if spec.satisfies("~cuda~rocm"): + args.append(self.define("GHEX_USE_GPU", False)) + + return args diff --git a/recipes/blueline/dev/g200/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/blueline/dev/g200/repo/packages/hwmalloc/cmake_install_path.patch new file mode 100644 index 0000000..fa6fde1 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/hwmalloc/cmake_install_path.patch @@ -0,0 +1,27 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d5420e0..35dbe56 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -105,11 +105,11 @@ install(FILES ${PROJECT_BINARY_DIR}/include/hwmalloc/config.hpp + install(EXPORT HWMALLOC-targets + FILE HWMALLOC-targets.cmake + NAMESPACE HWMALLOC:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HWMALLOCConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + write_basic_package_version_file(HWMALLOCConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -120,7 +120,7 @@ install( + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfigVersion.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindNUMA.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + export(EXPORT HWMALLOC-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/HWMALLOC-targets.cmake") diff --git a/recipes/blueline/dev/g200/repo/packages/hwmalloc/package.py b/recipes/blueline/dev/g200/repo/packages/hwmalloc/package.py new file mode 100644 index 0000000..c656dc1 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/hwmalloc/package.py @@ -0,0 +1,52 @@ +from spack.package import * + + +class Hwmalloc(CMakePackage, CudaPackage, ROCmPackage): + """HWMALLOC is a allocator which supports memory registration for e.g. remote memory access""" + + homepage = "https://github.com/ghex-org/hwmalloc" + url = "https://github.com/ghex-org/hwmalloc/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/hwmalloc.git" + maintainers = ["boeschf"] + + version("0.3.0", sha256="d4d4ac6087a806600d79fb62c02719ca3d58a412968fe1ef4a2fd58d9e7ee950") + version("0.2.0", sha256="734758a390a3258b86307e4aef50a7ca2e5d0e2e579f18aeefcd05397e114419") + version("0.1.0", sha256="06e9bfcef0ecce4d19531ccbe03592b502d1281c7a092bc0ff51ca187899b21c") + version("master", branch="master") + + depends_on("cxx", type="build") + + generator("ninja") + + depends_on("numactl", type=("build", "run")) + depends_on("boost", type=("build")) + depends_on("cmake@3.19:", type="build") + + variant( + "numa-throws", + default=False, + description="True if numa_tools may throw during initialization", + ) + variant("numa-local", default=True, description="Use numa_tools for local node allocations") + variant("logging", default=False, description="print logging info to cerr") + + patch("cmake_install_path.patch", when="@:0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("HWMALLOC_NUMA_THROWS", "numa-throws"), + self.define_from_variant("HWMALLOC_NUMA_FOR_LOCAL", "numa-local"), + self.define_from_variant("HWMALLOC_ENABLE_LOGGING", "logging"), + self.define("HWMALLOC_WITH_TESTING", self.run_tests), + ] + + if "+cuda" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "cuda")) + elif "+rocm" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "hip")) + else: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", False)) + + return args diff --git a/recipes/blueline/dev/g200/repo/packages/icon4py/package.py b/recipes/blueline/dev/g200/repo/packages/icon4py/package.py new file mode 100644 index 0000000..649a9f9 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/icon4py/package.py @@ -0,0 +1,113 @@ +import json +import os +import pathlib + +import llnl +from llnl.util import tty +from spack import * + + +class Icon4py(Package): + extends("python") + depends_on("python@3.11:") + + variant("cuda", default=True, description="Enable CUDA support") + variant("distributed", default=True, description="Enable multinode support") + + depends_on("git") + depends_on("boost@1.85:", type=("build", "run")) + depends_on("py-uv@0.7:") + depends_on("bzip2", type="build") + depends_on("py-numpy") + depends_on("py-cffi") + depends_on("py-pybind11") + depends_on("py-nanobind") + depends_on("py-mpi4py", when="+distributed") + depends_on("py-cupy +cuda", when="+cuda") + depends_on("ghex +python", when="+distributed") + depends_on("ghex +python +cuda", when="+distributed +cuda") + + version( + "icon_20250328", + sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", + extension="zip", + ) + + def url_for_version(self, version): + return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" + + def install(self, spec, prefix): + uv = prepare_uv() + python_spec = spec["python"] + venv_path = prefix.share.venv + + tty.msg(f"creating venv using spack python at: {python_spec.command.path}") + uv( + "venv", + "--seed", + "--relocatable", + "--system-site-packages", + str(venv_path), + "--python", + python_spec.command.path, + ) + + tty.msg(f"grabbing spack installed packages (distributions)") + pip = Executable(venv_path.bin.pip) + spack_installed = get_installed_pkg(pip) + + tty.msg(f"installing missing packages") + uv( + "sync", + "--active", + "--extra", + "fortran", + "--inexact", + "--no-editable", + "--python", + str(venv_path.bin.python), + *no_install_options(spack_installed), + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + tty.msg(f"linking spack installed packages into venv") + pathlib.Path( + f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" + ).write_text(pythonpath_to_pth()) + + # uv("run", "--active", "py2fgen", "icon4py.tools.py2fgen.wrappers.all_bindings", "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", "icon4py_bindings", "-o", prefix.src, extra_env={"VIRTUAL_ENV": str(venv_path)}) + + tty.msg(f"running py2fgen") + py2fgen = Executable(venv_path.bin.py2fgen) + py2fgen( + "icon4py.tools.py2fgen.wrappers.all_bindings", + "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", + "icon4py_bindings", + "-o", + prefix.src, + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + +def prepare_uv(): + uv = which("uv") + uv.add_default_env("UV_NO_CACHE", "true") + uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") + uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") + return uv + + +def get_installed_pkg(pip): + return [ + item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) + ] + + +def no_install_options(installed): + for name in installed: + yield "--no-install-package" + yield name + + +def pythonpath_to_pth(): + return "\n".join(os.environ["PYTHONPATH"].split(":")) diff --git a/recipes/blueline/dev/g200/repo/packages/oomph/install_0.2.patch b/recipes/blueline/dev/g200/repo/packages/oomph/install_0.2.patch new file mode 100644 index 0000000..5dc7e2e --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/oomph/install_0.2.patch @@ -0,0 +1,102 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ba19089..2ba222a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,12 @@ + cmake_minimum_required(VERSION 3.17) + # CMake version is set at 3.17 because of find_package(CUDAToolkit) + ++if (NOT ${CMAKE_VERSION} VERSION_LESS 3.27) ++ # new in 3.27: additionally use uppercase _ROOT ++ # environment and CMake variables for find_package ++ cmake_policy(SET CMP0144 NEW) ++endif() ++ + set(OOMPH_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + list(APPEND CMAKE_MODULE_PATH "${OOMPH_MODULE_PATH}") + +@@ -108,11 +114,11 @@ endif() + install(EXPORT oomph-targets + FILE oomph-targets.cmake + NAMESPACE oomph:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/oomphConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/oomphConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + write_basic_package_version_file(oomphConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -125,7 +131,7 @@ install( + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindUCX.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindPMIx.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + export(EXPORT oomph-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/oomph-targets.cmake") +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index ec672b5..a578ef5 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -31,17 +31,30 @@ endif() + # --------------------------------------------------------------------- + # google test setup + # --------------------------------------------------------------------- +-add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +-# on some systems we need link explicitly against threads +-if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON ++ "OOMPH_USE_BUNDLED_LIBS" OFF) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() ++ else() ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() ++ endif() + endif() +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 06d703a..5217bba 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -65,6 +65,7 @@ function(reg_parallel_test t_ lib n) + NAME ${t} + COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${n} ${MPIEXEC_PREFLAGS} + $ ${MPIEXEC_POSTFLAGS}) ++ set_tests_properties(${t} PROPERTIES RUN_SERIAL TRUE) + endfunction() + + if (OOMPH_WITH_MPI) diff --git a/recipes/blueline/dev/g200/repo/packages/oomph/install_0.3.patch b/recipes/blueline/dev/g200/repo/packages/oomph/install_0.3.patch new file mode 100644 index 0000000..aac73e8 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/oomph/install_0.3.patch @@ -0,0 +1,57 @@ +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index a578ef5..92de39b 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -33,28 +33,30 @@ endif() + # --------------------------------------------------------------------- + cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON + "OOMPH_USE_BUNDLED_LIBS" OFF) +-if(OOMPH_USE_BUNDLED_GTEST) +- add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +- # on some systems we need link explicitly against threads +- if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) +- endif() +-else() +- # Use system provided google test +- find_package(GTest REQUIRED) +- add_library(ext-gtest INTERFACE) +- if (${CMAKE_VERSION} VERSION_LESS "3.20.0") +- target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() + else() +- target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() + endif() + endif() diff --git a/recipes/blueline/dev/g200/repo/packages/oomph/package.py b/recipes/blueline/dev/g200/repo/packages/oomph/package.py new file mode 100644 index 0000000..3b320f9 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/oomph/package.py @@ -0,0 +1,109 @@ +from spack.package import * + + +class Oomph(CMakePackage, CudaPackage, ROCmPackage): + """Oomph is a non-blocking callback-based point-to-point communication library.""" + + homepage = "https://github.com/ghex-org/oomph" + url = "https://github.com/ghex-org/oomph/archive/refs/tags/v0.2.0.tar.gz" + git = "https://github.com/ghex-org/oomph.git" + maintainers = ["boeschf"] + + version("0.4.0", sha256="e342c872dfe4832be047f172dc55c12951950c79da2630b071c61607ef913144") + version("0.3.0", sha256="61e346d1ba28a859745de47f37edce39c7f5c5e1aab716493dc964e158fd99ec") + version("0.2.0", sha256="135cdb856aa817c053b6af1617869dbcd0ee97d34607e78874dd775ea389434e") + version("0.1.0", sha256="0ff36db0a5f30ae1bb02f6db6d411ea72eadd89688c00f76b4e722bd5a9ba90b") + version("main", branch="main") + + depends_on("cxx", type="build") + depends_on("fortran", type="build", when="+fortran-bindings") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", default="mpi", description="Transport backend", values=backends, multi=False + ) + + variant("fortran-bindings", default=False, description="Build Fortran bindings") + with when("+fortran-bindings"): + variant( + "fortran-fp", + default="float", + description="Floating point type", + values=("float", "double"), + multi=False, + ) + variant("fortran-openmp", default=True, description="Compile with OpenMP") + + variant( + "enable-barrier", + default=True, + description="Enable thread barrier (disable for task based runtime)", + ) + + depends_on("hwmalloc+cuda", when="+cuda") + depends_on("hwmalloc+rocm", when="+rocm") + depends_on("hwmalloc", when="~cuda~rocm") + + with when("backend=ucx"): + depends_on("ucx+thread_multiple") + depends_on("ucx+cuda", when="+cuda") + depends_on("ucx+rocm", when="+rocm") + variant("use-pmix", default="False", description="Use PMIx to establish out-of-band setup") + variant("use-spin-lock", default="False", description="Use pthread spin locks") + depends_on("pmix", when="+use-pmix") + + libfabric_providers = ("cxi", "efa", "gni", "psm2", "tcp", "verbs") + with when("backend=libfabric"): + variant( + "libfabric-provider", + default="tcp", + description="fabric", + values=libfabric_providers, + multi=False, + ) + for provider in libfabric_providers: + depends_on(f"libfabric fabrics={provider}", when=f"libfabric-provider={provider}") + + depends_on("mpi") + depends_on("boost+thread") + + depends_on("googletest", type=("build","test")) + + patch("install_0.2.patch", when="@:0.2.0", level=1) + patch("install_0.3.patch", when="@0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("OOMPH_BUILD_FORTRAN", "fortran-bindings"), + self.define_from_variant("OOMPH_FORTRAN_OPENMP", "fortran-openmp"), + self.define_from_variant("OOMPH_UCX_USE_PMI", "use-pmix"), + self.define_from_variant("OOMPH_UCX_USE_SPIN_LOCK", "use-spin-lock"), + self.define_from_variant("OOMPH_ENABLE_BARRIER", "enable-barrier"), + self.define("OOMPH_WITH_TESTING", self.run_tests), + self.define("OOMPH_GIT_SUBMODULE", False), + self.define("OOMPH_USE_BUNDLED_LIBS", False), + ] + + if self.run_tests and self.spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if self.spec.variants["fortran-bindings"].value == True: + args.append(self.define("OOMPH_FORTRAN_FP", self.spec.variants["fortran-fp"].value)) + + for backend in self.backends: + args.append( + self.define( + f"OOMPH_WITH_{backend.upper()}", self.spec.variants["backend"].value == backend + ) + ) + + if self.spec.satisfies("backend=libfabric"): + args.append( + self.define( + "OOMPH_LIBFABRIC_PROVIDER", self.spec.variants["libfabric-provider"].value + ) + ) + + return args diff --git a/recipes/blueline/dev/g200/repo/packages/py-uv/package.py b/recipes/blueline/dev/g200/repo/packages/py-uv/package.py new file mode 100644 index 0000000..8d81d87 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/py-uv/package.py @@ -0,0 +1,33 @@ +# 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.package import * + + +class PyUv(PythonPackage): + """An extremely fast Python package and project manager, written in Rust.""" + + homepage = "https://github.com/astral-sh/uv" + pypi = "uv/0.4.15.tar.gz" + + license("APACHE 2.0 or MIT") + + version("0.7.1", sha256="40a15f1fc73df852d7655530e5768e29dc7227ab25d9baeb711a8dde9e7f8234") + version("0.4.27", sha256="c13eea45257362ecfa2a2b31de9b62fbd0542e211a573562d98ab7c8fc50d8fc") + version("0.4.17", sha256="01564bd760eff885ad61f44173647a569732934d1a4a558839c8088fbf75e53f") + version("0.4.16", sha256="2144995a87b161d063bd4ef8294b1e948677bd90d01f8394d0e3fca037bb847f") + version("0.4.15", sha256="8e36b8e07595fc6216d01e729c81a0b4ff029a93cc2ef987a73d3b650d6d559c") + + depends_on("rust@1.84:", type=("build", "run")) + depends_on("python@3.8:", type=("build", "run")) + depends_on("py-maturin@1:1", type="build") + depends_on("cmake", type="build") + depends_on("bzip2", type=("build", "run",)) + + @when("@:0.6.3") + def setup_build_environment(self, env): + env.set("CMAKE", self.spec["cmake"].prefix.bin.cmake) + + executables = ["^uv$"] diff --git a/recipes/blueline/dev/g200/repo/packages/rust-bootstrap/package.py b/recipes/blueline/dev/g200/repo/packages/rust-bootstrap/package.py new file mode 100644 index 0000000..fb838e5 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/rust-bootstrap/package.py @@ -0,0 +1,179 @@ +# 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 platform +import re + +from spack.package import * + + +class RustBootstrap(Package): + """Binary bootstrap Rust compiler.""" + + homepage = "https://www.rust-lang.org" + url = "https://static.rust-lang.org/dist/rust-1.65.0-aarch64-apple-darwin.tar.gz" + + maintainers("alecbcs") + + skip_version_audit = ["platform=windows"] + + # List binary rust releases for multiple operating systems and architectures. + # These binary versions are not intended to stay up-to-date. Instead we + # should update these binary releases as bootstrapping requirements are + # modified by new releases of Rust. + rust_releases = { + "1.85.0": { + "darwin": { + "x86_64": "69a36d239e38cc08c6366d1d85071847406645346c6f2d2e0dfaf64b58050d3d", + "aarch64": "3ff45cefaf9a002069902acf3a6332113b76b530bb31803fe5cfd30f7ef8ba03", + }, + "linux": { + "x86_64": "be4ba7b777100c851ab268e95f70f405d28d7813ba60a9bdcf4e88c88acf8602", + "aarch64": "0306c30bee00469fbec4b07bb04ea0308c096454354c3dc96a92b729f1c2acd1", + "powerpc64le": "d0761bf0e1786a46dddfe60cc9397b899f680b86e6aebd7ca16b2a70a9dd631b", + }, + }, + "1.82.0": { + "darwin": { + "x86_64": "b1a289cabc523f259f65116a41374ac159d72fbbf6c373bd5e545c8e835ceb6a", + "aarch64": "49b6d36b308addcfd21ae56c94957688338ba7b8985bff57fc626c8e1b32f62c", + }, + "linux": { + "x86_64": "0265c08ae997c4de965048a244605fb1f24a600bbe35047b811c638b8fcf676b", + "aarch64": "d7db04fce65b5f73282941f3f1df5893be9810af17eb7c65b2e614461fe31a48", + "powerpc64le": "44f3a1e70be33f91927ae8d89a11843a79b8b6124d62a9ddd9030a5275ebc923", + }, + }, + "1.81.0": { + "darwin": { + "x86_64": "f74d8ad24cc3cbfb825da98a08d98319565e4d18ec2c3e9503bf0a33c81ba767", + "aarch64": "60a41dea4ae0f4006325745a6400e6fdc3e08ad3f924fac06f04c238cf23f4ec", + }, + "linux": { + "x86_64": "4ca7c24e573dae2f382d8d266babfddc307155e1a0a4025f3bc11db58a6cab3e", + "aarch64": "ef4da9c1ecd56bbbb36f42793524cce3062e6a823ae22cb679a945c075c7755b", + "powerpc64le": "bf98b27de08a2fd5a2202a2b621b02bfde2a6fde397df2a735d018aeffcdc5e2", + }, + }, + "1.78.0": { + "darwin": { + "x86_64": "6c91ed3bd90253961fcb4a2991b8b22e042e2aaa9aba9f389f1e17008171d898", + "aarch64": "3be74c31ee8dc4f1d49e2f2888228de374138eaeca1876d0c1b1a61df6023b3b", + }, + "linux": { + "x86_64": "1307747915e8bd925f4d5396ab2ae3d8d9c7fad564afbc358c081683d0f22e87", + "aarch64": "131eda738cd977fff2c912e5838e8e9b9c260ecddc1247c0fe5473bf09c594af", + "powerpc64le": "c5aedb12c552daa18072e386697205fb7b91cef1e8791fe6fb74834723851388", + }, + }, + "1.75.0": { + "darwin": { + "x86_64": "ad066e4dec7ae5948c4e7afe68e250c336a5ab3d655570bb119b3eba9cf22851", + "aarch64": "878ecf81e059507dd2ab256f59629a4fb00171035d2a2f5638cb582d999373b1", + }, + "linux": { + "x86_64": "473978b6f8ff216389f9e89315211c6b683cf95a966196e7914b46e8cf0d74f6", + "aarch64": "30828cd904fcfb47f1ac43627c7033c903889ea4aca538f53dcafbb3744a9a73", + "powerpc64le": "2599cdfea5860b4efbceb7bca69845a96ac1c96aa50cf8261151e82280b397a0", + }, + }, + "1.73.0": { + "darwin": { + "x86_64": "ece9646bb153d4bc0f7f1443989de0cbcd8989a7d0bf3b7fb9956e1223954f0c", + "aarch64": "9c96e4c57328fb438ee2d87aa75970ce89b4426b49780ccb3c16af0d7c617cc6", + }, + "linux": { + "x86_64": "aa4cf0b7e66a9f5b7c623d4b340bb1ac2864a5f2c2b981f39f796245dc84f2cb", + "aarch64": "e54d7d886ba413ae573151f668e76ea537f9a44406d3d29598269a4a536d12f6", + "powerpc64le": "8fa215ee3e274fb64364e7084613bc570369488fa22cf5bc8e0fe6dc810fe2b9", + }, + }, + "1.70.0": { + "darwin": { + "x86_64": "e5819fdbfc7f1a4d5d82cb4c3b7662250748450b45a585433bfb75648bc45547", + "aarch64": "75cbc356a06c9b2daf6b9249febda0f0c46df2a427f7cc8467c7edbd44636e53", + }, + "linux": { + "x86_64": "8499c0b034dd881cd9a880c44021632422a28dc23d7a81ca0a97b04652245982", + "aarch64": "3aa012fc4d9d5f17ca30af41f87e1c2aacdac46b51adc5213e7614797c6fd24c", + "powerpc64le": "ba8cb5e3078b1bc7c6b27ab53cfa3af14001728db9a047d0bdf29b8f05a4db34", + }, + }, + "1.65.0": { + "darwin": { + "x86_64": "139087a3937799415fd829e5a88162a69a32c23725a44457f9c96b98e4d64a7c", + "aarch64": "7ddc335bd10fc32d3039ef36248a5d0c4865db2437c8aad20a2428a6cf41df09", + }, + "linux": { + "x86_64": "8f754fdd5af783fe9020978c64e414cb45f3ad0a6f44d045219bbf2210ca3cb9", + "aarch64": "f406136010e6a1cdce3fb6573506f00d23858af49dd20a46723c3fa5257b7796", + "powerpc64le": "3f1d0d5bb13213348dc65e373f8c412fc0a12ee55abc1c864f7e0300932fc687", + }, + }, + "1.60.0": { + "darwin": { + "x86_64": "0b10dc45cddc4d2355e38cac86d71a504327cb41d41d702d4050b9847ad4258c", + "aarch64": "b532672c278c25683ca63d78e82bae829eea1a32308e844954fb66cfe34ad222", + }, + "linux": { + "x86_64": "b8a4c3959367d053825e31f90a5eb86418eb0d80cacda52bfa80b078e18150d5", + "aarch64": "99c419c2f35d4324446481c39402c7baecd7a8baed7edca9f8d6bbd33c05550c", + "powerpc64le": "80125e90285b214c2b1f56ab86a09c8509aa17aec9d7127960a86a7008e8f7de", + }, + }, + } + + # Normalize architectures returned by platform to those used by the + # Rust project. + rust_targets = { + "aarch64": "aarch64", + "amd64": "x86_64", + "arm64": "aarch64", + "powerpc64le": "powerpc64le", + "ppc64le": "powerpc64le", + "x86_64": "x86_64", + } + + # Convert operating system names into the format used for Rust + # download server. + rust_os = {"darwin": "apple-darwin", "linux": "unknown-linux-gnu"} + + # Determine system os and architecture/target. + os = platform.system().lower() + target = rust_targets.get(platform.machine().lower(), platform.machine().lower()) + + # Pre-release versions of the bootstrap compiler. + # Note: These versions are unchecksumed since they will change + # periodically as new versions are released. + version("beta") + version("nightly") + + # Stable releases of the bootstrap compiler. + # Construct releases for current system configuration. + for release in rust_releases: + if os in rust_releases[release] and target in rust_releases[release][os]: + version(release, sha256=rust_releases[release][os][target]) + + def url_for_version(self, version): + if self.os not in ("linux", "darwin"): + return None + + # Allow maintainers to checksum multiple architectures via + # `spack checksum rust-bootstrap@1.70.0-darwin-aarch64`. + match = re.search(r"(\S+)-(\S+)-(\S+)", str(version)) + if match: + version = match.group(1) + os = self.rust_os[match.group(2)] + target = self.rust_targets[match.group(3)] + else: + os = self.rust_os[self.os] + target = self.target + + url = "https://static.rust-lang.org/dist/rust-{0}-{1}-{2}.tar.gz" + return url.format(version, target, os) + + def install(self, spec, prefix): + install_script = Executable("./install.sh") + install_args = [f"--prefix={prefix}", "--without=rust-docs"] + install_script(" ".join(install_args)) diff --git a/recipes/blueline/dev/g200/repo/packages/rust/package.py b/recipes/blueline/dev/g200/repo/packages/rust/package.py new file mode 100644 index 0000000..87e4206 --- /dev/null +++ b/recipes/blueline/dev/g200/repo/packages/rust/package.py @@ -0,0 +1,217 @@ +# 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 re + +from spack.package import * + + +class Rust(Package): + """The Rust programming language toolchain.""" + + homepage = "https://www.rust-lang.org" + url = "https://static.rust-lang.org/dist/rustc-1.42.0-src.tar.gz" + git = "https://github.com/rust-lang/rust.git" + + maintainers("alecbcs") + + license("Apache-2.0 OR MIT") + + # When adding a version of Rust you may need to add an additional version + # to rust-bootstrap as the minimum bootstrapping requirements increase. + # As a general rule of thumb Rust can be built with either the previous major + # version or the current version of the compiler as shown above. + # + # Pre-release versions. + # Note: If you plan to use these versions remember to install with + # `-n` to prevent Spack from failing due to failed checksums. + # + # $ spack install -n rust@pre-release-version + # + version("beta") + version("master", branch="master", submodules=True) + version("nightly") + + # Stable versions. + version("1.86.0", sha256="022a27286df67900a044d227d9db69d4732ec3d833e4ffc259c4425ed71eed80") + version("1.85.0", sha256="2f4f3142ffb7c8402139cfa0796e24baaac8b9fd3f96b2deec3b94b4045c6a8a") + version("1.83.0", sha256="722d773bd4eab2d828d7dd35b59f0b017ddf9a97ee2b46c1b7f7fac5c8841c6e") + version("1.81.0", sha256="872448febdff32e50c3c90a7e15f9bb2db131d13c588fe9071b0ed88837ccfa7") + version("1.78.0", sha256="ff544823a5cb27f2738128577f1e7e00ee8f4c83f2a348781ae4fc355e91d5a9") + version("1.76.0", sha256="9e5cff033a7f0d2266818982ad90e4d3e4ef8f8ee1715776c6e25073a136c021") + version("1.75.0", sha256="5b739f45bc9d341e2d1c570d65d2375591e22c2d23ef5b8a37711a0386abc088") + version("1.74.0", sha256="882b584bc321c5dcfe77cdaa69f277906b936255ef7808fcd5c7492925cf1049") + version("1.73.0", sha256="96d62e6d1f2d21df7ac8acb3b9882411f9e7c7036173f7f2ede9e1f1f6b1bb3a") + version("1.70.0", sha256="b2bfae000b7a5040e4ec4bbc50a09f21548190cb7570b0ed77358368413bd27c") + version("1.65.0", sha256="5828bb67f677eabf8c384020582b0ce7af884e1c84389484f7f8d00dd82c0038") + version("1.60.0", sha256="20ca826d1cf674daf8e22c4f8c4b9743af07973211c839b85839742314c838b7") + + depends_on("c", type="build") + depends_on("cxx", type="build") + + variant( + "dev", + default=False, + description="Include rust developer tools like rustfmt, clippy, and rust-analyzer.", + ) + variant("docs", default=False, description="Build Rust core documentation.") + variant("src", default=True, description="Include standard library source files.") + + # Core dependencies + depends_on("curl+nghttp2") + depends_on("libgit2") + depends_on("libssh2") + depends_on("ninja", type="build") + depends_on("openssl") + depends_on("pkgconfig", type="build") + depends_on("python", type="build") + depends_on("zlib-api") + + # cmake dependency comes from LLVM. Rust has their own fork of LLVM, with tags corresponding + # to each Rust release, so it's easy to loop through tags and grep for "cmake_minimum_required" + depends_on("cmake@3.4.3:", type="build", when="@:1.51") + depends_on("cmake@3.13.4:", type="build", when="@1.52:1.72") + depends_on("cmake@3.20.0:", type="build", when="@1.73:") + + # Compiling Rust requires a previous version of Rust. + # The easiest way to bootstrap a Rust environment is to + # download the binary distribution of the compiler and build with that. + depends_on("rust-bootstrap", type="build") + + # Pre-release version dependencies + depends_on("rust-bootstrap@beta", type="build", when="@beta") + depends_on("rust-bootstrap@nightly", type="build", when="@master") + depends_on("rust-bootstrap@nightly", type="build", when="@nightly") + + # Stable version dependencies + depends_on("rust-bootstrap", type="build") + depends_on("rust-bootstrap@1.59:1.60", type="build", when="@1.60") + depends_on("rust-bootstrap@1.64:1.65", type="build", when="@1.65") + depends_on("rust-bootstrap@1.69:1.70", type="build", when="@1.70") + depends_on("rust-bootstrap@1.72:1.73", type="build", when="@1.73") + depends_on("rust-bootstrap@1.73:1.74", type="build", when="@1.74") + depends_on("rust-bootstrap@1.74:1.75", type="build", when="@1.75") + depends_on("rust-bootstrap@1.77:1.78", type="build", when="@1.78") + depends_on("rust-bootstrap@1.80:1.81", type="build", when="@1.81") + depends_on("rust-bootstrap@1.82:1.83", type="build", when="@1.83") + depends_on("rust-bootstrap@1.84:1.85", type="build", when="@1.85") + + # src/llvm-project/llvm/cmake/modules/CheckCompilerVersion.cmake + conflicts("%gcc@:7.3", when="@1.73:", msg="Host GCC version must be at least 7.4") + # https://github.com/rust-lang/llvm-project/commit/4d039a7a71899038b3bc6ed6fe5a8a48d915caa0 + conflicts("%gcc@13:", when="@:1.63", msg="Rust<1.64 not compatible with GCC>=13") + conflicts("%intel", msg="Rust not compatible with Intel Classic compilers") + conflicts("%oneapi", msg="Rust not compatible with Intel oneAPI compilers") + + extendable = True + executables = ["^rustc$", "^cargo$"] + + phases = ["configure", "build", "install"] + + @classmethod + def determine_spec_details(cls, prefix, exes_in_prefix): + rustc_candidates = [x for x in exes_in_prefix if os.path.basename(x) == "rustc"] + cargo_candidates = [x for x in exes_in_prefix if os.path.basename(x) == "cargo"] + # Both rustc and cargo must be present + if not (rustc_candidates and cargo_candidates): + return + output = Executable(rustc_candidates[0])("--version", output=str, error=str) + match = re.match(r"rustc (\S+)", output) + if match: + version_str = match.group(1) + return Spec.from_detection(f"rust@{version_str}", external_path=prefix) + + def setup_dependent_package(self, module, dependent_spec): + module.cargo = Executable(os.path.join(self.spec.prefix.bin, "cargo")) + + def setup_build_environment(self, env): + # Manually instruct Cargo dependency libssh2-sys to build with + # the Spack installed libssh2 package. For more info see + # https://github.com/alexcrichton/ssh2-rs/issues/173 + env.set("LIBSSH2_SYS_USE_PKG_CONFIG", "1") + + # Manually inject the path of ar for build. + ar = which("ar", required=True) + env.set("AR", ar.path) + + # Manually inject the path of openssl's certs for build + # if certs are present on system via Spack or via external + # openssl. + def get_test_path(p): + certs = join_path(p, "cert.pem") + if os.path.exists(certs): + return certs + return None + + # find certs, don't set if no file is found in case + # ca-certificates isn't installed + certs = None + openssl = self.spec["openssl"] + if openssl.external: + try: + output = which("openssl", required=True)("version", "-d", output=str, error=str) + openssl_dir = re.match('OPENSSLDIR: "([^"]+)"', output) + if openssl_dir: + certs = get_test_path(openssl_dir.group(1)) + except ProcessError: + pass + + if certs is None: + certs = get_test_path(join_path(openssl.prefix, "etc/openssl")) + + if certs is not None: + env.set("CARGO_HTTP_CAINFO", certs) + + def configure(self, spec, prefix): + opts = [] + + # Set prefix to install into spack prefix. + opts.append(f"install.prefix={prefix}") + + # Set relative path to put system configuration files + # under the Spack package prefix. + opts.append("install.sysconfdir=etc") + + # Build extended suite of tools so dependent packages + # packages can build using cargo. + opts.append("build.extended=true") + + # Build docs if specified by the +docs variant. + opts.append(f"build.docs={str(spec.satisfies('+docs')).lower()}") + + # Set binary locations for bootstrap rustc and cargo. + opts.append(f"build.cargo={spec['rust-bootstrap'].prefix.bin.cargo}") + opts.append(f"build.rustc={spec['rust-bootstrap'].prefix.bin.rustc}") + + # Disable bootstrap LLVM download. + opts.append("llvm.download-ci-llvm=false") + + # Convert opts to '--set key=value' format. + flags = [flag for opt in opts for flag in ("--set", opt)] + + # Core rust tools to install. + tools = ["cargo"] + + # Add additional tools as directed by the package variants. + if spec.satisfies("+dev"): + tools.extend(["clippy", "rustdoc", "rustfmt", "rust-analyzer"]) + + if spec.satisfies("+src"): + tools.append("src") + + # Compile tools into flag for configure. + flags.append(f"--tools={','.join(tools)}") + + # Use vendored resources to perform offline build. + flags.append("--enable-vendor") + + configure(*flags) + + def build(self, spec, prefix): + python("./x.py", "build") + + def install(self, spec, prefix): + python("./x.py", "install") From 2ed4c347a30c09b1ff38180acee0d33d7747eef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Tue, 10 Jun 2025 14:10:26 +0200 Subject: [PATCH 02/32] rename blueline -> icon-dsl & add to config --- config.yaml | 7 +++++++ recipes/blueline/dev/g200/README.md | 2 -- .../{blueline/dev => icon-dsl/25.8}/g200/compilers.yaml | 0 recipes/{blueline/dev => icon-dsl/25.8}/g200/config.yaml | 0 .../{blueline/dev => icon-dsl/25.8}/g200/environments.yaml | 0 .../25.8}/g200/repo/packages/ghex/package.py | 0 .../g200/repo/packages/hwmalloc/cmake_install_path.patch | 0 .../25.8}/g200/repo/packages/hwmalloc/package.py | 0 .../25.8}/g200/repo/packages/icon4py/package.py | 0 .../25.8}/g200/repo/packages/oomph/install_0.2.patch | 0 .../25.8}/g200/repo/packages/oomph/install_0.3.patch | 0 .../25.8}/g200/repo/packages/oomph/package.py | 0 .../25.8}/g200/repo/packages/py-uv/package.py | 0 .../25.8}/g200/repo/packages/rust-bootstrap/package.py | 0 .../25.8}/g200/repo/packages/rust/package.py | 0 recipes/icon-dsl/README.md | 2 ++ 16 files changed, 9 insertions(+), 2 deletions(-) delete mode 100644 recipes/blueline/dev/g200/README.md rename recipes/{blueline/dev => icon-dsl/25.8}/g200/compilers.yaml (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/config.yaml (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/environments.yaml (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/ghex/package.py (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/hwmalloc/cmake_install_path.patch (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/hwmalloc/package.py (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/icon4py/package.py (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/oomph/install_0.2.patch (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/oomph/install_0.3.patch (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/oomph/package.py (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/py-uv/package.py (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/rust-bootstrap/package.py (100%) rename recipes/{blueline/dev => icon-dsl/25.8}/g200/repo/packages/rust/package.py (100%) create mode 100644 recipes/icon-dsl/README.md diff --git a/config.yaml b/config.yaml index 0922ead..90e74d3 100644 --- a/config.yaml +++ b/config.yaml @@ -39,6 +39,13 @@ uenvs: santis: [gh200] balfrin: [a100] develop: False + icon-dsl: + "25.8": + recipes: + gh200: '25.8/gh200' + deploy: + santis: [gh200] + develop: False mch: "v7": recipes: diff --git a/recipes/blueline/dev/g200/README.md b/recipes/blueline/dev/g200/README.md deleted file mode 100644 index 27c75be..0000000 --- a/recipes/blueline/dev/g200/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# blueline-uenv -Experimental ALPS user environment for running blueline icon-exclaim diff --git a/recipes/blueline/dev/g200/compilers.yaml b/recipes/icon-dsl/25.8/g200/compilers.yaml similarity index 100% rename from recipes/blueline/dev/g200/compilers.yaml rename to recipes/icon-dsl/25.8/g200/compilers.yaml diff --git a/recipes/blueline/dev/g200/config.yaml b/recipes/icon-dsl/25.8/g200/config.yaml similarity index 100% rename from recipes/blueline/dev/g200/config.yaml rename to recipes/icon-dsl/25.8/g200/config.yaml diff --git a/recipes/blueline/dev/g200/environments.yaml b/recipes/icon-dsl/25.8/g200/environments.yaml similarity index 100% rename from recipes/blueline/dev/g200/environments.yaml rename to recipes/icon-dsl/25.8/g200/environments.yaml diff --git a/recipes/blueline/dev/g200/repo/packages/ghex/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/ghex/package.py similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/ghex/package.py rename to recipes/icon-dsl/25.8/g200/repo/packages/ghex/package.py diff --git a/recipes/blueline/dev/g200/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/cmake_install_path.patch similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/hwmalloc/cmake_install_path.patch rename to recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/cmake_install_path.patch diff --git a/recipes/blueline/dev/g200/repo/packages/hwmalloc/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/package.py similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/hwmalloc/package.py rename to recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/package.py diff --git a/recipes/blueline/dev/g200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/icon4py/package.py similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/icon4py/package.py rename to recipes/icon-dsl/25.8/g200/repo/packages/icon4py/package.py diff --git a/recipes/blueline/dev/g200/repo/packages/oomph/install_0.2.patch b/recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.2.patch similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/oomph/install_0.2.patch rename to recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.2.patch diff --git a/recipes/blueline/dev/g200/repo/packages/oomph/install_0.3.patch b/recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.3.patch similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/oomph/install_0.3.patch rename to recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.3.patch diff --git a/recipes/blueline/dev/g200/repo/packages/oomph/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/oomph/package.py similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/oomph/package.py rename to recipes/icon-dsl/25.8/g200/repo/packages/oomph/package.py diff --git a/recipes/blueline/dev/g200/repo/packages/py-uv/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/py-uv/package.py similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/py-uv/package.py rename to recipes/icon-dsl/25.8/g200/repo/packages/py-uv/package.py diff --git a/recipes/blueline/dev/g200/repo/packages/rust-bootstrap/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/rust-bootstrap/package.py similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/rust-bootstrap/package.py rename to recipes/icon-dsl/25.8/g200/repo/packages/rust-bootstrap/package.py diff --git a/recipes/blueline/dev/g200/repo/packages/rust/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/rust/package.py similarity index 100% rename from recipes/blueline/dev/g200/repo/packages/rust/package.py rename to recipes/icon-dsl/25.8/g200/repo/packages/rust/package.py diff --git a/recipes/icon-dsl/README.md b/recipes/icon-dsl/README.md new file mode 100644 index 0000000..bb7fc25 --- /dev/null +++ b/recipes/icon-dsl/README.md @@ -0,0 +1,2 @@ +# ICON-DSL UENV +Experimental ALPS user environment for running icon-exclaim with DSL dycore. From 6052ca2a44f3d52c05b572ed946ff886da534f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Fri, 13 Jun 2025 10:45:49 +0200 Subject: [PATCH 03/32] replace updated py-uv package with uv from binary releases also: - add variants for gh200 --- recipes/icon-dsl/25.8/g200/environments.yaml | 5 + .../25.8/g200/repo/packages/py-uv/package.py | 33 --- .../repo/packages/rust-bootstrap/package.py | 179 --------------- .../25.8/g200/repo/packages/rust/package.py | 217 ------------------ .../25.8/g200/repo/packages/uv/package.py | 61 +++++ 5 files changed, 66 insertions(+), 429 deletions(-) delete mode 100644 recipes/icon-dsl/25.8/g200/repo/packages/py-uv/package.py delete mode 100644 recipes/icon-dsl/25.8/g200/repo/packages/rust-bootstrap/package.py delete mode 100644 recipes/icon-dsl/25.8/g200/repo/packages/rust/package.py create mode 100644 recipes/icon-dsl/25.8/g200/repo/packages/uv/package.py diff --git a/recipes/icon-dsl/25.8/g200/environments.yaml b/recipes/icon-dsl/25.8/g200/environments.yaml index b02e8fd..f53b81f 100644 --- a/recipes/icon-dsl/25.8/g200/environments.yaml +++ b/recipes/icon-dsl/25.8/g200/environments.yaml @@ -4,8 +4,13 @@ myenv: spec: gcc specs: - icon4py@icon_20250328 +distributed +cuda + - py-cupy - py-mpi4py - python unify: true + variants: + - +mpi + - +cuda + - cuda_arch=90 views: default: diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/py-uv/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/py-uv/package.py deleted file mode 100644 index 8d81d87..0000000 --- a/recipes/icon-dsl/25.8/g200/repo/packages/py-uv/package.py +++ /dev/null @@ -1,33 +0,0 @@ -# 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.package import * - - -class PyUv(PythonPackage): - """An extremely fast Python package and project manager, written in Rust.""" - - homepage = "https://github.com/astral-sh/uv" - pypi = "uv/0.4.15.tar.gz" - - license("APACHE 2.0 or MIT") - - version("0.7.1", sha256="40a15f1fc73df852d7655530e5768e29dc7227ab25d9baeb711a8dde9e7f8234") - version("0.4.27", sha256="c13eea45257362ecfa2a2b31de9b62fbd0542e211a573562d98ab7c8fc50d8fc") - version("0.4.17", sha256="01564bd760eff885ad61f44173647a569732934d1a4a558839c8088fbf75e53f") - version("0.4.16", sha256="2144995a87b161d063bd4ef8294b1e948677bd90d01f8394d0e3fca037bb847f") - version("0.4.15", sha256="8e36b8e07595fc6216d01e729c81a0b4ff029a93cc2ef987a73d3b650d6d559c") - - depends_on("rust@1.84:", type=("build", "run")) - depends_on("python@3.8:", type=("build", "run")) - depends_on("py-maturin@1:1", type="build") - depends_on("cmake", type="build") - depends_on("bzip2", type=("build", "run",)) - - @when("@:0.6.3") - def setup_build_environment(self, env): - env.set("CMAKE", self.spec["cmake"].prefix.bin.cmake) - - executables = ["^uv$"] diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/rust-bootstrap/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/rust-bootstrap/package.py deleted file mode 100644 index fb838e5..0000000 --- a/recipes/icon-dsl/25.8/g200/repo/packages/rust-bootstrap/package.py +++ /dev/null @@ -1,179 +0,0 @@ -# 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 platform -import re - -from spack.package import * - - -class RustBootstrap(Package): - """Binary bootstrap Rust compiler.""" - - homepage = "https://www.rust-lang.org" - url = "https://static.rust-lang.org/dist/rust-1.65.0-aarch64-apple-darwin.tar.gz" - - maintainers("alecbcs") - - skip_version_audit = ["platform=windows"] - - # List binary rust releases for multiple operating systems and architectures. - # These binary versions are not intended to stay up-to-date. Instead we - # should update these binary releases as bootstrapping requirements are - # modified by new releases of Rust. - rust_releases = { - "1.85.0": { - "darwin": { - "x86_64": "69a36d239e38cc08c6366d1d85071847406645346c6f2d2e0dfaf64b58050d3d", - "aarch64": "3ff45cefaf9a002069902acf3a6332113b76b530bb31803fe5cfd30f7ef8ba03", - }, - "linux": { - "x86_64": "be4ba7b777100c851ab268e95f70f405d28d7813ba60a9bdcf4e88c88acf8602", - "aarch64": "0306c30bee00469fbec4b07bb04ea0308c096454354c3dc96a92b729f1c2acd1", - "powerpc64le": "d0761bf0e1786a46dddfe60cc9397b899f680b86e6aebd7ca16b2a70a9dd631b", - }, - }, - "1.82.0": { - "darwin": { - "x86_64": "b1a289cabc523f259f65116a41374ac159d72fbbf6c373bd5e545c8e835ceb6a", - "aarch64": "49b6d36b308addcfd21ae56c94957688338ba7b8985bff57fc626c8e1b32f62c", - }, - "linux": { - "x86_64": "0265c08ae997c4de965048a244605fb1f24a600bbe35047b811c638b8fcf676b", - "aarch64": "d7db04fce65b5f73282941f3f1df5893be9810af17eb7c65b2e614461fe31a48", - "powerpc64le": "44f3a1e70be33f91927ae8d89a11843a79b8b6124d62a9ddd9030a5275ebc923", - }, - }, - "1.81.0": { - "darwin": { - "x86_64": "f74d8ad24cc3cbfb825da98a08d98319565e4d18ec2c3e9503bf0a33c81ba767", - "aarch64": "60a41dea4ae0f4006325745a6400e6fdc3e08ad3f924fac06f04c238cf23f4ec", - }, - "linux": { - "x86_64": "4ca7c24e573dae2f382d8d266babfddc307155e1a0a4025f3bc11db58a6cab3e", - "aarch64": "ef4da9c1ecd56bbbb36f42793524cce3062e6a823ae22cb679a945c075c7755b", - "powerpc64le": "bf98b27de08a2fd5a2202a2b621b02bfde2a6fde397df2a735d018aeffcdc5e2", - }, - }, - "1.78.0": { - "darwin": { - "x86_64": "6c91ed3bd90253961fcb4a2991b8b22e042e2aaa9aba9f389f1e17008171d898", - "aarch64": "3be74c31ee8dc4f1d49e2f2888228de374138eaeca1876d0c1b1a61df6023b3b", - }, - "linux": { - "x86_64": "1307747915e8bd925f4d5396ab2ae3d8d9c7fad564afbc358c081683d0f22e87", - "aarch64": "131eda738cd977fff2c912e5838e8e9b9c260ecddc1247c0fe5473bf09c594af", - "powerpc64le": "c5aedb12c552daa18072e386697205fb7b91cef1e8791fe6fb74834723851388", - }, - }, - "1.75.0": { - "darwin": { - "x86_64": "ad066e4dec7ae5948c4e7afe68e250c336a5ab3d655570bb119b3eba9cf22851", - "aarch64": "878ecf81e059507dd2ab256f59629a4fb00171035d2a2f5638cb582d999373b1", - }, - "linux": { - "x86_64": "473978b6f8ff216389f9e89315211c6b683cf95a966196e7914b46e8cf0d74f6", - "aarch64": "30828cd904fcfb47f1ac43627c7033c903889ea4aca538f53dcafbb3744a9a73", - "powerpc64le": "2599cdfea5860b4efbceb7bca69845a96ac1c96aa50cf8261151e82280b397a0", - }, - }, - "1.73.0": { - "darwin": { - "x86_64": "ece9646bb153d4bc0f7f1443989de0cbcd8989a7d0bf3b7fb9956e1223954f0c", - "aarch64": "9c96e4c57328fb438ee2d87aa75970ce89b4426b49780ccb3c16af0d7c617cc6", - }, - "linux": { - "x86_64": "aa4cf0b7e66a9f5b7c623d4b340bb1ac2864a5f2c2b981f39f796245dc84f2cb", - "aarch64": "e54d7d886ba413ae573151f668e76ea537f9a44406d3d29598269a4a536d12f6", - "powerpc64le": "8fa215ee3e274fb64364e7084613bc570369488fa22cf5bc8e0fe6dc810fe2b9", - }, - }, - "1.70.0": { - "darwin": { - "x86_64": "e5819fdbfc7f1a4d5d82cb4c3b7662250748450b45a585433bfb75648bc45547", - "aarch64": "75cbc356a06c9b2daf6b9249febda0f0c46df2a427f7cc8467c7edbd44636e53", - }, - "linux": { - "x86_64": "8499c0b034dd881cd9a880c44021632422a28dc23d7a81ca0a97b04652245982", - "aarch64": "3aa012fc4d9d5f17ca30af41f87e1c2aacdac46b51adc5213e7614797c6fd24c", - "powerpc64le": "ba8cb5e3078b1bc7c6b27ab53cfa3af14001728db9a047d0bdf29b8f05a4db34", - }, - }, - "1.65.0": { - "darwin": { - "x86_64": "139087a3937799415fd829e5a88162a69a32c23725a44457f9c96b98e4d64a7c", - "aarch64": "7ddc335bd10fc32d3039ef36248a5d0c4865db2437c8aad20a2428a6cf41df09", - }, - "linux": { - "x86_64": "8f754fdd5af783fe9020978c64e414cb45f3ad0a6f44d045219bbf2210ca3cb9", - "aarch64": "f406136010e6a1cdce3fb6573506f00d23858af49dd20a46723c3fa5257b7796", - "powerpc64le": "3f1d0d5bb13213348dc65e373f8c412fc0a12ee55abc1c864f7e0300932fc687", - }, - }, - "1.60.0": { - "darwin": { - "x86_64": "0b10dc45cddc4d2355e38cac86d71a504327cb41d41d702d4050b9847ad4258c", - "aarch64": "b532672c278c25683ca63d78e82bae829eea1a32308e844954fb66cfe34ad222", - }, - "linux": { - "x86_64": "b8a4c3959367d053825e31f90a5eb86418eb0d80cacda52bfa80b078e18150d5", - "aarch64": "99c419c2f35d4324446481c39402c7baecd7a8baed7edca9f8d6bbd33c05550c", - "powerpc64le": "80125e90285b214c2b1f56ab86a09c8509aa17aec9d7127960a86a7008e8f7de", - }, - }, - } - - # Normalize architectures returned by platform to those used by the - # Rust project. - rust_targets = { - "aarch64": "aarch64", - "amd64": "x86_64", - "arm64": "aarch64", - "powerpc64le": "powerpc64le", - "ppc64le": "powerpc64le", - "x86_64": "x86_64", - } - - # Convert operating system names into the format used for Rust - # download server. - rust_os = {"darwin": "apple-darwin", "linux": "unknown-linux-gnu"} - - # Determine system os and architecture/target. - os = platform.system().lower() - target = rust_targets.get(platform.machine().lower(), platform.machine().lower()) - - # Pre-release versions of the bootstrap compiler. - # Note: These versions are unchecksumed since they will change - # periodically as new versions are released. - version("beta") - version("nightly") - - # Stable releases of the bootstrap compiler. - # Construct releases for current system configuration. - for release in rust_releases: - if os in rust_releases[release] and target in rust_releases[release][os]: - version(release, sha256=rust_releases[release][os][target]) - - def url_for_version(self, version): - if self.os not in ("linux", "darwin"): - return None - - # Allow maintainers to checksum multiple architectures via - # `spack checksum rust-bootstrap@1.70.0-darwin-aarch64`. - match = re.search(r"(\S+)-(\S+)-(\S+)", str(version)) - if match: - version = match.group(1) - os = self.rust_os[match.group(2)] - target = self.rust_targets[match.group(3)] - else: - os = self.rust_os[self.os] - target = self.target - - url = "https://static.rust-lang.org/dist/rust-{0}-{1}-{2}.tar.gz" - return url.format(version, target, os) - - def install(self, spec, prefix): - install_script = Executable("./install.sh") - install_args = [f"--prefix={prefix}", "--without=rust-docs"] - install_script(" ".join(install_args)) diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/rust/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/rust/package.py deleted file mode 100644 index 87e4206..0000000 --- a/recipes/icon-dsl/25.8/g200/repo/packages/rust/package.py +++ /dev/null @@ -1,217 +0,0 @@ -# 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 re - -from spack.package import * - - -class Rust(Package): - """The Rust programming language toolchain.""" - - homepage = "https://www.rust-lang.org" - url = "https://static.rust-lang.org/dist/rustc-1.42.0-src.tar.gz" - git = "https://github.com/rust-lang/rust.git" - - maintainers("alecbcs") - - license("Apache-2.0 OR MIT") - - # When adding a version of Rust you may need to add an additional version - # to rust-bootstrap as the minimum bootstrapping requirements increase. - # As a general rule of thumb Rust can be built with either the previous major - # version or the current version of the compiler as shown above. - # - # Pre-release versions. - # Note: If you plan to use these versions remember to install with - # `-n` to prevent Spack from failing due to failed checksums. - # - # $ spack install -n rust@pre-release-version - # - version("beta") - version("master", branch="master", submodules=True) - version("nightly") - - # Stable versions. - version("1.86.0", sha256="022a27286df67900a044d227d9db69d4732ec3d833e4ffc259c4425ed71eed80") - version("1.85.0", sha256="2f4f3142ffb7c8402139cfa0796e24baaac8b9fd3f96b2deec3b94b4045c6a8a") - version("1.83.0", sha256="722d773bd4eab2d828d7dd35b59f0b017ddf9a97ee2b46c1b7f7fac5c8841c6e") - version("1.81.0", sha256="872448febdff32e50c3c90a7e15f9bb2db131d13c588fe9071b0ed88837ccfa7") - version("1.78.0", sha256="ff544823a5cb27f2738128577f1e7e00ee8f4c83f2a348781ae4fc355e91d5a9") - version("1.76.0", sha256="9e5cff033a7f0d2266818982ad90e4d3e4ef8f8ee1715776c6e25073a136c021") - version("1.75.0", sha256="5b739f45bc9d341e2d1c570d65d2375591e22c2d23ef5b8a37711a0386abc088") - version("1.74.0", sha256="882b584bc321c5dcfe77cdaa69f277906b936255ef7808fcd5c7492925cf1049") - version("1.73.0", sha256="96d62e6d1f2d21df7ac8acb3b9882411f9e7c7036173f7f2ede9e1f1f6b1bb3a") - version("1.70.0", sha256="b2bfae000b7a5040e4ec4bbc50a09f21548190cb7570b0ed77358368413bd27c") - version("1.65.0", sha256="5828bb67f677eabf8c384020582b0ce7af884e1c84389484f7f8d00dd82c0038") - version("1.60.0", sha256="20ca826d1cf674daf8e22c4f8c4b9743af07973211c839b85839742314c838b7") - - depends_on("c", type="build") - depends_on("cxx", type="build") - - variant( - "dev", - default=False, - description="Include rust developer tools like rustfmt, clippy, and rust-analyzer.", - ) - variant("docs", default=False, description="Build Rust core documentation.") - variant("src", default=True, description="Include standard library source files.") - - # Core dependencies - depends_on("curl+nghttp2") - depends_on("libgit2") - depends_on("libssh2") - depends_on("ninja", type="build") - depends_on("openssl") - depends_on("pkgconfig", type="build") - depends_on("python", type="build") - depends_on("zlib-api") - - # cmake dependency comes from LLVM. Rust has their own fork of LLVM, with tags corresponding - # to each Rust release, so it's easy to loop through tags and grep for "cmake_minimum_required" - depends_on("cmake@3.4.3:", type="build", when="@:1.51") - depends_on("cmake@3.13.4:", type="build", when="@1.52:1.72") - depends_on("cmake@3.20.0:", type="build", when="@1.73:") - - # Compiling Rust requires a previous version of Rust. - # The easiest way to bootstrap a Rust environment is to - # download the binary distribution of the compiler and build with that. - depends_on("rust-bootstrap", type="build") - - # Pre-release version dependencies - depends_on("rust-bootstrap@beta", type="build", when="@beta") - depends_on("rust-bootstrap@nightly", type="build", when="@master") - depends_on("rust-bootstrap@nightly", type="build", when="@nightly") - - # Stable version dependencies - depends_on("rust-bootstrap", type="build") - depends_on("rust-bootstrap@1.59:1.60", type="build", when="@1.60") - depends_on("rust-bootstrap@1.64:1.65", type="build", when="@1.65") - depends_on("rust-bootstrap@1.69:1.70", type="build", when="@1.70") - depends_on("rust-bootstrap@1.72:1.73", type="build", when="@1.73") - depends_on("rust-bootstrap@1.73:1.74", type="build", when="@1.74") - depends_on("rust-bootstrap@1.74:1.75", type="build", when="@1.75") - depends_on("rust-bootstrap@1.77:1.78", type="build", when="@1.78") - depends_on("rust-bootstrap@1.80:1.81", type="build", when="@1.81") - depends_on("rust-bootstrap@1.82:1.83", type="build", when="@1.83") - depends_on("rust-bootstrap@1.84:1.85", type="build", when="@1.85") - - # src/llvm-project/llvm/cmake/modules/CheckCompilerVersion.cmake - conflicts("%gcc@:7.3", when="@1.73:", msg="Host GCC version must be at least 7.4") - # https://github.com/rust-lang/llvm-project/commit/4d039a7a71899038b3bc6ed6fe5a8a48d915caa0 - conflicts("%gcc@13:", when="@:1.63", msg="Rust<1.64 not compatible with GCC>=13") - conflicts("%intel", msg="Rust not compatible with Intel Classic compilers") - conflicts("%oneapi", msg="Rust not compatible with Intel oneAPI compilers") - - extendable = True - executables = ["^rustc$", "^cargo$"] - - phases = ["configure", "build", "install"] - - @classmethod - def determine_spec_details(cls, prefix, exes_in_prefix): - rustc_candidates = [x for x in exes_in_prefix if os.path.basename(x) == "rustc"] - cargo_candidates = [x for x in exes_in_prefix if os.path.basename(x) == "cargo"] - # Both rustc and cargo must be present - if not (rustc_candidates and cargo_candidates): - return - output = Executable(rustc_candidates[0])("--version", output=str, error=str) - match = re.match(r"rustc (\S+)", output) - if match: - version_str = match.group(1) - return Spec.from_detection(f"rust@{version_str}", external_path=prefix) - - def setup_dependent_package(self, module, dependent_spec): - module.cargo = Executable(os.path.join(self.spec.prefix.bin, "cargo")) - - def setup_build_environment(self, env): - # Manually instruct Cargo dependency libssh2-sys to build with - # the Spack installed libssh2 package. For more info see - # https://github.com/alexcrichton/ssh2-rs/issues/173 - env.set("LIBSSH2_SYS_USE_PKG_CONFIG", "1") - - # Manually inject the path of ar for build. - ar = which("ar", required=True) - env.set("AR", ar.path) - - # Manually inject the path of openssl's certs for build - # if certs are present on system via Spack or via external - # openssl. - def get_test_path(p): - certs = join_path(p, "cert.pem") - if os.path.exists(certs): - return certs - return None - - # find certs, don't set if no file is found in case - # ca-certificates isn't installed - certs = None - openssl = self.spec["openssl"] - if openssl.external: - try: - output = which("openssl", required=True)("version", "-d", output=str, error=str) - openssl_dir = re.match('OPENSSLDIR: "([^"]+)"', output) - if openssl_dir: - certs = get_test_path(openssl_dir.group(1)) - except ProcessError: - pass - - if certs is None: - certs = get_test_path(join_path(openssl.prefix, "etc/openssl")) - - if certs is not None: - env.set("CARGO_HTTP_CAINFO", certs) - - def configure(self, spec, prefix): - opts = [] - - # Set prefix to install into spack prefix. - opts.append(f"install.prefix={prefix}") - - # Set relative path to put system configuration files - # under the Spack package prefix. - opts.append("install.sysconfdir=etc") - - # Build extended suite of tools so dependent packages - # packages can build using cargo. - opts.append("build.extended=true") - - # Build docs if specified by the +docs variant. - opts.append(f"build.docs={str(spec.satisfies('+docs')).lower()}") - - # Set binary locations for bootstrap rustc and cargo. - opts.append(f"build.cargo={spec['rust-bootstrap'].prefix.bin.cargo}") - opts.append(f"build.rustc={spec['rust-bootstrap'].prefix.bin.rustc}") - - # Disable bootstrap LLVM download. - opts.append("llvm.download-ci-llvm=false") - - # Convert opts to '--set key=value' format. - flags = [flag for opt in opts for flag in ("--set", opt)] - - # Core rust tools to install. - tools = ["cargo"] - - # Add additional tools as directed by the package variants. - if spec.satisfies("+dev"): - tools.extend(["clippy", "rustdoc", "rustfmt", "rust-analyzer"]) - - if spec.satisfies("+src"): - tools.append("src") - - # Compile tools into flag for configure. - flags.append(f"--tools={','.join(tools)}") - - # Use vendored resources to perform offline build. - flags.append("--enable-vendor") - - configure(*flags) - - def build(self, spec, prefix): - python("./x.py", "build") - - def install(self, spec, prefix): - python("./x.py", "install") diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/uv/package.py b/recipes/icon-dsl/25.8/g200/repo/packages/uv/package.py new file mode 100644 index 0000000..937a8d2 --- /dev/null +++ b/recipes/icon-dsl/25.8/g200/repo/packages/uv/package.py @@ -0,0 +1,61 @@ +from spack.package import * + + +def translate_platform(platform_name: str) -> str: + if platform_name == "darwin": + return "apple-darwin" + elif platform_name == "linux": + return "unknown-linux-gnu" + return platform_name + + +def translate_arch(arch_name: str) -> str: + if arch_name in ["m1", "m2"]: + return "aarch64" + return arch_name + + +class Uv(Package): + """Install UV from binary releases""" + + url = ( + "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz", + ) + + version( + "0.7.12", + sha256="189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e", + extension=".tar.gz", + ) + + def url_for_version(self, version): + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + if platform == "darwin": + platform = "apple-darwin" + if arch == "m1": + arch = "aarch64" + return f"https://github.com/astral-sh/uv/releases/download/{version}/uv-{arch}-{platform}.tar.gz" + + def do_stage(self, mirror_only=False): + checksums = { + ("0.7.12", "apple-darwin", "aarch64"): ( + "189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e" + ) + } + version = str(self.spec.version) + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + key = (version, platform, arch) + + if key not in checksums: + msg = f"Unsupported platform/arch for version {version}: {platform}-{arch}." + raise InstallError(msg) + + self.fetcher.digest = checksums[key] + super().do_stage(mirror_only) + + def install(self, spec, prefix): + mkdir(prefix.bin) + install("uv", prefix.bin.uv) + install("uvx", prefix.bin.uvx) From d04c0078aa429398ec45002b95d9f95aa795d970 Mon Sep 17 00:00:00 2001 From: bcumming Date: Fri, 13 Jun 2025 12:33:30 +0200 Subject: [PATCH 04/32] rename recipe path g200 -> gh200 --- recipes/icon-dsl/25.8/{g200 => gh200}/compilers.yaml | 0 recipes/icon-dsl/25.8/{g200 => gh200}/config.yaml | 0 recipes/icon-dsl/25.8/{g200 => gh200}/environments.yaml | 0 .../icon-dsl/25.8/{g200 => gh200}/repo/packages/ghex/package.py | 0 .../repo/packages/hwmalloc/cmake_install_path.patch | 0 .../25.8/{g200 => gh200}/repo/packages/hwmalloc/package.py | 0 .../25.8/{g200 => gh200}/repo/packages/icon4py/package.py | 0 .../25.8/{g200 => gh200}/repo/packages/oomph/install_0.2.patch | 0 .../25.8/{g200 => gh200}/repo/packages/oomph/install_0.3.patch | 0 .../icon-dsl/25.8/{g200 => gh200}/repo/packages/oomph/package.py | 0 recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/uv/package.py | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename recipes/icon-dsl/25.8/{g200 => gh200}/compilers.yaml (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/config.yaml (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/environments.yaml (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/ghex/package.py (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/hwmalloc/cmake_install_path.patch (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/hwmalloc/package.py (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/icon4py/package.py (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/oomph/install_0.2.patch (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/oomph/install_0.3.patch (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/oomph/package.py (100%) rename recipes/icon-dsl/25.8/{g200 => gh200}/repo/packages/uv/package.py (100%) diff --git a/recipes/icon-dsl/25.8/g200/compilers.yaml b/recipes/icon-dsl/25.8/gh200/compilers.yaml similarity index 100% rename from recipes/icon-dsl/25.8/g200/compilers.yaml rename to recipes/icon-dsl/25.8/gh200/compilers.yaml diff --git a/recipes/icon-dsl/25.8/g200/config.yaml b/recipes/icon-dsl/25.8/gh200/config.yaml similarity index 100% rename from recipes/icon-dsl/25.8/g200/config.yaml rename to recipes/icon-dsl/25.8/gh200/config.yaml diff --git a/recipes/icon-dsl/25.8/g200/environments.yaml b/recipes/icon-dsl/25.8/gh200/environments.yaml similarity index 100% rename from recipes/icon-dsl/25.8/g200/environments.yaml rename to recipes/icon-dsl/25.8/gh200/environments.yaml diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/ghex/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/ghex/package.py similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/ghex/package.py rename to recipes/icon-dsl/25.8/gh200/repo/packages/ghex/package.py diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/icon-dsl/25.8/gh200/repo/packages/hwmalloc/cmake_install_path.patch similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/cmake_install_path.patch rename to recipes/icon-dsl/25.8/gh200/repo/packages/hwmalloc/cmake_install_path.patch diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/hwmalloc/package.py similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/hwmalloc/package.py rename to recipes/icon-dsl/25.8/gh200/repo/packages/hwmalloc/package.py diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/icon4py/package.py rename to recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.2.patch b/recipes/icon-dsl/25.8/gh200/repo/packages/oomph/install_0.2.patch similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.2.patch rename to recipes/icon-dsl/25.8/gh200/repo/packages/oomph/install_0.2.patch diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.3.patch b/recipes/icon-dsl/25.8/gh200/repo/packages/oomph/install_0.3.patch similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/oomph/install_0.3.patch rename to recipes/icon-dsl/25.8/gh200/repo/packages/oomph/install_0.3.patch diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/oomph/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/oomph/package.py similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/oomph/package.py rename to recipes/icon-dsl/25.8/gh200/repo/packages/oomph/package.py diff --git a/recipes/icon-dsl/25.8/g200/repo/packages/uv/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py similarity index 100% rename from recipes/icon-dsl/25.8/g200/repo/packages/uv/package.py rename to recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py From b6a8ae1ad77ff48950e1fd7c9e6fcaf639bba49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Tue, 15 Jul 2025 15:28:06 +0200 Subject: [PATCH 05/32] add fixes from experimenting on santis --- recipes/icon-dsl/25.8/gh200/compilers.yaml | 10 +++++++--- recipes/icon-dsl/25.8/gh200/environments.yaml | 12 +++++++++--- .../25.8/gh200/repo/packages/ghex/package.py | 12 +++++++++--- .../25.8/gh200/repo/packages/icon4py/package.py | 16 +++++----------- .../25.8/gh200/repo/packages/uv/package.py | 12 ++++++++++-- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/recipes/icon-dsl/25.8/gh200/compilers.yaml b/recipes/icon-dsl/25.8/gh200/compilers.yaml index 1a86a3d..a7197a6 100644 --- a/recipes/icon-dsl/25.8/gh200/compilers.yaml +++ b/recipes/icon-dsl/25.8/gh200/compilers.yaml @@ -1,5 +1,9 @@ bootstrap: - spec: gcc@11 + spec: gcc@11 gcc: - specs: - - gcc@11 + specs: + - gcc@13 +llvm: + requires: gcc@13 + specs: + - nvhpc@25.1 diff --git a/recipes/icon-dsl/25.8/gh200/environments.yaml b/recipes/icon-dsl/25.8/gh200/environments.yaml index f53b81f..e02b4c1 100644 --- a/recipes/icon-dsl/25.8/gh200/environments.yaml +++ b/recipes/icon-dsl/25.8/gh200/environments.yaml @@ -2,11 +2,17 @@ myenv: compiler: - toolchain: gcc spec: gcc + - toolchain: llvm + spec: nvhpc + mpi: + spec: cray-mpich@8.1.30%nvhpc + gpu: cuda specs: - - icon4py@icon_20250328 +distributed +cuda - - py-cupy + - python@3.11 + - py-cupy +cuda cuda_arch=90 + - ghex +python +cuda cuda_arch=90 - py-mpi4py - - python + - icon4py@icon_20250328 unify: true variants: - +mpi diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/ghex/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/ghex/package.py index fc03b88..8f50e28 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/ghex/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/ghex/package.py @@ -20,7 +20,11 @@ class Ghex(CMakePackage, CudaPackage, ROCmPackage): backends = ("mpi", "ucx", "libfabric") variant( - "backend", default="mpi", description="Transport backend", values=backends, multi=False + "backend", + default="mpi", + description="Transport backend", + values=backends, + multi=False, ) variant("xpmem", default=False, description="Use xpmem shared memory") variant("python", default=True, description="Build Python bindings") @@ -57,7 +61,9 @@ def cmake_args(self): self.define("GHEX_USE_BUNDLED_GRIDTOOLS", True), self.define("GHEX_USE_BUNDLED_GTEST", self.run_tests), self.define("GHEX_USE_BUNDLED_OOMPH", False), - self.define("GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper()), + self.define( + "GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper() + ), self.define_from_variant("GHEX_USE_XPMEM", "xpmem"), self.define_from_variant("GHEX_BUILD_PYTHON_BINDINGS", "python"), self.define("GHEX_WITH_TESTING", self.run_tests), @@ -73,7 +79,7 @@ def cmake_args(self): arch_str = ";".join(spec.variants["cuda_arch"].value) args.append(self.define("CMAKE_CUDA_ARCHITECTURES", arch_str)) args.append(self.define("GHEX_USE_GPU", True)) - args.append(self.define("GHEX_GPU_TYPE", "CUDA")) + args.append(self.define("GHEX_GPU_TYPE", "NVIDIA")) if "+rocm" in spec and spec.variants["amdgpu_target"].value != "none": arch_str = ";".join(spec.variants["amdgpu_target"].value) diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py index 649a9f9..9360e7c 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py @@ -11,21 +11,17 @@ class Icon4py(Package): extends("python") depends_on("python@3.11:") - variant("cuda", default=True, description="Enable CUDA support") - variant("distributed", default=True, description="Enable multinode support") - depends_on("git") - depends_on("boost@1.85:", type=("build", "run")) - depends_on("py-uv@0.7:") + depends_on("boost@1.85:+mpi+python", type=("build", "run")) + depends_on("py-uv@0.7:", type="build") depends_on("bzip2", type="build") depends_on("py-numpy") depends_on("py-cffi") depends_on("py-pybind11") depends_on("py-nanobind") - depends_on("py-mpi4py", when="+distributed") - depends_on("py-cupy +cuda", when="+cuda") - depends_on("ghex +python", when="+distributed") - depends_on("ghex +python +cuda", when="+distributed +cuda") + depends_on("py-mpi4py") + depends_on("py-cupy +cuda") + depends_on("ghex +python +cuda") version( "icon_20250328", @@ -75,8 +71,6 @@ def install(self, spec, prefix): f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" ).write_text(pythonpath_to_pth()) - # uv("run", "--active", "py2fgen", "icon4py.tools.py2fgen.wrappers.all_bindings", "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", "icon4py_bindings", "-o", prefix.src, extra_env={"VIRTUAL_ENV": str(venv_path)}) - tty.msg(f"running py2fgen") py2fgen = Executable(venv_path.bin.py2fgen) py2fgen( diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py index 937a8d2..4438db0 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py @@ -10,7 +10,7 @@ def translate_platform(platform_name: str) -> str: def translate_arch(arch_name: str) -> str: - if arch_name in ["m1", "m2"]: + if arch_name in ["m1", "m2", "neoverse_v2"]: return "aarch64" return arch_name @@ -27,6 +27,11 @@ class Uv(Package): sha256="189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e", extension=".tar.gz", ) + version( + "0.7.20", + sha256="675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9", + extension=".tar.gz", + ) def url_for_version(self, version): arch = translate_arch(self.spec.target) @@ -41,7 +46,10 @@ def do_stage(self, mirror_only=False): checksums = { ("0.7.12", "apple-darwin", "aarch64"): ( "189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e" - ) + ), + ("0.7.20", "unknown-linux-gnu", "aarch64"): ( + "675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9" + ), } version = str(self.spec.version) arch = translate_arch(self.spec.target) From e9ad287fb9cb01c46ed061220aafa57ccdb67daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Wed, 16 Jul 2025 16:16:41 +0200 Subject: [PATCH 06/32] clean up old "py-uv" dependence, get rid of "cudnn" dep. --- .../gh200/repo/packages/icon4py/package.py | 2 +- .../gh200/repo/packages/py-cupy/package.py | 140 ++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py index 9360e7c..40795af 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py @@ -13,7 +13,7 @@ class Icon4py(Package): depends_on("git") depends_on("boost@1.85:+mpi+python", type=("build", "run")) - depends_on("py-uv@0.7:", type="build") + depends_on("uv@0.7:", type="build") depends_on("bzip2", type="build") depends_on("py-numpy") depends_on("py-cffi") diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py new file mode 100644 index 0000000..5a29de7 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py @@ -0,0 +1,140 @@ +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import os + +from spack.package import * + + +class PyCupy(PythonPackage, CudaPackage, ROCmPackage): + """CuPy is an open-source array library accelerated with + NVIDIA CUDA. CuPy provides GPU accelerated computing with + Python. CuPy uses CUDA-related libraries including cuBLAS, + cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make + full use of the GPU architecture. + + This version does not use CudNN.""" + + homepage = "https://cupy.dev/" + pypi = "cupy/cupy-8.0.0.tar.gz" + + version( + "13.1.0", + sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", + ) + version( + "12.1.0", + sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", + ) + version( + "12.0.0", + sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", + ) + version( + "11.6.0", + sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", + ) + version( + "11.5.0", + sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", + ) + version( + "11.4.0", + sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", + ) + version( + "11.3.0", + sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", + ) + version( + "11.2.0", + sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", + ) + + variant( + "all", default=False, description="Enable optional py-scipy, optuna, and cython" + ) + + depends_on("cxx", type="build") # generated + + depends_on("python@3.7:", when="@:11", type=("build", "run")) + depends_on("python@3.8:", when="@12:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-cython@0.29.22:2", type="build") + depends_on("py-fastrlock@0.5:", type=("build", "run")) + depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) + depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) + depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) + + depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) + depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) + depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) + depends_on("py-optuna@2:", when="+all", type=("build", "run")) + + # Based on https://github.com/cupy/cupy/releases + depends_on("cuda@:11.9", when="@:11 +cuda") + depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") + depends_on("cuda@:12.4", when="@13: +cuda") + + for a in CudaPackage.cuda_arch_values: + depends_on( + "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) + ) + + depends_on("cutensor", when="@:12.1.0 +cuda") + depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") + + for _arch in ROCmPackage.amdgpu_targets: + arch_str = "amdgpu_target={0}".format(_arch) + rocm_str = "+rocm {0}".format(arch_str) + depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) + + depends_on("rccl", when="+rocm", type=("link")) + depends_on("roctracer-dev", when="+rocm", type=("link")) + depends_on("rocprofiler-dev", when="+rocm", type=("link")) + + conflicts("~cuda ~rocm") + conflicts("+cuda +rocm") + conflicts("+cuda cuda_arch=none") + + def setup_build_environment(self, env): + env.set("CUPY_NUM_BUILD_JOBS", make_jobs) + if self.spec.satisfies("+cuda"): + cuda_arch = self.spec.variants["cuda_arch"].value + arch_str = ";".join( + "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch + ) + env.set("CUPY_NVCC_GENERATE_CODE", arch_str) + elif self.spec.satisfies("+rocm"): + spec = self.spec + + incs = { + "roctracer-dev": ["include/roctracer"], + "hiprand": ["include"], + "rocrand": ["include"], + "rocthrust": ["include"], + "rocprim": ["include"], + "hip": ["include", "include/hip"], + } + + inc_dirs = [] + for pkg, ds in incs.items(): + for d in ds: + p = os.path.join(spec[pkg].prefix, d) + if os.path.exists(p): + inc_dirs.append(p) + + env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) + + env.set("HIPCC", self.spec["hip"].hipcc) + env.set("ROCM_HOME", self.spec["hipcub"].prefix) + env.set("CUPY_INSTALL_USE_HIP", 1) From 4a5fd2938df51e06c0f58ae165ce616ae32c0915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Thu, 17 Jul 2025 09:25:15 +0200 Subject: [PATCH 07/32] fix packages --- .../icon-dsl/25.8/gh200/repo/packages/icon4py/package.py | 4 +++- recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py | 8 +------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py index 40795af..ec64e39 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py @@ -57,7 +57,9 @@ def install(self, spec, prefix): "sync", "--active", "--extra", - "fortran", + "all", + "--extra", + "cuda12", "--inexact", "--no-editable", "--python", diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py index 4438db0..51da537 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py @@ -18,9 +18,7 @@ def translate_arch(arch_name: str) -> str: class Uv(Package): """Install UV from binary releases""" - url = ( - "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz", - ) + url = "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz" version( "0.7.12", @@ -36,10 +34,6 @@ class Uv(Package): def url_for_version(self, version): arch = translate_arch(self.spec.target) platform = translate_platform(self.spec.platform) - if platform == "darwin": - platform = "apple-darwin" - if arch == "m1": - arch = "aarch64" return f"https://github.com/astral-sh/uv/releases/download/{version}/uv-{arch}-{platform}.tar.gz" def do_stage(self, mirror_only=False): From 784d6f745e3677a1e0784230f47ab4fdd23252c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Thu, 17 Jul 2025 13:19:44 +0200 Subject: [PATCH 08/32] add a100 version for balfrin --- recipes/icon-dsl/25.8/a100/compilers.yaml | 9 ++ recipes/icon-dsl/25.8/a100/config.yaml | 7 + recipes/icon-dsl/25.8/a100/environments.yaml | 22 +++ .../25.8/a100/repo/packages/ghex/package.py | 93 ++++++++++++ .../hwmalloc/cmake_install_path.patch | 27 ++++ .../a100/repo/packages/hwmalloc/package.py | 52 +++++++ .../a100/repo/packages/icon4py/package.py | 109 ++++++++++++++ .../repo/packages/oomph/install_0.2.patch | 102 +++++++++++++ .../repo/packages/oomph/install_0.3.patch | 57 +++++++ .../25.8/a100/repo/packages/oomph/package.py | 109 ++++++++++++++ .../a100/repo/packages/py-cupy/package.py | 140 ++++++++++++++++++ .../25.8/a100/repo/packages/uv/package.py | 68 +++++++++ .../25.8/gh200/repo/packages/uv/package.py | 5 + 13 files changed, 800 insertions(+) create mode 100644 recipes/icon-dsl/25.8/a100/compilers.yaml create mode 100644 recipes/icon-dsl/25.8/a100/config.yaml create mode 100644 recipes/icon-dsl/25.8/a100/environments.yaml create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/ghex/package.py create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/cmake_install_path.patch create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/package.py create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.2.patch create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.3.patch create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/oomph/package.py create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/uv/package.py diff --git a/recipes/icon-dsl/25.8/a100/compilers.yaml b/recipes/icon-dsl/25.8/a100/compilers.yaml new file mode 100644 index 0000000..a7197a6 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/compilers.yaml @@ -0,0 +1,9 @@ +bootstrap: + spec: gcc@11 +gcc: + specs: + - gcc@13 +llvm: + requires: gcc@13 + specs: + - nvhpc@25.1 diff --git a/recipes/icon-dsl/25.8/a100/config.yaml b/recipes/icon-dsl/25.8/a100/config.yaml new file mode 100644 index 0000000..1c26eca --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/config.yaml @@ -0,0 +1,7 @@ +name: icon4pypoc +store: /user-environment +spack: + repo: https://github.com/spack/spack.git + commit: releases/v0.23 +modules: false +description: icon4py proof-of-concept diff --git a/recipes/icon-dsl/25.8/a100/environments.yaml b/recipes/icon-dsl/25.8/a100/environments.yaml new file mode 100644 index 0000000..3936e00 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/environments.yaml @@ -0,0 +1,22 @@ +myenv: + compiler: + - toolchain: gcc + spec: gcc + - toolchain: llvm + spec: nvhpc + mpi: + spec: cray-mpich@8.1.30%nvhpc + gpu: cuda + specs: + - python@3.11 + - py-cupy +cuda cuda_arch=90 + - ghex +python +cuda cuda_arch=90 + - py-mpi4py + - icon4py@icon_20250328 + unify: true + variants: + - +mpi + - +cuda + - cuda_arch=80 + views: + default: diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/ghex/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/ghex/package.py new file mode 100644 index 0000000..8f50e28 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/ghex/package.py @@ -0,0 +1,93 @@ +from spack.package import * + + +class Ghex(CMakePackage, CudaPackage, ROCmPackage): + """GHEX is a generic halo-exchange library.""" + + homepage = "https://github.com/ghex-org/GHEX" + url = "https://github.com/ghex-org/GHEX/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/GHEX.git" + maintainers = ["boeschf"] + + version("0.4.1", tag="v0.4.1", submodules=True) + version("0.4.0", tag="v0.4.0", submodules=True) + version("0.3.0", tag="v0.3.0", submodules=True) + version("master", branch="master", submodules=True) + + depends_on("cxx", type="build") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", + default="mpi", + description="Transport backend", + values=backends, + multi=False, + ) + variant("xpmem", default=False, description="Use xpmem shared memory") + variant("python", default=True, description="Build Python bindings") + + depends_on("cmake@3.21:", type="build") + depends_on("mpi") + depends_on("boost") + depends_on("xpmem", when="+xpmem", type=("build", "run")) + + depends_on("oomph") + for backend in backends: + depends_on(f"oomph backend={backend}", when=f"backend={backend}") + depends_on("oomph+cuda", when="+cuda") + depends_on("oomph+rocm", when="+rocm") + depends_on("oomph@0.3:", when="@0.3:") + + conflicts("+cuda+rocm") + + with when("+python"): + extends("python") + depends_on("python@3.7:", type="build") + depends_on("py-pip", type="build") + depends_on("py-pybind11", type="build") + depends_on("py-mpi4py", type=("build", "run")) + depends_on("py-numpy", type=("build", "run")) + + depends_on("py-pytest", when="+python", type=("test")) + + def cmake_args(self): + spec = self.spec + + args = [ + self.define("GHEX_USE_BUNDLED_LIBS", True), + self.define("GHEX_USE_BUNDLED_GRIDTOOLS", True), + self.define("GHEX_USE_BUNDLED_GTEST", self.run_tests), + self.define("GHEX_USE_BUNDLED_OOMPH", False), + self.define( + "GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper() + ), + self.define_from_variant("GHEX_USE_XPMEM", "xpmem"), + self.define_from_variant("GHEX_BUILD_PYTHON_BINDINGS", "python"), + self.define("GHEX_WITH_TESTING", self.run_tests), + ] + + if spec.satisfies("+python"): + args.append(self.define("GHEX_PYTHON_LIB_PATH", python_platlib)) + + if self.run_tests and spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if "+cuda" in spec and spec.variants["cuda_arch"].value != "none": + arch_str = ";".join(spec.variants["cuda_arch"].value) + args.append(self.define("CMAKE_CUDA_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "NVIDIA")) + + if "+rocm" in spec and spec.variants["amdgpu_target"].value != "none": + arch_str = ";".join(spec.variants["amdgpu_target"].value) + args.append(self.define("CMAKE_HIP_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "AMD")) + + if spec.satisfies("~cuda~rocm"): + args.append(self.define("GHEX_USE_GPU", False)) + + return args diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/cmake_install_path.patch new file mode 100644 index 0000000..fa6fde1 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/cmake_install_path.patch @@ -0,0 +1,27 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d5420e0..35dbe56 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -105,11 +105,11 @@ install(FILES ${PROJECT_BINARY_DIR}/include/hwmalloc/config.hpp + install(EXPORT HWMALLOC-targets + FILE HWMALLOC-targets.cmake + NAMESPACE HWMALLOC:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HWMALLOCConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + write_basic_package_version_file(HWMALLOCConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -120,7 +120,7 @@ install( + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfigVersion.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindNUMA.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + export(EXPORT HWMALLOC-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/HWMALLOC-targets.cmake") diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/package.py new file mode 100644 index 0000000..c656dc1 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/hwmalloc/package.py @@ -0,0 +1,52 @@ +from spack.package import * + + +class Hwmalloc(CMakePackage, CudaPackage, ROCmPackage): + """HWMALLOC is a allocator which supports memory registration for e.g. remote memory access""" + + homepage = "https://github.com/ghex-org/hwmalloc" + url = "https://github.com/ghex-org/hwmalloc/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/hwmalloc.git" + maintainers = ["boeschf"] + + version("0.3.0", sha256="d4d4ac6087a806600d79fb62c02719ca3d58a412968fe1ef4a2fd58d9e7ee950") + version("0.2.0", sha256="734758a390a3258b86307e4aef50a7ca2e5d0e2e579f18aeefcd05397e114419") + version("0.1.0", sha256="06e9bfcef0ecce4d19531ccbe03592b502d1281c7a092bc0ff51ca187899b21c") + version("master", branch="master") + + depends_on("cxx", type="build") + + generator("ninja") + + depends_on("numactl", type=("build", "run")) + depends_on("boost", type=("build")) + depends_on("cmake@3.19:", type="build") + + variant( + "numa-throws", + default=False, + description="True if numa_tools may throw during initialization", + ) + variant("numa-local", default=True, description="Use numa_tools for local node allocations") + variant("logging", default=False, description="print logging info to cerr") + + patch("cmake_install_path.patch", when="@:0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("HWMALLOC_NUMA_THROWS", "numa-throws"), + self.define_from_variant("HWMALLOC_NUMA_FOR_LOCAL", "numa-local"), + self.define_from_variant("HWMALLOC_ENABLE_LOGGING", "logging"), + self.define("HWMALLOC_WITH_TESTING", self.run_tests), + ] + + if "+cuda" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "cuda")) + elif "+rocm" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "hip")) + else: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", False)) + + return args diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py new file mode 100644 index 0000000..ec64e39 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py @@ -0,0 +1,109 @@ +import json +import os +import pathlib + +import llnl +from llnl.util import tty +from spack import * + + +class Icon4py(Package): + extends("python") + depends_on("python@3.11:") + + depends_on("git") + depends_on("boost@1.85:+mpi+python", type=("build", "run")) + depends_on("uv@0.7:", type="build") + depends_on("bzip2", type="build") + depends_on("py-numpy") + depends_on("py-cffi") + depends_on("py-pybind11") + depends_on("py-nanobind") + depends_on("py-mpi4py") + depends_on("py-cupy +cuda") + depends_on("ghex +python +cuda") + + version( + "icon_20250328", + sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", + extension="zip", + ) + + def url_for_version(self, version): + return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" + + def install(self, spec, prefix): + uv = prepare_uv() + python_spec = spec["python"] + venv_path = prefix.share.venv + + tty.msg(f"creating venv using spack python at: {python_spec.command.path}") + uv( + "venv", + "--seed", + "--relocatable", + "--system-site-packages", + str(venv_path), + "--python", + python_spec.command.path, + ) + + tty.msg(f"grabbing spack installed packages (distributions)") + pip = Executable(venv_path.bin.pip) + spack_installed = get_installed_pkg(pip) + + tty.msg(f"installing missing packages") + uv( + "sync", + "--active", + "--extra", + "all", + "--extra", + "cuda12", + "--inexact", + "--no-editable", + "--python", + str(venv_path.bin.python), + *no_install_options(spack_installed), + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + tty.msg(f"linking spack installed packages into venv") + pathlib.Path( + f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" + ).write_text(pythonpath_to_pth()) + + tty.msg(f"running py2fgen") + py2fgen = Executable(venv_path.bin.py2fgen) + py2fgen( + "icon4py.tools.py2fgen.wrappers.all_bindings", + "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", + "icon4py_bindings", + "-o", + prefix.src, + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + +def prepare_uv(): + uv = which("uv") + uv.add_default_env("UV_NO_CACHE", "true") + uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") + uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") + return uv + + +def get_installed_pkg(pip): + return [ + item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) + ] + + +def no_install_options(installed): + for name in installed: + yield "--no-install-package" + yield name + + +def pythonpath_to_pth(): + return "\n".join(os.environ["PYTHONPATH"].split(":")) diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.2.patch b/recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.2.patch new file mode 100644 index 0000000..5dc7e2e --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.2.patch @@ -0,0 +1,102 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ba19089..2ba222a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,12 @@ + cmake_minimum_required(VERSION 3.17) + # CMake version is set at 3.17 because of find_package(CUDAToolkit) + ++if (NOT ${CMAKE_VERSION} VERSION_LESS 3.27) ++ # new in 3.27: additionally use uppercase _ROOT ++ # environment and CMake variables for find_package ++ cmake_policy(SET CMP0144 NEW) ++endif() ++ + set(OOMPH_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + list(APPEND CMAKE_MODULE_PATH "${OOMPH_MODULE_PATH}") + +@@ -108,11 +114,11 @@ endif() + install(EXPORT oomph-targets + FILE oomph-targets.cmake + NAMESPACE oomph:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/oomphConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/oomphConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + write_basic_package_version_file(oomphConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -125,7 +131,7 @@ install( + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindUCX.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindPMIx.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + export(EXPORT oomph-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/oomph-targets.cmake") +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index ec672b5..a578ef5 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -31,17 +31,30 @@ endif() + # --------------------------------------------------------------------- + # google test setup + # --------------------------------------------------------------------- +-add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +-# on some systems we need link explicitly against threads +-if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON ++ "OOMPH_USE_BUNDLED_LIBS" OFF) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() ++ else() ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() ++ endif() + endif() +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 06d703a..5217bba 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -65,6 +65,7 @@ function(reg_parallel_test t_ lib n) + NAME ${t} + COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${n} ${MPIEXEC_PREFLAGS} + $ ${MPIEXEC_POSTFLAGS}) ++ set_tests_properties(${t} PROPERTIES RUN_SERIAL TRUE) + endfunction() + + if (OOMPH_WITH_MPI) diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.3.patch b/recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.3.patch new file mode 100644 index 0000000..aac73e8 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/oomph/install_0.3.patch @@ -0,0 +1,57 @@ +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index a578ef5..92de39b 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -33,28 +33,30 @@ endif() + # --------------------------------------------------------------------- + cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON + "OOMPH_USE_BUNDLED_LIBS" OFF) +-if(OOMPH_USE_BUNDLED_GTEST) +- add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +- # on some systems we need link explicitly against threads +- if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) +- endif() +-else() +- # Use system provided google test +- find_package(GTest REQUIRED) +- add_library(ext-gtest INTERFACE) +- if (${CMAKE_VERSION} VERSION_LESS "3.20.0") +- target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() + else() +- target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() + endif() + endif() diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/oomph/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/oomph/package.py new file mode 100644 index 0000000..3b320f9 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/oomph/package.py @@ -0,0 +1,109 @@ +from spack.package import * + + +class Oomph(CMakePackage, CudaPackage, ROCmPackage): + """Oomph is a non-blocking callback-based point-to-point communication library.""" + + homepage = "https://github.com/ghex-org/oomph" + url = "https://github.com/ghex-org/oomph/archive/refs/tags/v0.2.0.tar.gz" + git = "https://github.com/ghex-org/oomph.git" + maintainers = ["boeschf"] + + version("0.4.0", sha256="e342c872dfe4832be047f172dc55c12951950c79da2630b071c61607ef913144") + version("0.3.0", sha256="61e346d1ba28a859745de47f37edce39c7f5c5e1aab716493dc964e158fd99ec") + version("0.2.0", sha256="135cdb856aa817c053b6af1617869dbcd0ee97d34607e78874dd775ea389434e") + version("0.1.0", sha256="0ff36db0a5f30ae1bb02f6db6d411ea72eadd89688c00f76b4e722bd5a9ba90b") + version("main", branch="main") + + depends_on("cxx", type="build") + depends_on("fortran", type="build", when="+fortran-bindings") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", default="mpi", description="Transport backend", values=backends, multi=False + ) + + variant("fortran-bindings", default=False, description="Build Fortran bindings") + with when("+fortran-bindings"): + variant( + "fortran-fp", + default="float", + description="Floating point type", + values=("float", "double"), + multi=False, + ) + variant("fortran-openmp", default=True, description="Compile with OpenMP") + + variant( + "enable-barrier", + default=True, + description="Enable thread barrier (disable for task based runtime)", + ) + + depends_on("hwmalloc+cuda", when="+cuda") + depends_on("hwmalloc+rocm", when="+rocm") + depends_on("hwmalloc", when="~cuda~rocm") + + with when("backend=ucx"): + depends_on("ucx+thread_multiple") + depends_on("ucx+cuda", when="+cuda") + depends_on("ucx+rocm", when="+rocm") + variant("use-pmix", default="False", description="Use PMIx to establish out-of-band setup") + variant("use-spin-lock", default="False", description="Use pthread spin locks") + depends_on("pmix", when="+use-pmix") + + libfabric_providers = ("cxi", "efa", "gni", "psm2", "tcp", "verbs") + with when("backend=libfabric"): + variant( + "libfabric-provider", + default="tcp", + description="fabric", + values=libfabric_providers, + multi=False, + ) + for provider in libfabric_providers: + depends_on(f"libfabric fabrics={provider}", when=f"libfabric-provider={provider}") + + depends_on("mpi") + depends_on("boost+thread") + + depends_on("googletest", type=("build","test")) + + patch("install_0.2.patch", when="@:0.2.0", level=1) + patch("install_0.3.patch", when="@0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("OOMPH_BUILD_FORTRAN", "fortran-bindings"), + self.define_from_variant("OOMPH_FORTRAN_OPENMP", "fortran-openmp"), + self.define_from_variant("OOMPH_UCX_USE_PMI", "use-pmix"), + self.define_from_variant("OOMPH_UCX_USE_SPIN_LOCK", "use-spin-lock"), + self.define_from_variant("OOMPH_ENABLE_BARRIER", "enable-barrier"), + self.define("OOMPH_WITH_TESTING", self.run_tests), + self.define("OOMPH_GIT_SUBMODULE", False), + self.define("OOMPH_USE_BUNDLED_LIBS", False), + ] + + if self.run_tests and self.spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if self.spec.variants["fortran-bindings"].value == True: + args.append(self.define("OOMPH_FORTRAN_FP", self.spec.variants["fortran-fp"].value)) + + for backend in self.backends: + args.append( + self.define( + f"OOMPH_WITH_{backend.upper()}", self.spec.variants["backend"].value == backend + ) + ) + + if self.spec.satisfies("backend=libfabric"): + args.append( + self.define( + "OOMPH_LIBFABRIC_PROVIDER", self.spec.variants["libfabric-provider"].value + ) + ) + + return args diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py new file mode 100644 index 0000000..5a29de7 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py @@ -0,0 +1,140 @@ +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import os + +from spack.package import * + + +class PyCupy(PythonPackage, CudaPackage, ROCmPackage): + """CuPy is an open-source array library accelerated with + NVIDIA CUDA. CuPy provides GPU accelerated computing with + Python. CuPy uses CUDA-related libraries including cuBLAS, + cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make + full use of the GPU architecture. + + This version does not use CudNN.""" + + homepage = "https://cupy.dev/" + pypi = "cupy/cupy-8.0.0.tar.gz" + + version( + "13.1.0", + sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", + ) + version( + "12.1.0", + sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", + ) + version( + "12.0.0", + sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", + ) + version( + "11.6.0", + sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", + ) + version( + "11.5.0", + sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", + ) + version( + "11.4.0", + sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", + ) + version( + "11.3.0", + sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", + ) + version( + "11.2.0", + sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", + ) + + variant( + "all", default=False, description="Enable optional py-scipy, optuna, and cython" + ) + + depends_on("cxx", type="build") # generated + + depends_on("python@3.7:", when="@:11", type=("build", "run")) + depends_on("python@3.8:", when="@12:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-cython@0.29.22:2", type="build") + depends_on("py-fastrlock@0.5:", type=("build", "run")) + depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) + depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) + depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) + + depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) + depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) + depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) + depends_on("py-optuna@2:", when="+all", type=("build", "run")) + + # Based on https://github.com/cupy/cupy/releases + depends_on("cuda@:11.9", when="@:11 +cuda") + depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") + depends_on("cuda@:12.4", when="@13: +cuda") + + for a in CudaPackage.cuda_arch_values: + depends_on( + "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) + ) + + depends_on("cutensor", when="@:12.1.0 +cuda") + depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") + + for _arch in ROCmPackage.amdgpu_targets: + arch_str = "amdgpu_target={0}".format(_arch) + rocm_str = "+rocm {0}".format(arch_str) + depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) + + depends_on("rccl", when="+rocm", type=("link")) + depends_on("roctracer-dev", when="+rocm", type=("link")) + depends_on("rocprofiler-dev", when="+rocm", type=("link")) + + conflicts("~cuda ~rocm") + conflicts("+cuda +rocm") + conflicts("+cuda cuda_arch=none") + + def setup_build_environment(self, env): + env.set("CUPY_NUM_BUILD_JOBS", make_jobs) + if self.spec.satisfies("+cuda"): + cuda_arch = self.spec.variants["cuda_arch"].value + arch_str = ";".join( + "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch + ) + env.set("CUPY_NVCC_GENERATE_CODE", arch_str) + elif self.spec.satisfies("+rocm"): + spec = self.spec + + incs = { + "roctracer-dev": ["include/roctracer"], + "hiprand": ["include"], + "rocrand": ["include"], + "rocthrust": ["include"], + "rocprim": ["include"], + "hip": ["include", "include/hip"], + } + + inc_dirs = [] + for pkg, ds in incs.items(): + for d in ds: + p = os.path.join(spec[pkg].prefix, d) + if os.path.exists(p): + inc_dirs.append(p) + + env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) + + env.set("HIPCC", self.spec["hip"].hipcc) + env.set("ROCM_HOME", self.spec["hipcub"].prefix) + env.set("CUPY_INSTALL_USE_HIP", 1) diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/uv/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/uv/package.py new file mode 100644 index 0000000..6941eff --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/uv/package.py @@ -0,0 +1,68 @@ +from spack.package import * + + +def translate_platform(platform_name: str) -> str: + if platform_name == "darwin": + return "apple-darwin" + elif platform_name == "linux": + return "unknown-linux-gnu" + return platform_name + + +def translate_arch(arch_name: str) -> str: + if arch_name in ["m1", "m2", "neoverse_v2"]: + return "aarch64" + if arch_name in ["zen3"]: + return "x86_64" + return arch_name + + +class Uv(Package): + """Install UV from binary releases""" + + url = "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz" + + version( + "0.7.12", + sha256="189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e", + extension=".tar.gz", + ) + version( + "0.7.20", + sha256="675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9", + extension=".tar.gz", + ) + + def url_for_version(self, version): + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + return f"https://github.com/astral-sh/uv/releases/download/{version}/uv-{arch}-{platform}.tar.gz" + + def do_stage(self, mirror_only=False): + checksums = { + ("0.7.12", "apple-darwin", "aarch64"): ( + "189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e" + ), + ("0.7.20", "unknown-linux-gnu", "aarch64"): ( + "675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9" + ), + ("0.7.20", "unknown-linux-gnu", "x86_64"): ( + "10f204426ff188925d22a53c1d0310d190a8d4d24513712e1b8e2ca9873f0666" + ), + } + version = str(self.spec.version) + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + key = (version, platform, arch) + + if key not in checksums: + msg = f"Unsupported platform/arch for version {version}: {platform}-{arch}." + raise InstallError(msg) + + self.fetcher.digest = checksums[key] + super().do_stage(mirror_only) + + def install(self, spec, prefix): + mkdir(prefix.bin) + install("uv", prefix.bin.uv) + install("uvx", prefix.bin.uvx) diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py index 51da537..6941eff 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/uv/package.py @@ -12,6 +12,8 @@ def translate_platform(platform_name: str) -> str: def translate_arch(arch_name: str) -> str: if arch_name in ["m1", "m2", "neoverse_v2"]: return "aarch64" + if arch_name in ["zen3"]: + return "x86_64" return arch_name @@ -44,6 +46,9 @@ def do_stage(self, mirror_only=False): ("0.7.20", "unknown-linux-gnu", "aarch64"): ( "675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9" ), + ("0.7.20", "unknown-linux-gnu", "x86_64"): ( + "10f204426ff188925d22a53c1d0310d190a8d4d24513712e1b8e2ca9873f0666" + ), } version = str(self.spec.version) arch = translate_arch(self.spec.target) From 293f3c51cbbd7d42994271b2b5a69cc78c2489bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Thu, 17 Jul 2025 14:10:01 +0200 Subject: [PATCH 09/32] update config with a100 balfrin version of icon-dsl --- config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.yaml b/config.yaml index 90e74d3..1a3e930 100644 --- a/config.yaml +++ b/config.yaml @@ -43,8 +43,10 @@ uenvs: "25.8": recipes: gh200: '25.8/gh200' + a100: '25.8/a100' deploy: santis: [gh200] + balfrin: [a100] develop: False mch: "v7": From 8544c9cedb142fbcf44b39a4adcbefee53fe5ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Fri, 18 Jul 2025 10:49:53 +0200 Subject: [PATCH 10/32] manually block `cupy-cuda12x` and `ghex` from being reinstalled by uv --- recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py | 2 +- recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py index ec64e39..9ee413e 100644 --- a/recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/a100/repo/packages/icon4py/package.py @@ -64,7 +64,7 @@ def install(self, spec, prefix): "--no-editable", "--python", str(venv_path.bin.python), - *no_install_options(spack_installed), + *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), extra_env={"VIRTUAL_ENV": str(venv_path)}, ) diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py index ec64e39..9ee413e 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py @@ -64,7 +64,7 @@ def install(self, spec, prefix): "--no-editable", "--python", str(venv_path.bin.python), - *no_install_options(spack_installed), + *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), extra_env={"VIRTUAL_ENV": str(venv_path)}, ) From 366f5e4a3428e7e543c3ceaae0febc21e873b08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Mon, 21 Jul 2025 15:49:16 +0200 Subject: [PATCH 11/32] fix icon-dsl uenv name in config --- recipes/icon-dsl/25.8/a100/config.yaml | 2 +- recipes/icon-dsl/25.8/gh200/config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/icon-dsl/25.8/a100/config.yaml b/recipes/icon-dsl/25.8/a100/config.yaml index 1c26eca..fb6c610 100644 --- a/recipes/icon-dsl/25.8/a100/config.yaml +++ b/recipes/icon-dsl/25.8/a100/config.yaml @@ -1,4 +1,4 @@ -name: icon4pypoc +name: icon-dsl store: /user-environment spack: repo: https://github.com/spack/spack.git diff --git a/recipes/icon-dsl/25.8/gh200/config.yaml b/recipes/icon-dsl/25.8/gh200/config.yaml index 1c26eca..fb6c610 100644 --- a/recipes/icon-dsl/25.8/gh200/config.yaml +++ b/recipes/icon-dsl/25.8/gh200/config.yaml @@ -1,4 +1,4 @@ -name: icon4pypoc +name: icon-dsl store: /user-environment spack: repo: https://github.com/spack/spack.git From 9f06d6ece336b402059c323836c7f45b3fbe818f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Wed, 30 Jul 2025 10:56:51 +0200 Subject: [PATCH 12/32] merge icon dependencies from the "icon" uenv into this one --- recipes/icon-dsl/25.8/a100/compilers.yaml | 2 +- recipes/icon-dsl/25.8/a100/config.yaml | 2 +- recipes/icon-dsl/25.8/a100/environments.yaml | 25 ++ recipes/icon-dsl/25.8/a100/extra/reframe.yaml | 6 + recipes/icon-dsl/25.8/a100/modules.yaml | 26 ++ recipes/icon-dsl/25.8/a100/pre-install | 12 + .../eccodes/cmake_install_rpath.patch | 11 + .../packages/eccodes/openjpeg_jasper.patch | 39 ++ .../a100/repo/packages/eccodes/package.py | 385 ++++++++++++++++++ .../25.8/a100/repo/packages/eccodes/readme.md | 1 + recipes/icon-dsl/25.8/gh200/compilers.yaml | 2 +- recipes/icon-dsl/25.8/gh200/config.yaml | 2 +- recipes/icon-dsl/25.8/gh200/environments.yaml | 25 ++ .../icon-dsl/25.8/gh200/extra/reframe.yaml | 6 + recipes/icon-dsl/25.8/gh200/modules.yaml | 26 ++ recipes/icon-dsl/25.8/gh200/pre-install | 12 + .../eccodes/cmake_install_rpath.patch | 11 + .../packages/eccodes/openjpeg_jasper.patch | 39 ++ .../gh200/repo/packages/eccodes/package.py | 385 ++++++++++++++++++ .../gh200/repo/packages/eccodes/readme.md | 1 + 20 files changed, 1014 insertions(+), 4 deletions(-) create mode 100644 recipes/icon-dsl/25.8/a100/extra/reframe.yaml create mode 100644 recipes/icon-dsl/25.8/a100/modules.yaml create mode 100644 recipes/icon-dsl/25.8/a100/pre-install create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/eccodes/cmake_install_rpath.patch create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/eccodes/openjpeg_jasper.patch create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/eccodes/package.py create mode 100644 recipes/icon-dsl/25.8/a100/repo/packages/eccodes/readme.md create mode 100644 recipes/icon-dsl/25.8/gh200/extra/reframe.yaml create mode 100644 recipes/icon-dsl/25.8/gh200/modules.yaml create mode 100644 recipes/icon-dsl/25.8/gh200/pre-install create mode 100644 recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/cmake_install_rpath.patch create mode 100644 recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/openjpeg_jasper.patch create mode 100644 recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/package.py create mode 100644 recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/readme.md diff --git a/recipes/icon-dsl/25.8/a100/compilers.yaml b/recipes/icon-dsl/25.8/a100/compilers.yaml index a7197a6..f456b5a 100644 --- a/recipes/icon-dsl/25.8/a100/compilers.yaml +++ b/recipes/icon-dsl/25.8/a100/compilers.yaml @@ -1,5 +1,5 @@ bootstrap: - spec: gcc@11 + spec: gcc@12.3 gcc: specs: - gcc@13 diff --git a/recipes/icon-dsl/25.8/a100/config.yaml b/recipes/icon-dsl/25.8/a100/config.yaml index fb6c610..ac4ba9c 100644 --- a/recipes/icon-dsl/25.8/a100/config.yaml +++ b/recipes/icon-dsl/25.8/a100/config.yaml @@ -4,4 +4,4 @@ spack: repo: https://github.com/spack/spack.git commit: releases/v0.23 modules: false -description: icon4py proof-of-concept +description: Build and runtime dependencies for ICON-DSL diff --git a/recipes/icon-dsl/25.8/a100/environments.yaml b/recipes/icon-dsl/25.8/a100/environments.yaml index 3936e00..7f8ba10 100644 --- a/recipes/icon-dsl/25.8/a100/environments.yaml +++ b/recipes/icon-dsl/25.8/a100/environments.yaml @@ -8,11 +8,32 @@ myenv: spec: cray-mpich@8.1.30%nvhpc gpu: cuda specs: + # icon4py deps - python@3.11 - py-cupy +cuda cuda_arch=90 - ghex +python +cuda cuda_arch=90 - py-mpi4py - icon4py@icon_20250328 + # icon deps + - boost ~mpi + - cuda@12.6 + - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper + - cosmo-eccodes-definitions@2.36.0.3 + - hdf5%nvhpc +szip +hl +fortran +mpi + - netcdf-c@4.9.2%nvhpc + - netcdf-cxx4@4.3.1%nvhpc + - netcdf-fortran@4.6.1%nvhpc + - osu-micro-benchmarks@5.9%nvhpc + - openblas + # for validation + - cdo + # everything needed for nccl on SS11 + - nccl + - nccl-tests + # extras + - libfyaml + - zlib-ng + - cmake unify: true variants: - +mpi @@ -20,3 +41,7 @@ myenv: - cuda_arch=80 views: default: + link: roots + uenv: + prefix_paths: + LD_LIBRARY_PATH: [lib, lib64] diff --git a/recipes/icon-dsl/25.8/a100/extra/reframe.yaml b/recipes/icon-dsl/25.8/a100/extra/reframe.yaml new file mode 100644 index 0000000..363f809 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/extra/reframe.yaml @@ -0,0 +1,6 @@ +default: + features: [osu-micro-benchmarks, mpi, serial, openmp] + cc: mpicc + cxx: mpic++ + ftn: mpifort + activation: /user-environment/env/default/activate.sh diff --git a/recipes/icon-dsl/25.8/a100/modules.yaml b/recipes/icon-dsl/25.8/a100/modules.yaml new file mode 100644 index 0000000..a4010ae --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/modules.yaml @@ -0,0 +1,26 @@ +modules: + # Paths to check when creating modules for all module sets + prefix_inspections: + bin: + - PATH + lib: + - LD_LIBRARY_PATH + lib64: + - LD_LIBRARY_PATH + + default: + arch_folder: false + # Where to install modules + roots: + tcl: /snap/modules + tcl: + all: + autoload: run + hash_length: 0 + hide_implicits: true + exclude: + - '%gcc@7.5.0' + - '%gcc@12' + - 'gcc %gcc@7.5.0' + projections: + all: '{name}/{version}' diff --git a/recipes/icon-dsl/25.8/a100/pre-install b/recipes/icon-dsl/25.8/a100/pre-install new file mode 100644 index 0000000..ba88283 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/pre-install @@ -0,0 +1,12 @@ +#!/bin/bash + +packages=("cosmo-eccodes-definitions") +SPACK_C2SM_TAG="v0.22.2.1" + +git clone -b ${SPACK_C2SM_TAG} https://github.com/C2SM/spack-c2sm.git + +for package in "${packages[@]}"; do + cp -r spack-c2sm/repos/c2sm/packages/"${package}" store/repo/packages +done + +rm -rf spack-c2sm diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/cmake_install_rpath.patch b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/cmake_install_rpath.patch new file mode 100644 index 0000000..7e2b250 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/cmake_install_rpath.patch @@ -0,0 +1,11 @@ +--- a/cmake/ecbuild_append_to_rpath.cmake ++++ b/cmake/ecbuild_append_to_rpath.cmake +@@ -31,7 +31,7 @@ function( _path_append var path ) + else() + list( FIND ${var} ${path} _found ) + if( _found EQUAL "-1" ) +- set( ${var} "${${var}}:${path}" PARENT_SCOPE ) ++ set( ${var} "${${var}};${path}" PARENT_SCOPE ) + endif() + endif() + endfunction() diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/openjpeg_jasper.patch b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/openjpeg_jasper.patch new file mode 100644 index 0000000..5793f56 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/openjpeg_jasper.patch @@ -0,0 +1,39 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,6 +43,18 @@ ecbuild_add_option( FEATURE JPG + DESCRIPTION "support for JPG decoding/encoding" + DEFAULT ON + ) ++# Options related to JPG. The Jasper and OpenJPEG libraries ++ecbuild_add_option( FEATURE JPG_LIBJASPER ++ DESCRIPTION "Support for JPG decoding/encoding with the Jasper library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ecbuild_add_option( FEATURE JPG_LIBOPENJPEG ++ DESCRIPTION "Support for JPG decoding/encoding with the OpenJPEG library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ + + ecbuild_add_option( FEATURE PNG + DESCRIPTION "support for PNG decoding/encoding" +@@ -144,7 +156,7 @@ if( ENABLE_JPG ) + + find_package( OpenJPEG ) + +- if( JASPER_FOUND ) ++ if( JASPER_FOUND AND ENABLE_JPG_LIBJASPER ) + list( APPEND ECCODES_TPLS Jasper ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBJASPER 1 ) +@@ -152,7 +164,7 @@ if( ENABLE_JPG ) + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" JASPER_VERSION_MAJOR "${JASPER_VERSION_STRING}") + endif() + +- if( OPENJPEG_FOUND ) ++ if( OPENJPEG_FOUND AND ENABLE_JPG_LIBOPENJPEG ) + list( APPEND ECCODES_TPLS OpenJPEG ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBOPENJPEG 1 ) diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/package.py new file mode 100644 index 0000000..aeb4692 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/package.py @@ -0,0 +1,385 @@ +# 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.package import * + +_definitions = { + # German Meteorological Service (Deutscher Wetterdienst, DWD): + "edzw": { + "conflicts": {"when": "@:2.19.1,2.22.0,2.24.0:"}, + "resources": [ + { + "when": "@2.20.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.20.0-1.tar.gz", + "sha256": "a92932f8a13c33cba65d3a33aa06c7fb4a37ed12a78e9abe2c5e966402b99af4", + }, + { + "when": "@2.21.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.21.0-3.tar.bz2", + "sha256": "046f1f6450abb3b44c31dee6229f4aab06ca0d3576e27e93e05ccb7cd6e2d9d9", + }, + { + "when": "@2.22.1", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.22.1-1.tar.bz2", + "sha256": "be73102a0dcabb236bacd2a70c7b5475f673fda91b49e34df61bef0fa5ad3389", + }, + { + "when": "@2.23.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.23.0-4.tar.bz2", + "sha256": "c5db32861c7d23410aed466ffef3ca661410d252870a3949442d3ecb176aa338", + }, + ], + } +} + + +class Eccodes(CMakePackage): + """ecCodes is a package developed by ECMWF for processing meteorological + data in GRIB (1/2), BUFR (3/4) and GTS header formats.""" + + homepage = "https://software.ecmwf.int/wiki/display/ECC/ecCodes+Home" + url = "https://confluence.ecmwf.int/download/attachments/45757960/eccodes-2.2.0-Source.tar.gz?api=v2" + git = "https://github.com/ecmwf/eccodes.git" + list_url = "https://confluence.ecmwf.int/display/ECC/Releases" + + maintainers("skosukhin", "victoria-cherkas", "dominichofer", "climbfuji") + + license("Apache-2.0") + + version("develop", branch="develop") + version("2.36.4", + sha256="198ccb26e8df96544c668ea6853ea153535ab78b10c43339a678f271337aa0da", + url="https://github.com/ecmwf/eccodes/archive/refs/tags/2.36.4.tar.gz" + ) + version("2.34.0", sha256="3cd208c8ddad132789662cf8f67a9405514bfefcacac403c0d8c84507f303aba") + version("2.33.0", sha256="bdcec8ce63654ec6803400c507f01220a9aa403a45fa6b5bdff7fdcc44fd7daf") + version("2.32.1", sha256="ad2ac1bf36577b1d35c4a771b4d174a06f522a1e5ef6c1f5e53a795fb624863e") + version("2.32.0", sha256="b57e8eeb0eba0c05d66fda5527c4ffa84b5ab35c46bcbc9a2227142973ccb8e6") + version("2.31.0", sha256="808ecd2c11fbf2c3f9fc7a36f8c2965b343f3151011b58a1d6e7cc2e6b3cac5d") + version("2.25.0", sha256="8975131aac54d406e5457706fd4e6ba46a8cc9c7dd817a41f2aa64ce1193c04e") + version("2.24.2", sha256="c60ad0fd89e11918ace0d84c01489f21222b11d6cad3ff7495856a0add610403") + version("2.23.0", sha256="cbdc8532537e9682f1a93ddb03440416b66906a4cc25dec3cbd73940d194bf0c") + version("2.22.1", sha256="75c7ee96469bb30b0c8f7edbdc4429ece4415897969f75c36173545242bc9e85") + version("2.21.0", sha256="da0a0bf184bb436052e3eae582defafecdb7c08cdaab7216780476e49b509755") + version("2.20.0", sha256="207a3d7966e75d85920569b55a19824673e8cd0b50db4c4dac2d3d52eacd7985") + version("2.19.1", sha256="9964bed5058e873d514bd4920951122a95963128b12f55aa199d9afbafdd5d4b") + version("2.18.0", sha256="d88943df0f246843a1a062796edbf709ef911de7269648eef864be259e9704e3") + version("2.13.0", sha256="c5ce1183b5257929fc1f1c8496239e52650707cfab24f4e0e1f1a471135b8272") + version("2.5.0", sha256="18ab44bc444168fd324d07f7dea94f89e056f5c5cd973e818c8783f952702e4e") + version("2.2.0", sha256="1a4112196497b8421480e2a0a1164071221e467853486577c4f07627a702f4c3") + + # we are still using spack v0.21 v0.22, so comment these out for now + #depends_on("c", type="build") # generated + #depends_on("cxx", type="build") # generated + #depends_on("fortran", type="build") # generated + + variant("tools", default=False, description="Build the command line tools") + variant("netcdf", default=False, description="Enable GRIB to NetCDF conversion tool") + variant( + "jp2k", + default="openjpeg", + values=("openjpeg", "jasper", "none"), + description="Specify JPEG2000 decoding/encoding backend", + ) + variant("png", default=False, description="Enable PNG support for decoding/encoding") + variant( + "aec", default=True, description="Enable Adaptive Entropy Coding for decoding/encoding" + ) + variant("pthreads", default=False, description="Enable POSIX threads") + variant("openmp", default=False, description="Enable OpenMP threads") + variant( + "memfs", default=False, description="Enable memory based access to definitions/samples" + ) + variant("fortran", default=False, description="Enable the Fortran support") + variant("shared", default=True, description="Build shared versions of the libraries") + + variant( + "extra_definitions", + values=any_combination_of(*_definitions.keys()), + description="List of extra definitions to install", + ) + + depends_on("netcdf-c", when="+netcdf") + # Cannot be built with openjpeg@2.0.x. + depends_on("openjpeg@1.5.0:1.5,2.1.0:2.3", when="jp2k=openjpeg") + # Additional constraint for older versions. + depends_on("openjpeg@:2.1", when="@:2.16 jp2k=openjpeg") + + with when("jp2k=jasper"): + depends_on("jasper") + # jasper 3.x compat from commit 86f0b35f1a8492cb16f82fb976a0a5acd2986ac2 + depends_on("jasper@:2", when="@:2.25.0") + + depends_on("libpng", when="+png") + depends_on("libaec", when="+aec") + # Can be built with Python 2 or Python 3. + depends_on("python", when="+memfs", type="build") + + depends_on("cmake@3.6:", type="build") + depends_on("cmake@3.12:", when="@2.19:", type="build") + + # TODO: ecbuild was only used for the @develop branch + # however, testing 2.36.4, it appears to be a requirement. + # this might be because they package the software differently in GitHub + # (they normally provide releases as tar balls on Confluence) + depends_on("ecbuild", type="build") + #depends_on("ecbuild", type="build", when="@develop") + + conflicts("+openmp", when="+pthreads", msg="Cannot enable both POSIX threads and OMP") + + conflicts( + "+netcdf", + when="~tools", + msg="Cannot enable the NetCDF conversion tool " "when the command line tools are disabled", + ) + + conflicts( + "~tools", + when="@:2.18.0", + msg="The command line tools can be disabled " "only starting version 2.19.0", + ) + + for center, definitions in _definitions.items(): + kwargs = definitions.get("conflicts", None) + if kwargs: + conflicts("extra_definitions={0}".format(center), **kwargs) + for kwargs in definitions.get("resources", []): + resource( + name=center, + destination="spack-definitions", + placement="definitions.{0}".format(center), + **kwargs, + ) + + # Enforce linking against the specified JPEG2000 backend, see also + # https://github.com/ecmwf/eccodes/commit/2c10828495900ff3d80d1e570fe96c1df16d97fb + patch("openjpeg_jasper.patch", when="@:2.16") + + # CMAKE_INSTALL_RPATH must be a semicolon-separated list. + patch("cmake_install_rpath.patch", when="@:2.10") + + # Fix a bug preventing cmake from finding NetCDF: + patch( + "https://github.com/ecmwf/ecbuild/commit/3916c7d22575c45166fcc89edcbe02a6e9b81aa2.patch?full_index=1", + sha256="9dcc4affaaa850d4b7247baa939d0f9ffedea132369f1afc3f248dbf720386c9", + when="@:2.4.0+netcdf", + ) + + @when("%nag+fortran") + def patch(self): + # A number of Fortran source files assume that the kinds of integer and + # real variables are specified in bytes. However, the NAG compiler + # accepts such code only with an additional compiler flag -kind=byte. + # We do not simply add the flag because all user applications would + # have to be compiled with this flag too, which goes against one of the + # purposes of using the NAG compiler: make sure the code does not + # contradict the Fortran standards. The following logic could have been + # implemented as regular patch files, which would, however, be quite + # large. We would also have to introduce several versions of each patch + # file to support different versions of the package. + + patch_kind_files = [ + "fortran/eccodes_f90_head.f90", + "fortran/eccodes_f90_tail.f90", + "fortran/grib_f90_head.f90", + "fortran/grib_f90_tail.f90", + "fortran/grib_types.f90", + ] + + patch_unix_ext_files = [] + + if self.run_tests: + patch_kind_files.extend( + [ + "examples/F90/grib_print_data.f90", + "examples/F90/grib_print_data_static.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_attributes.f90', + # 'examples/F90/bufr_expanded.f90', + # 'examples/F90/bufr_get_keys.f90', + # 'examples/F90/bufr_read_scatterometer.f90', + # 'examples/F90/bufr_read_synop.f90', + # 'examples/F90/bufr_read_temp.f90', + # 'examples/F90/bufr_read_tempf.f90', + # 'examples/F90/bufr_read_tropical_cyclone.f90', + # 'examples/F90/grib_clone.f90', + # 'examples/F90/grib_get_data.f90', + # 'examples/F90/grib_nearest.f90', + # 'examples/F90/grib_precision.f90', + # 'examples/F90/grib_read_from_file.f90', + # 'examples/F90/grib_samples.f90', + # 'examples/F90/grib_set_keys.f90' + ] + ) + + patch_unix_ext_files.extend( + [ + "examples/F90/bufr_ecc-1284.f90", + "examples/F90/grib_set_data.f90", + "examples/F90/grib_set_packing.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_copy_data.f90', + # 'examples/F90/bufr_get_string_array.f90', + # 'examples/F90/bufr_keys_iterator.f90', + # 'examples/F90/get_product_kind.f90', + # 'examples/F90/grib_count_messages_multi.f90' + ] + ) + + kwargs = {"string": False, "backup": False, "ignore_absent": True} + + # Return the kind and not the size: + filter_file( + r"(^\s*kind_of_double\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(real\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + filter_file( + r"(^\s*kind_of_\w+\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(x\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + + # Replace integer kinds: + for size, r in [(2, 4), (4, 9), (8, 18)]: + filter_file( + r"(^\s*integer\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_int_kind({0})\\2".format(r), + *patch_kind_files, + **kwargs, + ) + + # Replace real kinds: + for size, p, r in [(4, 6, 37), (8, 15, 307)]: + filter_file( + r"(^\s*real\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_real_kind({0}, {1})\\2".format(p, r), + *patch_kind_files, + **kwargs, + ) + + # Enable getarg and exit subroutines: + filter_file( + r"(^\s*program\s+\w+)(\s*$)", + "\\1; use f90_unix_env; use f90_unix_proc\\2", + *patch_unix_ext_files, + **kwargs, + ) + + @property + def libs(self): + libraries = [] + + query_parameters = self.spec.last_query.extra_parameters + + if "shared" in query_parameters: + shared = True + elif "static" in query_parameters: + shared = False + else: + shared = "+shared" in self.spec + + # Return Fortran library if requested: + return_fortran = "fortran" in query_parameters + # Return C library if either requested or the Fortran library is not + # requested (to avoid overlinking) or the static libraries are + # requested: + return_c = "c" in query_parameters or not (return_fortran and shared) + # Return MEMFS library only if enabled and the static libraries are + # requested: + return_memfs = "+memfs" in self.spec and not shared + + if return_fortran: + libraries.append("libeccodes_f90") + + if return_c: + libraries.append("libeccodes") + + if return_memfs: + libraries.append("libeccodes_memfs") + + libs = find_libraries(libraries, root=self.prefix, shared=shared, recursive=True) + + if libs and len(libs) == len(libraries): + return libs + + msg = "Unable to recursively locate {0} {1} libraries in {2}" + raise spack.error.NoLibrariesError( + msg.format("shared" if shared else "static", self.spec.name, self.spec.prefix) + ) + + @run_before("cmake") + def check_fortran(self): + if "+fortran" in self.spec and self.compiler.fc is None: + raise InstallError("Fortran interface requires a Fortran compiler!") + + def cmake_args(self): + jp2k = self.spec.variants["jp2k"].value + + args = [ + self.define_from_variant("ENABLE_BUILD_TOOLS", "tools"), + self.define_from_variant("ENABLE_NETCDF", "netcdf"), + self.define("ENABLE_JPG", jp2k != "none"), + self.define("ENABLE_JPG_LIBJASPER", jp2k == "jasper"), + self.define("ENABLE_JPG_LIBOPENJPEG", jp2k == "openjpeg"), + self.define_from_variant("ENABLE_PNG", "png"), + self.define_from_variant("ENABLE_AEC", "aec"), + self.define_from_variant("ENABLE_ECCODES_THREADS", "pthreads"), + self.define_from_variant("ENABLE_ECCODES_OMP_THREADS", "openmp"), + self.define_from_variant("ENABLE_MEMFS", "memfs"), + self.define( + "ENABLE_PYTHON{0}".format("2" if self.spec.satisfies("@2.20.0:") else ""), False + ), + self.define_from_variant("ENABLE_FORTRAN", "fortran"), + self.define("BUILD_SHARED_LIBS", "BOTH" if "+shared" in self.spec else "OFF"), + self.define("ENABLE_TESTS", self.run_tests), + # Examples are not installed and are just part of the test suite: + self.define("ENABLE_EXAMPLES", self.run_tests), + # Unconditionally disable the extended regression tests, since they + # download additional data (~134MB): + self.define("ENABLE_EXTRA_TESTS", False), + ] + + if self.spec.satisfies("+netcdf"): + # Prevent possible overriding by environment variables NETCDF_ROOT, NETCDF_DIR, and + # NETCDF_PATH: + args.append(self.define("NETCDF_PATH", self.spec["netcdf-c"].prefix)) + # Prevent overriding by environment variable HDF5_ROOT (starting version 2.14.0, + # ecCodes is shipped with ecBuild 3.1.0+, which does not seem to rely on the HDF5_ROOT + # variable): + if self.spec.satisfies("@:2.13"): + args.append(self.define("HDF5_ROOT", self.spec["hdf5"].prefix)) + + if jp2k == "openjpeg": + args.append(self.define("OPENJPEG_PATH", self.spec["openjpeg"].prefix)) + + if self.spec.satisfies("+png"): + args.append(self.define("ZLIB_ROOT", self.spec["zlib-api"].prefix)) + + if self.spec.satisfies("+aec"): + # Prevent overriding by environment variables AEC_DIR and AEC_PATH: + args.append(self.define("AEC_DIR", self.spec["libaec"].prefix)) + + return args + + @run_after("install") + def install_extra_definitions(self): + for center in self.spec.variants["extra_definitions"].value: + if center != "none": + center_dir = "definitions.{0}".format(center) + install_tree( + join_path(self.stage.source_path, "spack-definitions", center_dir), + join_path(self.prefix.share.eccodes, center_dir), + ) + + def check(self): + # https://confluence.ecmwf.int/display/ECC/ecCodes+installation + with working_dir(self.build_directory): + ctest() diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/readme.md b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/readme.md new file mode 100644 index 0000000..9678342 --- /dev/null +++ b/recipes/icon-dsl/25.8/a100/repo/packages/eccodes/readme.md @@ -0,0 +1 @@ +copied from mainline spack November 5 2024 so that we can add eccodes 2.36.0 for mch production diff --git a/recipes/icon-dsl/25.8/gh200/compilers.yaml b/recipes/icon-dsl/25.8/gh200/compilers.yaml index a7197a6..f456b5a 100644 --- a/recipes/icon-dsl/25.8/gh200/compilers.yaml +++ b/recipes/icon-dsl/25.8/gh200/compilers.yaml @@ -1,5 +1,5 @@ bootstrap: - spec: gcc@11 + spec: gcc@12.3 gcc: specs: - gcc@13 diff --git a/recipes/icon-dsl/25.8/gh200/config.yaml b/recipes/icon-dsl/25.8/gh200/config.yaml index fb6c610..ac4ba9c 100644 --- a/recipes/icon-dsl/25.8/gh200/config.yaml +++ b/recipes/icon-dsl/25.8/gh200/config.yaml @@ -4,4 +4,4 @@ spack: repo: https://github.com/spack/spack.git commit: releases/v0.23 modules: false -description: icon4py proof-of-concept +description: Build and runtime dependencies for ICON-DSL diff --git a/recipes/icon-dsl/25.8/gh200/environments.yaml b/recipes/icon-dsl/25.8/gh200/environments.yaml index e02b4c1..73030fa 100644 --- a/recipes/icon-dsl/25.8/gh200/environments.yaml +++ b/recipes/icon-dsl/25.8/gh200/environments.yaml @@ -8,11 +8,32 @@ myenv: spec: cray-mpich@8.1.30%nvhpc gpu: cuda specs: + # icon4py deps - python@3.11 - py-cupy +cuda cuda_arch=90 - ghex +python +cuda cuda_arch=90 - py-mpi4py - icon4py@icon_20250328 + # icon deps + - boost ~mpi + - cuda@12.6 + - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper + - cosmo-eccodes-definitions@2.36.0.3 + - hdf5%nvhpc +szip +hl +fortran +mpi + - netcdf-c@4.9.2%nvhpc + - netcdf-cxx4@4.3.1%nvhpc + - netcdf-fortran@4.6.1%nvhpc + - osu-micro-benchmarks@5.9%nvhpc + - openblas + # for validation + - cdo + # everything needed for nccl on SS11 + - nccl + - nccl-tests + # extras + - libfyaml + - zlib-ng + - cmake unify: true variants: - +mpi @@ -20,3 +41,7 @@ myenv: - cuda_arch=90 views: default: + link: roots + uenv: + prefix_paths: + LD_LIBRARY_PATH: [lib, lib64] diff --git a/recipes/icon-dsl/25.8/gh200/extra/reframe.yaml b/recipes/icon-dsl/25.8/gh200/extra/reframe.yaml new file mode 100644 index 0000000..363f809 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/extra/reframe.yaml @@ -0,0 +1,6 @@ +default: + features: [osu-micro-benchmarks, mpi, serial, openmp] + cc: mpicc + cxx: mpic++ + ftn: mpifort + activation: /user-environment/env/default/activate.sh diff --git a/recipes/icon-dsl/25.8/gh200/modules.yaml b/recipes/icon-dsl/25.8/gh200/modules.yaml new file mode 100644 index 0000000..a4010ae --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/modules.yaml @@ -0,0 +1,26 @@ +modules: + # Paths to check when creating modules for all module sets + prefix_inspections: + bin: + - PATH + lib: + - LD_LIBRARY_PATH + lib64: + - LD_LIBRARY_PATH + + default: + arch_folder: false + # Where to install modules + roots: + tcl: /snap/modules + tcl: + all: + autoload: run + hash_length: 0 + hide_implicits: true + exclude: + - '%gcc@7.5.0' + - '%gcc@12' + - 'gcc %gcc@7.5.0' + projections: + all: '{name}/{version}' diff --git a/recipes/icon-dsl/25.8/gh200/pre-install b/recipes/icon-dsl/25.8/gh200/pre-install new file mode 100644 index 0000000..ba88283 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/pre-install @@ -0,0 +1,12 @@ +#!/bin/bash + +packages=("cosmo-eccodes-definitions") +SPACK_C2SM_TAG="v0.22.2.1" + +git clone -b ${SPACK_C2SM_TAG} https://github.com/C2SM/spack-c2sm.git + +for package in "${packages[@]}"; do + cp -r spack-c2sm/repos/c2sm/packages/"${package}" store/repo/packages +done + +rm -rf spack-c2sm diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/cmake_install_rpath.patch b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/cmake_install_rpath.patch new file mode 100644 index 0000000..7e2b250 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/cmake_install_rpath.patch @@ -0,0 +1,11 @@ +--- a/cmake/ecbuild_append_to_rpath.cmake ++++ b/cmake/ecbuild_append_to_rpath.cmake +@@ -31,7 +31,7 @@ function( _path_append var path ) + else() + list( FIND ${var} ${path} _found ) + if( _found EQUAL "-1" ) +- set( ${var} "${${var}}:${path}" PARENT_SCOPE ) ++ set( ${var} "${${var}};${path}" PARENT_SCOPE ) + endif() + endif() + endfunction() diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/openjpeg_jasper.patch b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/openjpeg_jasper.patch new file mode 100644 index 0000000..5793f56 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/openjpeg_jasper.patch @@ -0,0 +1,39 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,6 +43,18 @@ ecbuild_add_option( FEATURE JPG + DESCRIPTION "support for JPG decoding/encoding" + DEFAULT ON + ) ++# Options related to JPG. The Jasper and OpenJPEG libraries ++ecbuild_add_option( FEATURE JPG_LIBJASPER ++ DESCRIPTION "Support for JPG decoding/encoding with the Jasper library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ecbuild_add_option( FEATURE JPG_LIBOPENJPEG ++ DESCRIPTION "Support for JPG decoding/encoding with the OpenJPEG library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ + + ecbuild_add_option( FEATURE PNG + DESCRIPTION "support for PNG decoding/encoding" +@@ -144,7 +156,7 @@ if( ENABLE_JPG ) + + find_package( OpenJPEG ) + +- if( JASPER_FOUND ) ++ if( JASPER_FOUND AND ENABLE_JPG_LIBJASPER ) + list( APPEND ECCODES_TPLS Jasper ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBJASPER 1 ) +@@ -152,7 +164,7 @@ if( ENABLE_JPG ) + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" JASPER_VERSION_MAJOR "${JASPER_VERSION_STRING}") + endif() + +- if( OPENJPEG_FOUND ) ++ if( OPENJPEG_FOUND AND ENABLE_JPG_LIBOPENJPEG ) + list( APPEND ECCODES_TPLS OpenJPEG ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBOPENJPEG 1 ) diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/package.py new file mode 100644 index 0000000..aeb4692 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/package.py @@ -0,0 +1,385 @@ +# 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.package import * + +_definitions = { + # German Meteorological Service (Deutscher Wetterdienst, DWD): + "edzw": { + "conflicts": {"when": "@:2.19.1,2.22.0,2.24.0:"}, + "resources": [ + { + "when": "@2.20.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.20.0-1.tar.gz", + "sha256": "a92932f8a13c33cba65d3a33aa06c7fb4a37ed12a78e9abe2c5e966402b99af4", + }, + { + "when": "@2.21.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.21.0-3.tar.bz2", + "sha256": "046f1f6450abb3b44c31dee6229f4aab06ca0d3576e27e93e05ccb7cd6e2d9d9", + }, + { + "when": "@2.22.1", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.22.1-1.tar.bz2", + "sha256": "be73102a0dcabb236bacd2a70c7b5475f673fda91b49e34df61bef0fa5ad3389", + }, + { + "when": "@2.23.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.23.0-4.tar.bz2", + "sha256": "c5db32861c7d23410aed466ffef3ca661410d252870a3949442d3ecb176aa338", + }, + ], + } +} + + +class Eccodes(CMakePackage): + """ecCodes is a package developed by ECMWF for processing meteorological + data in GRIB (1/2), BUFR (3/4) and GTS header formats.""" + + homepage = "https://software.ecmwf.int/wiki/display/ECC/ecCodes+Home" + url = "https://confluence.ecmwf.int/download/attachments/45757960/eccodes-2.2.0-Source.tar.gz?api=v2" + git = "https://github.com/ecmwf/eccodes.git" + list_url = "https://confluence.ecmwf.int/display/ECC/Releases" + + maintainers("skosukhin", "victoria-cherkas", "dominichofer", "climbfuji") + + license("Apache-2.0") + + version("develop", branch="develop") + version("2.36.4", + sha256="198ccb26e8df96544c668ea6853ea153535ab78b10c43339a678f271337aa0da", + url="https://github.com/ecmwf/eccodes/archive/refs/tags/2.36.4.tar.gz" + ) + version("2.34.0", sha256="3cd208c8ddad132789662cf8f67a9405514bfefcacac403c0d8c84507f303aba") + version("2.33.0", sha256="bdcec8ce63654ec6803400c507f01220a9aa403a45fa6b5bdff7fdcc44fd7daf") + version("2.32.1", sha256="ad2ac1bf36577b1d35c4a771b4d174a06f522a1e5ef6c1f5e53a795fb624863e") + version("2.32.0", sha256="b57e8eeb0eba0c05d66fda5527c4ffa84b5ab35c46bcbc9a2227142973ccb8e6") + version("2.31.0", sha256="808ecd2c11fbf2c3f9fc7a36f8c2965b343f3151011b58a1d6e7cc2e6b3cac5d") + version("2.25.0", sha256="8975131aac54d406e5457706fd4e6ba46a8cc9c7dd817a41f2aa64ce1193c04e") + version("2.24.2", sha256="c60ad0fd89e11918ace0d84c01489f21222b11d6cad3ff7495856a0add610403") + version("2.23.0", sha256="cbdc8532537e9682f1a93ddb03440416b66906a4cc25dec3cbd73940d194bf0c") + version("2.22.1", sha256="75c7ee96469bb30b0c8f7edbdc4429ece4415897969f75c36173545242bc9e85") + version("2.21.0", sha256="da0a0bf184bb436052e3eae582defafecdb7c08cdaab7216780476e49b509755") + version("2.20.0", sha256="207a3d7966e75d85920569b55a19824673e8cd0b50db4c4dac2d3d52eacd7985") + version("2.19.1", sha256="9964bed5058e873d514bd4920951122a95963128b12f55aa199d9afbafdd5d4b") + version("2.18.0", sha256="d88943df0f246843a1a062796edbf709ef911de7269648eef864be259e9704e3") + version("2.13.0", sha256="c5ce1183b5257929fc1f1c8496239e52650707cfab24f4e0e1f1a471135b8272") + version("2.5.0", sha256="18ab44bc444168fd324d07f7dea94f89e056f5c5cd973e818c8783f952702e4e") + version("2.2.0", sha256="1a4112196497b8421480e2a0a1164071221e467853486577c4f07627a702f4c3") + + # we are still using spack v0.21 v0.22, so comment these out for now + #depends_on("c", type="build") # generated + #depends_on("cxx", type="build") # generated + #depends_on("fortran", type="build") # generated + + variant("tools", default=False, description="Build the command line tools") + variant("netcdf", default=False, description="Enable GRIB to NetCDF conversion tool") + variant( + "jp2k", + default="openjpeg", + values=("openjpeg", "jasper", "none"), + description="Specify JPEG2000 decoding/encoding backend", + ) + variant("png", default=False, description="Enable PNG support for decoding/encoding") + variant( + "aec", default=True, description="Enable Adaptive Entropy Coding for decoding/encoding" + ) + variant("pthreads", default=False, description="Enable POSIX threads") + variant("openmp", default=False, description="Enable OpenMP threads") + variant( + "memfs", default=False, description="Enable memory based access to definitions/samples" + ) + variant("fortran", default=False, description="Enable the Fortran support") + variant("shared", default=True, description="Build shared versions of the libraries") + + variant( + "extra_definitions", + values=any_combination_of(*_definitions.keys()), + description="List of extra definitions to install", + ) + + depends_on("netcdf-c", when="+netcdf") + # Cannot be built with openjpeg@2.0.x. + depends_on("openjpeg@1.5.0:1.5,2.1.0:2.3", when="jp2k=openjpeg") + # Additional constraint for older versions. + depends_on("openjpeg@:2.1", when="@:2.16 jp2k=openjpeg") + + with when("jp2k=jasper"): + depends_on("jasper") + # jasper 3.x compat from commit 86f0b35f1a8492cb16f82fb976a0a5acd2986ac2 + depends_on("jasper@:2", when="@:2.25.0") + + depends_on("libpng", when="+png") + depends_on("libaec", when="+aec") + # Can be built with Python 2 or Python 3. + depends_on("python", when="+memfs", type="build") + + depends_on("cmake@3.6:", type="build") + depends_on("cmake@3.12:", when="@2.19:", type="build") + + # TODO: ecbuild was only used for the @develop branch + # however, testing 2.36.4, it appears to be a requirement. + # this might be because they package the software differently in GitHub + # (they normally provide releases as tar balls on Confluence) + depends_on("ecbuild", type="build") + #depends_on("ecbuild", type="build", when="@develop") + + conflicts("+openmp", when="+pthreads", msg="Cannot enable both POSIX threads and OMP") + + conflicts( + "+netcdf", + when="~tools", + msg="Cannot enable the NetCDF conversion tool " "when the command line tools are disabled", + ) + + conflicts( + "~tools", + when="@:2.18.0", + msg="The command line tools can be disabled " "only starting version 2.19.0", + ) + + for center, definitions in _definitions.items(): + kwargs = definitions.get("conflicts", None) + if kwargs: + conflicts("extra_definitions={0}".format(center), **kwargs) + for kwargs in definitions.get("resources", []): + resource( + name=center, + destination="spack-definitions", + placement="definitions.{0}".format(center), + **kwargs, + ) + + # Enforce linking against the specified JPEG2000 backend, see also + # https://github.com/ecmwf/eccodes/commit/2c10828495900ff3d80d1e570fe96c1df16d97fb + patch("openjpeg_jasper.patch", when="@:2.16") + + # CMAKE_INSTALL_RPATH must be a semicolon-separated list. + patch("cmake_install_rpath.patch", when="@:2.10") + + # Fix a bug preventing cmake from finding NetCDF: + patch( + "https://github.com/ecmwf/ecbuild/commit/3916c7d22575c45166fcc89edcbe02a6e9b81aa2.patch?full_index=1", + sha256="9dcc4affaaa850d4b7247baa939d0f9ffedea132369f1afc3f248dbf720386c9", + when="@:2.4.0+netcdf", + ) + + @when("%nag+fortran") + def patch(self): + # A number of Fortran source files assume that the kinds of integer and + # real variables are specified in bytes. However, the NAG compiler + # accepts such code only with an additional compiler flag -kind=byte. + # We do not simply add the flag because all user applications would + # have to be compiled with this flag too, which goes against one of the + # purposes of using the NAG compiler: make sure the code does not + # contradict the Fortran standards. The following logic could have been + # implemented as regular patch files, which would, however, be quite + # large. We would also have to introduce several versions of each patch + # file to support different versions of the package. + + patch_kind_files = [ + "fortran/eccodes_f90_head.f90", + "fortran/eccodes_f90_tail.f90", + "fortran/grib_f90_head.f90", + "fortran/grib_f90_tail.f90", + "fortran/grib_types.f90", + ] + + patch_unix_ext_files = [] + + if self.run_tests: + patch_kind_files.extend( + [ + "examples/F90/grib_print_data.f90", + "examples/F90/grib_print_data_static.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_attributes.f90', + # 'examples/F90/bufr_expanded.f90', + # 'examples/F90/bufr_get_keys.f90', + # 'examples/F90/bufr_read_scatterometer.f90', + # 'examples/F90/bufr_read_synop.f90', + # 'examples/F90/bufr_read_temp.f90', + # 'examples/F90/bufr_read_tempf.f90', + # 'examples/F90/bufr_read_tropical_cyclone.f90', + # 'examples/F90/grib_clone.f90', + # 'examples/F90/grib_get_data.f90', + # 'examples/F90/grib_nearest.f90', + # 'examples/F90/grib_precision.f90', + # 'examples/F90/grib_read_from_file.f90', + # 'examples/F90/grib_samples.f90', + # 'examples/F90/grib_set_keys.f90' + ] + ) + + patch_unix_ext_files.extend( + [ + "examples/F90/bufr_ecc-1284.f90", + "examples/F90/grib_set_data.f90", + "examples/F90/grib_set_packing.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_copy_data.f90', + # 'examples/F90/bufr_get_string_array.f90', + # 'examples/F90/bufr_keys_iterator.f90', + # 'examples/F90/get_product_kind.f90', + # 'examples/F90/grib_count_messages_multi.f90' + ] + ) + + kwargs = {"string": False, "backup": False, "ignore_absent": True} + + # Return the kind and not the size: + filter_file( + r"(^\s*kind_of_double\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(real\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + filter_file( + r"(^\s*kind_of_\w+\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(x\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + + # Replace integer kinds: + for size, r in [(2, 4), (4, 9), (8, 18)]: + filter_file( + r"(^\s*integer\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_int_kind({0})\\2".format(r), + *patch_kind_files, + **kwargs, + ) + + # Replace real kinds: + for size, p, r in [(4, 6, 37), (8, 15, 307)]: + filter_file( + r"(^\s*real\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_real_kind({0}, {1})\\2".format(p, r), + *patch_kind_files, + **kwargs, + ) + + # Enable getarg and exit subroutines: + filter_file( + r"(^\s*program\s+\w+)(\s*$)", + "\\1; use f90_unix_env; use f90_unix_proc\\2", + *patch_unix_ext_files, + **kwargs, + ) + + @property + def libs(self): + libraries = [] + + query_parameters = self.spec.last_query.extra_parameters + + if "shared" in query_parameters: + shared = True + elif "static" in query_parameters: + shared = False + else: + shared = "+shared" in self.spec + + # Return Fortran library if requested: + return_fortran = "fortran" in query_parameters + # Return C library if either requested or the Fortran library is not + # requested (to avoid overlinking) or the static libraries are + # requested: + return_c = "c" in query_parameters or not (return_fortran and shared) + # Return MEMFS library only if enabled and the static libraries are + # requested: + return_memfs = "+memfs" in self.spec and not shared + + if return_fortran: + libraries.append("libeccodes_f90") + + if return_c: + libraries.append("libeccodes") + + if return_memfs: + libraries.append("libeccodes_memfs") + + libs = find_libraries(libraries, root=self.prefix, shared=shared, recursive=True) + + if libs and len(libs) == len(libraries): + return libs + + msg = "Unable to recursively locate {0} {1} libraries in {2}" + raise spack.error.NoLibrariesError( + msg.format("shared" if shared else "static", self.spec.name, self.spec.prefix) + ) + + @run_before("cmake") + def check_fortran(self): + if "+fortran" in self.spec and self.compiler.fc is None: + raise InstallError("Fortran interface requires a Fortran compiler!") + + def cmake_args(self): + jp2k = self.spec.variants["jp2k"].value + + args = [ + self.define_from_variant("ENABLE_BUILD_TOOLS", "tools"), + self.define_from_variant("ENABLE_NETCDF", "netcdf"), + self.define("ENABLE_JPG", jp2k != "none"), + self.define("ENABLE_JPG_LIBJASPER", jp2k == "jasper"), + self.define("ENABLE_JPG_LIBOPENJPEG", jp2k == "openjpeg"), + self.define_from_variant("ENABLE_PNG", "png"), + self.define_from_variant("ENABLE_AEC", "aec"), + self.define_from_variant("ENABLE_ECCODES_THREADS", "pthreads"), + self.define_from_variant("ENABLE_ECCODES_OMP_THREADS", "openmp"), + self.define_from_variant("ENABLE_MEMFS", "memfs"), + self.define( + "ENABLE_PYTHON{0}".format("2" if self.spec.satisfies("@2.20.0:") else ""), False + ), + self.define_from_variant("ENABLE_FORTRAN", "fortran"), + self.define("BUILD_SHARED_LIBS", "BOTH" if "+shared" in self.spec else "OFF"), + self.define("ENABLE_TESTS", self.run_tests), + # Examples are not installed and are just part of the test suite: + self.define("ENABLE_EXAMPLES", self.run_tests), + # Unconditionally disable the extended regression tests, since they + # download additional data (~134MB): + self.define("ENABLE_EXTRA_TESTS", False), + ] + + if self.spec.satisfies("+netcdf"): + # Prevent possible overriding by environment variables NETCDF_ROOT, NETCDF_DIR, and + # NETCDF_PATH: + args.append(self.define("NETCDF_PATH", self.spec["netcdf-c"].prefix)) + # Prevent overriding by environment variable HDF5_ROOT (starting version 2.14.0, + # ecCodes is shipped with ecBuild 3.1.0+, which does not seem to rely on the HDF5_ROOT + # variable): + if self.spec.satisfies("@:2.13"): + args.append(self.define("HDF5_ROOT", self.spec["hdf5"].prefix)) + + if jp2k == "openjpeg": + args.append(self.define("OPENJPEG_PATH", self.spec["openjpeg"].prefix)) + + if self.spec.satisfies("+png"): + args.append(self.define("ZLIB_ROOT", self.spec["zlib-api"].prefix)) + + if self.spec.satisfies("+aec"): + # Prevent overriding by environment variables AEC_DIR and AEC_PATH: + args.append(self.define("AEC_DIR", self.spec["libaec"].prefix)) + + return args + + @run_after("install") + def install_extra_definitions(self): + for center in self.spec.variants["extra_definitions"].value: + if center != "none": + center_dir = "definitions.{0}".format(center) + install_tree( + join_path(self.stage.source_path, "spack-definitions", center_dir), + join_path(self.prefix.share.eccodes, center_dir), + ) + + def check(self): + # https://confluence.ecmwf.int/display/ECC/ecCodes+installation + with working_dir(self.build_directory): + ctest() diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/readme.md b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/readme.md new file mode 100644 index 0000000..9678342 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/eccodes/readme.md @@ -0,0 +1 @@ +copied from mainline spack November 5 2024 so that we can add eccodes 2.36.0 for mch production From f1b48ca65e65b1484622b51a7c7c5dcda5ec6764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Wed, 30 Jul 2025 14:58:24 +0200 Subject: [PATCH 13/32] update cupy to a version that supports cuda 12.6, fix mpi spec --- recipes/icon-dsl/25.8/a100/environments.yaml | 2 +- .../a100/repo/packages/py-cupy/package.py | 9 +- recipes/icon-dsl/25.8/gh200/environments.yaml | 2 +- .../gh200/repo/packages/icon4py/package.py | 232 ++++++++++-------- 4 files changed, 145 insertions(+), 100 deletions(-) diff --git a/recipes/icon-dsl/25.8/a100/environments.yaml b/recipes/icon-dsl/25.8/a100/environments.yaml index 7f8ba10..2225f30 100644 --- a/recipes/icon-dsl/25.8/a100/environments.yaml +++ b/recipes/icon-dsl/25.8/a100/environments.yaml @@ -15,7 +15,7 @@ myenv: - py-mpi4py - icon4py@icon_20250328 # icon deps - - boost ~mpi + - boost - cuda@12.6 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper - cosmo-eccodes-definitions@2.36.0.3 diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py index 5a29de7..b7e6949 100644 --- a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py +++ b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py @@ -19,6 +19,10 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): homepage = "https://cupy.dev/" pypi = "cupy/cupy-8.0.0.tar.gz" + version( + "13.5.1", + sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + ) version( "13.1.0", sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", @@ -75,7 +79,10 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): # Based on https://github.com/cupy/cupy/releases depends_on("cuda@:11.9", when="@:11 +cuda") depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") - depends_on("cuda@:12.4", when="@13: +cuda") + depends_on("cuda@:12.4", when="@13:13.2 +cuda") + depends_on("cuda@:12.6", when="@13:3:13.4 +cuda") + depends_on("cuda@:12.8", when="@13.4:13.5 +cuda") + depends_on("cuda@:12.9", when="@13.5: +cuda") for a in CudaPackage.cuda_arch_values: depends_on( diff --git a/recipes/icon-dsl/25.8/gh200/environments.yaml b/recipes/icon-dsl/25.8/gh200/environments.yaml index 73030fa..1325e60 100644 --- a/recipes/icon-dsl/25.8/gh200/environments.yaml +++ b/recipes/icon-dsl/25.8/gh200/environments.yaml @@ -15,7 +15,7 @@ myenv: - py-mpi4py - icon4py@icon_20250328 # icon deps - - boost ~mpi + - boost - cuda@12.6 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper - cosmo-eccodes-definitions@2.36.0.3 diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py index 9ee413e..b7e6949 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py @@ -1,109 +1,147 @@ -import json +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + import os -import pathlib -import llnl -from llnl.util import tty -from spack import * +from spack.package import * + +class PyCupy(PythonPackage, CudaPackage, ROCmPackage): + """CuPy is an open-source array library accelerated with + NVIDIA CUDA. CuPy provides GPU accelerated computing with + Python. CuPy uses CUDA-related libraries including cuBLAS, + cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make + full use of the GPU architecture. -class Icon4py(Package): - extends("python") - depends_on("python@3.11:") + This version does not use CudNN.""" - depends_on("git") - depends_on("boost@1.85:+mpi+python", type=("build", "run")) - depends_on("uv@0.7:", type="build") - depends_on("bzip2", type="build") - depends_on("py-numpy") - depends_on("py-cffi") - depends_on("py-pybind11") - depends_on("py-nanobind") - depends_on("py-mpi4py") - depends_on("py-cupy +cuda") - depends_on("ghex +python +cuda") + homepage = "https://cupy.dev/" + pypi = "cupy/cupy-8.0.0.tar.gz" version( - "icon_20250328", - sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", - extension="zip", + "13.5.1", + sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + ) + version( + "13.1.0", + sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", + ) + version( + "12.1.0", + sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", + ) + version( + "12.0.0", + sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", + ) + version( + "11.6.0", + sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", + ) + version( + "11.5.0", + sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", + ) + version( + "11.4.0", + sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", + ) + version( + "11.3.0", + sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", + ) + version( + "11.2.0", + sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", ) - def url_for_version(self, version): - return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" - - def install(self, spec, prefix): - uv = prepare_uv() - python_spec = spec["python"] - venv_path = prefix.share.venv - - tty.msg(f"creating venv using spack python at: {python_spec.command.path}") - uv( - "venv", - "--seed", - "--relocatable", - "--system-site-packages", - str(venv_path), - "--python", - python_spec.command.path, - ) - - tty.msg(f"grabbing spack installed packages (distributions)") - pip = Executable(venv_path.bin.pip) - spack_installed = get_installed_pkg(pip) - - tty.msg(f"installing missing packages") - uv( - "sync", - "--active", - "--extra", - "all", - "--extra", - "cuda12", - "--inexact", - "--no-editable", - "--python", - str(venv_path.bin.python), - *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), - extra_env={"VIRTUAL_ENV": str(venv_path)}, - ) + variant( + "all", default=False, description="Enable optional py-scipy, optuna, and cython" + ) - tty.msg(f"linking spack installed packages into venv") - pathlib.Path( - f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" - ).write_text(pythonpath_to_pth()) - - tty.msg(f"running py2fgen") - py2fgen = Executable(venv_path.bin.py2fgen) - py2fgen( - "icon4py.tools.py2fgen.wrappers.all_bindings", - "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", - "icon4py_bindings", - "-o", - prefix.src, - extra_env={"VIRTUAL_ENV": str(venv_path)}, + depends_on("cxx", type="build") # generated + + depends_on("python@3.7:", when="@:11", type=("build", "run")) + depends_on("python@3.8:", when="@12:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-cython@0.29.22:2", type="build") + depends_on("py-fastrlock@0.5:", type=("build", "run")) + depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) + depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) + depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) + + depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) + depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) + depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) + depends_on("py-optuna@2:", when="+all", type=("build", "run")) + + # Based on https://github.com/cupy/cupy/releases + depends_on("cuda@:11.9", when="@:11 +cuda") + depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") + depends_on("cuda@:12.4", when="@13:13.2 +cuda") + depends_on("cuda@:12.6", when="@13:3:13.4 +cuda") + depends_on("cuda@:12.8", when="@13.4:13.5 +cuda") + depends_on("cuda@:12.9", when="@13.5: +cuda") + + for a in CudaPackage.cuda_arch_values: + depends_on( + "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) ) - -def prepare_uv(): - uv = which("uv") - uv.add_default_env("UV_NO_CACHE", "true") - uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") - uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") - return uv - - -def get_installed_pkg(pip): - return [ - item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) - ] - - -def no_install_options(installed): - for name in installed: - yield "--no-install-package" - yield name - - -def pythonpath_to_pth(): - return "\n".join(os.environ["PYTHONPATH"].split(":")) + depends_on("cutensor", when="@:12.1.0 +cuda") + depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") + + for _arch in ROCmPackage.amdgpu_targets: + arch_str = "amdgpu_target={0}".format(_arch) + rocm_str = "+rocm {0}".format(arch_str) + depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) + + depends_on("rccl", when="+rocm", type=("link")) + depends_on("roctracer-dev", when="+rocm", type=("link")) + depends_on("rocprofiler-dev", when="+rocm", type=("link")) + + conflicts("~cuda ~rocm") + conflicts("+cuda +rocm") + conflicts("+cuda cuda_arch=none") + + def setup_build_environment(self, env): + env.set("CUPY_NUM_BUILD_JOBS", make_jobs) + if self.spec.satisfies("+cuda"): + cuda_arch = self.spec.variants["cuda_arch"].value + arch_str = ";".join( + "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch + ) + env.set("CUPY_NVCC_GENERATE_CODE", arch_str) + elif self.spec.satisfies("+rocm"): + spec = self.spec + + incs = { + "roctracer-dev": ["include/roctracer"], + "hiprand": ["include"], + "rocrand": ["include"], + "rocthrust": ["include"], + "rocprim": ["include"], + "hip": ["include", "include/hip"], + } + + inc_dirs = [] + for pkg, ds in incs.items(): + for d in ds: + p = os.path.join(spec[pkg].prefix, d) + if os.path.exists(p): + inc_dirs.append(p) + + env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) + + env.set("HIPCC", self.spec["hip"].hipcc) + env.set("ROCM_HOME", self.spec["hipcub"].prefix) + env.set("CUPY_INSTALL_USE_HIP", 1) From eddca3f32432cae4fb455acc92458476a14845f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Wed, 30 Jul 2025 15:36:22 +0200 Subject: [PATCH 14/32] fix cupy package depends_on calls --- recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py | 4 ++-- recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py index b7e6949..4a0bd00 100644 --- a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py +++ b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py @@ -79,8 +79,8 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): # Based on https://github.com/cupy/cupy/releases depends_on("cuda@:11.9", when="@:11 +cuda") depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") - depends_on("cuda@:12.4", when="@13:13.2 +cuda") - depends_on("cuda@:12.6", when="@13:3:13.4 +cuda") + depends_on("cuda@:12.4", when="@13:13.3 +cuda") + depends_on("cuda@:12.6", when="@13.3:13.4 +cuda") depends_on("cuda@:12.8", when="@13.4:13.5 +cuda") depends_on("cuda@:12.9", when="@13.5: +cuda") diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py index b7e6949..4a0bd00 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py @@ -79,8 +79,8 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): # Based on https://github.com/cupy/cupy/releases depends_on("cuda@:11.9", when="@:11 +cuda") depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") - depends_on("cuda@:12.4", when="@13:13.2 +cuda") - depends_on("cuda@:12.6", when="@13:3:13.4 +cuda") + depends_on("cuda@:12.4", when="@13:13.3 +cuda") + depends_on("cuda@:12.6", when="@13.3:13.4 +cuda") depends_on("cuda@:12.8", when="@13.4:13.5 +cuda") depends_on("cuda@:12.9", when="@13.5: +cuda") From c6f60c5cd35c5ce0c57d2a83286689dfd34efa67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Wed, 30 Jul 2025 16:00:38 +0200 Subject: [PATCH 15/32] fix cupy and icon4py packages --- .../a100/repo/packages/py-cupy/package.py | 6 +- .../gh200/repo/packages/icon4py/package.py | 232 ++++++++---------- .../repo/packages/py-cupy/py-cupy/package.py | 145 +++++++++++ 3 files changed, 244 insertions(+), 139 deletions(-) create mode 100644 recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py index 4a0bd00..e7dae04 100644 --- a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py +++ b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py @@ -79,10 +79,8 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): # Based on https://github.com/cupy/cupy/releases depends_on("cuda@:11.9", when="@:11 +cuda") depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") - depends_on("cuda@:12.4", when="@13:13.3 +cuda") - depends_on("cuda@:12.6", when="@13.3:13.4 +cuda") - depends_on("cuda@:12.8", when="@13.4:13.5 +cuda") - depends_on("cuda@:12.9", when="@13.5: +cuda") + depends_on("cuda@:12.4", when="@13:13.4.1 +cuda") + depends_on("cuda@:12.9", when="@13.5.1: +cuda") for a in CudaPackage.cuda_arch_values: depends_on( diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py index 4a0bd00..9ee413e 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/icon4py/package.py @@ -1,147 +1,109 @@ -# Copyright Spack Project Developers. See COPYRIGHT file for details. -# -# SPDX-License-Identifier: (Apache-2.0 OR MIT) - +import json import os +import pathlib -from spack.package import * - +import llnl +from llnl.util import tty +from spack import * -class PyCupy(PythonPackage, CudaPackage, ROCmPackage): - """CuPy is an open-source array library accelerated with - NVIDIA CUDA. CuPy provides GPU accelerated computing with - Python. CuPy uses CUDA-related libraries including cuBLAS, - cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make - full use of the GPU architecture. - This version does not use CudNN.""" +class Icon4py(Package): + extends("python") + depends_on("python@3.11:") - homepage = "https://cupy.dev/" - pypi = "cupy/cupy-8.0.0.tar.gz" + depends_on("git") + depends_on("boost@1.85:+mpi+python", type=("build", "run")) + depends_on("uv@0.7:", type="build") + depends_on("bzip2", type="build") + depends_on("py-numpy") + depends_on("py-cffi") + depends_on("py-pybind11") + depends_on("py-nanobind") + depends_on("py-mpi4py") + depends_on("py-cupy +cuda") + depends_on("ghex +python +cuda") version( - "13.5.1", - sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", - ) - version( - "13.1.0", - sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", - ) - version( - "12.1.0", - sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", - ) - version( - "12.0.0", - sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", - ) - version( - "11.6.0", - sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", - ) - version( - "11.5.0", - sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", - ) - version( - "11.4.0", - sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", - ) - version( - "11.3.0", - sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", - ) - version( - "11.2.0", - sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", + "icon_20250328", + sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", + extension="zip", ) - variant( - "all", default=False, description="Enable optional py-scipy, optuna, and cython" - ) + def url_for_version(self, version): + return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" + + def install(self, spec, prefix): + uv = prepare_uv() + python_spec = spec["python"] + venv_path = prefix.share.venv + + tty.msg(f"creating venv using spack python at: {python_spec.command.path}") + uv( + "venv", + "--seed", + "--relocatable", + "--system-site-packages", + str(venv_path), + "--python", + python_spec.command.path, + ) + + tty.msg(f"grabbing spack installed packages (distributions)") + pip = Executable(venv_path.bin.pip) + spack_installed = get_installed_pkg(pip) + + tty.msg(f"installing missing packages") + uv( + "sync", + "--active", + "--extra", + "all", + "--extra", + "cuda12", + "--inexact", + "--no-editable", + "--python", + str(venv_path.bin.python), + *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) - depends_on("cxx", type="build") # generated - - depends_on("python@3.7:", when="@:11", type=("build", "run")) - depends_on("python@3.8:", when="@12:", type=("build", "run")) - depends_on("py-setuptools", type="build") - depends_on("py-cython@0.29.22:2", type="build") - depends_on("py-fastrlock@0.5:", type=("build", "run")) - depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) - depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) - depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) - - depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) - depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) - depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) - depends_on("py-optuna@2:", when="+all", type=("build", "run")) - - # Based on https://github.com/cupy/cupy/releases - depends_on("cuda@:11.9", when="@:11 +cuda") - depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") - depends_on("cuda@:12.4", when="@13:13.3 +cuda") - depends_on("cuda@:12.6", when="@13.3:13.4 +cuda") - depends_on("cuda@:12.8", when="@13.4:13.5 +cuda") - depends_on("cuda@:12.9", when="@13.5: +cuda") - - for a in CudaPackage.cuda_arch_values: - depends_on( - "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) + tty.msg(f"linking spack installed packages into venv") + pathlib.Path( + f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" + ).write_text(pythonpath_to_pth()) + + tty.msg(f"running py2fgen") + py2fgen = Executable(venv_path.bin.py2fgen) + py2fgen( + "icon4py.tools.py2fgen.wrappers.all_bindings", + "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", + "icon4py_bindings", + "-o", + prefix.src, + extra_env={"VIRTUAL_ENV": str(venv_path)}, ) - depends_on("cutensor", when="@:12.1.0 +cuda") - depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") - - for _arch in ROCmPackage.amdgpu_targets: - arch_str = "amdgpu_target={0}".format(_arch) - rocm_str = "+rocm {0}".format(arch_str) - depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) - - depends_on("rccl", when="+rocm", type=("link")) - depends_on("roctracer-dev", when="+rocm", type=("link")) - depends_on("rocprofiler-dev", when="+rocm", type=("link")) - - conflicts("~cuda ~rocm") - conflicts("+cuda +rocm") - conflicts("+cuda cuda_arch=none") - - def setup_build_environment(self, env): - env.set("CUPY_NUM_BUILD_JOBS", make_jobs) - if self.spec.satisfies("+cuda"): - cuda_arch = self.spec.variants["cuda_arch"].value - arch_str = ";".join( - "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch - ) - env.set("CUPY_NVCC_GENERATE_CODE", arch_str) - elif self.spec.satisfies("+rocm"): - spec = self.spec - - incs = { - "roctracer-dev": ["include/roctracer"], - "hiprand": ["include"], - "rocrand": ["include"], - "rocthrust": ["include"], - "rocprim": ["include"], - "hip": ["include", "include/hip"], - } - - inc_dirs = [] - for pkg, ds in incs.items(): - for d in ds: - p = os.path.join(spec[pkg].prefix, d) - if os.path.exists(p): - inc_dirs.append(p) - - env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) - - env.set("HIPCC", self.spec["hip"].hipcc) - env.set("ROCM_HOME", self.spec["hipcub"].prefix) - env.set("CUPY_INSTALL_USE_HIP", 1) + +def prepare_uv(): + uv = which("uv") + uv.add_default_env("UV_NO_CACHE", "true") + uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") + uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") + return uv + + +def get_installed_pkg(pip): + return [ + item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) + ] + + +def no_install_options(installed): + for name in installed: + yield "--no-install-package" + yield name + + +def pythonpath_to_pth(): + return "\n".join(os.environ["PYTHONPATH"].split(":")) diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py new file mode 100644 index 0000000..e7dae04 --- /dev/null +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py @@ -0,0 +1,145 @@ +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import os + +from spack.package import * + + +class PyCupy(PythonPackage, CudaPackage, ROCmPackage): + """CuPy is an open-source array library accelerated with + NVIDIA CUDA. CuPy provides GPU accelerated computing with + Python. CuPy uses CUDA-related libraries including cuBLAS, + cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make + full use of the GPU architecture. + + This version does not use CudNN.""" + + homepage = "https://cupy.dev/" + pypi = "cupy/cupy-8.0.0.tar.gz" + + version( + "13.5.1", + sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + ) + version( + "13.1.0", + sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", + ) + version( + "12.1.0", + sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", + ) + version( + "12.0.0", + sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", + ) + version( + "11.6.0", + sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", + ) + version( + "11.5.0", + sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", + ) + version( + "11.4.0", + sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", + ) + version( + "11.3.0", + sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", + ) + version( + "11.2.0", + sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", + ) + + variant( + "all", default=False, description="Enable optional py-scipy, optuna, and cython" + ) + + depends_on("cxx", type="build") # generated + + depends_on("python@3.7:", when="@:11", type=("build", "run")) + depends_on("python@3.8:", when="@12:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-cython@0.29.22:2", type="build") + depends_on("py-fastrlock@0.5:", type=("build", "run")) + depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) + depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) + depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) + + depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) + depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) + depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) + depends_on("py-optuna@2:", when="+all", type=("build", "run")) + + # Based on https://github.com/cupy/cupy/releases + depends_on("cuda@:11.9", when="@:11 +cuda") + depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") + depends_on("cuda@:12.4", when="@13:13.4.1 +cuda") + depends_on("cuda@:12.9", when="@13.5.1: +cuda") + + for a in CudaPackage.cuda_arch_values: + depends_on( + "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) + ) + + depends_on("cutensor", when="@:12.1.0 +cuda") + depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") + + for _arch in ROCmPackage.amdgpu_targets: + arch_str = "amdgpu_target={0}".format(_arch) + rocm_str = "+rocm {0}".format(arch_str) + depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) + + depends_on("rccl", when="+rocm", type=("link")) + depends_on("roctracer-dev", when="+rocm", type=("link")) + depends_on("rocprofiler-dev", when="+rocm", type=("link")) + + conflicts("~cuda ~rocm") + conflicts("+cuda +rocm") + conflicts("+cuda cuda_arch=none") + + def setup_build_environment(self, env): + env.set("CUPY_NUM_BUILD_JOBS", make_jobs) + if self.spec.satisfies("+cuda"): + cuda_arch = self.spec.variants["cuda_arch"].value + arch_str = ";".join( + "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch + ) + env.set("CUPY_NVCC_GENERATE_CODE", arch_str) + elif self.spec.satisfies("+rocm"): + spec = self.spec + + incs = { + "roctracer-dev": ["include/roctracer"], + "hiprand": ["include"], + "rocrand": ["include"], + "rocthrust": ["include"], + "rocprim": ["include"], + "hip": ["include", "include/hip"], + } + + inc_dirs = [] + for pkg, ds in incs.items(): + for d in ds: + p = os.path.join(spec[pkg].prefix, d) + if os.path.exists(p): + inc_dirs.append(p) + + env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) + + env.set("HIPCC", self.spec["hip"].hipcc) + env.set("ROCM_HOME", self.spec["hipcub"].prefix) + env.set("CUPY_INSTALL_USE_HIP", 1) From 1b544bbf76edf0c2b47df20611f9f981a71ffe03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Thu, 31 Jul 2025 15:41:41 +0200 Subject: [PATCH 16/32] fix gh200 cupy package --- .../gh200/repo/packages/py-cupy/package.py | 7 +- .../repo/packages/py-cupy/py-cupy/package.py | 145 ------------------ 2 files changed, 6 insertions(+), 146 deletions(-) delete mode 100644 recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py index 5a29de7..e7dae04 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py @@ -19,6 +19,10 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): homepage = "https://cupy.dev/" pypi = "cupy/cupy-8.0.0.tar.gz" + version( + "13.5.1", + sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + ) version( "13.1.0", sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", @@ -75,7 +79,8 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): # Based on https://github.com/cupy/cupy/releases depends_on("cuda@:11.9", when="@:11 +cuda") depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") - depends_on("cuda@:12.4", when="@13: +cuda") + depends_on("cuda@:12.4", when="@13:13.4.1 +cuda") + depends_on("cuda@:12.9", when="@13.5.1: +cuda") for a in CudaPackage.cuda_arch_values: depends_on( diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py deleted file mode 100644 index e7dae04..0000000 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/py-cupy/package.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright Spack Project Developers. See COPYRIGHT file for details. -# -# SPDX-License-Identifier: (Apache-2.0 OR MIT) - -import os - -from spack.package import * - - -class PyCupy(PythonPackage, CudaPackage, ROCmPackage): - """CuPy is an open-source array library accelerated with - NVIDIA CUDA. CuPy provides GPU accelerated computing with - Python. CuPy uses CUDA-related libraries including cuBLAS, - cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make - full use of the GPU architecture. - - This version does not use CudNN.""" - - homepage = "https://cupy.dev/" - pypi = "cupy/cupy-8.0.0.tar.gz" - - version( - "13.5.1", - sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", - ) - version( - "13.1.0", - sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", - ) - version( - "12.1.0", - sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", - ) - version( - "12.0.0", - sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", - ) - version( - "11.6.0", - sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", - ) - version( - "11.5.0", - sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", - ) - version( - "11.4.0", - sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", - ) - version( - "11.3.0", - sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", - ) - version( - "11.2.0", - sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", - ) - - variant( - "all", default=False, description="Enable optional py-scipy, optuna, and cython" - ) - - depends_on("cxx", type="build") # generated - - depends_on("python@3.7:", when="@:11", type=("build", "run")) - depends_on("python@3.8:", when="@12:", type=("build", "run")) - depends_on("py-setuptools", type="build") - depends_on("py-cython@0.29.22:2", type="build") - depends_on("py-fastrlock@0.5:", type=("build", "run")) - depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) - depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) - depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) - - depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) - depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) - depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) - depends_on("py-optuna@2:", when="+all", type=("build", "run")) - - # Based on https://github.com/cupy/cupy/releases - depends_on("cuda@:11.9", when="@:11 +cuda") - depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") - depends_on("cuda@:12.4", when="@13:13.4.1 +cuda") - depends_on("cuda@:12.9", when="@13.5.1: +cuda") - - for a in CudaPackage.cuda_arch_values: - depends_on( - "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) - ) - - depends_on("cutensor", when="@:12.1.0 +cuda") - depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") - - for _arch in ROCmPackage.amdgpu_targets: - arch_str = "amdgpu_target={0}".format(_arch) - rocm_str = "+rocm {0}".format(arch_str) - depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) - depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) - depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) - - depends_on("rccl", when="+rocm", type=("link")) - depends_on("roctracer-dev", when="+rocm", type=("link")) - depends_on("rocprofiler-dev", when="+rocm", type=("link")) - - conflicts("~cuda ~rocm") - conflicts("+cuda +rocm") - conflicts("+cuda cuda_arch=none") - - def setup_build_environment(self, env): - env.set("CUPY_NUM_BUILD_JOBS", make_jobs) - if self.spec.satisfies("+cuda"): - cuda_arch = self.spec.variants["cuda_arch"].value - arch_str = ";".join( - "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch - ) - env.set("CUPY_NVCC_GENERATE_CODE", arch_str) - elif self.spec.satisfies("+rocm"): - spec = self.spec - - incs = { - "roctracer-dev": ["include/roctracer"], - "hiprand": ["include"], - "rocrand": ["include"], - "rocthrust": ["include"], - "rocprim": ["include"], - "hip": ["include", "include/hip"], - } - - inc_dirs = [] - for pkg, ds in incs.items(): - for d in ds: - p = os.path.join(spec[pkg].prefix, d) - if os.path.exists(p): - inc_dirs.append(p) - - env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) - - env.set("HIPCC", self.spec["hip"].hipcc) - env.set("ROCM_HOME", self.spec["hipcub"].prefix) - env.set("CUPY_INSTALL_USE_HIP", 1) From 6d105849461eb48d18d17aac9631c116a65a8da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Mon, 4 Aug 2025 15:58:24 +0200 Subject: [PATCH 17/32] downgrade cuda to 12.4 --- recipes/icon-dsl/25.8/a100/environments.yaml | 2 +- recipes/icon-dsl/25.8/gh200/environments.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/icon-dsl/25.8/a100/environments.yaml b/recipes/icon-dsl/25.8/a100/environments.yaml index 2225f30..3a399e0 100644 --- a/recipes/icon-dsl/25.8/a100/environments.yaml +++ b/recipes/icon-dsl/25.8/a100/environments.yaml @@ -16,7 +16,7 @@ myenv: - icon4py@icon_20250328 # icon deps - boost - - cuda@12.6 + - cuda@12.4 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper - cosmo-eccodes-definitions@2.36.0.3 - hdf5%nvhpc +szip +hl +fortran +mpi diff --git a/recipes/icon-dsl/25.8/gh200/environments.yaml b/recipes/icon-dsl/25.8/gh200/environments.yaml index 1325e60..7fde2c8 100644 --- a/recipes/icon-dsl/25.8/gh200/environments.yaml +++ b/recipes/icon-dsl/25.8/gh200/environments.yaml @@ -14,9 +14,9 @@ myenv: - ghex +python +cuda cuda_arch=90 - py-mpi4py - icon4py@icon_20250328 - # icon deps + # icon deps - boost - - cuda@12.6 + - cuda@12 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper - cosmo-eccodes-definitions@2.36.0.3 - hdf5%nvhpc +szip +hl +fortran +mpi From e11032a2b355131b29c55a89585a004dabe4dea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rico=20H=C3=A4uselmann?= Date: Mon, 4 Aug 2025 16:22:28 +0200 Subject: [PATCH 18/32] try using cupy version 13.1.0 with cuda 12.4 --- .../icon-dsl/25.8/a100/repo/packages/py-cupy/package.py | 8 ++++---- .../icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py index e7dae04..e2be01e 100644 --- a/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py +++ b/recipes/icon-dsl/25.8/a100/repo/packages/py-cupy/package.py @@ -19,10 +19,10 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): homepage = "https://cupy.dev/" pypi = "cupy/cupy-8.0.0.tar.gz" - version( - "13.5.1", - sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", - ) + # version( + # "13.5.1", + # sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + # ) version( "13.1.0", sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", diff --git a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py index e7dae04..e2be01e 100644 --- a/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py +++ b/recipes/icon-dsl/25.8/gh200/repo/packages/py-cupy/package.py @@ -19,10 +19,10 @@ class PyCupy(PythonPackage, CudaPackage, ROCmPackage): homepage = "https://cupy.dev/" pypi = "cupy/cupy-8.0.0.tar.gz" - version( - "13.5.1", - sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", - ) + # version( + # "13.5.1", + # sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + # ) version( "13.1.0", sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", From d9902ff4c2d9192a2e6e24d9582387c4480b6876 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Thu, 4 Dec 2025 11:58:49 +0100 Subject: [PATCH 19/32] start with new version --- recipes/icon-dsl/25.12/a100/compilers.yaml | 9 + recipes/icon-dsl/25.12/a100/config.yaml | 7 + recipes/icon-dsl/25.12/a100/environments.yaml | 47 +++ .../icon-dsl/25.12/a100/extra/reframe.yaml | 6 + recipes/icon-dsl/25.12/a100/modules.yaml | 26 ++ recipes/icon-dsl/25.12/a100/pre-install | 12 + .../eccodes/cmake_install_rpath.patch | 11 + .../packages/eccodes/openjpeg_jasper.patch | 39 ++ .../a100/repo/packages/eccodes/package.py | 385 ++++++++++++++++++ .../a100/repo/packages/eccodes/readme.md | 1 + .../25.12/a100/repo/packages/ghex/package.py | 93 +++++ .../hwmalloc/cmake_install_path.patch | 27 ++ .../a100/repo/packages/hwmalloc/package.py | 52 +++ .../a100/repo/packages/icon4py/package.py | 109 +++++ .../repo/packages/oomph/install_0.2.patch | 102 +++++ .../repo/packages/oomph/install_0.3.patch | 57 +++ .../25.12/a100/repo/packages/oomph/package.py | 109 +++++ .../a100/repo/packages/py-cupy/package.py | 145 +++++++ .../25.12/a100/repo/packages/uv/package.py | 68 ++++ recipes/icon-dsl/25.12/gh200/compilers.yaml | 9 + recipes/icon-dsl/25.12/gh200/config.yaml | 7 + .../icon-dsl/25.12/gh200/environments.yaml | 47 +++ .../icon-dsl/25.12/gh200/extra/reframe.yaml | 6 + recipes/icon-dsl/25.12/gh200/modules.yaml | 26 ++ recipes/icon-dsl/25.12/gh200/pre-install | 12 + .../eccodes/cmake_install_rpath.patch | 11 + .../packages/eccodes/openjpeg_jasper.patch | 39 ++ .../gh200/repo/packages/eccodes/package.py | 385 ++++++++++++++++++ .../gh200/repo/packages/eccodes/readme.md | 1 + .../25.12/gh200/repo/packages/ghex/package.py | 93 +++++ .../hwmalloc/cmake_install_path.patch | 27 ++ .../gh200/repo/packages/hwmalloc/package.py | 52 +++ .../gh200/repo/packages/icon4py/package.py | 109 +++++ .../repo/packages/oomph/install_0.2.patch | 102 +++++ .../repo/packages/oomph/install_0.3.patch | 57 +++ .../gh200/repo/packages/oomph/package.py | 109 +++++ .../gh200/repo/packages/py-cupy/package.py | 145 +++++++ .../25.12/gh200/repo/packages/uv/package.py | 68 ++++ 38 files changed, 2610 insertions(+) create mode 100644 recipes/icon-dsl/25.12/a100/compilers.yaml create mode 100644 recipes/icon-dsl/25.12/a100/config.yaml create mode 100644 recipes/icon-dsl/25.12/a100/environments.yaml create mode 100644 recipes/icon-dsl/25.12/a100/extra/reframe.yaml create mode 100644 recipes/icon-dsl/25.12/a100/modules.yaml create mode 100644 recipes/icon-dsl/25.12/a100/pre-install create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/eccodes/cmake_install_rpath.patch create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/eccodes/openjpeg_jasper.patch create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/eccodes/package.py create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/eccodes/readme.md create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/py-cupy/package.py create mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/compilers.yaml create mode 100644 recipes/icon-dsl/25.12/gh200/config.yaml create mode 100644 recipes/icon-dsl/25.12/gh200/environments.yaml create mode 100644 recipes/icon-dsl/25.12/gh200/extra/reframe.yaml create mode 100644 recipes/icon-dsl/25.12/gh200/modules.yaml create mode 100644 recipes/icon-dsl/25.12/gh200/pre-install create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/cmake_install_rpath.patch create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/openjpeg_jasper.patch create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/readme.md create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/py-cupy/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py diff --git a/recipes/icon-dsl/25.12/a100/compilers.yaml b/recipes/icon-dsl/25.12/a100/compilers.yaml new file mode 100644 index 0000000..f456b5a --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/compilers.yaml @@ -0,0 +1,9 @@ +bootstrap: + spec: gcc@12.3 +gcc: + specs: + - gcc@13 +llvm: + requires: gcc@13 + specs: + - nvhpc@25.1 diff --git a/recipes/icon-dsl/25.12/a100/config.yaml b/recipes/icon-dsl/25.12/a100/config.yaml new file mode 100644 index 0000000..fe6d1bc --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/config.yaml @@ -0,0 +1,7 @@ +name: icon-dsl +store: /user-environment +spack: + repo: https://github.com/spack/spack.git + commit: releases/v0.22 +modules: false +description: Build and runtime dependencies for ICON-DSL diff --git a/recipes/icon-dsl/25.12/a100/environments.yaml b/recipes/icon-dsl/25.12/a100/environments.yaml new file mode 100644 index 0000000..ae80558 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/environments.yaml @@ -0,0 +1,47 @@ +myenv: + compiler: + - toolchain: gcc + spec: gcc + - toolchain: llvm + spec: nvhpc + mpi: + spec: cray-mpich@8.1.30%nvhpc + gpu: cuda + specs: + # icon4py deps + - python@3.11 + - py-cupy +cuda cuda_arch=80 + - ghex +python +cuda cuda_arch=80 + - py-mpi4py + - icon4py@icon_20250328 + # icon deps + - boost + - cuda@12.4 + - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper + - cosmo-eccodes-definitions@2.36.0.3 + - hdf5%nvhpc +szip +hl +fortran +mpi + - netcdf-c@4.9.2%nvhpc + - netcdf-cxx4@4.3.1%nvhpc + - netcdf-fortran@4.6.1%nvhpc + - osu-micro-benchmarks@5.9%nvhpc + - openblas + # for validation + - cdo + # everything needed for nccl on SS11 + - nccl + - nccl-tests + # extras + - libfyaml + - zlib-ng + - cmake + unify: true + variants: + - +mpi + - +cuda + - cuda_arch=80 + views: + default: + link: roots + uenv: + prefix_paths: + LD_LIBRARY_PATH: [lib, lib64] diff --git a/recipes/icon-dsl/25.12/a100/extra/reframe.yaml b/recipes/icon-dsl/25.12/a100/extra/reframe.yaml new file mode 100644 index 0000000..363f809 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/extra/reframe.yaml @@ -0,0 +1,6 @@ +default: + features: [osu-micro-benchmarks, mpi, serial, openmp] + cc: mpicc + cxx: mpic++ + ftn: mpifort + activation: /user-environment/env/default/activate.sh diff --git a/recipes/icon-dsl/25.12/a100/modules.yaml b/recipes/icon-dsl/25.12/a100/modules.yaml new file mode 100644 index 0000000..a4010ae --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/modules.yaml @@ -0,0 +1,26 @@ +modules: + # Paths to check when creating modules for all module sets + prefix_inspections: + bin: + - PATH + lib: + - LD_LIBRARY_PATH + lib64: + - LD_LIBRARY_PATH + + default: + arch_folder: false + # Where to install modules + roots: + tcl: /snap/modules + tcl: + all: + autoload: run + hash_length: 0 + hide_implicits: true + exclude: + - '%gcc@7.5.0' + - '%gcc@12' + - 'gcc %gcc@7.5.0' + projections: + all: '{name}/{version}' diff --git a/recipes/icon-dsl/25.12/a100/pre-install b/recipes/icon-dsl/25.12/a100/pre-install new file mode 100644 index 0000000..ba88283 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/pre-install @@ -0,0 +1,12 @@ +#!/bin/bash + +packages=("cosmo-eccodes-definitions") +SPACK_C2SM_TAG="v0.22.2.1" + +git clone -b ${SPACK_C2SM_TAG} https://github.com/C2SM/spack-c2sm.git + +for package in "${packages[@]}"; do + cp -r spack-c2sm/repos/c2sm/packages/"${package}" store/repo/packages +done + +rm -rf spack-c2sm diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/cmake_install_rpath.patch b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/cmake_install_rpath.patch new file mode 100644 index 0000000..7e2b250 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/cmake_install_rpath.patch @@ -0,0 +1,11 @@ +--- a/cmake/ecbuild_append_to_rpath.cmake ++++ b/cmake/ecbuild_append_to_rpath.cmake +@@ -31,7 +31,7 @@ function( _path_append var path ) + else() + list( FIND ${var} ${path} _found ) + if( _found EQUAL "-1" ) +- set( ${var} "${${var}}:${path}" PARENT_SCOPE ) ++ set( ${var} "${${var}};${path}" PARENT_SCOPE ) + endif() + endif() + endfunction() diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/openjpeg_jasper.patch b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/openjpeg_jasper.patch new file mode 100644 index 0000000..5793f56 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/openjpeg_jasper.patch @@ -0,0 +1,39 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,6 +43,18 @@ ecbuild_add_option( FEATURE JPG + DESCRIPTION "support for JPG decoding/encoding" + DEFAULT ON + ) ++# Options related to JPG. The Jasper and OpenJPEG libraries ++ecbuild_add_option( FEATURE JPG_LIBJASPER ++ DESCRIPTION "Support for JPG decoding/encoding with the Jasper library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ecbuild_add_option( FEATURE JPG_LIBOPENJPEG ++ DESCRIPTION "Support for JPG decoding/encoding with the OpenJPEG library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ + + ecbuild_add_option( FEATURE PNG + DESCRIPTION "support for PNG decoding/encoding" +@@ -144,7 +156,7 @@ if( ENABLE_JPG ) + + find_package( OpenJPEG ) + +- if( JASPER_FOUND ) ++ if( JASPER_FOUND AND ENABLE_JPG_LIBJASPER ) + list( APPEND ECCODES_TPLS Jasper ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBJASPER 1 ) +@@ -152,7 +164,7 @@ if( ENABLE_JPG ) + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" JASPER_VERSION_MAJOR "${JASPER_VERSION_STRING}") + endif() + +- if( OPENJPEG_FOUND ) ++ if( OPENJPEG_FOUND AND ENABLE_JPG_LIBOPENJPEG ) + list( APPEND ECCODES_TPLS OpenJPEG ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBOPENJPEG 1 ) diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/package.py new file mode 100644 index 0000000..aeb4692 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/package.py @@ -0,0 +1,385 @@ +# 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.package import * + +_definitions = { + # German Meteorological Service (Deutscher Wetterdienst, DWD): + "edzw": { + "conflicts": {"when": "@:2.19.1,2.22.0,2.24.0:"}, + "resources": [ + { + "when": "@2.20.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.20.0-1.tar.gz", + "sha256": "a92932f8a13c33cba65d3a33aa06c7fb4a37ed12a78e9abe2c5e966402b99af4", + }, + { + "when": "@2.21.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.21.0-3.tar.bz2", + "sha256": "046f1f6450abb3b44c31dee6229f4aab06ca0d3576e27e93e05ccb7cd6e2d9d9", + }, + { + "when": "@2.22.1", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.22.1-1.tar.bz2", + "sha256": "be73102a0dcabb236bacd2a70c7b5475f673fda91b49e34df61bef0fa5ad3389", + }, + { + "when": "@2.23.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.23.0-4.tar.bz2", + "sha256": "c5db32861c7d23410aed466ffef3ca661410d252870a3949442d3ecb176aa338", + }, + ], + } +} + + +class Eccodes(CMakePackage): + """ecCodes is a package developed by ECMWF for processing meteorological + data in GRIB (1/2), BUFR (3/4) and GTS header formats.""" + + homepage = "https://software.ecmwf.int/wiki/display/ECC/ecCodes+Home" + url = "https://confluence.ecmwf.int/download/attachments/45757960/eccodes-2.2.0-Source.tar.gz?api=v2" + git = "https://github.com/ecmwf/eccodes.git" + list_url = "https://confluence.ecmwf.int/display/ECC/Releases" + + maintainers("skosukhin", "victoria-cherkas", "dominichofer", "climbfuji") + + license("Apache-2.0") + + version("develop", branch="develop") + version("2.36.4", + sha256="198ccb26e8df96544c668ea6853ea153535ab78b10c43339a678f271337aa0da", + url="https://github.com/ecmwf/eccodes/archive/refs/tags/2.36.4.tar.gz" + ) + version("2.34.0", sha256="3cd208c8ddad132789662cf8f67a9405514bfefcacac403c0d8c84507f303aba") + version("2.33.0", sha256="bdcec8ce63654ec6803400c507f01220a9aa403a45fa6b5bdff7fdcc44fd7daf") + version("2.32.1", sha256="ad2ac1bf36577b1d35c4a771b4d174a06f522a1e5ef6c1f5e53a795fb624863e") + version("2.32.0", sha256="b57e8eeb0eba0c05d66fda5527c4ffa84b5ab35c46bcbc9a2227142973ccb8e6") + version("2.31.0", sha256="808ecd2c11fbf2c3f9fc7a36f8c2965b343f3151011b58a1d6e7cc2e6b3cac5d") + version("2.25.0", sha256="8975131aac54d406e5457706fd4e6ba46a8cc9c7dd817a41f2aa64ce1193c04e") + version("2.24.2", sha256="c60ad0fd89e11918ace0d84c01489f21222b11d6cad3ff7495856a0add610403") + version("2.23.0", sha256="cbdc8532537e9682f1a93ddb03440416b66906a4cc25dec3cbd73940d194bf0c") + version("2.22.1", sha256="75c7ee96469bb30b0c8f7edbdc4429ece4415897969f75c36173545242bc9e85") + version("2.21.0", sha256="da0a0bf184bb436052e3eae582defafecdb7c08cdaab7216780476e49b509755") + version("2.20.0", sha256="207a3d7966e75d85920569b55a19824673e8cd0b50db4c4dac2d3d52eacd7985") + version("2.19.1", sha256="9964bed5058e873d514bd4920951122a95963128b12f55aa199d9afbafdd5d4b") + version("2.18.0", sha256="d88943df0f246843a1a062796edbf709ef911de7269648eef864be259e9704e3") + version("2.13.0", sha256="c5ce1183b5257929fc1f1c8496239e52650707cfab24f4e0e1f1a471135b8272") + version("2.5.0", sha256="18ab44bc444168fd324d07f7dea94f89e056f5c5cd973e818c8783f952702e4e") + version("2.2.0", sha256="1a4112196497b8421480e2a0a1164071221e467853486577c4f07627a702f4c3") + + # we are still using spack v0.21 v0.22, so comment these out for now + #depends_on("c", type="build") # generated + #depends_on("cxx", type="build") # generated + #depends_on("fortran", type="build") # generated + + variant("tools", default=False, description="Build the command line tools") + variant("netcdf", default=False, description="Enable GRIB to NetCDF conversion tool") + variant( + "jp2k", + default="openjpeg", + values=("openjpeg", "jasper", "none"), + description="Specify JPEG2000 decoding/encoding backend", + ) + variant("png", default=False, description="Enable PNG support for decoding/encoding") + variant( + "aec", default=True, description="Enable Adaptive Entropy Coding for decoding/encoding" + ) + variant("pthreads", default=False, description="Enable POSIX threads") + variant("openmp", default=False, description="Enable OpenMP threads") + variant( + "memfs", default=False, description="Enable memory based access to definitions/samples" + ) + variant("fortran", default=False, description="Enable the Fortran support") + variant("shared", default=True, description="Build shared versions of the libraries") + + variant( + "extra_definitions", + values=any_combination_of(*_definitions.keys()), + description="List of extra definitions to install", + ) + + depends_on("netcdf-c", when="+netcdf") + # Cannot be built with openjpeg@2.0.x. + depends_on("openjpeg@1.5.0:1.5,2.1.0:2.3", when="jp2k=openjpeg") + # Additional constraint for older versions. + depends_on("openjpeg@:2.1", when="@:2.16 jp2k=openjpeg") + + with when("jp2k=jasper"): + depends_on("jasper") + # jasper 3.x compat from commit 86f0b35f1a8492cb16f82fb976a0a5acd2986ac2 + depends_on("jasper@:2", when="@:2.25.0") + + depends_on("libpng", when="+png") + depends_on("libaec", when="+aec") + # Can be built with Python 2 or Python 3. + depends_on("python", when="+memfs", type="build") + + depends_on("cmake@3.6:", type="build") + depends_on("cmake@3.12:", when="@2.19:", type="build") + + # TODO: ecbuild was only used for the @develop branch + # however, testing 2.36.4, it appears to be a requirement. + # this might be because they package the software differently in GitHub + # (they normally provide releases as tar balls on Confluence) + depends_on("ecbuild", type="build") + #depends_on("ecbuild", type="build", when="@develop") + + conflicts("+openmp", when="+pthreads", msg="Cannot enable both POSIX threads and OMP") + + conflicts( + "+netcdf", + when="~tools", + msg="Cannot enable the NetCDF conversion tool " "when the command line tools are disabled", + ) + + conflicts( + "~tools", + when="@:2.18.0", + msg="The command line tools can be disabled " "only starting version 2.19.0", + ) + + for center, definitions in _definitions.items(): + kwargs = definitions.get("conflicts", None) + if kwargs: + conflicts("extra_definitions={0}".format(center), **kwargs) + for kwargs in definitions.get("resources", []): + resource( + name=center, + destination="spack-definitions", + placement="definitions.{0}".format(center), + **kwargs, + ) + + # Enforce linking against the specified JPEG2000 backend, see also + # https://github.com/ecmwf/eccodes/commit/2c10828495900ff3d80d1e570fe96c1df16d97fb + patch("openjpeg_jasper.patch", when="@:2.16") + + # CMAKE_INSTALL_RPATH must be a semicolon-separated list. + patch("cmake_install_rpath.patch", when="@:2.10") + + # Fix a bug preventing cmake from finding NetCDF: + patch( + "https://github.com/ecmwf/ecbuild/commit/3916c7d22575c45166fcc89edcbe02a6e9b81aa2.patch?full_index=1", + sha256="9dcc4affaaa850d4b7247baa939d0f9ffedea132369f1afc3f248dbf720386c9", + when="@:2.4.0+netcdf", + ) + + @when("%nag+fortran") + def patch(self): + # A number of Fortran source files assume that the kinds of integer and + # real variables are specified in bytes. However, the NAG compiler + # accepts such code only with an additional compiler flag -kind=byte. + # We do not simply add the flag because all user applications would + # have to be compiled with this flag too, which goes against one of the + # purposes of using the NAG compiler: make sure the code does not + # contradict the Fortran standards. The following logic could have been + # implemented as regular patch files, which would, however, be quite + # large. We would also have to introduce several versions of each patch + # file to support different versions of the package. + + patch_kind_files = [ + "fortran/eccodes_f90_head.f90", + "fortran/eccodes_f90_tail.f90", + "fortran/grib_f90_head.f90", + "fortran/grib_f90_tail.f90", + "fortran/grib_types.f90", + ] + + patch_unix_ext_files = [] + + if self.run_tests: + patch_kind_files.extend( + [ + "examples/F90/grib_print_data.f90", + "examples/F90/grib_print_data_static.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_attributes.f90', + # 'examples/F90/bufr_expanded.f90', + # 'examples/F90/bufr_get_keys.f90', + # 'examples/F90/bufr_read_scatterometer.f90', + # 'examples/F90/bufr_read_synop.f90', + # 'examples/F90/bufr_read_temp.f90', + # 'examples/F90/bufr_read_tempf.f90', + # 'examples/F90/bufr_read_tropical_cyclone.f90', + # 'examples/F90/grib_clone.f90', + # 'examples/F90/grib_get_data.f90', + # 'examples/F90/grib_nearest.f90', + # 'examples/F90/grib_precision.f90', + # 'examples/F90/grib_read_from_file.f90', + # 'examples/F90/grib_samples.f90', + # 'examples/F90/grib_set_keys.f90' + ] + ) + + patch_unix_ext_files.extend( + [ + "examples/F90/bufr_ecc-1284.f90", + "examples/F90/grib_set_data.f90", + "examples/F90/grib_set_packing.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_copy_data.f90', + # 'examples/F90/bufr_get_string_array.f90', + # 'examples/F90/bufr_keys_iterator.f90', + # 'examples/F90/get_product_kind.f90', + # 'examples/F90/grib_count_messages_multi.f90' + ] + ) + + kwargs = {"string": False, "backup": False, "ignore_absent": True} + + # Return the kind and not the size: + filter_file( + r"(^\s*kind_of_double\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(real\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + filter_file( + r"(^\s*kind_of_\w+\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(x\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + + # Replace integer kinds: + for size, r in [(2, 4), (4, 9), (8, 18)]: + filter_file( + r"(^\s*integer\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_int_kind({0})\\2".format(r), + *patch_kind_files, + **kwargs, + ) + + # Replace real kinds: + for size, p, r in [(4, 6, 37), (8, 15, 307)]: + filter_file( + r"(^\s*real\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_real_kind({0}, {1})\\2".format(p, r), + *patch_kind_files, + **kwargs, + ) + + # Enable getarg and exit subroutines: + filter_file( + r"(^\s*program\s+\w+)(\s*$)", + "\\1; use f90_unix_env; use f90_unix_proc\\2", + *patch_unix_ext_files, + **kwargs, + ) + + @property + def libs(self): + libraries = [] + + query_parameters = self.spec.last_query.extra_parameters + + if "shared" in query_parameters: + shared = True + elif "static" in query_parameters: + shared = False + else: + shared = "+shared" in self.spec + + # Return Fortran library if requested: + return_fortran = "fortran" in query_parameters + # Return C library if either requested or the Fortran library is not + # requested (to avoid overlinking) or the static libraries are + # requested: + return_c = "c" in query_parameters or not (return_fortran and shared) + # Return MEMFS library only if enabled and the static libraries are + # requested: + return_memfs = "+memfs" in self.spec and not shared + + if return_fortran: + libraries.append("libeccodes_f90") + + if return_c: + libraries.append("libeccodes") + + if return_memfs: + libraries.append("libeccodes_memfs") + + libs = find_libraries(libraries, root=self.prefix, shared=shared, recursive=True) + + if libs and len(libs) == len(libraries): + return libs + + msg = "Unable to recursively locate {0} {1} libraries in {2}" + raise spack.error.NoLibrariesError( + msg.format("shared" if shared else "static", self.spec.name, self.spec.prefix) + ) + + @run_before("cmake") + def check_fortran(self): + if "+fortran" in self.spec and self.compiler.fc is None: + raise InstallError("Fortran interface requires a Fortran compiler!") + + def cmake_args(self): + jp2k = self.spec.variants["jp2k"].value + + args = [ + self.define_from_variant("ENABLE_BUILD_TOOLS", "tools"), + self.define_from_variant("ENABLE_NETCDF", "netcdf"), + self.define("ENABLE_JPG", jp2k != "none"), + self.define("ENABLE_JPG_LIBJASPER", jp2k == "jasper"), + self.define("ENABLE_JPG_LIBOPENJPEG", jp2k == "openjpeg"), + self.define_from_variant("ENABLE_PNG", "png"), + self.define_from_variant("ENABLE_AEC", "aec"), + self.define_from_variant("ENABLE_ECCODES_THREADS", "pthreads"), + self.define_from_variant("ENABLE_ECCODES_OMP_THREADS", "openmp"), + self.define_from_variant("ENABLE_MEMFS", "memfs"), + self.define( + "ENABLE_PYTHON{0}".format("2" if self.spec.satisfies("@2.20.0:") else ""), False + ), + self.define_from_variant("ENABLE_FORTRAN", "fortran"), + self.define("BUILD_SHARED_LIBS", "BOTH" if "+shared" in self.spec else "OFF"), + self.define("ENABLE_TESTS", self.run_tests), + # Examples are not installed and are just part of the test suite: + self.define("ENABLE_EXAMPLES", self.run_tests), + # Unconditionally disable the extended regression tests, since they + # download additional data (~134MB): + self.define("ENABLE_EXTRA_TESTS", False), + ] + + if self.spec.satisfies("+netcdf"): + # Prevent possible overriding by environment variables NETCDF_ROOT, NETCDF_DIR, and + # NETCDF_PATH: + args.append(self.define("NETCDF_PATH", self.spec["netcdf-c"].prefix)) + # Prevent overriding by environment variable HDF5_ROOT (starting version 2.14.0, + # ecCodes is shipped with ecBuild 3.1.0+, which does not seem to rely on the HDF5_ROOT + # variable): + if self.spec.satisfies("@:2.13"): + args.append(self.define("HDF5_ROOT", self.spec["hdf5"].prefix)) + + if jp2k == "openjpeg": + args.append(self.define("OPENJPEG_PATH", self.spec["openjpeg"].prefix)) + + if self.spec.satisfies("+png"): + args.append(self.define("ZLIB_ROOT", self.spec["zlib-api"].prefix)) + + if self.spec.satisfies("+aec"): + # Prevent overriding by environment variables AEC_DIR and AEC_PATH: + args.append(self.define("AEC_DIR", self.spec["libaec"].prefix)) + + return args + + @run_after("install") + def install_extra_definitions(self): + for center in self.spec.variants["extra_definitions"].value: + if center != "none": + center_dir = "definitions.{0}".format(center) + install_tree( + join_path(self.stage.source_path, "spack-definitions", center_dir), + join_path(self.prefix.share.eccodes, center_dir), + ) + + def check(self): + # https://confluence.ecmwf.int/display/ECC/ecCodes+installation + with working_dir(self.build_directory): + ctest() diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/readme.md b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/readme.md new file mode 100644 index 0000000..9678342 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/eccodes/readme.md @@ -0,0 +1 @@ +copied from mainline spack November 5 2024 so that we can add eccodes 2.36.0 for mch production diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py new file mode 100644 index 0000000..8f50e28 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py @@ -0,0 +1,93 @@ +from spack.package import * + + +class Ghex(CMakePackage, CudaPackage, ROCmPackage): + """GHEX is a generic halo-exchange library.""" + + homepage = "https://github.com/ghex-org/GHEX" + url = "https://github.com/ghex-org/GHEX/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/GHEX.git" + maintainers = ["boeschf"] + + version("0.4.1", tag="v0.4.1", submodules=True) + version("0.4.0", tag="v0.4.0", submodules=True) + version("0.3.0", tag="v0.3.0", submodules=True) + version("master", branch="master", submodules=True) + + depends_on("cxx", type="build") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", + default="mpi", + description="Transport backend", + values=backends, + multi=False, + ) + variant("xpmem", default=False, description="Use xpmem shared memory") + variant("python", default=True, description="Build Python bindings") + + depends_on("cmake@3.21:", type="build") + depends_on("mpi") + depends_on("boost") + depends_on("xpmem", when="+xpmem", type=("build", "run")) + + depends_on("oomph") + for backend in backends: + depends_on(f"oomph backend={backend}", when=f"backend={backend}") + depends_on("oomph+cuda", when="+cuda") + depends_on("oomph+rocm", when="+rocm") + depends_on("oomph@0.3:", when="@0.3:") + + conflicts("+cuda+rocm") + + with when("+python"): + extends("python") + depends_on("python@3.7:", type="build") + depends_on("py-pip", type="build") + depends_on("py-pybind11", type="build") + depends_on("py-mpi4py", type=("build", "run")) + depends_on("py-numpy", type=("build", "run")) + + depends_on("py-pytest", when="+python", type=("test")) + + def cmake_args(self): + spec = self.spec + + args = [ + self.define("GHEX_USE_BUNDLED_LIBS", True), + self.define("GHEX_USE_BUNDLED_GRIDTOOLS", True), + self.define("GHEX_USE_BUNDLED_GTEST", self.run_tests), + self.define("GHEX_USE_BUNDLED_OOMPH", False), + self.define( + "GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper() + ), + self.define_from_variant("GHEX_USE_XPMEM", "xpmem"), + self.define_from_variant("GHEX_BUILD_PYTHON_BINDINGS", "python"), + self.define("GHEX_WITH_TESTING", self.run_tests), + ] + + if spec.satisfies("+python"): + args.append(self.define("GHEX_PYTHON_LIB_PATH", python_platlib)) + + if self.run_tests and spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if "+cuda" in spec and spec.variants["cuda_arch"].value != "none": + arch_str = ";".join(spec.variants["cuda_arch"].value) + args.append(self.define("CMAKE_CUDA_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "NVIDIA")) + + if "+rocm" in spec and spec.variants["amdgpu_target"].value != "none": + arch_str = ";".join(spec.variants["amdgpu_target"].value) + args.append(self.define("CMAKE_HIP_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "AMD")) + + if spec.satisfies("~cuda~rocm"): + args.append(self.define("GHEX_USE_GPU", False)) + + return args diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch new file mode 100644 index 0000000..fa6fde1 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch @@ -0,0 +1,27 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d5420e0..35dbe56 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -105,11 +105,11 @@ install(FILES ${PROJECT_BINARY_DIR}/include/hwmalloc/config.hpp + install(EXPORT HWMALLOC-targets + FILE HWMALLOC-targets.cmake + NAMESPACE HWMALLOC:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HWMALLOCConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + write_basic_package_version_file(HWMALLOCConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -120,7 +120,7 @@ install( + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfigVersion.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindNUMA.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + export(EXPORT HWMALLOC-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/HWMALLOC-targets.cmake") diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py new file mode 100644 index 0000000..c656dc1 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py @@ -0,0 +1,52 @@ +from spack.package import * + + +class Hwmalloc(CMakePackage, CudaPackage, ROCmPackage): + """HWMALLOC is a allocator which supports memory registration for e.g. remote memory access""" + + homepage = "https://github.com/ghex-org/hwmalloc" + url = "https://github.com/ghex-org/hwmalloc/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/hwmalloc.git" + maintainers = ["boeschf"] + + version("0.3.0", sha256="d4d4ac6087a806600d79fb62c02719ca3d58a412968fe1ef4a2fd58d9e7ee950") + version("0.2.0", sha256="734758a390a3258b86307e4aef50a7ca2e5d0e2e579f18aeefcd05397e114419") + version("0.1.0", sha256="06e9bfcef0ecce4d19531ccbe03592b502d1281c7a092bc0ff51ca187899b21c") + version("master", branch="master") + + depends_on("cxx", type="build") + + generator("ninja") + + depends_on("numactl", type=("build", "run")) + depends_on("boost", type=("build")) + depends_on("cmake@3.19:", type="build") + + variant( + "numa-throws", + default=False, + description="True if numa_tools may throw during initialization", + ) + variant("numa-local", default=True, description="Use numa_tools for local node allocations") + variant("logging", default=False, description="print logging info to cerr") + + patch("cmake_install_path.patch", when="@:0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("HWMALLOC_NUMA_THROWS", "numa-throws"), + self.define_from_variant("HWMALLOC_NUMA_FOR_LOCAL", "numa-local"), + self.define_from_variant("HWMALLOC_ENABLE_LOGGING", "logging"), + self.define("HWMALLOC_WITH_TESTING", self.run_tests), + ] + + if "+cuda" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "cuda")) + elif "+rocm" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "hip")) + else: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", False)) + + return args diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py new file mode 100644 index 0000000..9ee413e --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py @@ -0,0 +1,109 @@ +import json +import os +import pathlib + +import llnl +from llnl.util import tty +from spack import * + + +class Icon4py(Package): + extends("python") + depends_on("python@3.11:") + + depends_on("git") + depends_on("boost@1.85:+mpi+python", type=("build", "run")) + depends_on("uv@0.7:", type="build") + depends_on("bzip2", type="build") + depends_on("py-numpy") + depends_on("py-cffi") + depends_on("py-pybind11") + depends_on("py-nanobind") + depends_on("py-mpi4py") + depends_on("py-cupy +cuda") + depends_on("ghex +python +cuda") + + version( + "icon_20250328", + sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", + extension="zip", + ) + + def url_for_version(self, version): + return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" + + def install(self, spec, prefix): + uv = prepare_uv() + python_spec = spec["python"] + venv_path = prefix.share.venv + + tty.msg(f"creating venv using spack python at: {python_spec.command.path}") + uv( + "venv", + "--seed", + "--relocatable", + "--system-site-packages", + str(venv_path), + "--python", + python_spec.command.path, + ) + + tty.msg(f"grabbing spack installed packages (distributions)") + pip = Executable(venv_path.bin.pip) + spack_installed = get_installed_pkg(pip) + + tty.msg(f"installing missing packages") + uv( + "sync", + "--active", + "--extra", + "all", + "--extra", + "cuda12", + "--inexact", + "--no-editable", + "--python", + str(venv_path.bin.python), + *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + tty.msg(f"linking spack installed packages into venv") + pathlib.Path( + f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" + ).write_text(pythonpath_to_pth()) + + tty.msg(f"running py2fgen") + py2fgen = Executable(venv_path.bin.py2fgen) + py2fgen( + "icon4py.tools.py2fgen.wrappers.all_bindings", + "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", + "icon4py_bindings", + "-o", + prefix.src, + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + +def prepare_uv(): + uv = which("uv") + uv.add_default_env("UV_NO_CACHE", "true") + uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") + uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") + return uv + + +def get_installed_pkg(pip): + return [ + item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) + ] + + +def no_install_options(installed): + for name in installed: + yield "--no-install-package" + yield name + + +def pythonpath_to_pth(): + return "\n".join(os.environ["PYTHONPATH"].split(":")) diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch new file mode 100644 index 0000000..5dc7e2e --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch @@ -0,0 +1,102 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ba19089..2ba222a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,12 @@ + cmake_minimum_required(VERSION 3.17) + # CMake version is set at 3.17 because of find_package(CUDAToolkit) + ++if (NOT ${CMAKE_VERSION} VERSION_LESS 3.27) ++ # new in 3.27: additionally use uppercase _ROOT ++ # environment and CMake variables for find_package ++ cmake_policy(SET CMP0144 NEW) ++endif() ++ + set(OOMPH_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + list(APPEND CMAKE_MODULE_PATH "${OOMPH_MODULE_PATH}") + +@@ -108,11 +114,11 @@ endif() + install(EXPORT oomph-targets + FILE oomph-targets.cmake + NAMESPACE oomph:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/oomphConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/oomphConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + write_basic_package_version_file(oomphConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -125,7 +131,7 @@ install( + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindUCX.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindPMIx.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + export(EXPORT oomph-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/oomph-targets.cmake") +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index ec672b5..a578ef5 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -31,17 +31,30 @@ endif() + # --------------------------------------------------------------------- + # google test setup + # --------------------------------------------------------------------- +-add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +-# on some systems we need link explicitly against threads +-if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON ++ "OOMPH_USE_BUNDLED_LIBS" OFF) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() ++ else() ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() ++ endif() + endif() +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 06d703a..5217bba 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -65,6 +65,7 @@ function(reg_parallel_test t_ lib n) + NAME ${t} + COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${n} ${MPIEXEC_PREFLAGS} + $ ${MPIEXEC_POSTFLAGS}) ++ set_tests_properties(${t} PROPERTIES RUN_SERIAL TRUE) + endfunction() + + if (OOMPH_WITH_MPI) diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch new file mode 100644 index 0000000..aac73e8 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch @@ -0,0 +1,57 @@ +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index a578ef5..92de39b 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -33,28 +33,30 @@ endif() + # --------------------------------------------------------------------- + cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON + "OOMPH_USE_BUNDLED_LIBS" OFF) +-if(OOMPH_USE_BUNDLED_GTEST) +- add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +- # on some systems we need link explicitly against threads +- if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) +- endif() +-else() +- # Use system provided google test +- find_package(GTest REQUIRED) +- add_library(ext-gtest INTERFACE) +- if (${CMAKE_VERSION} VERSION_LESS "3.20.0") +- target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() + else() +- target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() + endif() + endif() diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py new file mode 100644 index 0000000..3b320f9 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py @@ -0,0 +1,109 @@ +from spack.package import * + + +class Oomph(CMakePackage, CudaPackage, ROCmPackage): + """Oomph is a non-blocking callback-based point-to-point communication library.""" + + homepage = "https://github.com/ghex-org/oomph" + url = "https://github.com/ghex-org/oomph/archive/refs/tags/v0.2.0.tar.gz" + git = "https://github.com/ghex-org/oomph.git" + maintainers = ["boeschf"] + + version("0.4.0", sha256="e342c872dfe4832be047f172dc55c12951950c79da2630b071c61607ef913144") + version("0.3.0", sha256="61e346d1ba28a859745de47f37edce39c7f5c5e1aab716493dc964e158fd99ec") + version("0.2.0", sha256="135cdb856aa817c053b6af1617869dbcd0ee97d34607e78874dd775ea389434e") + version("0.1.0", sha256="0ff36db0a5f30ae1bb02f6db6d411ea72eadd89688c00f76b4e722bd5a9ba90b") + version("main", branch="main") + + depends_on("cxx", type="build") + depends_on("fortran", type="build", when="+fortran-bindings") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", default="mpi", description="Transport backend", values=backends, multi=False + ) + + variant("fortran-bindings", default=False, description="Build Fortran bindings") + with when("+fortran-bindings"): + variant( + "fortran-fp", + default="float", + description="Floating point type", + values=("float", "double"), + multi=False, + ) + variant("fortran-openmp", default=True, description="Compile with OpenMP") + + variant( + "enable-barrier", + default=True, + description="Enable thread barrier (disable for task based runtime)", + ) + + depends_on("hwmalloc+cuda", when="+cuda") + depends_on("hwmalloc+rocm", when="+rocm") + depends_on("hwmalloc", when="~cuda~rocm") + + with when("backend=ucx"): + depends_on("ucx+thread_multiple") + depends_on("ucx+cuda", when="+cuda") + depends_on("ucx+rocm", when="+rocm") + variant("use-pmix", default="False", description="Use PMIx to establish out-of-band setup") + variant("use-spin-lock", default="False", description="Use pthread spin locks") + depends_on("pmix", when="+use-pmix") + + libfabric_providers = ("cxi", "efa", "gni", "psm2", "tcp", "verbs") + with when("backend=libfabric"): + variant( + "libfabric-provider", + default="tcp", + description="fabric", + values=libfabric_providers, + multi=False, + ) + for provider in libfabric_providers: + depends_on(f"libfabric fabrics={provider}", when=f"libfabric-provider={provider}") + + depends_on("mpi") + depends_on("boost+thread") + + depends_on("googletest", type=("build","test")) + + patch("install_0.2.patch", when="@:0.2.0", level=1) + patch("install_0.3.patch", when="@0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("OOMPH_BUILD_FORTRAN", "fortran-bindings"), + self.define_from_variant("OOMPH_FORTRAN_OPENMP", "fortran-openmp"), + self.define_from_variant("OOMPH_UCX_USE_PMI", "use-pmix"), + self.define_from_variant("OOMPH_UCX_USE_SPIN_LOCK", "use-spin-lock"), + self.define_from_variant("OOMPH_ENABLE_BARRIER", "enable-barrier"), + self.define("OOMPH_WITH_TESTING", self.run_tests), + self.define("OOMPH_GIT_SUBMODULE", False), + self.define("OOMPH_USE_BUNDLED_LIBS", False), + ] + + if self.run_tests and self.spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if self.spec.variants["fortran-bindings"].value == True: + args.append(self.define("OOMPH_FORTRAN_FP", self.spec.variants["fortran-fp"].value)) + + for backend in self.backends: + args.append( + self.define( + f"OOMPH_WITH_{backend.upper()}", self.spec.variants["backend"].value == backend + ) + ) + + if self.spec.satisfies("backend=libfabric"): + args.append( + self.define( + "OOMPH_LIBFABRIC_PROVIDER", self.spec.variants["libfabric-provider"].value + ) + ) + + return args diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/py-cupy/package.py new file mode 100644 index 0000000..e2be01e --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/py-cupy/package.py @@ -0,0 +1,145 @@ +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import os + +from spack.package import * + + +class PyCupy(PythonPackage, CudaPackage, ROCmPackage): + """CuPy is an open-source array library accelerated with + NVIDIA CUDA. CuPy provides GPU accelerated computing with + Python. CuPy uses CUDA-related libraries including cuBLAS, + cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make + full use of the GPU architecture. + + This version does not use CudNN.""" + + homepage = "https://cupy.dev/" + pypi = "cupy/cupy-8.0.0.tar.gz" + + # version( + # "13.5.1", + # sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + # ) + version( + "13.1.0", + sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", + ) + version( + "12.1.0", + sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", + ) + version( + "12.0.0", + sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", + ) + version( + "11.6.0", + sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", + ) + version( + "11.5.0", + sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", + ) + version( + "11.4.0", + sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", + ) + version( + "11.3.0", + sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", + ) + version( + "11.2.0", + sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", + ) + + variant( + "all", default=False, description="Enable optional py-scipy, optuna, and cython" + ) + + depends_on("cxx", type="build") # generated + + depends_on("python@3.7:", when="@:11", type=("build", "run")) + depends_on("python@3.8:", when="@12:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-cython@0.29.22:2", type="build") + depends_on("py-fastrlock@0.5:", type=("build", "run")) + depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) + depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) + depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) + + depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) + depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) + depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) + depends_on("py-optuna@2:", when="+all", type=("build", "run")) + + # Based on https://github.com/cupy/cupy/releases + depends_on("cuda@:11.9", when="@:11 +cuda") + depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") + depends_on("cuda@:12.4", when="@13:13.4.1 +cuda") + depends_on("cuda@:12.9", when="@13.5.1: +cuda") + + for a in CudaPackage.cuda_arch_values: + depends_on( + "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) + ) + + depends_on("cutensor", when="@:12.1.0 +cuda") + depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") + + for _arch in ROCmPackage.amdgpu_targets: + arch_str = "amdgpu_target={0}".format(_arch) + rocm_str = "+rocm {0}".format(arch_str) + depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) + + depends_on("rccl", when="+rocm", type=("link")) + depends_on("roctracer-dev", when="+rocm", type=("link")) + depends_on("rocprofiler-dev", when="+rocm", type=("link")) + + conflicts("~cuda ~rocm") + conflicts("+cuda +rocm") + conflicts("+cuda cuda_arch=none") + + def setup_build_environment(self, env): + env.set("CUPY_NUM_BUILD_JOBS", make_jobs) + if self.spec.satisfies("+cuda"): + cuda_arch = self.spec.variants["cuda_arch"].value + arch_str = ";".join( + "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch + ) + env.set("CUPY_NVCC_GENERATE_CODE", arch_str) + elif self.spec.satisfies("+rocm"): + spec = self.spec + + incs = { + "roctracer-dev": ["include/roctracer"], + "hiprand": ["include"], + "rocrand": ["include"], + "rocthrust": ["include"], + "rocprim": ["include"], + "hip": ["include", "include/hip"], + } + + inc_dirs = [] + for pkg, ds in incs.items(): + for d in ds: + p = os.path.join(spec[pkg].prefix, d) + if os.path.exists(p): + inc_dirs.append(p) + + env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) + + env.set("HIPCC", self.spec["hip"].hipcc) + env.set("ROCM_HOME", self.spec["hipcub"].prefix) + env.set("CUPY_INSTALL_USE_HIP", 1) diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py new file mode 100644 index 0000000..6941eff --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py @@ -0,0 +1,68 @@ +from spack.package import * + + +def translate_platform(platform_name: str) -> str: + if platform_name == "darwin": + return "apple-darwin" + elif platform_name == "linux": + return "unknown-linux-gnu" + return platform_name + + +def translate_arch(arch_name: str) -> str: + if arch_name in ["m1", "m2", "neoverse_v2"]: + return "aarch64" + if arch_name in ["zen3"]: + return "x86_64" + return arch_name + + +class Uv(Package): + """Install UV from binary releases""" + + url = "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz" + + version( + "0.7.12", + sha256="189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e", + extension=".tar.gz", + ) + version( + "0.7.20", + sha256="675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9", + extension=".tar.gz", + ) + + def url_for_version(self, version): + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + return f"https://github.com/astral-sh/uv/releases/download/{version}/uv-{arch}-{platform}.tar.gz" + + def do_stage(self, mirror_only=False): + checksums = { + ("0.7.12", "apple-darwin", "aarch64"): ( + "189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e" + ), + ("0.7.20", "unknown-linux-gnu", "aarch64"): ( + "675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9" + ), + ("0.7.20", "unknown-linux-gnu", "x86_64"): ( + "10f204426ff188925d22a53c1d0310d190a8d4d24513712e1b8e2ca9873f0666" + ), + } + version = str(self.spec.version) + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + key = (version, platform, arch) + + if key not in checksums: + msg = f"Unsupported platform/arch for version {version}: {platform}-{arch}." + raise InstallError(msg) + + self.fetcher.digest = checksums[key] + super().do_stage(mirror_only) + + def install(self, spec, prefix): + mkdir(prefix.bin) + install("uv", prefix.bin.uv) + install("uvx", prefix.bin.uvx) diff --git a/recipes/icon-dsl/25.12/gh200/compilers.yaml b/recipes/icon-dsl/25.12/gh200/compilers.yaml new file mode 100644 index 0000000..f456b5a --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/compilers.yaml @@ -0,0 +1,9 @@ +bootstrap: + spec: gcc@12.3 +gcc: + specs: + - gcc@13 +llvm: + requires: gcc@13 + specs: + - nvhpc@25.1 diff --git a/recipes/icon-dsl/25.12/gh200/config.yaml b/recipes/icon-dsl/25.12/gh200/config.yaml new file mode 100644 index 0000000..ac4ba9c --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/config.yaml @@ -0,0 +1,7 @@ +name: icon-dsl +store: /user-environment +spack: + repo: https://github.com/spack/spack.git + commit: releases/v0.23 +modules: false +description: Build and runtime dependencies for ICON-DSL diff --git a/recipes/icon-dsl/25.12/gh200/environments.yaml b/recipes/icon-dsl/25.12/gh200/environments.yaml new file mode 100644 index 0000000..7fde2c8 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/environments.yaml @@ -0,0 +1,47 @@ +myenv: + compiler: + - toolchain: gcc + spec: gcc + - toolchain: llvm + spec: nvhpc + mpi: + spec: cray-mpich@8.1.30%nvhpc + gpu: cuda + specs: + # icon4py deps + - python@3.11 + - py-cupy +cuda cuda_arch=90 + - ghex +python +cuda cuda_arch=90 + - py-mpi4py + - icon4py@icon_20250328 + # icon deps + - boost + - cuda@12 + - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper + - cosmo-eccodes-definitions@2.36.0.3 + - hdf5%nvhpc +szip +hl +fortran +mpi + - netcdf-c@4.9.2%nvhpc + - netcdf-cxx4@4.3.1%nvhpc + - netcdf-fortran@4.6.1%nvhpc + - osu-micro-benchmarks@5.9%nvhpc + - openblas + # for validation + - cdo + # everything needed for nccl on SS11 + - nccl + - nccl-tests + # extras + - libfyaml + - zlib-ng + - cmake + unify: true + variants: + - +mpi + - +cuda + - cuda_arch=90 + views: + default: + link: roots + uenv: + prefix_paths: + LD_LIBRARY_PATH: [lib, lib64] diff --git a/recipes/icon-dsl/25.12/gh200/extra/reframe.yaml b/recipes/icon-dsl/25.12/gh200/extra/reframe.yaml new file mode 100644 index 0000000..363f809 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/extra/reframe.yaml @@ -0,0 +1,6 @@ +default: + features: [osu-micro-benchmarks, mpi, serial, openmp] + cc: mpicc + cxx: mpic++ + ftn: mpifort + activation: /user-environment/env/default/activate.sh diff --git a/recipes/icon-dsl/25.12/gh200/modules.yaml b/recipes/icon-dsl/25.12/gh200/modules.yaml new file mode 100644 index 0000000..a4010ae --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/modules.yaml @@ -0,0 +1,26 @@ +modules: + # Paths to check when creating modules for all module sets + prefix_inspections: + bin: + - PATH + lib: + - LD_LIBRARY_PATH + lib64: + - LD_LIBRARY_PATH + + default: + arch_folder: false + # Where to install modules + roots: + tcl: /snap/modules + tcl: + all: + autoload: run + hash_length: 0 + hide_implicits: true + exclude: + - '%gcc@7.5.0' + - '%gcc@12' + - 'gcc %gcc@7.5.0' + projections: + all: '{name}/{version}' diff --git a/recipes/icon-dsl/25.12/gh200/pre-install b/recipes/icon-dsl/25.12/gh200/pre-install new file mode 100644 index 0000000..ba88283 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/pre-install @@ -0,0 +1,12 @@ +#!/bin/bash + +packages=("cosmo-eccodes-definitions") +SPACK_C2SM_TAG="v0.22.2.1" + +git clone -b ${SPACK_C2SM_TAG} https://github.com/C2SM/spack-c2sm.git + +for package in "${packages[@]}"; do + cp -r spack-c2sm/repos/c2sm/packages/"${package}" store/repo/packages +done + +rm -rf spack-c2sm diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/cmake_install_rpath.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/cmake_install_rpath.patch new file mode 100644 index 0000000..7e2b250 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/cmake_install_rpath.patch @@ -0,0 +1,11 @@ +--- a/cmake/ecbuild_append_to_rpath.cmake ++++ b/cmake/ecbuild_append_to_rpath.cmake +@@ -31,7 +31,7 @@ function( _path_append var path ) + else() + list( FIND ${var} ${path} _found ) + if( _found EQUAL "-1" ) +- set( ${var} "${${var}}:${path}" PARENT_SCOPE ) ++ set( ${var} "${${var}};${path}" PARENT_SCOPE ) + endif() + endif() + endfunction() diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/openjpeg_jasper.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/openjpeg_jasper.patch new file mode 100644 index 0000000..5793f56 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/openjpeg_jasper.patch @@ -0,0 +1,39 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,6 +43,18 @@ ecbuild_add_option( FEATURE JPG + DESCRIPTION "support for JPG decoding/encoding" + DEFAULT ON + ) ++# Options related to JPG. The Jasper and OpenJPEG libraries ++ecbuild_add_option( FEATURE JPG_LIBJASPER ++ DESCRIPTION "Support for JPG decoding/encoding with the Jasper library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ecbuild_add_option( FEATURE JPG_LIBOPENJPEG ++ DESCRIPTION "Support for JPG decoding/encoding with the OpenJPEG library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ + + ecbuild_add_option( FEATURE PNG + DESCRIPTION "support for PNG decoding/encoding" +@@ -144,7 +156,7 @@ if( ENABLE_JPG ) + + find_package( OpenJPEG ) + +- if( JASPER_FOUND ) ++ if( JASPER_FOUND AND ENABLE_JPG_LIBJASPER ) + list( APPEND ECCODES_TPLS Jasper ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBJASPER 1 ) +@@ -152,7 +164,7 @@ if( ENABLE_JPG ) + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" JASPER_VERSION_MAJOR "${JASPER_VERSION_STRING}") + endif() + +- if( OPENJPEG_FOUND ) ++ if( OPENJPEG_FOUND AND ENABLE_JPG_LIBOPENJPEG ) + list( APPEND ECCODES_TPLS OpenJPEG ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBOPENJPEG 1 ) diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/package.py new file mode 100644 index 0000000..aeb4692 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/package.py @@ -0,0 +1,385 @@ +# 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.package import * + +_definitions = { + # German Meteorological Service (Deutscher Wetterdienst, DWD): + "edzw": { + "conflicts": {"when": "@:2.19.1,2.22.0,2.24.0:"}, + "resources": [ + { + "when": "@2.20.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.20.0-1.tar.gz", + "sha256": "a92932f8a13c33cba65d3a33aa06c7fb4a37ed12a78e9abe2c5e966402b99af4", + }, + { + "when": "@2.21.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.21.0-3.tar.bz2", + "sha256": "046f1f6450abb3b44c31dee6229f4aab06ca0d3576e27e93e05ccb7cd6e2d9d9", + }, + { + "when": "@2.22.1", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.22.1-1.tar.bz2", + "sha256": "be73102a0dcabb236bacd2a70c7b5475f673fda91b49e34df61bef0fa5ad3389", + }, + { + "when": "@2.23.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.23.0-4.tar.bz2", + "sha256": "c5db32861c7d23410aed466ffef3ca661410d252870a3949442d3ecb176aa338", + }, + ], + } +} + + +class Eccodes(CMakePackage): + """ecCodes is a package developed by ECMWF for processing meteorological + data in GRIB (1/2), BUFR (3/4) and GTS header formats.""" + + homepage = "https://software.ecmwf.int/wiki/display/ECC/ecCodes+Home" + url = "https://confluence.ecmwf.int/download/attachments/45757960/eccodes-2.2.0-Source.tar.gz?api=v2" + git = "https://github.com/ecmwf/eccodes.git" + list_url = "https://confluence.ecmwf.int/display/ECC/Releases" + + maintainers("skosukhin", "victoria-cherkas", "dominichofer", "climbfuji") + + license("Apache-2.0") + + version("develop", branch="develop") + version("2.36.4", + sha256="198ccb26e8df96544c668ea6853ea153535ab78b10c43339a678f271337aa0da", + url="https://github.com/ecmwf/eccodes/archive/refs/tags/2.36.4.tar.gz" + ) + version("2.34.0", sha256="3cd208c8ddad132789662cf8f67a9405514bfefcacac403c0d8c84507f303aba") + version("2.33.0", sha256="bdcec8ce63654ec6803400c507f01220a9aa403a45fa6b5bdff7fdcc44fd7daf") + version("2.32.1", sha256="ad2ac1bf36577b1d35c4a771b4d174a06f522a1e5ef6c1f5e53a795fb624863e") + version("2.32.0", sha256="b57e8eeb0eba0c05d66fda5527c4ffa84b5ab35c46bcbc9a2227142973ccb8e6") + version("2.31.0", sha256="808ecd2c11fbf2c3f9fc7a36f8c2965b343f3151011b58a1d6e7cc2e6b3cac5d") + version("2.25.0", sha256="8975131aac54d406e5457706fd4e6ba46a8cc9c7dd817a41f2aa64ce1193c04e") + version("2.24.2", sha256="c60ad0fd89e11918ace0d84c01489f21222b11d6cad3ff7495856a0add610403") + version("2.23.0", sha256="cbdc8532537e9682f1a93ddb03440416b66906a4cc25dec3cbd73940d194bf0c") + version("2.22.1", sha256="75c7ee96469bb30b0c8f7edbdc4429ece4415897969f75c36173545242bc9e85") + version("2.21.0", sha256="da0a0bf184bb436052e3eae582defafecdb7c08cdaab7216780476e49b509755") + version("2.20.0", sha256="207a3d7966e75d85920569b55a19824673e8cd0b50db4c4dac2d3d52eacd7985") + version("2.19.1", sha256="9964bed5058e873d514bd4920951122a95963128b12f55aa199d9afbafdd5d4b") + version("2.18.0", sha256="d88943df0f246843a1a062796edbf709ef911de7269648eef864be259e9704e3") + version("2.13.0", sha256="c5ce1183b5257929fc1f1c8496239e52650707cfab24f4e0e1f1a471135b8272") + version("2.5.0", sha256="18ab44bc444168fd324d07f7dea94f89e056f5c5cd973e818c8783f952702e4e") + version("2.2.0", sha256="1a4112196497b8421480e2a0a1164071221e467853486577c4f07627a702f4c3") + + # we are still using spack v0.21 v0.22, so comment these out for now + #depends_on("c", type="build") # generated + #depends_on("cxx", type="build") # generated + #depends_on("fortran", type="build") # generated + + variant("tools", default=False, description="Build the command line tools") + variant("netcdf", default=False, description="Enable GRIB to NetCDF conversion tool") + variant( + "jp2k", + default="openjpeg", + values=("openjpeg", "jasper", "none"), + description="Specify JPEG2000 decoding/encoding backend", + ) + variant("png", default=False, description="Enable PNG support for decoding/encoding") + variant( + "aec", default=True, description="Enable Adaptive Entropy Coding for decoding/encoding" + ) + variant("pthreads", default=False, description="Enable POSIX threads") + variant("openmp", default=False, description="Enable OpenMP threads") + variant( + "memfs", default=False, description="Enable memory based access to definitions/samples" + ) + variant("fortran", default=False, description="Enable the Fortran support") + variant("shared", default=True, description="Build shared versions of the libraries") + + variant( + "extra_definitions", + values=any_combination_of(*_definitions.keys()), + description="List of extra definitions to install", + ) + + depends_on("netcdf-c", when="+netcdf") + # Cannot be built with openjpeg@2.0.x. + depends_on("openjpeg@1.5.0:1.5,2.1.0:2.3", when="jp2k=openjpeg") + # Additional constraint for older versions. + depends_on("openjpeg@:2.1", when="@:2.16 jp2k=openjpeg") + + with when("jp2k=jasper"): + depends_on("jasper") + # jasper 3.x compat from commit 86f0b35f1a8492cb16f82fb976a0a5acd2986ac2 + depends_on("jasper@:2", when="@:2.25.0") + + depends_on("libpng", when="+png") + depends_on("libaec", when="+aec") + # Can be built with Python 2 or Python 3. + depends_on("python", when="+memfs", type="build") + + depends_on("cmake@3.6:", type="build") + depends_on("cmake@3.12:", when="@2.19:", type="build") + + # TODO: ecbuild was only used for the @develop branch + # however, testing 2.36.4, it appears to be a requirement. + # this might be because they package the software differently in GitHub + # (they normally provide releases as tar balls on Confluence) + depends_on("ecbuild", type="build") + #depends_on("ecbuild", type="build", when="@develop") + + conflicts("+openmp", when="+pthreads", msg="Cannot enable both POSIX threads and OMP") + + conflicts( + "+netcdf", + when="~tools", + msg="Cannot enable the NetCDF conversion tool " "when the command line tools are disabled", + ) + + conflicts( + "~tools", + when="@:2.18.0", + msg="The command line tools can be disabled " "only starting version 2.19.0", + ) + + for center, definitions in _definitions.items(): + kwargs = definitions.get("conflicts", None) + if kwargs: + conflicts("extra_definitions={0}".format(center), **kwargs) + for kwargs in definitions.get("resources", []): + resource( + name=center, + destination="spack-definitions", + placement="definitions.{0}".format(center), + **kwargs, + ) + + # Enforce linking against the specified JPEG2000 backend, see also + # https://github.com/ecmwf/eccodes/commit/2c10828495900ff3d80d1e570fe96c1df16d97fb + patch("openjpeg_jasper.patch", when="@:2.16") + + # CMAKE_INSTALL_RPATH must be a semicolon-separated list. + patch("cmake_install_rpath.patch", when="@:2.10") + + # Fix a bug preventing cmake from finding NetCDF: + patch( + "https://github.com/ecmwf/ecbuild/commit/3916c7d22575c45166fcc89edcbe02a6e9b81aa2.patch?full_index=1", + sha256="9dcc4affaaa850d4b7247baa939d0f9ffedea132369f1afc3f248dbf720386c9", + when="@:2.4.0+netcdf", + ) + + @when("%nag+fortran") + def patch(self): + # A number of Fortran source files assume that the kinds of integer and + # real variables are specified in bytes. However, the NAG compiler + # accepts such code only with an additional compiler flag -kind=byte. + # We do not simply add the flag because all user applications would + # have to be compiled with this flag too, which goes against one of the + # purposes of using the NAG compiler: make sure the code does not + # contradict the Fortran standards. The following logic could have been + # implemented as regular patch files, which would, however, be quite + # large. We would also have to introduce several versions of each patch + # file to support different versions of the package. + + patch_kind_files = [ + "fortran/eccodes_f90_head.f90", + "fortran/eccodes_f90_tail.f90", + "fortran/grib_f90_head.f90", + "fortran/grib_f90_tail.f90", + "fortran/grib_types.f90", + ] + + patch_unix_ext_files = [] + + if self.run_tests: + patch_kind_files.extend( + [ + "examples/F90/grib_print_data.f90", + "examples/F90/grib_print_data_static.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_attributes.f90', + # 'examples/F90/bufr_expanded.f90', + # 'examples/F90/bufr_get_keys.f90', + # 'examples/F90/bufr_read_scatterometer.f90', + # 'examples/F90/bufr_read_synop.f90', + # 'examples/F90/bufr_read_temp.f90', + # 'examples/F90/bufr_read_tempf.f90', + # 'examples/F90/bufr_read_tropical_cyclone.f90', + # 'examples/F90/grib_clone.f90', + # 'examples/F90/grib_get_data.f90', + # 'examples/F90/grib_nearest.f90', + # 'examples/F90/grib_precision.f90', + # 'examples/F90/grib_read_from_file.f90', + # 'examples/F90/grib_samples.f90', + # 'examples/F90/grib_set_keys.f90' + ] + ) + + patch_unix_ext_files.extend( + [ + "examples/F90/bufr_ecc-1284.f90", + "examples/F90/grib_set_data.f90", + "examples/F90/grib_set_packing.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_copy_data.f90', + # 'examples/F90/bufr_get_string_array.f90', + # 'examples/F90/bufr_keys_iterator.f90', + # 'examples/F90/get_product_kind.f90', + # 'examples/F90/grib_count_messages_multi.f90' + ] + ) + + kwargs = {"string": False, "backup": False, "ignore_absent": True} + + # Return the kind and not the size: + filter_file( + r"(^\s*kind_of_double\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(real\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + filter_file( + r"(^\s*kind_of_\w+\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(x\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + + # Replace integer kinds: + for size, r in [(2, 4), (4, 9), (8, 18)]: + filter_file( + r"(^\s*integer\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_int_kind({0})\\2".format(r), + *patch_kind_files, + **kwargs, + ) + + # Replace real kinds: + for size, p, r in [(4, 6, 37), (8, 15, 307)]: + filter_file( + r"(^\s*real\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_real_kind({0}, {1})\\2".format(p, r), + *patch_kind_files, + **kwargs, + ) + + # Enable getarg and exit subroutines: + filter_file( + r"(^\s*program\s+\w+)(\s*$)", + "\\1; use f90_unix_env; use f90_unix_proc\\2", + *patch_unix_ext_files, + **kwargs, + ) + + @property + def libs(self): + libraries = [] + + query_parameters = self.spec.last_query.extra_parameters + + if "shared" in query_parameters: + shared = True + elif "static" in query_parameters: + shared = False + else: + shared = "+shared" in self.spec + + # Return Fortran library if requested: + return_fortran = "fortran" in query_parameters + # Return C library if either requested or the Fortran library is not + # requested (to avoid overlinking) or the static libraries are + # requested: + return_c = "c" in query_parameters or not (return_fortran and shared) + # Return MEMFS library only if enabled and the static libraries are + # requested: + return_memfs = "+memfs" in self.spec and not shared + + if return_fortran: + libraries.append("libeccodes_f90") + + if return_c: + libraries.append("libeccodes") + + if return_memfs: + libraries.append("libeccodes_memfs") + + libs = find_libraries(libraries, root=self.prefix, shared=shared, recursive=True) + + if libs and len(libs) == len(libraries): + return libs + + msg = "Unable to recursively locate {0} {1} libraries in {2}" + raise spack.error.NoLibrariesError( + msg.format("shared" if shared else "static", self.spec.name, self.spec.prefix) + ) + + @run_before("cmake") + def check_fortran(self): + if "+fortran" in self.spec and self.compiler.fc is None: + raise InstallError("Fortran interface requires a Fortran compiler!") + + def cmake_args(self): + jp2k = self.spec.variants["jp2k"].value + + args = [ + self.define_from_variant("ENABLE_BUILD_TOOLS", "tools"), + self.define_from_variant("ENABLE_NETCDF", "netcdf"), + self.define("ENABLE_JPG", jp2k != "none"), + self.define("ENABLE_JPG_LIBJASPER", jp2k == "jasper"), + self.define("ENABLE_JPG_LIBOPENJPEG", jp2k == "openjpeg"), + self.define_from_variant("ENABLE_PNG", "png"), + self.define_from_variant("ENABLE_AEC", "aec"), + self.define_from_variant("ENABLE_ECCODES_THREADS", "pthreads"), + self.define_from_variant("ENABLE_ECCODES_OMP_THREADS", "openmp"), + self.define_from_variant("ENABLE_MEMFS", "memfs"), + self.define( + "ENABLE_PYTHON{0}".format("2" if self.spec.satisfies("@2.20.0:") else ""), False + ), + self.define_from_variant("ENABLE_FORTRAN", "fortran"), + self.define("BUILD_SHARED_LIBS", "BOTH" if "+shared" in self.spec else "OFF"), + self.define("ENABLE_TESTS", self.run_tests), + # Examples are not installed and are just part of the test suite: + self.define("ENABLE_EXAMPLES", self.run_tests), + # Unconditionally disable the extended regression tests, since they + # download additional data (~134MB): + self.define("ENABLE_EXTRA_TESTS", False), + ] + + if self.spec.satisfies("+netcdf"): + # Prevent possible overriding by environment variables NETCDF_ROOT, NETCDF_DIR, and + # NETCDF_PATH: + args.append(self.define("NETCDF_PATH", self.spec["netcdf-c"].prefix)) + # Prevent overriding by environment variable HDF5_ROOT (starting version 2.14.0, + # ecCodes is shipped with ecBuild 3.1.0+, which does not seem to rely on the HDF5_ROOT + # variable): + if self.spec.satisfies("@:2.13"): + args.append(self.define("HDF5_ROOT", self.spec["hdf5"].prefix)) + + if jp2k == "openjpeg": + args.append(self.define("OPENJPEG_PATH", self.spec["openjpeg"].prefix)) + + if self.spec.satisfies("+png"): + args.append(self.define("ZLIB_ROOT", self.spec["zlib-api"].prefix)) + + if self.spec.satisfies("+aec"): + # Prevent overriding by environment variables AEC_DIR and AEC_PATH: + args.append(self.define("AEC_DIR", self.spec["libaec"].prefix)) + + return args + + @run_after("install") + def install_extra_definitions(self): + for center in self.spec.variants["extra_definitions"].value: + if center != "none": + center_dir = "definitions.{0}".format(center) + install_tree( + join_path(self.stage.source_path, "spack-definitions", center_dir), + join_path(self.prefix.share.eccodes, center_dir), + ) + + def check(self): + # https://confluence.ecmwf.int/display/ECC/ecCodes+installation + with working_dir(self.build_directory): + ctest() diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/readme.md b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/readme.md new file mode 100644 index 0000000..9678342 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/eccodes/readme.md @@ -0,0 +1 @@ +copied from mainline spack November 5 2024 so that we can add eccodes 2.36.0 for mch production diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py new file mode 100644 index 0000000..8f50e28 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py @@ -0,0 +1,93 @@ +from spack.package import * + + +class Ghex(CMakePackage, CudaPackage, ROCmPackage): + """GHEX is a generic halo-exchange library.""" + + homepage = "https://github.com/ghex-org/GHEX" + url = "https://github.com/ghex-org/GHEX/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/GHEX.git" + maintainers = ["boeschf"] + + version("0.4.1", tag="v0.4.1", submodules=True) + version("0.4.0", tag="v0.4.0", submodules=True) + version("0.3.0", tag="v0.3.0", submodules=True) + version("master", branch="master", submodules=True) + + depends_on("cxx", type="build") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", + default="mpi", + description="Transport backend", + values=backends, + multi=False, + ) + variant("xpmem", default=False, description="Use xpmem shared memory") + variant("python", default=True, description="Build Python bindings") + + depends_on("cmake@3.21:", type="build") + depends_on("mpi") + depends_on("boost") + depends_on("xpmem", when="+xpmem", type=("build", "run")) + + depends_on("oomph") + for backend in backends: + depends_on(f"oomph backend={backend}", when=f"backend={backend}") + depends_on("oomph+cuda", when="+cuda") + depends_on("oomph+rocm", when="+rocm") + depends_on("oomph@0.3:", when="@0.3:") + + conflicts("+cuda+rocm") + + with when("+python"): + extends("python") + depends_on("python@3.7:", type="build") + depends_on("py-pip", type="build") + depends_on("py-pybind11", type="build") + depends_on("py-mpi4py", type=("build", "run")) + depends_on("py-numpy", type=("build", "run")) + + depends_on("py-pytest", when="+python", type=("test")) + + def cmake_args(self): + spec = self.spec + + args = [ + self.define("GHEX_USE_BUNDLED_LIBS", True), + self.define("GHEX_USE_BUNDLED_GRIDTOOLS", True), + self.define("GHEX_USE_BUNDLED_GTEST", self.run_tests), + self.define("GHEX_USE_BUNDLED_OOMPH", False), + self.define( + "GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper() + ), + self.define_from_variant("GHEX_USE_XPMEM", "xpmem"), + self.define_from_variant("GHEX_BUILD_PYTHON_BINDINGS", "python"), + self.define("GHEX_WITH_TESTING", self.run_tests), + ] + + if spec.satisfies("+python"): + args.append(self.define("GHEX_PYTHON_LIB_PATH", python_platlib)) + + if self.run_tests and spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if "+cuda" in spec and spec.variants["cuda_arch"].value != "none": + arch_str = ";".join(spec.variants["cuda_arch"].value) + args.append(self.define("CMAKE_CUDA_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "NVIDIA")) + + if "+rocm" in spec and spec.variants["amdgpu_target"].value != "none": + arch_str = ";".join(spec.variants["amdgpu_target"].value) + args.append(self.define("CMAKE_HIP_ARCHITECTURES", arch_str)) + args.append(self.define("GHEX_USE_GPU", True)) + args.append(self.define("GHEX_GPU_TYPE", "AMD")) + + if spec.satisfies("~cuda~rocm"): + args.append(self.define("GHEX_USE_GPU", False)) + + return args diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch new file mode 100644 index 0000000..fa6fde1 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch @@ -0,0 +1,27 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d5420e0..35dbe56 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -105,11 +105,11 @@ install(FILES ${PROJECT_BINARY_DIR}/include/hwmalloc/config.hpp + install(EXPORT HWMALLOC-targets + FILE HWMALLOC-targets.cmake + NAMESPACE HWMALLOC:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HWMALLOCConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + write_basic_package_version_file(HWMALLOCConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -120,7 +120,7 @@ install( + ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfigVersion.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindNUMA.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) + + export(EXPORT HWMALLOC-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/HWMALLOC-targets.cmake") diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py new file mode 100644 index 0000000..c656dc1 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py @@ -0,0 +1,52 @@ +from spack.package import * + + +class Hwmalloc(CMakePackage, CudaPackage, ROCmPackage): + """HWMALLOC is a allocator which supports memory registration for e.g. remote memory access""" + + homepage = "https://github.com/ghex-org/hwmalloc" + url = "https://github.com/ghex-org/hwmalloc/archive/refs/tags/v0.3.0.tar.gz" + git = "https://github.com/ghex-org/hwmalloc.git" + maintainers = ["boeschf"] + + version("0.3.0", sha256="d4d4ac6087a806600d79fb62c02719ca3d58a412968fe1ef4a2fd58d9e7ee950") + version("0.2.0", sha256="734758a390a3258b86307e4aef50a7ca2e5d0e2e579f18aeefcd05397e114419") + version("0.1.0", sha256="06e9bfcef0ecce4d19531ccbe03592b502d1281c7a092bc0ff51ca187899b21c") + version("master", branch="master") + + depends_on("cxx", type="build") + + generator("ninja") + + depends_on("numactl", type=("build", "run")) + depends_on("boost", type=("build")) + depends_on("cmake@3.19:", type="build") + + variant( + "numa-throws", + default=False, + description="True if numa_tools may throw during initialization", + ) + variant("numa-local", default=True, description="Use numa_tools for local node allocations") + variant("logging", default=False, description="print logging info to cerr") + + patch("cmake_install_path.patch", when="@:0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("HWMALLOC_NUMA_THROWS", "numa-throws"), + self.define_from_variant("HWMALLOC_NUMA_FOR_LOCAL", "numa-local"), + self.define_from_variant("HWMALLOC_ENABLE_LOGGING", "logging"), + self.define("HWMALLOC_WITH_TESTING", self.run_tests), + ] + + if "+cuda" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "cuda")) + elif "+rocm" in self.spec: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) + args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "hip")) + else: + args.append(self.define("HWMALLOC_ENABLE_DEVICE", False)) + + return args diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py new file mode 100644 index 0000000..9ee413e --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py @@ -0,0 +1,109 @@ +import json +import os +import pathlib + +import llnl +from llnl.util import tty +from spack import * + + +class Icon4py(Package): + extends("python") + depends_on("python@3.11:") + + depends_on("git") + depends_on("boost@1.85:+mpi+python", type=("build", "run")) + depends_on("uv@0.7:", type="build") + depends_on("bzip2", type="build") + depends_on("py-numpy") + depends_on("py-cffi") + depends_on("py-pybind11") + depends_on("py-nanobind") + depends_on("py-mpi4py") + depends_on("py-cupy +cuda") + depends_on("ghex +python +cuda") + + version( + "icon_20250328", + sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", + extension="zip", + ) + + def url_for_version(self, version): + return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" + + def install(self, spec, prefix): + uv = prepare_uv() + python_spec = spec["python"] + venv_path = prefix.share.venv + + tty.msg(f"creating venv using spack python at: {python_spec.command.path}") + uv( + "venv", + "--seed", + "--relocatable", + "--system-site-packages", + str(venv_path), + "--python", + python_spec.command.path, + ) + + tty.msg(f"grabbing spack installed packages (distributions)") + pip = Executable(venv_path.bin.pip) + spack_installed = get_installed_pkg(pip) + + tty.msg(f"installing missing packages") + uv( + "sync", + "--active", + "--extra", + "all", + "--extra", + "cuda12", + "--inexact", + "--no-editable", + "--python", + str(venv_path.bin.python), + *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + tty.msg(f"linking spack installed packages into venv") + pathlib.Path( + f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" + ).write_text(pythonpath_to_pth()) + + tty.msg(f"running py2fgen") + py2fgen = Executable(venv_path.bin.py2fgen) + py2fgen( + "icon4py.tools.py2fgen.wrappers.all_bindings", + "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", + "icon4py_bindings", + "-o", + prefix.src, + extra_env={"VIRTUAL_ENV": str(venv_path)}, + ) + + +def prepare_uv(): + uv = which("uv") + uv.add_default_env("UV_NO_CACHE", "true") + uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") + uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") + return uv + + +def get_installed_pkg(pip): + return [ + item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) + ] + + +def no_install_options(installed): + for name in installed: + yield "--no-install-package" + yield name + + +def pythonpath_to_pth(): + return "\n".join(os.environ["PYTHONPATH"].split(":")) diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch new file mode 100644 index 0000000..5dc7e2e --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch @@ -0,0 +1,102 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index ba19089..2ba222a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,6 +1,12 @@ + cmake_minimum_required(VERSION 3.17) + # CMake version is set at 3.17 because of find_package(CUDAToolkit) + ++if (NOT ${CMAKE_VERSION} VERSION_LESS 3.27) ++ # new in 3.27: additionally use uppercase _ROOT ++ # environment and CMake variables for find_package ++ cmake_policy(SET CMP0144 NEW) ++endif() ++ + set(OOMPH_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + list(APPEND CMAKE_MODULE_PATH "${OOMPH_MODULE_PATH}") + +@@ -108,11 +114,11 @@ endif() + install(EXPORT oomph-targets + FILE oomph-targets.cmake + NAMESPACE oomph:: +- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/oomphConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/oomphConfig.cmake +- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) ++ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + write_basic_package_version_file(oomphConfigVersion.cmake + VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) +@@ -125,7 +131,7 @@ install( + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindUCX.cmake + ${CMAKE_CURRENT_LIST_DIR}/cmake/FindPMIx.cmake + DESTINATION +- ${CMAKE_INSTALL_LIBDIR}/cmake) ++ ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) + + export(EXPORT oomph-targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/oomph-targets.cmake") +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index ec672b5..a578ef5 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -31,17 +31,30 @@ endif() + # --------------------------------------------------------------------- + # google test setup + # --------------------------------------------------------------------- +-add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +-# on some systems we need link explicitly against threads +-if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON ++ "OOMPH_USE_BUNDLED_LIBS" OFF) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() ++ else() ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() ++ endif() + endif() +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 06d703a..5217bba 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -65,6 +65,7 @@ function(reg_parallel_test t_ lib n) + NAME ${t} + COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${n} ${MPIEXEC_PREFLAGS} + $ ${MPIEXEC_POSTFLAGS}) ++ set_tests_properties(${t} PROPERTIES RUN_SERIAL TRUE) + endfunction() + + if (OOMPH_WITH_MPI) diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch new file mode 100644 index 0000000..aac73e8 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch @@ -0,0 +1,57 @@ +diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake +index a578ef5..92de39b 100644 +--- a/cmake/oomph_external_dependencies.cmake ++++ b/cmake/oomph_external_dependencies.cmake +@@ -33,28 +33,30 @@ endif() + # --------------------------------------------------------------------- + cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON + "OOMPH_USE_BUNDLED_LIBS" OFF) +-if(OOMPH_USE_BUNDLED_GTEST) +- add_external_cmake_project( +- NAME googletest +- PATH ext/googletest +- INTERFACE_NAME ext-gtest +- LIBS libgtest.a libgtest_main.a +- CMAKE_ARGS +- "-DCMAKE_BUILD_TYPE=release" +- "-DBUILD_SHARED_LIBS=OFF" +- "-DBUILD_GMOCK=OFF") +- # on some systems we need link explicitly against threads +- if (TARGET ext-gtest) +- find_package (Threads) +- target_link_libraries(ext-gtest INTERFACE Threads::Threads) +- endif() +-else() +- # Use system provided google test +- find_package(GTest REQUIRED) +- add_library(ext-gtest INTERFACE) +- if (${CMAKE_VERSION} VERSION_LESS "3.20.0") +- target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++if (OOMPH_WITH_TESTING) ++ if(OOMPH_USE_BUNDLED_GTEST) ++ add_external_cmake_project( ++ NAME googletest ++ PATH ext/googletest ++ INTERFACE_NAME ext-gtest ++ LIBS libgtest.a libgtest_main.a ++ CMAKE_ARGS ++ "-DCMAKE_BUILD_TYPE=release" ++ "-DBUILD_SHARED_LIBS=OFF" ++ "-DBUILD_GMOCK=OFF") ++ # on some systems we need link explicitly against threads ++ if (TARGET ext-gtest) ++ find_package (Threads) ++ target_link_libraries(ext-gtest INTERFACE Threads::Threads) ++ endif() + else() +- target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ # Use system provided google test ++ find_package(GTest REQUIRED) ++ add_library(ext-gtest INTERFACE) ++ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") ++ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) ++ else() ++ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) ++ endif() + endif() + endif() diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py new file mode 100644 index 0000000..3b320f9 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py @@ -0,0 +1,109 @@ +from spack.package import * + + +class Oomph(CMakePackage, CudaPackage, ROCmPackage): + """Oomph is a non-blocking callback-based point-to-point communication library.""" + + homepage = "https://github.com/ghex-org/oomph" + url = "https://github.com/ghex-org/oomph/archive/refs/tags/v0.2.0.tar.gz" + git = "https://github.com/ghex-org/oomph.git" + maintainers = ["boeschf"] + + version("0.4.0", sha256="e342c872dfe4832be047f172dc55c12951950c79da2630b071c61607ef913144") + version("0.3.0", sha256="61e346d1ba28a859745de47f37edce39c7f5c5e1aab716493dc964e158fd99ec") + version("0.2.0", sha256="135cdb856aa817c053b6af1617869dbcd0ee97d34607e78874dd775ea389434e") + version("0.1.0", sha256="0ff36db0a5f30ae1bb02f6db6d411ea72eadd89688c00f76b4e722bd5a9ba90b") + version("main", branch="main") + + depends_on("cxx", type="build") + depends_on("fortran", type="build", when="+fortran-bindings") + + generator("ninja") + + backends = ("mpi", "ucx", "libfabric") + variant( + "backend", default="mpi", description="Transport backend", values=backends, multi=False + ) + + variant("fortran-bindings", default=False, description="Build Fortran bindings") + with when("+fortran-bindings"): + variant( + "fortran-fp", + default="float", + description="Floating point type", + values=("float", "double"), + multi=False, + ) + variant("fortran-openmp", default=True, description="Compile with OpenMP") + + variant( + "enable-barrier", + default=True, + description="Enable thread barrier (disable for task based runtime)", + ) + + depends_on("hwmalloc+cuda", when="+cuda") + depends_on("hwmalloc+rocm", when="+rocm") + depends_on("hwmalloc", when="~cuda~rocm") + + with when("backend=ucx"): + depends_on("ucx+thread_multiple") + depends_on("ucx+cuda", when="+cuda") + depends_on("ucx+rocm", when="+rocm") + variant("use-pmix", default="False", description="Use PMIx to establish out-of-band setup") + variant("use-spin-lock", default="False", description="Use pthread spin locks") + depends_on("pmix", when="+use-pmix") + + libfabric_providers = ("cxi", "efa", "gni", "psm2", "tcp", "verbs") + with when("backend=libfabric"): + variant( + "libfabric-provider", + default="tcp", + description="fabric", + values=libfabric_providers, + multi=False, + ) + for provider in libfabric_providers: + depends_on(f"libfabric fabrics={provider}", when=f"libfabric-provider={provider}") + + depends_on("mpi") + depends_on("boost+thread") + + depends_on("googletest", type=("build","test")) + + patch("install_0.2.patch", when="@:0.2.0", level=1) + patch("install_0.3.patch", when="@0.3.0", level=1) + + def cmake_args(self): + args = [ + self.define_from_variant("OOMPH_BUILD_FORTRAN", "fortran-bindings"), + self.define_from_variant("OOMPH_FORTRAN_OPENMP", "fortran-openmp"), + self.define_from_variant("OOMPH_UCX_USE_PMI", "use-pmix"), + self.define_from_variant("OOMPH_UCX_USE_SPIN_LOCK", "use-spin-lock"), + self.define_from_variant("OOMPH_ENABLE_BARRIER", "enable-barrier"), + self.define("OOMPH_WITH_TESTING", self.run_tests), + self.define("OOMPH_GIT_SUBMODULE", False), + self.define("OOMPH_USE_BUNDLED_LIBS", False), + ] + + if self.run_tests and self.spec.satisfies("^openmpi"): + args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) + + if self.spec.variants["fortran-bindings"].value == True: + args.append(self.define("OOMPH_FORTRAN_FP", self.spec.variants["fortran-fp"].value)) + + for backend in self.backends: + args.append( + self.define( + f"OOMPH_WITH_{backend.upper()}", self.spec.variants["backend"].value == backend + ) + ) + + if self.spec.satisfies("backend=libfabric"): + args.append( + self.define( + "OOMPH_LIBFABRIC_PROVIDER", self.spec.variants["libfabric-provider"].value + ) + ) + + return args diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/py-cupy/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/py-cupy/package.py new file mode 100644 index 0000000..e2be01e --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/py-cupy/package.py @@ -0,0 +1,145 @@ +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import os + +from spack.package import * + + +class PyCupy(PythonPackage, CudaPackage, ROCmPackage): + """CuPy is an open-source array library accelerated with + NVIDIA CUDA. CuPy provides GPU accelerated computing with + Python. CuPy uses CUDA-related libraries including cuBLAS, + cuRand, cuSolver, cuSPARSE, cuFFT and NCCL to make + full use of the GPU architecture. + + This version does not use CudNN.""" + + homepage = "https://cupy.dev/" + pypi = "cupy/cupy-8.0.0.tar.gz" + + # version( + # "13.5.1", + # sha256="3dba2f30258463482d52deb420862fbbbaf2c446165a5e8d67377ac6cb5c0870", + # ) + version( + "13.1.0", + sha256="5caf62288481a27713384523623045380ff42e618be4245f478238ed1786f32d", + ) + version( + "12.1.0", + sha256="f6d31989cdb2d96581da12822e28b102f29e254427195c2017eac327869b7320", + ) + version( + "12.0.0", + sha256="61ddbbef73d50d606bd5087570645f3c91ec9176c2566784c1d486d6a3404545", + ) + version( + "11.6.0", + sha256="53dbb840072bb32d4bfbaa6bfa072365a30c98b1fcd1f43e48969071ad98f1a7", + ) + version( + "11.5.0", + sha256="4bc8565bded22cc89b210fd9fb48a5d5316f30701e12bb23852a60314e1f9f6e", + ) + version( + "11.4.0", + sha256="03d52b2626e02a3a2b46d714c1cd03e702c8fe33915fcca6ed8de5c539964f49", + ) + version( + "11.3.0", + sha256="d057cc2f73ecca06fae8b9c270d9e14116203abfd211a704810cc50a453b4c9e", + ) + version( + "11.2.0", + sha256="c33361f117a347a63f6996ea97446d17f1c038f1a1f533e502464235076923e2", + ) + + variant( + "all", default=False, description="Enable optional py-scipy, optuna, and cython" + ) + + depends_on("cxx", type="build") # generated + + depends_on("python@3.7:", when="@:11", type=("build", "run")) + depends_on("python@3.8:", when="@12:", type=("build", "run")) + depends_on("py-setuptools", type="build") + depends_on("py-cython@0.29.22:2", type="build") + depends_on("py-fastrlock@0.5:", type=("build", "run")) + depends_on("py-numpy@1.20:1.25", when="@:11", type=("build", "run")) + depends_on("py-numpy@1.20:1.26", when="@12:", type=("build", "run")) + depends_on("py-numpy@1.22:1.28", when="@13:", type=("build", "run")) + + depends_on("py-scipy@1.6:1.12", when="@:12+all", type=("build", "run")) + depends_on("py-scipy@1.7:1.13", when="@13:+all", type=("build", "run")) + depends_on("py-cython@0.29.22:2", when="+all", type=("build", "run")) + depends_on("py-optuna@2:", when="+all", type=("build", "run")) + + # Based on https://github.com/cupy/cupy/releases + depends_on("cuda@:11.9", when="@:11 +cuda") + depends_on("cuda@:12.1", when="@12:12.1.0 +cuda") + depends_on("cuda@:12.4", when="@13:13.4.1 +cuda") + depends_on("cuda@:12.9", when="@13.5.1: +cuda") + + for a in CudaPackage.cuda_arch_values: + depends_on( + "nccl +cuda cuda_arch={0}".format(a), when="+cuda cuda_arch={0}".format(a) + ) + + depends_on("cutensor", when="@:12.1.0 +cuda") + depends_on("cutensor@2.0.1.2", when="@13.1: +cuda") + + for _arch in ROCmPackage.amdgpu_targets: + arch_str = "amdgpu_target={0}".format(_arch) + rocm_str = "+rocm {0}".format(arch_str) + depends_on("rocprim {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocsolver {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocthrust {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("rocrand {0}".format(arch_str), when=rocm_str, type=("link")) + depends_on("hipcub {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipblas {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hiprand {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipsparse {0}".format(rocm_str), when=rocm_str, type=("link")) + depends_on("hipfft {0}".format(rocm_str), when=rocm_str, type=("link")) + + depends_on("rccl", when="+rocm", type=("link")) + depends_on("roctracer-dev", when="+rocm", type=("link")) + depends_on("rocprofiler-dev", when="+rocm", type=("link")) + + conflicts("~cuda ~rocm") + conflicts("+cuda +rocm") + conflicts("+cuda cuda_arch=none") + + def setup_build_environment(self, env): + env.set("CUPY_NUM_BUILD_JOBS", make_jobs) + if self.spec.satisfies("+cuda"): + cuda_arch = self.spec.variants["cuda_arch"].value + arch_str = ";".join( + "arch=compute_{0},code=sm_{0}".format(i) for i in cuda_arch + ) + env.set("CUPY_NVCC_GENERATE_CODE", arch_str) + elif self.spec.satisfies("+rocm"): + spec = self.spec + + incs = { + "roctracer-dev": ["include/roctracer"], + "hiprand": ["include"], + "rocrand": ["include"], + "rocthrust": ["include"], + "rocprim": ["include"], + "hip": ["include", "include/hip"], + } + + inc_dirs = [] + for pkg, ds in incs.items(): + for d in ds: + p = os.path.join(spec[pkg].prefix, d) + if os.path.exists(p): + inc_dirs.append(p) + + env.set("CUPY_INCLUDE_PATH", ":".join(inc_dirs)) + + env.set("HIPCC", self.spec["hip"].hipcc) + env.set("ROCM_HOME", self.spec["hipcub"].prefix) + env.set("CUPY_INSTALL_USE_HIP", 1) diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py new file mode 100644 index 0000000..6941eff --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py @@ -0,0 +1,68 @@ +from spack.package import * + + +def translate_platform(platform_name: str) -> str: + if platform_name == "darwin": + return "apple-darwin" + elif platform_name == "linux": + return "unknown-linux-gnu" + return platform_name + + +def translate_arch(arch_name: str) -> str: + if arch_name in ["m1", "m2", "neoverse_v2"]: + return "aarch64" + if arch_name in ["zen3"]: + return "x86_64" + return arch_name + + +class Uv(Package): + """Install UV from binary releases""" + + url = "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz" + + version( + "0.7.12", + sha256="189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e", + extension=".tar.gz", + ) + version( + "0.7.20", + sha256="675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9", + extension=".tar.gz", + ) + + def url_for_version(self, version): + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + return f"https://github.com/astral-sh/uv/releases/download/{version}/uv-{arch}-{platform}.tar.gz" + + def do_stage(self, mirror_only=False): + checksums = { + ("0.7.12", "apple-darwin", "aarch64"): ( + "189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e" + ), + ("0.7.20", "unknown-linux-gnu", "aarch64"): ( + "675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9" + ), + ("0.7.20", "unknown-linux-gnu", "x86_64"): ( + "10f204426ff188925d22a53c1d0310d190a8d4d24513712e1b8e2ca9873f0666" + ), + } + version = str(self.spec.version) + arch = translate_arch(self.spec.target) + platform = translate_platform(self.spec.platform) + key = (version, platform, arch) + + if key not in checksums: + msg = f"Unsupported platform/arch for version {version}: {platform}-{arch}." + raise InstallError(msg) + + self.fetcher.digest = checksums[key] + super().do_stage(mirror_only) + + def install(self, spec, prefix): + mkdir(prefix.bin) + install("uv", prefix.bin.uv) + install("uvx", prefix.bin.uvx) From 48395bbb92c886a8ed1cf39846fd177c045f1769 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Mon, 8 Dec 2025 14:32:36 +0100 Subject: [PATCH 20/32] builds --- recipes/icon-dsl/25.12/a100/config.yaml | 9 +- recipes/icon-dsl/25.12/a100/environments.yaml | 29 +++-- recipes/icon-dsl/25.12/a100/pre-install | 53 ++++++++- .../25.12/a100/repo/packages/ghex/package.py | 93 --------------- .../hwmalloc/cmake_install_path.patch | 27 ----- .../a100/repo/packages/hwmalloc/package.py | 52 --------- .../a100/repo/packages/icon4py/package.py | 109 ------------------ .../repo/packages/oomph/install_0.2.patch | 102 ---------------- .../repo/packages/oomph/install_0.3.patch | 57 --------- .../25.12/a100/repo/packages/oomph/package.py | 109 ------------------ .../25.12/a100/repo/packages/uv/package.py | 68 ----------- recipes/icon-dsl/25.8/a100/config.yaml | 2 +- recipes/icon-dsl/25.8/a100/environments.yaml | 4 +- recipes/icon/25.2/a100/environments.yaml | 2 +- 14 files changed, 71 insertions(+), 645 deletions(-) delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py delete mode 100644 recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py diff --git a/recipes/icon-dsl/25.12/a100/config.yaml b/recipes/icon-dsl/25.12/a100/config.yaml index fe6d1bc..5f9ad15 100644 --- a/recipes/icon-dsl/25.12/a100/config.yaml +++ b/recipes/icon-dsl/25.12/a100/config.yaml @@ -1,7 +1,6 @@ -name: icon-dsl +name: icon store: /user-environment spack: - repo: https://github.com/spack/spack.git - commit: releases/v0.22 -modules: false -description: Build and runtime dependencies for ICON-DSL + commit: releases/v0.22 + repo: https://github.com/spack/spack.git +description: Compilers and libraries required to build ICON diff --git a/recipes/icon-dsl/25.12/a100/environments.yaml b/recipes/icon-dsl/25.12/a100/environments.yaml index ae80558..bc36f42 100644 --- a/recipes/icon-dsl/25.12/a100/environments.yaml +++ b/recipes/icon-dsl/25.12/a100/environments.yaml @@ -1,22 +1,22 @@ -myenv: +icon: compiler: - - toolchain: gcc - spec: gcc - - toolchain: llvm - spec: nvhpc + - toolchain: gcc + spec: gcc + - toolchain: llvm + spec: nvhpc mpi: - spec: cray-mpich@8.1.30%nvhpc - gpu: cuda + spec: cray-mpich@8.1.30%nvhpc + gpu: cuda + unify: true specs: # icon4py deps - - python@3.11 - - py-cupy +cuda cuda_arch=80 - - ghex +python +cuda cuda_arch=80 - - py-mpi4py - - icon4py@icon_20250328 + # - python@3.11 + # - py-cupy +cuda cuda_arch=80 + # - ghex +python +cuda cuda_arch=80 + # - py-mpi4py + # - icon4py # icon deps - - boost - - cuda@12.4 + - cuda@12.6 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper - cosmo-eccodes-definitions@2.36.0.3 - hdf5%nvhpc +szip +hl +fortran +mpi @@ -34,7 +34,6 @@ myenv: - libfyaml - zlib-ng - cmake - unify: true variants: - +mpi - +cuda diff --git a/recipes/icon-dsl/25.12/a100/pre-install b/recipes/icon-dsl/25.12/a100/pre-install index ba88283..a139f10 100644 --- a/recipes/icon-dsl/25.12/a100/pre-install +++ b/recipes/icon-dsl/25.12/a100/pre-install @@ -1,12 +1,57 @@ #!/bin/bash +set -euo pipefail -packages=("cosmo-eccodes-definitions") -SPACK_C2SM_TAG="v0.22.2.1" +# -------------------------- +# Configuration +# -------------------------- +packages=( + "cosmo-eccodes-definitions" + "ghex" + "hwmalloc" + "oomph" + "uv" + "icon4py" +) +SPACK_C2SM_TAG="v0.22.2.5" -git clone -b ${SPACK_C2SM_TAG} https://github.com/C2SM/spack-c2sm.git +echo "----------------------------------------" +echo "SPACK C2SM Setup Script" +echo "Tag to clone: ${SPACK_C2SM_TAG}" +echo "Packages to copy: ${packages[*]}" +echo "----------------------------------------" +# -------------------------- +# Clone the spack-c2sm repository +# -------------------------- +echo "Cloning spack-c2sm repository (branch/tag: ${SPACK_C2SM_TAG})..." +git clone --depth 1 -b "${SPACK_C2SM_TAG}" https://github.com/C2SM/spack-c2sm.git +echo "Clone complete." + +# -------------------------- +# Copy packages into store/repo/packages +# -------------------------- for package in "${packages[@]}"; do - cp -r spack-c2sm/repos/c2sm/packages/"${package}" store/repo/packages + SRC="spack-c2sm/repos/c2sm/packages/${package}" + DEST="store/repo/packages/${package}" + + echo "Copying package '${package}'..." + + if [[ ! -d "$SRC" ]]; then + echo "ERROR: Source package directory does not exist: $SRC" + exit 1 + fi + + mkdir -p "$(dirname "$DEST")" + cp -r "$SRC" "$DEST" + + echo "Package '${package}' copied to '$DEST'." done +# -------------------------- +# Cleanup +# -------------------------- +echo "Removing temporary clone 'spack-c2sm'..." rm -rf spack-c2sm +echo "Cleanup complete." + +echo "All done!" diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py deleted file mode 100644 index 8f50e28..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/ghex/package.py +++ /dev/null @@ -1,93 +0,0 @@ -from spack.package import * - - -class Ghex(CMakePackage, CudaPackage, ROCmPackage): - """GHEX is a generic halo-exchange library.""" - - homepage = "https://github.com/ghex-org/GHEX" - url = "https://github.com/ghex-org/GHEX/archive/refs/tags/v0.3.0.tar.gz" - git = "https://github.com/ghex-org/GHEX.git" - maintainers = ["boeschf"] - - version("0.4.1", tag="v0.4.1", submodules=True) - version("0.4.0", tag="v0.4.0", submodules=True) - version("0.3.0", tag="v0.3.0", submodules=True) - version("master", branch="master", submodules=True) - - depends_on("cxx", type="build") - - generator("ninja") - - backends = ("mpi", "ucx", "libfabric") - variant( - "backend", - default="mpi", - description="Transport backend", - values=backends, - multi=False, - ) - variant("xpmem", default=False, description="Use xpmem shared memory") - variant("python", default=True, description="Build Python bindings") - - depends_on("cmake@3.21:", type="build") - depends_on("mpi") - depends_on("boost") - depends_on("xpmem", when="+xpmem", type=("build", "run")) - - depends_on("oomph") - for backend in backends: - depends_on(f"oomph backend={backend}", when=f"backend={backend}") - depends_on("oomph+cuda", when="+cuda") - depends_on("oomph+rocm", when="+rocm") - depends_on("oomph@0.3:", when="@0.3:") - - conflicts("+cuda+rocm") - - with when("+python"): - extends("python") - depends_on("python@3.7:", type="build") - depends_on("py-pip", type="build") - depends_on("py-pybind11", type="build") - depends_on("py-mpi4py", type=("build", "run")) - depends_on("py-numpy", type=("build", "run")) - - depends_on("py-pytest", when="+python", type=("test")) - - def cmake_args(self): - spec = self.spec - - args = [ - self.define("GHEX_USE_BUNDLED_LIBS", True), - self.define("GHEX_USE_BUNDLED_GRIDTOOLS", True), - self.define("GHEX_USE_BUNDLED_GTEST", self.run_tests), - self.define("GHEX_USE_BUNDLED_OOMPH", False), - self.define( - "GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper() - ), - self.define_from_variant("GHEX_USE_XPMEM", "xpmem"), - self.define_from_variant("GHEX_BUILD_PYTHON_BINDINGS", "python"), - self.define("GHEX_WITH_TESTING", self.run_tests), - ] - - if spec.satisfies("+python"): - args.append(self.define("GHEX_PYTHON_LIB_PATH", python_platlib)) - - if self.run_tests and spec.satisfies("^openmpi"): - args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) - - if "+cuda" in spec and spec.variants["cuda_arch"].value != "none": - arch_str = ";".join(spec.variants["cuda_arch"].value) - args.append(self.define("CMAKE_CUDA_ARCHITECTURES", arch_str)) - args.append(self.define("GHEX_USE_GPU", True)) - args.append(self.define("GHEX_GPU_TYPE", "NVIDIA")) - - if "+rocm" in spec and spec.variants["amdgpu_target"].value != "none": - arch_str = ";".join(spec.variants["amdgpu_target"].value) - args.append(self.define("CMAKE_HIP_ARCHITECTURES", arch_str)) - args.append(self.define("GHEX_USE_GPU", True)) - args.append(self.define("GHEX_GPU_TYPE", "AMD")) - - if spec.satisfies("~cuda~rocm"): - args.append(self.define("GHEX_USE_GPU", False)) - - return args diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch deleted file mode 100644 index fa6fde1..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/cmake_install_path.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index d5420e0..35dbe56 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -105,11 +105,11 @@ install(FILES ${PROJECT_BINARY_DIR}/include/hwmalloc/config.hpp - install(EXPORT HWMALLOC-targets - FILE HWMALLOC-targets.cmake - NAMESPACE HWMALLOC:: -- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) - - configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HWMALLOCConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfig.cmake -- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) - - write_basic_package_version_file(HWMALLOCConfigVersion.cmake - VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) -@@ -120,7 +120,7 @@ install( - ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfigVersion.cmake - ${CMAKE_CURRENT_LIST_DIR}/cmake/FindNUMA.cmake - DESTINATION -- ${CMAKE_INSTALL_LIBDIR}/cmake) -+ ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) - - export(EXPORT HWMALLOC-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/HWMALLOC-targets.cmake") diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py deleted file mode 100644 index c656dc1..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/hwmalloc/package.py +++ /dev/null @@ -1,52 +0,0 @@ -from spack.package import * - - -class Hwmalloc(CMakePackage, CudaPackage, ROCmPackage): - """HWMALLOC is a allocator which supports memory registration for e.g. remote memory access""" - - homepage = "https://github.com/ghex-org/hwmalloc" - url = "https://github.com/ghex-org/hwmalloc/archive/refs/tags/v0.3.0.tar.gz" - git = "https://github.com/ghex-org/hwmalloc.git" - maintainers = ["boeschf"] - - version("0.3.0", sha256="d4d4ac6087a806600d79fb62c02719ca3d58a412968fe1ef4a2fd58d9e7ee950") - version("0.2.0", sha256="734758a390a3258b86307e4aef50a7ca2e5d0e2e579f18aeefcd05397e114419") - version("0.1.0", sha256="06e9bfcef0ecce4d19531ccbe03592b502d1281c7a092bc0ff51ca187899b21c") - version("master", branch="master") - - depends_on("cxx", type="build") - - generator("ninja") - - depends_on("numactl", type=("build", "run")) - depends_on("boost", type=("build")) - depends_on("cmake@3.19:", type="build") - - variant( - "numa-throws", - default=False, - description="True if numa_tools may throw during initialization", - ) - variant("numa-local", default=True, description="Use numa_tools for local node allocations") - variant("logging", default=False, description="print logging info to cerr") - - patch("cmake_install_path.patch", when="@:0.3.0", level=1) - - def cmake_args(self): - args = [ - self.define_from_variant("HWMALLOC_NUMA_THROWS", "numa-throws"), - self.define_from_variant("HWMALLOC_NUMA_FOR_LOCAL", "numa-local"), - self.define_from_variant("HWMALLOC_ENABLE_LOGGING", "logging"), - self.define("HWMALLOC_WITH_TESTING", self.run_tests), - ] - - if "+cuda" in self.spec: - args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) - args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "cuda")) - elif "+rocm" in self.spec: - args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) - args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "hip")) - else: - args.append(self.define("HWMALLOC_ENABLE_DEVICE", False)) - - return args diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py deleted file mode 100644 index 9ee413e..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/icon4py/package.py +++ /dev/null @@ -1,109 +0,0 @@ -import json -import os -import pathlib - -import llnl -from llnl.util import tty -from spack import * - - -class Icon4py(Package): - extends("python") - depends_on("python@3.11:") - - depends_on("git") - depends_on("boost@1.85:+mpi+python", type=("build", "run")) - depends_on("uv@0.7:", type="build") - depends_on("bzip2", type="build") - depends_on("py-numpy") - depends_on("py-cffi") - depends_on("py-pybind11") - depends_on("py-nanobind") - depends_on("py-mpi4py") - depends_on("py-cupy +cuda") - depends_on("ghex +python +cuda") - - version( - "icon_20250328", - sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", - extension="zip", - ) - - def url_for_version(self, version): - return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" - - def install(self, spec, prefix): - uv = prepare_uv() - python_spec = spec["python"] - venv_path = prefix.share.venv - - tty.msg(f"creating venv using spack python at: {python_spec.command.path}") - uv( - "venv", - "--seed", - "--relocatable", - "--system-site-packages", - str(venv_path), - "--python", - python_spec.command.path, - ) - - tty.msg(f"grabbing spack installed packages (distributions)") - pip = Executable(venv_path.bin.pip) - spack_installed = get_installed_pkg(pip) - - tty.msg(f"installing missing packages") - uv( - "sync", - "--active", - "--extra", - "all", - "--extra", - "cuda12", - "--inexact", - "--no-editable", - "--python", - str(venv_path.bin.python), - *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), - extra_env={"VIRTUAL_ENV": str(venv_path)}, - ) - - tty.msg(f"linking spack installed packages into venv") - pathlib.Path( - f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" - ).write_text(pythonpath_to_pth()) - - tty.msg(f"running py2fgen") - py2fgen = Executable(venv_path.bin.py2fgen) - py2fgen( - "icon4py.tools.py2fgen.wrappers.all_bindings", - "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", - "icon4py_bindings", - "-o", - prefix.src, - extra_env={"VIRTUAL_ENV": str(venv_path)}, - ) - - -def prepare_uv(): - uv = which("uv") - uv.add_default_env("UV_NO_CACHE", "true") - uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") - uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") - return uv - - -def get_installed_pkg(pip): - return [ - item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) - ] - - -def no_install_options(installed): - for name in installed: - yield "--no-install-package" - yield name - - -def pythonpath_to_pth(): - return "\n".join(os.environ["PYTHONPATH"].split(":")) diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch deleted file mode 100644 index 5dc7e2e..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.2.patch +++ /dev/null @@ -1,102 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index ba19089..2ba222a 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -1,6 +1,12 @@ - cmake_minimum_required(VERSION 3.17) - # CMake version is set at 3.17 because of find_package(CUDAToolkit) - -+if (NOT ${CMAKE_VERSION} VERSION_LESS 3.27) -+ # new in 3.27: additionally use uppercase _ROOT -+ # environment and CMake variables for find_package -+ cmake_policy(SET CMP0144 NEW) -+endif() -+ - set(OOMPH_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - list(APPEND CMAKE_MODULE_PATH "${OOMPH_MODULE_PATH}") - -@@ -108,11 +114,11 @@ endif() - install(EXPORT oomph-targets - FILE oomph-targets.cmake - NAMESPACE oomph:: -- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) - - configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/oomphConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/oomphConfig.cmake -- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) - - write_basic_package_version_file(oomphConfigVersion.cmake - VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) -@@ -125,7 +131,7 @@ install( - ${CMAKE_CURRENT_LIST_DIR}/cmake/FindUCX.cmake - ${CMAKE_CURRENT_LIST_DIR}/cmake/FindPMIx.cmake - DESTINATION -- ${CMAKE_INSTALL_LIBDIR}/cmake) -+ ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) - - export(EXPORT oomph-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/oomph-targets.cmake") -diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake -index ec672b5..a578ef5 100644 ---- a/cmake/oomph_external_dependencies.cmake -+++ b/cmake/oomph_external_dependencies.cmake -@@ -31,17 +31,30 @@ endif() - # --------------------------------------------------------------------- - # google test setup - # --------------------------------------------------------------------- --add_external_cmake_project( -- NAME googletest -- PATH ext/googletest -- INTERFACE_NAME ext-gtest -- LIBS libgtest.a libgtest_main.a -- CMAKE_ARGS -- "-DCMAKE_BUILD_TYPE=release" -- "-DBUILD_SHARED_LIBS=OFF" -- "-DBUILD_GMOCK=OFF") --# on some systems we need link explicitly against threads --if (TARGET ext-gtest) -- find_package (Threads) -- target_link_libraries(ext-gtest INTERFACE Threads::Threads) -+cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON -+ "OOMPH_USE_BUNDLED_LIBS" OFF) -+if (OOMPH_WITH_TESTING) -+ if(OOMPH_USE_BUNDLED_GTEST) -+ add_external_cmake_project( -+ NAME googletest -+ PATH ext/googletest -+ INTERFACE_NAME ext-gtest -+ LIBS libgtest.a libgtest_main.a -+ CMAKE_ARGS -+ "-DCMAKE_BUILD_TYPE=release" -+ "-DBUILD_SHARED_LIBS=OFF" -+ "-DBUILD_GMOCK=OFF") -+ # on some systems we need link explicitly against threads -+ if (TARGET ext-gtest) -+ find_package (Threads) -+ target_link_libraries(ext-gtest INTERFACE Threads::Threads) -+ endif() -+ else() -+ # Use system provided google test -+ find_package(GTest REQUIRED) -+ add_library(ext-gtest INTERFACE) -+ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") -+ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) -+ else() -+ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) -+ endif() -+ endif() - endif() -diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt -index 06d703a..5217bba 100644 ---- a/test/CMakeLists.txt -+++ b/test/CMakeLists.txt -@@ -65,6 +65,7 @@ function(reg_parallel_test t_ lib n) - NAME ${t} - COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${n} ${MPIEXEC_PREFLAGS} - $ ${MPIEXEC_POSTFLAGS}) -+ set_tests_properties(${t} PROPERTIES RUN_SERIAL TRUE) - endfunction() - - if (OOMPH_WITH_MPI) diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch deleted file mode 100644 index aac73e8..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/install_0.3.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake -index a578ef5..92de39b 100644 ---- a/cmake/oomph_external_dependencies.cmake -+++ b/cmake/oomph_external_dependencies.cmake -@@ -33,28 +33,30 @@ endif() - # --------------------------------------------------------------------- - cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON - "OOMPH_USE_BUNDLED_LIBS" OFF) --if(OOMPH_USE_BUNDLED_GTEST) -- add_external_cmake_project( -- NAME googletest -- PATH ext/googletest -- INTERFACE_NAME ext-gtest -- LIBS libgtest.a libgtest_main.a -- CMAKE_ARGS -- "-DCMAKE_BUILD_TYPE=release" -- "-DBUILD_SHARED_LIBS=OFF" -- "-DBUILD_GMOCK=OFF") -- # on some systems we need link explicitly against threads -- if (TARGET ext-gtest) -- find_package (Threads) -- target_link_libraries(ext-gtest INTERFACE Threads::Threads) -- endif() --else() -- # Use system provided google test -- find_package(GTest REQUIRED) -- add_library(ext-gtest INTERFACE) -- if (${CMAKE_VERSION} VERSION_LESS "3.20.0") -- target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) -+if (OOMPH_WITH_TESTING) -+ if(OOMPH_USE_BUNDLED_GTEST) -+ add_external_cmake_project( -+ NAME googletest -+ PATH ext/googletest -+ INTERFACE_NAME ext-gtest -+ LIBS libgtest.a libgtest_main.a -+ CMAKE_ARGS -+ "-DCMAKE_BUILD_TYPE=release" -+ "-DBUILD_SHARED_LIBS=OFF" -+ "-DBUILD_GMOCK=OFF") -+ # on some systems we need link explicitly against threads -+ if (TARGET ext-gtest) -+ find_package (Threads) -+ target_link_libraries(ext-gtest INTERFACE Threads::Threads) -+ endif() - else() -- target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) -+ # Use system provided google test -+ find_package(GTest REQUIRED) -+ add_library(ext-gtest INTERFACE) -+ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") -+ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) -+ else() -+ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) -+ endif() - endif() - endif() diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py deleted file mode 100644 index 3b320f9..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/oomph/package.py +++ /dev/null @@ -1,109 +0,0 @@ -from spack.package import * - - -class Oomph(CMakePackage, CudaPackage, ROCmPackage): - """Oomph is a non-blocking callback-based point-to-point communication library.""" - - homepage = "https://github.com/ghex-org/oomph" - url = "https://github.com/ghex-org/oomph/archive/refs/tags/v0.2.0.tar.gz" - git = "https://github.com/ghex-org/oomph.git" - maintainers = ["boeschf"] - - version("0.4.0", sha256="e342c872dfe4832be047f172dc55c12951950c79da2630b071c61607ef913144") - version("0.3.0", sha256="61e346d1ba28a859745de47f37edce39c7f5c5e1aab716493dc964e158fd99ec") - version("0.2.0", sha256="135cdb856aa817c053b6af1617869dbcd0ee97d34607e78874dd775ea389434e") - version("0.1.0", sha256="0ff36db0a5f30ae1bb02f6db6d411ea72eadd89688c00f76b4e722bd5a9ba90b") - version("main", branch="main") - - depends_on("cxx", type="build") - depends_on("fortran", type="build", when="+fortran-bindings") - - generator("ninja") - - backends = ("mpi", "ucx", "libfabric") - variant( - "backend", default="mpi", description="Transport backend", values=backends, multi=False - ) - - variant("fortran-bindings", default=False, description="Build Fortran bindings") - with when("+fortran-bindings"): - variant( - "fortran-fp", - default="float", - description="Floating point type", - values=("float", "double"), - multi=False, - ) - variant("fortran-openmp", default=True, description="Compile with OpenMP") - - variant( - "enable-barrier", - default=True, - description="Enable thread barrier (disable for task based runtime)", - ) - - depends_on("hwmalloc+cuda", when="+cuda") - depends_on("hwmalloc+rocm", when="+rocm") - depends_on("hwmalloc", when="~cuda~rocm") - - with when("backend=ucx"): - depends_on("ucx+thread_multiple") - depends_on("ucx+cuda", when="+cuda") - depends_on("ucx+rocm", when="+rocm") - variant("use-pmix", default="False", description="Use PMIx to establish out-of-band setup") - variant("use-spin-lock", default="False", description="Use pthread spin locks") - depends_on("pmix", when="+use-pmix") - - libfabric_providers = ("cxi", "efa", "gni", "psm2", "tcp", "verbs") - with when("backend=libfabric"): - variant( - "libfabric-provider", - default="tcp", - description="fabric", - values=libfabric_providers, - multi=False, - ) - for provider in libfabric_providers: - depends_on(f"libfabric fabrics={provider}", when=f"libfabric-provider={provider}") - - depends_on("mpi") - depends_on("boost+thread") - - depends_on("googletest", type=("build","test")) - - patch("install_0.2.patch", when="@:0.2.0", level=1) - patch("install_0.3.patch", when="@0.3.0", level=1) - - def cmake_args(self): - args = [ - self.define_from_variant("OOMPH_BUILD_FORTRAN", "fortran-bindings"), - self.define_from_variant("OOMPH_FORTRAN_OPENMP", "fortran-openmp"), - self.define_from_variant("OOMPH_UCX_USE_PMI", "use-pmix"), - self.define_from_variant("OOMPH_UCX_USE_SPIN_LOCK", "use-spin-lock"), - self.define_from_variant("OOMPH_ENABLE_BARRIER", "enable-barrier"), - self.define("OOMPH_WITH_TESTING", self.run_tests), - self.define("OOMPH_GIT_SUBMODULE", False), - self.define("OOMPH_USE_BUNDLED_LIBS", False), - ] - - if self.run_tests and self.spec.satisfies("^openmpi"): - args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) - - if self.spec.variants["fortran-bindings"].value == True: - args.append(self.define("OOMPH_FORTRAN_FP", self.spec.variants["fortran-fp"].value)) - - for backend in self.backends: - args.append( - self.define( - f"OOMPH_WITH_{backend.upper()}", self.spec.variants["backend"].value == backend - ) - ) - - if self.spec.satisfies("backend=libfabric"): - args.append( - self.define( - "OOMPH_LIBFABRIC_PROVIDER", self.spec.variants["libfabric-provider"].value - ) - ) - - return args diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py deleted file mode 100644 index 6941eff..0000000 --- a/recipes/icon-dsl/25.12/a100/repo/packages/uv/package.py +++ /dev/null @@ -1,68 +0,0 @@ -from spack.package import * - - -def translate_platform(platform_name: str) -> str: - if platform_name == "darwin": - return "apple-darwin" - elif platform_name == "linux": - return "unknown-linux-gnu" - return platform_name - - -def translate_arch(arch_name: str) -> str: - if arch_name in ["m1", "m2", "neoverse_v2"]: - return "aarch64" - if arch_name in ["zen3"]: - return "x86_64" - return arch_name - - -class Uv(Package): - """Install UV from binary releases""" - - url = "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz" - - version( - "0.7.12", - sha256="189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e", - extension=".tar.gz", - ) - version( - "0.7.20", - sha256="675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9", - extension=".tar.gz", - ) - - def url_for_version(self, version): - arch = translate_arch(self.spec.target) - platform = translate_platform(self.spec.platform) - return f"https://github.com/astral-sh/uv/releases/download/{version}/uv-{arch}-{platform}.tar.gz" - - def do_stage(self, mirror_only=False): - checksums = { - ("0.7.12", "apple-darwin", "aarch64"): ( - "189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e" - ), - ("0.7.20", "unknown-linux-gnu", "aarch64"): ( - "675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9" - ), - ("0.7.20", "unknown-linux-gnu", "x86_64"): ( - "10f204426ff188925d22a53c1d0310d190a8d4d24513712e1b8e2ca9873f0666" - ), - } - version = str(self.spec.version) - arch = translate_arch(self.spec.target) - platform = translate_platform(self.spec.platform) - key = (version, platform, arch) - - if key not in checksums: - msg = f"Unsupported platform/arch for version {version}: {platform}-{arch}." - raise InstallError(msg) - - self.fetcher.digest = checksums[key] - super().do_stage(mirror_only) - - def install(self, spec, prefix): - mkdir(prefix.bin) - install("uv", prefix.bin.uv) - install("uvx", prefix.bin.uvx) diff --git a/recipes/icon-dsl/25.8/a100/config.yaml b/recipes/icon-dsl/25.8/a100/config.yaml index ac4ba9c..fe6d1bc 100644 --- a/recipes/icon-dsl/25.8/a100/config.yaml +++ b/recipes/icon-dsl/25.8/a100/config.yaml @@ -2,6 +2,6 @@ name: icon-dsl store: /user-environment spack: repo: https://github.com/spack/spack.git - commit: releases/v0.23 + commit: releases/v0.22 modules: false description: Build and runtime dependencies for ICON-DSL diff --git a/recipes/icon-dsl/25.8/a100/environments.yaml b/recipes/icon-dsl/25.8/a100/environments.yaml index 3a399e0..ae80558 100644 --- a/recipes/icon-dsl/25.8/a100/environments.yaml +++ b/recipes/icon-dsl/25.8/a100/environments.yaml @@ -10,8 +10,8 @@ myenv: specs: # icon4py deps - python@3.11 - - py-cupy +cuda cuda_arch=90 - - ghex +python +cuda cuda_arch=90 + - py-cupy +cuda cuda_arch=80 + - ghex +python +cuda cuda_arch=80 - py-mpi4py - icon4py@icon_20250328 # icon deps diff --git a/recipes/icon/25.2/a100/environments.yaml b/recipes/icon/25.2/a100/environments.yaml index 49deeb7..9a4aa6e 100644 --- a/recipes/icon/25.2/a100/environments.yaml +++ b/recipes/icon/25.2/a100/environments.yaml @@ -19,7 +19,7 @@ icon: - netcdf-cxx4@4.3.1%nvhpc - netcdf-fortran@4.6.1%nvhpc - osu-micro-benchmarks@5.9%nvhpc - - openblas + - openblas@0.3.21%nvhpc # for validation - cdo # everything needed for nccl on SS11 From 9a5324918c4c6e897ef0cf7f20787a009afc7489 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Mon, 8 Dec 2025 15:08:05 +0100 Subject: [PATCH 21/32] revert --- recipes/icon/25.2/a100/environments.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/icon/25.2/a100/environments.yaml b/recipes/icon/25.2/a100/environments.yaml index 9a4aa6e..49deeb7 100644 --- a/recipes/icon/25.2/a100/environments.yaml +++ b/recipes/icon/25.2/a100/environments.yaml @@ -19,7 +19,7 @@ icon: - netcdf-cxx4@4.3.1%nvhpc - netcdf-fortran@4.6.1%nvhpc - osu-micro-benchmarks@5.9%nvhpc - - openblas@0.3.21%nvhpc + - openblas # for validation - cdo # everything needed for nccl on SS11 From b35b3e3b07603105cf87a71ac45f29019e55dc99 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Mon, 8 Dec 2025 17:18:31 +0100 Subject: [PATCH 22/32] wip --- recipes/icon-dsl/25.12/a100/environments.yaml | 11 ++++++----- recipes/icon-dsl/25.8/a100/config.yaml | 2 +- recipes/icon-dsl/25.8/a100/environments.yaml | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/recipes/icon-dsl/25.12/a100/environments.yaml b/recipes/icon-dsl/25.12/a100/environments.yaml index bc36f42..587ebcb 100644 --- a/recipes/icon-dsl/25.12/a100/environments.yaml +++ b/recipes/icon-dsl/25.12/a100/environments.yaml @@ -10,13 +10,14 @@ icon: unify: true specs: # icon4py deps - # - python@3.11 - # - py-cupy +cuda cuda_arch=80 - # - ghex +python +cuda cuda_arch=80 + - python@3.11 + - py-cupy@13.1.0%gcc +cuda cuda_arch=80 + - cutensor@2.0.1.2%gcc + - ghex +python +cuda cuda_arch=80 # - py-mpi4py # - icon4py # icon deps - - cuda@12.6 + - cuda@12.4 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper - cosmo-eccodes-definitions@2.36.0.3 - hdf5%nvhpc +szip +hl +fortran +mpi @@ -24,7 +25,7 @@ icon: - netcdf-cxx4@4.3.1%nvhpc - netcdf-fortran@4.6.1%nvhpc - osu-micro-benchmarks@5.9%nvhpc - - openblas + - openblas@0.3.21%nvhpc # for validation - cdo # everything needed for nccl on SS11 diff --git a/recipes/icon-dsl/25.8/a100/config.yaml b/recipes/icon-dsl/25.8/a100/config.yaml index fe6d1bc..ac4ba9c 100644 --- a/recipes/icon-dsl/25.8/a100/config.yaml +++ b/recipes/icon-dsl/25.8/a100/config.yaml @@ -2,6 +2,6 @@ name: icon-dsl store: /user-environment spack: repo: https://github.com/spack/spack.git - commit: releases/v0.22 + commit: releases/v0.23 modules: false description: Build and runtime dependencies for ICON-DSL diff --git a/recipes/icon-dsl/25.8/a100/environments.yaml b/recipes/icon-dsl/25.8/a100/environments.yaml index ae80558..3a399e0 100644 --- a/recipes/icon-dsl/25.8/a100/environments.yaml +++ b/recipes/icon-dsl/25.8/a100/environments.yaml @@ -10,8 +10,8 @@ myenv: specs: # icon4py deps - python@3.11 - - py-cupy +cuda cuda_arch=80 - - ghex +python +cuda cuda_arch=80 + - py-cupy +cuda cuda_arch=90 + - ghex +python +cuda cuda_arch=90 - py-mpi4py - icon4py@icon_20250328 # icon deps From fbc299b32cc81da51089ea9d9b65f885d799461d Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Tue, 9 Dec 2025 13:59:27 +0100 Subject: [PATCH 23/32] add all spack-c2sm packages --- recipes/icon-dsl/25.12/a100/pre-install | 2 ++ 1 file changed, 2 insertions(+) diff --git a/recipes/icon-dsl/25.12/a100/pre-install b/recipes/icon-dsl/25.12/a100/pre-install index a139f10..555b4fa 100644 --- a/recipes/icon-dsl/25.12/a100/pre-install +++ b/recipes/icon-dsl/25.12/a100/pre-install @@ -11,6 +11,8 @@ packages=( "oomph" "uv" "icon4py" + "icon" + "icon-exclaim" ) SPACK_C2SM_TAG="v0.22.2.5" From d0703fa4860b43e5fcef8fb2f0bef92e1bc15e3a Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Wed, 10 Dec 2025 11:25:33 +0100 Subject: [PATCH 24/32] revert --- recipes/icon-dsl/25.12/a100/config.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/recipes/icon-dsl/25.12/a100/config.yaml b/recipes/icon-dsl/25.12/a100/config.yaml index 5f9ad15..ac4ba9c 100644 --- a/recipes/icon-dsl/25.12/a100/config.yaml +++ b/recipes/icon-dsl/25.12/a100/config.yaml @@ -1,6 +1,7 @@ -name: icon +name: icon-dsl store: /user-environment spack: - commit: releases/v0.22 - repo: https://github.com/spack/spack.git -description: Compilers and libraries required to build ICON + repo: https://github.com/spack/spack.git + commit: releases/v0.23 +modules: false +description: Build and runtime dependencies for ICON-DSL From 5376273cd009e9497401227b9c826fdd8017c768 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Wed, 10 Dec 2025 11:31:49 +0100 Subject: [PATCH 25/32] first minimal pre-install --- recipes/icon-dsl/25.12/a100/pre-install | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/recipes/icon-dsl/25.12/a100/pre-install b/recipes/icon-dsl/25.12/a100/pre-install index 555b4fa..78fa3ca 100644 --- a/recipes/icon-dsl/25.12/a100/pre-install +++ b/recipes/icon-dsl/25.12/a100/pre-install @@ -6,13 +6,13 @@ set -euo pipefail # -------------------------- packages=( "cosmo-eccodes-definitions" - "ghex" - "hwmalloc" - "oomph" - "uv" - "icon4py" - "icon" - "icon-exclaim" + # "ghex" + # "hwmalloc" + # "oomph" + # "uv" + # "icon4py" + # "icon" + # "icon-exclaim" ) SPACK_C2SM_TAG="v0.22.2.5" From 89771f9ffdace055d618508c8a4c956f480c4d45 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Wed, 10 Dec 2025 12:00:13 +0100 Subject: [PATCH 26/32] new pre-install --- recipes/icon-dsl/25.12/gh200/pre-install | 55 ++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/recipes/icon-dsl/25.12/gh200/pre-install b/recipes/icon-dsl/25.12/gh200/pre-install index ba88283..78fa3ca 100644 --- a/recipes/icon-dsl/25.12/gh200/pre-install +++ b/recipes/icon-dsl/25.12/gh200/pre-install @@ -1,12 +1,59 @@ #!/bin/bash +set -euo pipefail -packages=("cosmo-eccodes-definitions") -SPACK_C2SM_TAG="v0.22.2.1" +# -------------------------- +# Configuration +# -------------------------- +packages=( + "cosmo-eccodes-definitions" + # "ghex" + # "hwmalloc" + # "oomph" + # "uv" + # "icon4py" + # "icon" + # "icon-exclaim" +) +SPACK_C2SM_TAG="v0.22.2.5" -git clone -b ${SPACK_C2SM_TAG} https://github.com/C2SM/spack-c2sm.git +echo "----------------------------------------" +echo "SPACK C2SM Setup Script" +echo "Tag to clone: ${SPACK_C2SM_TAG}" +echo "Packages to copy: ${packages[*]}" +echo "----------------------------------------" +# -------------------------- +# Clone the spack-c2sm repository +# -------------------------- +echo "Cloning spack-c2sm repository (branch/tag: ${SPACK_C2SM_TAG})..." +git clone --depth 1 -b "${SPACK_C2SM_TAG}" https://github.com/C2SM/spack-c2sm.git +echo "Clone complete." + +# -------------------------- +# Copy packages into store/repo/packages +# -------------------------- for package in "${packages[@]}"; do - cp -r spack-c2sm/repos/c2sm/packages/"${package}" store/repo/packages + SRC="spack-c2sm/repos/c2sm/packages/${package}" + DEST="store/repo/packages/${package}" + + echo "Copying package '${package}'..." + + if [[ ! -d "$SRC" ]]; then + echo "ERROR: Source package directory does not exist: $SRC" + exit 1 + fi + + mkdir -p "$(dirname "$DEST")" + cp -r "$SRC" "$DEST" + + echo "Package '${package}' copied to '$DEST'." done +# -------------------------- +# Cleanup +# -------------------------- +echo "Removing temporary clone 'spack-c2sm'..." rm -rf spack-c2sm +echo "Cleanup complete." + +echo "All done!" From 27d4d4bd52280fb810c6b552ed8c697705a60533 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Wed, 10 Dec 2025 13:13:10 +0100 Subject: [PATCH 27/32] More --- recipes/icon-dsl/25.12/a100/pre-install | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/icon-dsl/25.12/a100/pre-install b/recipes/icon-dsl/25.12/a100/pre-install index 78fa3ca..69750f5 100644 --- a/recipes/icon-dsl/25.12/a100/pre-install +++ b/recipes/icon-dsl/25.12/a100/pre-install @@ -7,9 +7,9 @@ set -euo pipefail packages=( "cosmo-eccodes-definitions" # "ghex" - # "hwmalloc" - # "oomph" - # "uv" + "hwmalloc" + "oomph" + "uv" # "icon4py" # "icon" # "icon-exclaim" From 6d90f91420901984f90ecce7d90ed49d761892ab Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Wed, 10 Dec 2025 14:18:36 +0100 Subject: [PATCH 28/32] almost there --- recipes/icon-dsl/25.12/a100/environments.yaml | 9 ++++----- recipes/icon-dsl/25.12/a100/pre-install | 2 +- recipes/icon-dsl/25.8/a100/environments.yaml | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/recipes/icon-dsl/25.12/a100/environments.yaml b/recipes/icon-dsl/25.12/a100/environments.yaml index 587ebcb..6ff89b0 100644 --- a/recipes/icon-dsl/25.12/a100/environments.yaml +++ b/recipes/icon-dsl/25.12/a100/environments.yaml @@ -11,11 +11,10 @@ icon: specs: # icon4py deps - python@3.11 - - py-cupy@13.1.0%gcc +cuda cuda_arch=80 - - cutensor@2.0.1.2%gcc + - py-cupy +cuda cuda_arch=80 - ghex +python +cuda cuda_arch=80 - # - py-mpi4py - # - icon4py + - py-mpi4py + - icon4py@icon_20250328 # icon deps - cuda@12.4 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper @@ -25,7 +24,7 @@ icon: - netcdf-cxx4@4.3.1%nvhpc - netcdf-fortran@4.6.1%nvhpc - osu-micro-benchmarks@5.9%nvhpc - - openblas@0.3.21%nvhpc + - openblas # for validation - cdo # everything needed for nccl on SS11 diff --git a/recipes/icon-dsl/25.12/a100/pre-install b/recipes/icon-dsl/25.12/a100/pre-install index 69750f5..93c3f79 100644 --- a/recipes/icon-dsl/25.12/a100/pre-install +++ b/recipes/icon-dsl/25.12/a100/pre-install @@ -6,7 +6,7 @@ set -euo pipefail # -------------------------- packages=( "cosmo-eccodes-definitions" - # "ghex" + "ghex" "hwmalloc" "oomph" "uv" diff --git a/recipes/icon-dsl/25.8/a100/environments.yaml b/recipes/icon-dsl/25.8/a100/environments.yaml index 3a399e0..ae80558 100644 --- a/recipes/icon-dsl/25.8/a100/environments.yaml +++ b/recipes/icon-dsl/25.8/a100/environments.yaml @@ -10,8 +10,8 @@ myenv: specs: # icon4py deps - python@3.11 - - py-cupy +cuda cuda_arch=90 - - ghex +python +cuda cuda_arch=90 + - py-cupy +cuda cuda_arch=80 + - ghex +python +cuda cuda_arch=80 - py-mpi4py - icon4py@icon_20250328 # icon deps From 423d444adceaa0a7441c09b2c229bf4e4c022d51 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Wed, 10 Dec 2025 16:01:37 +0100 Subject: [PATCH 29/32] icon4py kind of works --- recipes/icon-dsl/25.12/a100/environments.yaml | 2 +- recipes/icon-dsl/25.12/a100/pre-install | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/icon-dsl/25.12/a100/environments.yaml b/recipes/icon-dsl/25.12/a100/environments.yaml index 6ff89b0..d8b2aff 100644 --- a/recipes/icon-dsl/25.12/a100/environments.yaml +++ b/recipes/icon-dsl/25.12/a100/environments.yaml @@ -14,7 +14,7 @@ icon: - py-cupy +cuda cuda_arch=80 - ghex +python +cuda cuda_arch=80 - py-mpi4py - - icon4py@icon_20250328 + - icon4py@main # icon deps - cuda@12.4 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper diff --git a/recipes/icon-dsl/25.12/a100/pre-install b/recipes/icon-dsl/25.12/a100/pre-install index 93c3f79..2f66fd6 100644 --- a/recipes/icon-dsl/25.12/a100/pre-install +++ b/recipes/icon-dsl/25.12/a100/pre-install @@ -10,7 +10,7 @@ packages=( "hwmalloc" "oomph" "uv" - # "icon4py" + "icon4py" # "icon" # "icon-exclaim" ) From 8f8f1a6bf4d449b50b7a1b92424d7f32642012d5 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Tue, 16 Dec 2025 09:23:19 +0100 Subject: [PATCH 30/32] include icon-exclaim --- recipes/icon-dsl/25.12/a100/environments.yaml | 3 + .../repo/packages/icon-exclaim/package.py | 454 ++++++++++++++++++ 2 files changed, 457 insertions(+) create mode 100755 recipes/icon-dsl/25.12/a100/repo/packages/icon-exclaim/package.py diff --git a/recipes/icon-dsl/25.12/a100/environments.yaml b/recipes/icon-dsl/25.12/a100/environments.yaml index d8b2aff..1100d81 100644 --- a/recipes/icon-dsl/25.12/a100/environments.yaml +++ b/recipes/icon-dsl/25.12/a100/environments.yaml @@ -15,6 +15,9 @@ icon: - ghex +python +cuda cuda_arch=80 - py-mpi4py - icon4py@main + - icon-exclaim @develop %nvhpc dsl=substitute +grib2 +eccodes-definitions +ecrad + ~emvorado +art +dace gpu=nvidia-80 +mpi-gpu +realloc-buf ~aes ~jsbach ~ocean ~coupling + ~rte-rrtmgp ~loop-exchange ~async-io-rma ~cuda-graphs fflags="-traceback" # icon deps - cuda@12.4 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper diff --git a/recipes/icon-dsl/25.12/a100/repo/packages/icon-exclaim/package.py b/recipes/icon-dsl/25.12/a100/repo/packages/icon-exclaim/package.py new file mode 100755 index 0000000..ab78bf1 --- /dev/null +++ b/recipes/icon-dsl/25.12/a100/repo/packages/icon-exclaim/package.py @@ -0,0 +1,454 @@ +from spack.pkg.builtin.icon import Icon as SpackIcon +import os +import re +import glob +from collections import defaultdict +from llnl.util import tty +from spack.util.environment import is_system_path +import spack.error as error + +import shutil +import re +from collections import defaultdict + +def check_variant_fcgroup(fcgroup): + pattern = re.compile(r"^[A-Z]+\..+\..") + # fcgroup is False as default + if pattern.match(fcgroup) or fcgroup == 'none': + return True + else: + tty.warn('Variant fcgroup needs format GROUP.files.flag') + return False + + +def check_variant_extra_config_args(extra_config_arg): + pattern = re.compile(r'--(enable|disable)-\S+') + if pattern.match(extra_config_arg) or extra_config_arg == 'none': + return True + else: + tty.warn( + f'The value "{extra_config_arg}" for the extra_config_args variant must follow the format "--enable-arg" or "--disable-arg"' + ) + return False + + +class Icon(SpackIcon): + git = 'git@gitlab.dkrz.de:icon/icon-nwp.git' + + maintainers('jonasjucker', 'huppd') + + version('develop', submodules=True) + version("2024.10", + tag="icon-2024.10", + git='git@gitlab.dkrz.de:icon/icon.git', + submodules=True) + version("2024.01-1", + tag="icon-2024.01-1", + git='git@gitlab.dkrz.de:icon/icon.git', + submodules=True) + version('2.6.6-mch2b', tag='icon-nwp/icon-2.6.6-mch2b', submodules=True) + version('2.6.6-mch2a', tag='icon-nwp/icon-2.6.6-mch2a', submodules=True) + version('nwp-master', submodules=True) + + # The variants' default follow those of ICON + # as described here + # https://gitlab.dkrz.de/icon/icon/-/blob/icon-2024.01/configure?ref_type=tags#L1492-1638 + + # Model Features: + variant('dace', + default=False, + description='Enable the DACE modules for data assimilation') + requires("+mpi", when="+dace") + + variant('emvorado', + default=False, + description='Enable the radar forward operator EMVORADO') + requires("+mpi", when="+emvorado") + + variant('art-gpl', + default=False, + description='Enable GPL-licensed code parts of the ART component') + variant( + 'acm-license', + default=False, + description= + 'Enable code parts that require accepting the ACM Software License') + + # Infrastructural Features: + variant( + 'active-target-sync', + default=False, + description= + 'Enable MPI active target mode (otherwise, passive target mode is used)' + ) + variant('async-io-rma', + default=True, + description='Enable remote memory access (RMA) for async I/O') + variant('realloc-buf', + default=False, + description='Enable reallocatable communication buffer') + variant('sct', default=False, description='Enable the SCT timer') + variant( + 'extra-config-args', + default='none', + multi=True, + values=check_variant_extra_config_args, + description= + 'Inject any configure argument not yet available as variant\nUse this feature cautiously, as injecting non-variant configure arguments may potentially disrupt the build process' + ) + + # Optimization Features: + variant('loop-exchange', default=False, description='Enable loop exchange') + variant('vectorized-lrtm', + default=False, + description='Enable the parallelization-invariant version of LRTM') + variant( + 'pgi-inlib', + default=False, + description= + 'Enable PGI/NVIDIA cross-file function inlining via an inline library') + variant('nccl', default=False, description='Enable NCCL for communication') + + variant('cuda-graphs', default=False, description='Enable CUDA graphs.') + requires('%nvhpc@23.3:', when='+cuda-graphs') + + variant( + 'fcgroup', + default='none', + multi=True, + values=check_variant_fcgroup, + description= + 'Create a Fortran compile group: GROUP;files;flag \nNote: flag can only be one single value, i.e. -O1' + ) + + # verbosity + variant('silent-rules', + default=True, + description='Enable silent-rules for build-process') + variant( + 'eccodes-definitions', + default=False, + description= + 'Enable extension of eccodes with center specific definition files') + + depends_on('cosmo-eccodes-definitions', + type='run', + when='+eccodes-definitions') + + with when('+emvorado'): + depends_on('eccodes +fortran') + depends_on('hdf5 +szip +hl +fortran') + depends_on('zlib-ng') + # WORKAROUND: A build and link dependency should imply that the same compiler is used. This enforces it. + depends_on('eccodes %nvhpc', when='%nvhpc') + depends_on('eccodes %gcc', when='%gcc') + + # WORKAROUND: A build and link dependency should imply that the same compiler is used. This enforces it. + for __x in SpackIcon.serialization_values: + depends_on('serialbox+fortran %nvhpc', + when='serialization={0} %nvhpc'.format(__x)) + depends_on('serialbox+fortran %gcc', + when='serialization={0} %gcc'.format(__x)) + + # WORKAROUND: A build and link dependency should imply that the same compiler is used. This enforces it. + depends_on('netcdf-fortran %nvhpc', when='%nvhpc') + depends_on('netcdf-fortran %gcc', when='%gcc') + + depends_on('hdf5 +szip', when='+sct') + + # patch_libtool is a function from Autotoolspackage. + # For BB we cannot use it because it finds all files + # named "libtool". spack-c2sm is cloned into icon-repo, + # therefore this function detects not only "libtool" files, but + # also the folder where libtool package itself is installed. + patch_libtool = False + + def configure_args(self): + args = super().configure_args() + super_libs = args.pop() + + libs = LibraryList([]) + flags = defaultdict(list) + + for x in [ + 'dace', + 'emvorado', + 'art-gpl', + 'acm-license', + 'active-target-sync', + 'async-io-rma', + 'realloc-buf', + 'parallel-netcdf', + 'sct', + 'loop-exchange', + 'vectorized-lrtm', + 'pgi-inlib', + 'nccl', + 'cuda-graphs', + 'silent-rules', + ]: + args += self.enable_or_disable(x) + + if '+emvorado' in self.spec: + libs += self.spec['eccodes:fortran'].libs + libs += self.spec['hdf5:fortran,hl'].libs + libs += self.spec['zlib-ng'].libs + + if '+sct' in self.spec: + libs += self.spec['hdf5'].libs + + fcgroup = self.spec.variants['fcgroup'].value + # ('none',) is the values spack assign if fcgroup is not set + if fcgroup != ('none', ): + args.extend(self.fcgroup_to_config_arg()) + flags.update(self.fcgroup_to_config_var()) + + # add configure arguments not yet available as variant + extra_config_args = self.spec.variants['extra-config-args'].value + if extra_config_args != ('none', ): + for x in extra_config_args: + # prevent configure-args already available as variant + # to be set through variant extra_config_args + self.validate_extra_config_args(x) + args.append(x) + tty.warn( + 'You use variant extra-config-args. Injecting non-variant configure arguments may potentially disrupt the build process!' + ) + + # Help the libtool scripts of the bundled libraries find the correct + # paths to the external libraries. Specify the library search (-L) flags + # in the reversed order + # (see https://gitlab.dkrz.de/icon/icon#icon-dependencies): + # and for non-system directories only: + flags['LDFLAGS'].extend([ + '-L{0}'.format(d) for d in reversed(libs.directories) + if not is_system_path(d) + ]) + + # Temporary back port fix from upstream package for building comin on cpu + # See https://github.com/spack/spack-packages/commit/b992c44bb52d034fe57637f3da42483501442af3 + # TODO: Remove this dupplicate once spack-c2sm points to an upstream spack containing the fix. + if self.spec.variants[ + "gpu"].value in self.nvidia_targets or self.spec.satisfies( + "+comin"): + flags["ICON_LDFLAGS"].extend(self.compiler.stdcxx_libs) + + args.extend([ + "{0}={1}".format(name, " ".join(value)) + for name, value in flags.items() + ]) + args.append(f"{super_libs} {libs.link_flags}") + return args + + def fcgroup_to_config_arg(self): + arg = [] + for group in self.spec.variants['fcgroup'].value: + name = group.split('.')[0] + files = group.split('.')[1] + arg.append(f'--enable-fcgroup-{name}={files}') + return arg + + def fcgroup_to_config_var(self): + var = {} + for group in self.spec.variants['fcgroup'].value: + name = group.split('.')[0] + flag = group.split('.')[2] + # Note: flag needs to be a list + var[f'ICON_{name}_FCFLAGS'] = [flag] + return var + + def strip_variant_prefix(self, variant_string): + prefixes = ["--enable-", "--disable-"] + + for prefix in prefixes: + if variant_string.startswith(prefix): + return variant_string[len(prefix):] + + raise ValueError + + def validate_extra_config_args(self, arg): + variant_from_arg = self.strip_variant_prefix(arg) + if variant_from_arg in self.spec.variants: + raise error.SpecError( + f'The value "{arg}" for the extra_config_args variant conflicts ' + f'with the existing variant {variant_from_arg}. Set this variant instead.' + ) + + def configure(self, spec, prefix): + if os.path.exists( + os.path.join(self.build_directory, + 'icon.mk')) and self.build_uses_same_spec(): + tty.warn( + 'icon.mk already present -> skip configure stage', + '\t delete "icon.mk" or run "make distclean" to not skip configure' + ) + return + + # Call configure of Autotools + super().configure(spec, prefix) + + def build_uses_same_spec(self): + """ + Ensure that configure is rerun in case spec has changed, + otherwise for the case below + + $ spack dev-build icon @develop ~dace + $ spack dev-build icon @develop +dace + + configure is skipped for the latter. + """ + + is_same_spec = False + + previous_spec = os.path.join(self.build_directory, + '.previous_spec.yaml') + + # not the first build in self.build_directory + if os.path.exists(previous_spec): + with open(previous_spec, mode='r') as f: + if self.spec == Spec.from_yaml(f): + is_same_spec = True + else: + is_same_spec = False + tty.warn( + 'Cannot skip configure phase because spec changed') + + # first build in self.build_directory, no worries + else: + is_same_spec = True + + # dump spec of new build + with open(previous_spec, mode='w') as f: + f.write(self.spec.to_yaml()) + + return is_same_spec + + @run_after('configure') + def copy_runscript_related_input_files(self): + with working_dir(self.build_directory): + icon_dir = self.configure_directory + # only synchronize if out-of-source build + if os.path.abspath(icon_dir) != os.path.abspath( + self.build_directory): + Rsync = which('rsync', required=True) + Rsync("-uavz", f"{icon_dir}/run", ".", "--exclude=*.in", + "--exclude=.*", "--exclude=standard_*") + Rsync("-uavz", f"{icon_dir}/externals", ".", "--exclude=.git", + "--exclude=*.f90", "--exclude=*.F90", "--exclude=*.c", + "--exclude=*.h", "--exclude=*.Po", "--exclude=tests", + "--exclude=*.mod", "--exclude=*.o") + Rsync("-uavz", f"{icon_dir}/make_runscripts", ".") + + Ln = which('ln', required=True) + dirs = glob.glob(f"{icon_dir}/run/standard_*") + for dir in dirs: + Ln("-sf", "-t", "run/", f"{dir}") + Ln("-sf", f"{icon_dir}/data") + Ln("-sf", f"{icon_dir}/vertical_coord_tables") + Ln("-sf", f"{icon_dir}/scripts") + + + +def validate_variant_dsl(pkg, name, value): + set_mutual_excl = set(['substitute', 'verify', 'serialize']) + set_input_var = set(value) + if len(set_mutual_excl.intersection(set_input_var)) > 1: + raise error.SpecError( + 'Cannot have more than one of (substitute, verify, serialize) in the same build' + ) + + +class IconExclaim(Icon): + git = 'git@github.com:C2SM/icon-exclaim.git' + + maintainers('jonasjucker', 'huppd') + + version('develop', branch='icon-dsl', submodules=True) + + # EXCLAIM-GT4Py specific features: + dsl_values = ('substitute', 'verify') + variant('dsl', + default='none', + validator=validate_variant_dsl, + values=('none', ) + dsl_values, + description='Build with GT4Py dynamical core', + multi=True) + + for x in dsl_values: + depends_on('icon4py', type="build", when=f"dsl={x}") + + def configure_args(self): + raw_args = super().configure_args() + + # Split into categories + args_flags = [] + icon_ldflags = [] + ldflags = [] + libs = [] + + for a in raw_args: + if a.startswith("LIBS="): + libs.append(a.split("=", 1)[1].strip()) + elif a.startswith("ICON_LDFLAGS="): + icon_ldflags.append(a.split("=", 1)[1].strip()) + elif a.startswith("LDFLAGS="): + ldflags.append(a.split("=", 1)[1].strip()) + else: + args_flags.append(a) + + # Handle DSL variants + dsl = self.spec.variants['dsl'].value + if dsl != ('none', ): + if 'substitute' in dsl: + args_flags.append('--enable-py2f=substitute') + elif 'verify' in dsl: + args_flags.append('--enable-py2f=verify') + else: + raise ValueError( + f"Unknown DSL variant '{dsl}'. " + f"Valid options are: {', '.join(('none',) + dsl_values)}") + + # Add icon4py paths and libs + icon4py_prefix = self.spec["icon4py"].prefix + bindings_dir = os.path.join(icon4py_prefix, "src") + + ldflags.append(f"-L{bindings_dir} -Wl,-rpath,{bindings_dir}") + libs.append("-licon4py_bindings") + + # Remove duplicates + icon_ldflags = list(dict.fromkeys(icon_ldflags)) + ldflags = list(dict.fromkeys(ldflags)) + libs = list(dict.fromkeys(libs)) + + # Reconstruct final configure args + final_args = args_flags + if icon_ldflags: + final_args.append("ICON_LDFLAGS=" + " ".join(icon_ldflags)) + if ldflags: + final_args.append("LDFLAGS=" + " ".join(ldflags)) + if libs: + final_args.append("LIBS=" + " ".join(libs)) + + return final_args + + def build(self, spec, prefix): + # Check the variant + dsl = self.spec.variants['dsl'].value + if dsl != ('none', ): + file = "icon4py_bindings.f90" + + bindings_dir = os.path.join(self.spec["icon4py"].prefix, "src") + src_file = os.path.join(bindings_dir, file) + + build_py2f_dir = os.path.join(self.stage.source_path, "src", + "build_py2f") + os.makedirs(build_py2f_dir, exist_ok=True) + dest_file = os.path.join(build_py2f_dir, file) + + shutil.copy2(src_file, dest_file) + print( + f"Copied {src_file} to build directory {dest_file} because +dsl is enabled" + ) + + # Proceed with the normal build + super().build(spec, prefix) From ad5c8e360865c47adef7178177090ad940cb5600 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Tue, 16 Dec 2025 09:24:06 +0100 Subject: [PATCH 31/32] cleanup --- .../icon-dsl/25.12/gh200/environments.yaml | 8 +- recipes/icon-dsl/25.12/gh200/pre-install | 13 +- .../25.12/gh200/repo/packages/ghex/package.py | 93 ---- .../hwmalloc/cmake_install_path.patch | 27 -- .../gh200/repo/packages/hwmalloc/package.py | 52 -- .../repo/packages/icon-exclaim/package.py | 454 ++++++++++++++++++ .../gh200/repo/packages/icon4py/package.py | 109 ----- .../repo/packages/oomph/install_0.2.patch | 102 ---- .../repo/packages/oomph/install_0.3.patch | 57 --- .../gh200/repo/packages/oomph/package.py | 109 ----- .../25.12/gh200/repo/packages/uv/package.py | 68 --- 11 files changed, 465 insertions(+), 627 deletions(-) delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py create mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/icon-exclaim/package.py delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py delete mode 100644 recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py diff --git a/recipes/icon-dsl/25.12/gh200/environments.yaml b/recipes/icon-dsl/25.12/gh200/environments.yaml index 7fde2c8..6a826c6 100644 --- a/recipes/icon-dsl/25.12/gh200/environments.yaml +++ b/recipes/icon-dsl/25.12/gh200/environments.yaml @@ -1,4 +1,4 @@ -myenv: +icon: compiler: - toolchain: gcc spec: gcc @@ -13,9 +13,11 @@ myenv: - py-cupy +cuda cuda_arch=90 - ghex +python +cuda cuda_arch=90 - py-mpi4py - - icon4py@icon_20250328 + - icon4py@main + - icon-exclaim @develop %nvhpc dsl=substitute +grib2 +eccodes-definitions +ecrad + ~emvorado +art +dace gpu=nvidia-80 +mpi-gpu +realloc-buf ~aes ~jsbach ~ocean ~coupling + ~rte-rrtmgp ~loop-exchange ~async-io-rma ~cuda-graphs fflags="-traceback" # icon deps - - boost - cuda@12 - eccodes@2.36.4%nvhpc +tools +fortran +aec +openmp jp2k=jasper - cosmo-eccodes-definitions@2.36.0.3 diff --git a/recipes/icon-dsl/25.12/gh200/pre-install b/recipes/icon-dsl/25.12/gh200/pre-install index 78fa3ca..03ac24a 100644 --- a/recipes/icon-dsl/25.12/gh200/pre-install +++ b/recipes/icon-dsl/25.12/gh200/pre-install @@ -6,13 +6,12 @@ set -euo pipefail # -------------------------- packages=( "cosmo-eccodes-definitions" - # "ghex" - # "hwmalloc" - # "oomph" - # "uv" - # "icon4py" - # "icon" - # "icon-exclaim" + "ghex" + "hwmalloc" + "oomph" + "uv" + "icon4py" + "icon-exclaim" ) SPACK_C2SM_TAG="v0.22.2.5" diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py deleted file mode 100644 index 8f50e28..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/ghex/package.py +++ /dev/null @@ -1,93 +0,0 @@ -from spack.package import * - - -class Ghex(CMakePackage, CudaPackage, ROCmPackage): - """GHEX is a generic halo-exchange library.""" - - homepage = "https://github.com/ghex-org/GHEX" - url = "https://github.com/ghex-org/GHEX/archive/refs/tags/v0.3.0.tar.gz" - git = "https://github.com/ghex-org/GHEX.git" - maintainers = ["boeschf"] - - version("0.4.1", tag="v0.4.1", submodules=True) - version("0.4.0", tag="v0.4.0", submodules=True) - version("0.3.0", tag="v0.3.0", submodules=True) - version("master", branch="master", submodules=True) - - depends_on("cxx", type="build") - - generator("ninja") - - backends = ("mpi", "ucx", "libfabric") - variant( - "backend", - default="mpi", - description="Transport backend", - values=backends, - multi=False, - ) - variant("xpmem", default=False, description="Use xpmem shared memory") - variant("python", default=True, description="Build Python bindings") - - depends_on("cmake@3.21:", type="build") - depends_on("mpi") - depends_on("boost") - depends_on("xpmem", when="+xpmem", type=("build", "run")) - - depends_on("oomph") - for backend in backends: - depends_on(f"oomph backend={backend}", when=f"backend={backend}") - depends_on("oomph+cuda", when="+cuda") - depends_on("oomph+rocm", when="+rocm") - depends_on("oomph@0.3:", when="@0.3:") - - conflicts("+cuda+rocm") - - with when("+python"): - extends("python") - depends_on("python@3.7:", type="build") - depends_on("py-pip", type="build") - depends_on("py-pybind11", type="build") - depends_on("py-mpi4py", type=("build", "run")) - depends_on("py-numpy", type=("build", "run")) - - depends_on("py-pytest", when="+python", type=("test")) - - def cmake_args(self): - spec = self.spec - - args = [ - self.define("GHEX_USE_BUNDLED_LIBS", True), - self.define("GHEX_USE_BUNDLED_GRIDTOOLS", True), - self.define("GHEX_USE_BUNDLED_GTEST", self.run_tests), - self.define("GHEX_USE_BUNDLED_OOMPH", False), - self.define( - "GHEX_TRANSPORT_BACKEND", spec.variants["backend"].value.upper() - ), - self.define_from_variant("GHEX_USE_XPMEM", "xpmem"), - self.define_from_variant("GHEX_BUILD_PYTHON_BINDINGS", "python"), - self.define("GHEX_WITH_TESTING", self.run_tests), - ] - - if spec.satisfies("+python"): - args.append(self.define("GHEX_PYTHON_LIB_PATH", python_platlib)) - - if self.run_tests and spec.satisfies("^openmpi"): - args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) - - if "+cuda" in spec and spec.variants["cuda_arch"].value != "none": - arch_str = ";".join(spec.variants["cuda_arch"].value) - args.append(self.define("CMAKE_CUDA_ARCHITECTURES", arch_str)) - args.append(self.define("GHEX_USE_GPU", True)) - args.append(self.define("GHEX_GPU_TYPE", "NVIDIA")) - - if "+rocm" in spec and spec.variants["amdgpu_target"].value != "none": - arch_str = ";".join(spec.variants["amdgpu_target"].value) - args.append(self.define("CMAKE_HIP_ARCHITECTURES", arch_str)) - args.append(self.define("GHEX_USE_GPU", True)) - args.append(self.define("GHEX_GPU_TYPE", "AMD")) - - if spec.satisfies("~cuda~rocm"): - args.append(self.define("GHEX_USE_GPU", False)) - - return args diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch deleted file mode 100644 index fa6fde1..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/cmake_install_path.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index d5420e0..35dbe56 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -105,11 +105,11 @@ install(FILES ${PROJECT_BINARY_DIR}/include/hwmalloc/config.hpp - install(EXPORT HWMALLOC-targets - FILE HWMALLOC-targets.cmake - NAMESPACE HWMALLOC:: -- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) - - configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HWMALLOCConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfig.cmake -- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) - - write_basic_package_version_file(HWMALLOCConfigVersion.cmake - VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) -@@ -120,7 +120,7 @@ install( - ${CMAKE_CURRENT_BINARY_DIR}/HWMALLOCConfigVersion.cmake - ${CMAKE_CURRENT_LIST_DIR}/cmake/FindNUMA.cmake - DESTINATION -- ${CMAKE_INSTALL_LIBDIR}/cmake) -+ ${CMAKE_INSTALL_LIBDIR}/hwmalloc/cmake) - - export(EXPORT HWMALLOC-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/HWMALLOC-targets.cmake") diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py deleted file mode 100644 index c656dc1..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/hwmalloc/package.py +++ /dev/null @@ -1,52 +0,0 @@ -from spack.package import * - - -class Hwmalloc(CMakePackage, CudaPackage, ROCmPackage): - """HWMALLOC is a allocator which supports memory registration for e.g. remote memory access""" - - homepage = "https://github.com/ghex-org/hwmalloc" - url = "https://github.com/ghex-org/hwmalloc/archive/refs/tags/v0.3.0.tar.gz" - git = "https://github.com/ghex-org/hwmalloc.git" - maintainers = ["boeschf"] - - version("0.3.0", sha256="d4d4ac6087a806600d79fb62c02719ca3d58a412968fe1ef4a2fd58d9e7ee950") - version("0.2.0", sha256="734758a390a3258b86307e4aef50a7ca2e5d0e2e579f18aeefcd05397e114419") - version("0.1.0", sha256="06e9bfcef0ecce4d19531ccbe03592b502d1281c7a092bc0ff51ca187899b21c") - version("master", branch="master") - - depends_on("cxx", type="build") - - generator("ninja") - - depends_on("numactl", type=("build", "run")) - depends_on("boost", type=("build")) - depends_on("cmake@3.19:", type="build") - - variant( - "numa-throws", - default=False, - description="True if numa_tools may throw during initialization", - ) - variant("numa-local", default=True, description="Use numa_tools for local node allocations") - variant("logging", default=False, description="print logging info to cerr") - - patch("cmake_install_path.patch", when="@:0.3.0", level=1) - - def cmake_args(self): - args = [ - self.define_from_variant("HWMALLOC_NUMA_THROWS", "numa-throws"), - self.define_from_variant("HWMALLOC_NUMA_FOR_LOCAL", "numa-local"), - self.define_from_variant("HWMALLOC_ENABLE_LOGGING", "logging"), - self.define("HWMALLOC_WITH_TESTING", self.run_tests), - ] - - if "+cuda" in self.spec: - args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) - args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "cuda")) - elif "+rocm" in self.spec: - args.append(self.define("HWMALLOC_ENABLE_DEVICE", True)) - args.append(self.define("HWMALLOC_DEVICE_RUNTIME", "hip")) - else: - args.append(self.define("HWMALLOC_ENABLE_DEVICE", False)) - - return args diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/icon-exclaim/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/icon-exclaim/package.py new file mode 100644 index 0000000..ab78bf1 --- /dev/null +++ b/recipes/icon-dsl/25.12/gh200/repo/packages/icon-exclaim/package.py @@ -0,0 +1,454 @@ +from spack.pkg.builtin.icon import Icon as SpackIcon +import os +import re +import glob +from collections import defaultdict +from llnl.util import tty +from spack.util.environment import is_system_path +import spack.error as error + +import shutil +import re +from collections import defaultdict + +def check_variant_fcgroup(fcgroup): + pattern = re.compile(r"^[A-Z]+\..+\..") + # fcgroup is False as default + if pattern.match(fcgroup) or fcgroup == 'none': + return True + else: + tty.warn('Variant fcgroup needs format GROUP.files.flag') + return False + + +def check_variant_extra_config_args(extra_config_arg): + pattern = re.compile(r'--(enable|disable)-\S+') + if pattern.match(extra_config_arg) or extra_config_arg == 'none': + return True + else: + tty.warn( + f'The value "{extra_config_arg}" for the extra_config_args variant must follow the format "--enable-arg" or "--disable-arg"' + ) + return False + + +class Icon(SpackIcon): + git = 'git@gitlab.dkrz.de:icon/icon-nwp.git' + + maintainers('jonasjucker', 'huppd') + + version('develop', submodules=True) + version("2024.10", + tag="icon-2024.10", + git='git@gitlab.dkrz.de:icon/icon.git', + submodules=True) + version("2024.01-1", + tag="icon-2024.01-1", + git='git@gitlab.dkrz.de:icon/icon.git', + submodules=True) + version('2.6.6-mch2b', tag='icon-nwp/icon-2.6.6-mch2b', submodules=True) + version('2.6.6-mch2a', tag='icon-nwp/icon-2.6.6-mch2a', submodules=True) + version('nwp-master', submodules=True) + + # The variants' default follow those of ICON + # as described here + # https://gitlab.dkrz.de/icon/icon/-/blob/icon-2024.01/configure?ref_type=tags#L1492-1638 + + # Model Features: + variant('dace', + default=False, + description='Enable the DACE modules for data assimilation') + requires("+mpi", when="+dace") + + variant('emvorado', + default=False, + description='Enable the radar forward operator EMVORADO') + requires("+mpi", when="+emvorado") + + variant('art-gpl', + default=False, + description='Enable GPL-licensed code parts of the ART component') + variant( + 'acm-license', + default=False, + description= + 'Enable code parts that require accepting the ACM Software License') + + # Infrastructural Features: + variant( + 'active-target-sync', + default=False, + description= + 'Enable MPI active target mode (otherwise, passive target mode is used)' + ) + variant('async-io-rma', + default=True, + description='Enable remote memory access (RMA) for async I/O') + variant('realloc-buf', + default=False, + description='Enable reallocatable communication buffer') + variant('sct', default=False, description='Enable the SCT timer') + variant( + 'extra-config-args', + default='none', + multi=True, + values=check_variant_extra_config_args, + description= + 'Inject any configure argument not yet available as variant\nUse this feature cautiously, as injecting non-variant configure arguments may potentially disrupt the build process' + ) + + # Optimization Features: + variant('loop-exchange', default=False, description='Enable loop exchange') + variant('vectorized-lrtm', + default=False, + description='Enable the parallelization-invariant version of LRTM') + variant( + 'pgi-inlib', + default=False, + description= + 'Enable PGI/NVIDIA cross-file function inlining via an inline library') + variant('nccl', default=False, description='Enable NCCL for communication') + + variant('cuda-graphs', default=False, description='Enable CUDA graphs.') + requires('%nvhpc@23.3:', when='+cuda-graphs') + + variant( + 'fcgroup', + default='none', + multi=True, + values=check_variant_fcgroup, + description= + 'Create a Fortran compile group: GROUP;files;flag \nNote: flag can only be one single value, i.e. -O1' + ) + + # verbosity + variant('silent-rules', + default=True, + description='Enable silent-rules for build-process') + variant( + 'eccodes-definitions', + default=False, + description= + 'Enable extension of eccodes with center specific definition files') + + depends_on('cosmo-eccodes-definitions', + type='run', + when='+eccodes-definitions') + + with when('+emvorado'): + depends_on('eccodes +fortran') + depends_on('hdf5 +szip +hl +fortran') + depends_on('zlib-ng') + # WORKAROUND: A build and link dependency should imply that the same compiler is used. This enforces it. + depends_on('eccodes %nvhpc', when='%nvhpc') + depends_on('eccodes %gcc', when='%gcc') + + # WORKAROUND: A build and link dependency should imply that the same compiler is used. This enforces it. + for __x in SpackIcon.serialization_values: + depends_on('serialbox+fortran %nvhpc', + when='serialization={0} %nvhpc'.format(__x)) + depends_on('serialbox+fortran %gcc', + when='serialization={0} %gcc'.format(__x)) + + # WORKAROUND: A build and link dependency should imply that the same compiler is used. This enforces it. + depends_on('netcdf-fortran %nvhpc', when='%nvhpc') + depends_on('netcdf-fortran %gcc', when='%gcc') + + depends_on('hdf5 +szip', when='+sct') + + # patch_libtool is a function from Autotoolspackage. + # For BB we cannot use it because it finds all files + # named "libtool". spack-c2sm is cloned into icon-repo, + # therefore this function detects not only "libtool" files, but + # also the folder where libtool package itself is installed. + patch_libtool = False + + def configure_args(self): + args = super().configure_args() + super_libs = args.pop() + + libs = LibraryList([]) + flags = defaultdict(list) + + for x in [ + 'dace', + 'emvorado', + 'art-gpl', + 'acm-license', + 'active-target-sync', + 'async-io-rma', + 'realloc-buf', + 'parallel-netcdf', + 'sct', + 'loop-exchange', + 'vectorized-lrtm', + 'pgi-inlib', + 'nccl', + 'cuda-graphs', + 'silent-rules', + ]: + args += self.enable_or_disable(x) + + if '+emvorado' in self.spec: + libs += self.spec['eccodes:fortran'].libs + libs += self.spec['hdf5:fortran,hl'].libs + libs += self.spec['zlib-ng'].libs + + if '+sct' in self.spec: + libs += self.spec['hdf5'].libs + + fcgroup = self.spec.variants['fcgroup'].value + # ('none',) is the values spack assign if fcgroup is not set + if fcgroup != ('none', ): + args.extend(self.fcgroup_to_config_arg()) + flags.update(self.fcgroup_to_config_var()) + + # add configure arguments not yet available as variant + extra_config_args = self.spec.variants['extra-config-args'].value + if extra_config_args != ('none', ): + for x in extra_config_args: + # prevent configure-args already available as variant + # to be set through variant extra_config_args + self.validate_extra_config_args(x) + args.append(x) + tty.warn( + 'You use variant extra-config-args. Injecting non-variant configure arguments may potentially disrupt the build process!' + ) + + # Help the libtool scripts of the bundled libraries find the correct + # paths to the external libraries. Specify the library search (-L) flags + # in the reversed order + # (see https://gitlab.dkrz.de/icon/icon#icon-dependencies): + # and for non-system directories only: + flags['LDFLAGS'].extend([ + '-L{0}'.format(d) for d in reversed(libs.directories) + if not is_system_path(d) + ]) + + # Temporary back port fix from upstream package for building comin on cpu + # See https://github.com/spack/spack-packages/commit/b992c44bb52d034fe57637f3da42483501442af3 + # TODO: Remove this dupplicate once spack-c2sm points to an upstream spack containing the fix. + if self.spec.variants[ + "gpu"].value in self.nvidia_targets or self.spec.satisfies( + "+comin"): + flags["ICON_LDFLAGS"].extend(self.compiler.stdcxx_libs) + + args.extend([ + "{0}={1}".format(name, " ".join(value)) + for name, value in flags.items() + ]) + args.append(f"{super_libs} {libs.link_flags}") + return args + + def fcgroup_to_config_arg(self): + arg = [] + for group in self.spec.variants['fcgroup'].value: + name = group.split('.')[0] + files = group.split('.')[1] + arg.append(f'--enable-fcgroup-{name}={files}') + return arg + + def fcgroup_to_config_var(self): + var = {} + for group in self.spec.variants['fcgroup'].value: + name = group.split('.')[0] + flag = group.split('.')[2] + # Note: flag needs to be a list + var[f'ICON_{name}_FCFLAGS'] = [flag] + return var + + def strip_variant_prefix(self, variant_string): + prefixes = ["--enable-", "--disable-"] + + for prefix in prefixes: + if variant_string.startswith(prefix): + return variant_string[len(prefix):] + + raise ValueError + + def validate_extra_config_args(self, arg): + variant_from_arg = self.strip_variant_prefix(arg) + if variant_from_arg in self.spec.variants: + raise error.SpecError( + f'The value "{arg}" for the extra_config_args variant conflicts ' + f'with the existing variant {variant_from_arg}. Set this variant instead.' + ) + + def configure(self, spec, prefix): + if os.path.exists( + os.path.join(self.build_directory, + 'icon.mk')) and self.build_uses_same_spec(): + tty.warn( + 'icon.mk already present -> skip configure stage', + '\t delete "icon.mk" or run "make distclean" to not skip configure' + ) + return + + # Call configure of Autotools + super().configure(spec, prefix) + + def build_uses_same_spec(self): + """ + Ensure that configure is rerun in case spec has changed, + otherwise for the case below + + $ spack dev-build icon @develop ~dace + $ spack dev-build icon @develop +dace + + configure is skipped for the latter. + """ + + is_same_spec = False + + previous_spec = os.path.join(self.build_directory, + '.previous_spec.yaml') + + # not the first build in self.build_directory + if os.path.exists(previous_spec): + with open(previous_spec, mode='r') as f: + if self.spec == Spec.from_yaml(f): + is_same_spec = True + else: + is_same_spec = False + tty.warn( + 'Cannot skip configure phase because spec changed') + + # first build in self.build_directory, no worries + else: + is_same_spec = True + + # dump spec of new build + with open(previous_spec, mode='w') as f: + f.write(self.spec.to_yaml()) + + return is_same_spec + + @run_after('configure') + def copy_runscript_related_input_files(self): + with working_dir(self.build_directory): + icon_dir = self.configure_directory + # only synchronize if out-of-source build + if os.path.abspath(icon_dir) != os.path.abspath( + self.build_directory): + Rsync = which('rsync', required=True) + Rsync("-uavz", f"{icon_dir}/run", ".", "--exclude=*.in", + "--exclude=.*", "--exclude=standard_*") + Rsync("-uavz", f"{icon_dir}/externals", ".", "--exclude=.git", + "--exclude=*.f90", "--exclude=*.F90", "--exclude=*.c", + "--exclude=*.h", "--exclude=*.Po", "--exclude=tests", + "--exclude=*.mod", "--exclude=*.o") + Rsync("-uavz", f"{icon_dir}/make_runscripts", ".") + + Ln = which('ln', required=True) + dirs = glob.glob(f"{icon_dir}/run/standard_*") + for dir in dirs: + Ln("-sf", "-t", "run/", f"{dir}") + Ln("-sf", f"{icon_dir}/data") + Ln("-sf", f"{icon_dir}/vertical_coord_tables") + Ln("-sf", f"{icon_dir}/scripts") + + + +def validate_variant_dsl(pkg, name, value): + set_mutual_excl = set(['substitute', 'verify', 'serialize']) + set_input_var = set(value) + if len(set_mutual_excl.intersection(set_input_var)) > 1: + raise error.SpecError( + 'Cannot have more than one of (substitute, verify, serialize) in the same build' + ) + + +class IconExclaim(Icon): + git = 'git@github.com:C2SM/icon-exclaim.git' + + maintainers('jonasjucker', 'huppd') + + version('develop', branch='icon-dsl', submodules=True) + + # EXCLAIM-GT4Py specific features: + dsl_values = ('substitute', 'verify') + variant('dsl', + default='none', + validator=validate_variant_dsl, + values=('none', ) + dsl_values, + description='Build with GT4Py dynamical core', + multi=True) + + for x in dsl_values: + depends_on('icon4py', type="build", when=f"dsl={x}") + + def configure_args(self): + raw_args = super().configure_args() + + # Split into categories + args_flags = [] + icon_ldflags = [] + ldflags = [] + libs = [] + + for a in raw_args: + if a.startswith("LIBS="): + libs.append(a.split("=", 1)[1].strip()) + elif a.startswith("ICON_LDFLAGS="): + icon_ldflags.append(a.split("=", 1)[1].strip()) + elif a.startswith("LDFLAGS="): + ldflags.append(a.split("=", 1)[1].strip()) + else: + args_flags.append(a) + + # Handle DSL variants + dsl = self.spec.variants['dsl'].value + if dsl != ('none', ): + if 'substitute' in dsl: + args_flags.append('--enable-py2f=substitute') + elif 'verify' in dsl: + args_flags.append('--enable-py2f=verify') + else: + raise ValueError( + f"Unknown DSL variant '{dsl}'. " + f"Valid options are: {', '.join(('none',) + dsl_values)}") + + # Add icon4py paths and libs + icon4py_prefix = self.spec["icon4py"].prefix + bindings_dir = os.path.join(icon4py_prefix, "src") + + ldflags.append(f"-L{bindings_dir} -Wl,-rpath,{bindings_dir}") + libs.append("-licon4py_bindings") + + # Remove duplicates + icon_ldflags = list(dict.fromkeys(icon_ldflags)) + ldflags = list(dict.fromkeys(ldflags)) + libs = list(dict.fromkeys(libs)) + + # Reconstruct final configure args + final_args = args_flags + if icon_ldflags: + final_args.append("ICON_LDFLAGS=" + " ".join(icon_ldflags)) + if ldflags: + final_args.append("LDFLAGS=" + " ".join(ldflags)) + if libs: + final_args.append("LIBS=" + " ".join(libs)) + + return final_args + + def build(self, spec, prefix): + # Check the variant + dsl = self.spec.variants['dsl'].value + if dsl != ('none', ): + file = "icon4py_bindings.f90" + + bindings_dir = os.path.join(self.spec["icon4py"].prefix, "src") + src_file = os.path.join(bindings_dir, file) + + build_py2f_dir = os.path.join(self.stage.source_path, "src", + "build_py2f") + os.makedirs(build_py2f_dir, exist_ok=True) + dest_file = os.path.join(build_py2f_dir, file) + + shutil.copy2(src_file, dest_file) + print( + f"Copied {src_file} to build directory {dest_file} because +dsl is enabled" + ) + + # Proceed with the normal build + super().build(spec, prefix) diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py deleted file mode 100644 index 9ee413e..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/icon4py/package.py +++ /dev/null @@ -1,109 +0,0 @@ -import json -import os -import pathlib - -import llnl -from llnl.util import tty -from spack import * - - -class Icon4py(Package): - extends("python") - depends_on("python@3.11:") - - depends_on("git") - depends_on("boost@1.85:+mpi+python", type=("build", "run")) - depends_on("uv@0.7:", type="build") - depends_on("bzip2", type="build") - depends_on("py-numpy") - depends_on("py-cffi") - depends_on("py-pybind11") - depends_on("py-nanobind") - depends_on("py-mpi4py") - depends_on("py-cupy +cuda") - depends_on("ghex +python +cuda") - - version( - "icon_20250328", - sha256="8573ef031d207438f549511e859f522c60163ea660aafea93ef4991b9010739a", - extension="zip", - ) - - def url_for_version(self, version): - return f"https://github.com/c2sm/icon4py/archive/refs/heads/{version}.zip" - - def install(self, spec, prefix): - uv = prepare_uv() - python_spec = spec["python"] - venv_path = prefix.share.venv - - tty.msg(f"creating venv using spack python at: {python_spec.command.path}") - uv( - "venv", - "--seed", - "--relocatable", - "--system-site-packages", - str(venv_path), - "--python", - python_spec.command.path, - ) - - tty.msg(f"grabbing spack installed packages (distributions)") - pip = Executable(venv_path.bin.pip) - spack_installed = get_installed_pkg(pip) - - tty.msg(f"installing missing packages") - uv( - "sync", - "--active", - "--extra", - "all", - "--extra", - "cuda12", - "--inexact", - "--no-editable", - "--python", - str(venv_path.bin.python), - *no_install_options([*spack_installed, "cupy-cuda12x", "ghex"]), - extra_env={"VIRTUAL_ENV": str(venv_path)}, - ) - - tty.msg(f"linking spack installed packages into venv") - pathlib.Path( - f"{venv_path.lib.python}{python_spec.version.up_to(2)}/site-packages/spack_installed.pth" - ).write_text(pythonpath_to_pth()) - - tty.msg(f"running py2fgen") - py2fgen = Executable(venv_path.bin.py2fgen) - py2fgen( - "icon4py.tools.py2fgen.wrappers.all_bindings", - "diffusion_init,diffusion_run,grid_init,solve_nh_init,solve_nh_run", - "icon4py_bindings", - "-o", - prefix.src, - extra_env={"VIRTUAL_ENV": str(venv_path)}, - ) - - -def prepare_uv(): - uv = which("uv") - uv.add_default_env("UV_NO_CACHE", "true") - uv.add_default_env("UV_NO_MANAGED_PYTHON", "true") - uv.add_default_env("UV_PYTHON_DOWNLOADS", "never") - return uv - - -def get_installed_pkg(pip): - return [ - item["name"] for item in json.loads(pip("list", "--format", "json", output=str)) - ] - - -def no_install_options(installed): - for name in installed: - yield "--no-install-package" - yield name - - -def pythonpath_to_pth(): - return "\n".join(os.environ["PYTHONPATH"].split(":")) diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch deleted file mode 100644 index 5dc7e2e..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.2.patch +++ /dev/null @@ -1,102 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index ba19089..2ba222a 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -1,6 +1,12 @@ - cmake_minimum_required(VERSION 3.17) - # CMake version is set at 3.17 because of find_package(CUDAToolkit) - -+if (NOT ${CMAKE_VERSION} VERSION_LESS 3.27) -+ # new in 3.27: additionally use uppercase _ROOT -+ # environment and CMake variables for find_package -+ cmake_policy(SET CMP0144 NEW) -+endif() -+ - set(OOMPH_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - list(APPEND CMAKE_MODULE_PATH "${OOMPH_MODULE_PATH}") - -@@ -108,11 +114,11 @@ endif() - install(EXPORT oomph-targets - FILE oomph-targets.cmake - NAMESPACE oomph:: -- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) - - configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/oomphConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/oomphConfig.cmake -- INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) -+ INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) - - write_basic_package_version_file(oomphConfigVersion.cmake - VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) -@@ -125,7 +131,7 @@ install( - ${CMAKE_CURRENT_LIST_DIR}/cmake/FindUCX.cmake - ${CMAKE_CURRENT_LIST_DIR}/cmake/FindPMIx.cmake - DESTINATION -- ${CMAKE_INSTALL_LIBDIR}/cmake) -+ ${CMAKE_INSTALL_LIBDIR}/oomph/cmake) - - export(EXPORT oomph-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/oomph-targets.cmake") -diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake -index ec672b5..a578ef5 100644 ---- a/cmake/oomph_external_dependencies.cmake -+++ b/cmake/oomph_external_dependencies.cmake -@@ -31,17 +31,30 @@ endif() - # --------------------------------------------------------------------- - # google test setup - # --------------------------------------------------------------------- --add_external_cmake_project( -- NAME googletest -- PATH ext/googletest -- INTERFACE_NAME ext-gtest -- LIBS libgtest.a libgtest_main.a -- CMAKE_ARGS -- "-DCMAKE_BUILD_TYPE=release" -- "-DBUILD_SHARED_LIBS=OFF" -- "-DBUILD_GMOCK=OFF") --# on some systems we need link explicitly against threads --if (TARGET ext-gtest) -- find_package (Threads) -- target_link_libraries(ext-gtest INTERFACE Threads::Threads) -+cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON -+ "OOMPH_USE_BUNDLED_LIBS" OFF) -+if (OOMPH_WITH_TESTING) -+ if(OOMPH_USE_BUNDLED_GTEST) -+ add_external_cmake_project( -+ NAME googletest -+ PATH ext/googletest -+ INTERFACE_NAME ext-gtest -+ LIBS libgtest.a libgtest_main.a -+ CMAKE_ARGS -+ "-DCMAKE_BUILD_TYPE=release" -+ "-DBUILD_SHARED_LIBS=OFF" -+ "-DBUILD_GMOCK=OFF") -+ # on some systems we need link explicitly against threads -+ if (TARGET ext-gtest) -+ find_package (Threads) -+ target_link_libraries(ext-gtest INTERFACE Threads::Threads) -+ endif() -+ else() -+ # Use system provided google test -+ find_package(GTest REQUIRED) -+ add_library(ext-gtest INTERFACE) -+ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") -+ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) -+ else() -+ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) -+ endif() -+ endif() - endif() -diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt -index 06d703a..5217bba 100644 ---- a/test/CMakeLists.txt -+++ b/test/CMakeLists.txt -@@ -65,6 +65,7 @@ function(reg_parallel_test t_ lib n) - NAME ${t} - COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${n} ${MPIEXEC_PREFLAGS} - $ ${MPIEXEC_POSTFLAGS}) -+ set_tests_properties(${t} PROPERTIES RUN_SERIAL TRUE) - endfunction() - - if (OOMPH_WITH_MPI) diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch deleted file mode 100644 index aac73e8..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/install_0.3.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff --git a/cmake/oomph_external_dependencies.cmake b/cmake/oomph_external_dependencies.cmake -index a578ef5..92de39b 100644 ---- a/cmake/oomph_external_dependencies.cmake -+++ b/cmake/oomph_external_dependencies.cmake -@@ -33,28 +33,30 @@ endif() - # --------------------------------------------------------------------- - cmake_dependent_option(OOMPH_USE_BUNDLED_GTEST "Use bundled googletest lib." ON - "OOMPH_USE_BUNDLED_LIBS" OFF) --if(OOMPH_USE_BUNDLED_GTEST) -- add_external_cmake_project( -- NAME googletest -- PATH ext/googletest -- INTERFACE_NAME ext-gtest -- LIBS libgtest.a libgtest_main.a -- CMAKE_ARGS -- "-DCMAKE_BUILD_TYPE=release" -- "-DBUILD_SHARED_LIBS=OFF" -- "-DBUILD_GMOCK=OFF") -- # on some systems we need link explicitly against threads -- if (TARGET ext-gtest) -- find_package (Threads) -- target_link_libraries(ext-gtest INTERFACE Threads::Threads) -- endif() --else() -- # Use system provided google test -- find_package(GTest REQUIRED) -- add_library(ext-gtest INTERFACE) -- if (${CMAKE_VERSION} VERSION_LESS "3.20.0") -- target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) -+if (OOMPH_WITH_TESTING) -+ if(OOMPH_USE_BUNDLED_GTEST) -+ add_external_cmake_project( -+ NAME googletest -+ PATH ext/googletest -+ INTERFACE_NAME ext-gtest -+ LIBS libgtest.a libgtest_main.a -+ CMAKE_ARGS -+ "-DCMAKE_BUILD_TYPE=release" -+ "-DBUILD_SHARED_LIBS=OFF" -+ "-DBUILD_GMOCK=OFF") -+ # on some systems we need link explicitly against threads -+ if (TARGET ext-gtest) -+ find_package (Threads) -+ target_link_libraries(ext-gtest INTERFACE Threads::Threads) -+ endif() - else() -- target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) -+ # Use system provided google test -+ find_package(GTest REQUIRED) -+ add_library(ext-gtest INTERFACE) -+ if (${CMAKE_VERSION} VERSION_LESS "3.20.0") -+ target_link_libraries(ext-gtest INTERFACE GTest::GTest GTest::Main) -+ else() -+ target_link_libraries(ext-gtest INTERFACE GTest::gtest GTest::gtest_main) -+ endif() - endif() - endif() diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py deleted file mode 100644 index 3b320f9..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/oomph/package.py +++ /dev/null @@ -1,109 +0,0 @@ -from spack.package import * - - -class Oomph(CMakePackage, CudaPackage, ROCmPackage): - """Oomph is a non-blocking callback-based point-to-point communication library.""" - - homepage = "https://github.com/ghex-org/oomph" - url = "https://github.com/ghex-org/oomph/archive/refs/tags/v0.2.0.tar.gz" - git = "https://github.com/ghex-org/oomph.git" - maintainers = ["boeschf"] - - version("0.4.0", sha256="e342c872dfe4832be047f172dc55c12951950c79da2630b071c61607ef913144") - version("0.3.0", sha256="61e346d1ba28a859745de47f37edce39c7f5c5e1aab716493dc964e158fd99ec") - version("0.2.0", sha256="135cdb856aa817c053b6af1617869dbcd0ee97d34607e78874dd775ea389434e") - version("0.1.0", sha256="0ff36db0a5f30ae1bb02f6db6d411ea72eadd89688c00f76b4e722bd5a9ba90b") - version("main", branch="main") - - depends_on("cxx", type="build") - depends_on("fortran", type="build", when="+fortran-bindings") - - generator("ninja") - - backends = ("mpi", "ucx", "libfabric") - variant( - "backend", default="mpi", description="Transport backend", values=backends, multi=False - ) - - variant("fortran-bindings", default=False, description="Build Fortran bindings") - with when("+fortran-bindings"): - variant( - "fortran-fp", - default="float", - description="Floating point type", - values=("float", "double"), - multi=False, - ) - variant("fortran-openmp", default=True, description="Compile with OpenMP") - - variant( - "enable-barrier", - default=True, - description="Enable thread barrier (disable for task based runtime)", - ) - - depends_on("hwmalloc+cuda", when="+cuda") - depends_on("hwmalloc+rocm", when="+rocm") - depends_on("hwmalloc", when="~cuda~rocm") - - with when("backend=ucx"): - depends_on("ucx+thread_multiple") - depends_on("ucx+cuda", when="+cuda") - depends_on("ucx+rocm", when="+rocm") - variant("use-pmix", default="False", description="Use PMIx to establish out-of-band setup") - variant("use-spin-lock", default="False", description="Use pthread spin locks") - depends_on("pmix", when="+use-pmix") - - libfabric_providers = ("cxi", "efa", "gni", "psm2", "tcp", "verbs") - with when("backend=libfabric"): - variant( - "libfabric-provider", - default="tcp", - description="fabric", - values=libfabric_providers, - multi=False, - ) - for provider in libfabric_providers: - depends_on(f"libfabric fabrics={provider}", when=f"libfabric-provider={provider}") - - depends_on("mpi") - depends_on("boost+thread") - - depends_on("googletest", type=("build","test")) - - patch("install_0.2.patch", when="@:0.2.0", level=1) - patch("install_0.3.patch", when="@0.3.0", level=1) - - def cmake_args(self): - args = [ - self.define_from_variant("OOMPH_BUILD_FORTRAN", "fortran-bindings"), - self.define_from_variant("OOMPH_FORTRAN_OPENMP", "fortran-openmp"), - self.define_from_variant("OOMPH_UCX_USE_PMI", "use-pmix"), - self.define_from_variant("OOMPH_UCX_USE_SPIN_LOCK", "use-spin-lock"), - self.define_from_variant("OOMPH_ENABLE_BARRIER", "enable-barrier"), - self.define("OOMPH_WITH_TESTING", self.run_tests), - self.define("OOMPH_GIT_SUBMODULE", False), - self.define("OOMPH_USE_BUNDLED_LIBS", False), - ] - - if self.run_tests and self.spec.satisfies("^openmpi"): - args.append(self.define("MPIEXEC_PREFLAGS", "--oversubscribe")) - - if self.spec.variants["fortran-bindings"].value == True: - args.append(self.define("OOMPH_FORTRAN_FP", self.spec.variants["fortran-fp"].value)) - - for backend in self.backends: - args.append( - self.define( - f"OOMPH_WITH_{backend.upper()}", self.spec.variants["backend"].value == backend - ) - ) - - if self.spec.satisfies("backend=libfabric"): - args.append( - self.define( - "OOMPH_LIBFABRIC_PROVIDER", self.spec.variants["libfabric-provider"].value - ) - ) - - return args diff --git a/recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py b/recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py deleted file mode 100644 index 6941eff..0000000 --- a/recipes/icon-dsl/25.12/gh200/repo/packages/uv/package.py +++ /dev/null @@ -1,68 +0,0 @@ -from spack.package import * - - -def translate_platform(platform_name: str) -> str: - if platform_name == "darwin": - return "apple-darwin" - elif platform_name == "linux": - return "unknown-linux-gnu" - return platform_name - - -def translate_arch(arch_name: str) -> str: - if arch_name in ["m1", "m2", "neoverse_v2"]: - return "aarch64" - if arch_name in ["zen3"]: - return "x86_64" - return arch_name - - -class Uv(Package): - """Install UV from binary releases""" - - url = "https://github.com/astral-sh/uv/releases/download/0.7.12/uv-aarch64-apple-darwin.tar.gz" - - version( - "0.7.12", - sha256="189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e", - extension=".tar.gz", - ) - version( - "0.7.20", - sha256="675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9", - extension=".tar.gz", - ) - - def url_for_version(self, version): - arch = translate_arch(self.spec.target) - platform = translate_platform(self.spec.platform) - return f"https://github.com/astral-sh/uv/releases/download/{version}/uv-{arch}-{platform}.tar.gz" - - def do_stage(self, mirror_only=False): - checksums = { - ("0.7.12", "apple-darwin", "aarch64"): ( - "189108cd026c25d40fb086eaaf320aac52c3f7aab63e185bac51305a1576fc7e" - ), - ("0.7.20", "unknown-linux-gnu", "aarch64"): ( - "675165f879d6833aa313ecb25ac44781e131933a984727e180b3218d2cd6c1e9" - ), - ("0.7.20", "unknown-linux-gnu", "x86_64"): ( - "10f204426ff188925d22a53c1d0310d190a8d4d24513712e1b8e2ca9873f0666" - ), - } - version = str(self.spec.version) - arch = translate_arch(self.spec.target) - platform = translate_platform(self.spec.platform) - key = (version, platform, arch) - - if key not in checksums: - msg = f"Unsupported platform/arch for version {version}: {platform}-{arch}." - raise InstallError(msg) - - self.fetcher.digest = checksums[key] - super().do_stage(mirror_only) - - def install(self, spec, prefix): - mkdir(prefix.bin) - install("uv", prefix.bin.uv) - install("uvx", prefix.bin.uvx) From 6612a26728f6ed895c5d5cce9d80b3c8441cada4 Mon Sep 17 00:00:00 2001 From: Daniel Hupp Date: Tue, 16 Dec 2025 14:47:58 +0100 Subject: [PATCH 32/32] add recipes to config.yml --- config.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config.yaml b/config.yaml index 1a3e930..adc3caf 100644 --- a/config.yaml +++ b/config.yaml @@ -48,6 +48,14 @@ uenvs: santis: [gh200] balfrin: [a100] develop: False + "25.12": + recipes: + gh200: '25.12/gh200' + a100: '25.12/a100' + deploy: + santis: [gh200] + balfrin: [a100] + develop: False mch: "v7": recipes: