Adding a System

Glossary terms: Package, Spec, Variant, System

Create the System Definition

This example defines the fluxtainer system. Start systems/fluxtainer/system.py with the definition below. The steps that follow add the components omitted from this initial version.

  1# Copyright 2023 Lawrence Livermore National Security, LLC and other
  2# Benchpark Project Developers. See the top-level COPYRIGHT file for details.
  3#
  4# SPDX-License-Identifier: Apache-2.0
  5
  6from benchpark.directives import maintainers, variant
  7from benchpark.openmpsystem import OpenMPCPUOnlySystem
  8from benchpark.system import System, compiler_def, compiler_section_for
  9
 10
 11class Fluxtainer(System):
 12    """This is the system class for a container running Flux.
 13    See https://flux-framework.readthedocs.io/en/latest/tutorials/containers/index.html for more
 14    information."""
 15
 16    maintainers("nhanford")
 17
 18    id_to_resources = {
 19        # Step 1 adds the ARM64 resource mapping here.
 20        "amd64": {"cpu_arch": "x86_64_v3"},
 21    }
 22
 23    variant(
 24        "instance_type",
 25        values=(
 26            "amd64",
 27            # Step 1 adds the ARM64 instance type here.
 28        ),
 29        default="amd64",
 30        description="Target Architecture",
 31    )
 32
 33    variant(
 34        "compiler",
 35        default="gcc",
 36        values=(
 37            "gcc",
 38            # Step 3 adds the Clang compiler value here.
 39        ),
 40        description="Which compiler to use",
 41    )
 42
 43    def __init__(self, spec):
 44        super().__init__(spec)
 45        # Step 2 adds runtime and resource attributes here.
 46
 47    def compute_compilers_section(self):
 48        cfg = compiler_section_for(
 49            "gcc",
 50            [
 51                compiler_def(
 52                    "gcc@14.3.1 languages=c,c++,fortran",
 53                    "/usr/",
 54                    {"c": "gcc", "cxx": "g++", "fortran": "gfortran"},
 55                )
 56            ],
 57        )
 58
 59        # Step 3 adds the Clang compiler definition here.
 60
 61        return cfg
 62
 63    def compute_packages_section(self):
 64        return {
 65            "packages": {
 66                "mpi": {"buildable": False},
 67                "mpich": {
 68                    "externals": [
 69                        {
 70                            "spec": "mpich@4.1.2",
 71                            "prefix": "/usr/lib64/mpich",
 72                        }
 73                    ]
 74                },
 75                "cmake": {
 76                    "externals": [{"spec": "cmake@3.30.5", "prefix": "/usr"}],
 77                    "buildable": False,
 78                },
 79                "git": {
 80                    "externals": [{"spec": "git@2.47.3~tcltk", "prefix": "/usr"}],
 81                    "buildable": False,
 82                },
 83                "openssl": {
 84                    "externals": [{"spec": "openssl@3.0.2", "prefix": "/usr"}],
 85                    "buildable": False,
 86                },
 87                "automake": {
 88                    "externals": [{"spec": "automake@1.16.5", "prefix": "/usr"}],
 89                    "buildable": False,
 90                },
 91                "openssh": {
 92                    "externals": [{"spec": "openssh@9.9p1", "prefix": "/usr"}],
 93                    "buildable": False,
 94                },
 95                "m4": {
 96                    "externals": [{"spec": "m4@1.4.19", "prefix": "/usr"}],
 97                    "buildable": False,
 98                },
 99                "sed": {
100                    "externals": [{"spec": "sed@4.9", "prefix": "/usr"}],
101                    "buildable": False,
102                },
103                "autoconf": {
104                    "externals": [{"spec": "autoconf@2.71", "prefix": "/usr"}],
105                    "buildable": False,
106                },
107                "diffutils": {
108                    "externals": [{"spec": "diffutils@3.10", "prefix": "/usr"}],
109                    "buildable": False,
110                },
111                "coreutils": {
112                    "externals": [{"spec": "coreutils@8.32", "prefix": "/usr"}],
113                    "buildable": False,
114                },
115                "findutils": {
116                    "externals": [{"spec": "findutils@4.10.0", "prefix": "/usr"}],
117                    "buildable": False,
118                },
119                "binutils": {
120                    "externals": [
121                        {"spec": "binutils@2.41+gold~headers", "prefix": "/usr"}
122                    ],
123                    "buildable": False,
124                },
125                "perl": {
126                    "externals": [
127                        {
128                            "spec": "perl@5.74.0~cpanm+opcode+open+shared+threads",
129                            "prefix": "/usr",
130                        }
131                    ],
132                    "buildable": False,
133                },
134                "groff": {
135                    "externals": [{"spec": "groff@1.22.4", "prefix": "/usr"}],
136                    "buildable": False,
137                },
138                "curl": {
139                    "externals": [
140                        {"spec": "curl@8.12.1+gssapi+ldap+nghttp2", "prefix": "/usr"}
141                    ],
142                    "buildable": False,
143                },
144                "ccache": {
145                    "externals": [{"spec": "ccache@4.11.3", "prefix": "/usr"}],
146                    "buildable": False,
147                },
148                "flex": {
149                    "externals": [{"spec": "flex@2.6.4+lex", "prefix": "/usr"}],
150                    "buildable": False,
151                },
152                "pkg-config": {
153                    "externals": [{"spec": "pkg-config@0.29.2", "prefix": "/usr"}],
154                    "buildable": False,
155                },
156                "zlib-ng": {
157                    "externals": [{"spec": "zlib-ng@2.2.3", "prefix": "/usr"}],
158                    "buildable": False,
159                },
160                "ninja": {
161                    "externals": [{"spec": "ninja@1.11.1", "prefix": "/usr"}],
162                    "buildable": False,
163                },
164                "libtool": {
165                    "externals": [{"spec": "libtool@2.4.7", "prefix": "/usr"}],
166                    "buildable": False,
167                },
168                "bzip2": {
169                    "externals": [{"spec": "bzip2@1.0.8", "prefix": "/usr"}],
170                    "buildable": False,
171                },
172                "expat": {
173                    "externals": [{"spec": "expat@2.7.1", "prefix": "/usr"}],
174                    "buildable": False,
175                },
176                "gdbm": {
177                    "externals": [{"spec": "gdbm@1.23", "prefix": "/usr"}],
178                    "buildable": False,
179                },
180                "gettext": {
181                    "externals": [{"spec": "gettext@0.22.5", "prefix": "/usr"}],
182                    "buildable": False,
183                },
184                "libffi": {
185                    "externals": [{"spec": "libffi@3.4.4", "prefix": "/usr"}],
186                    "buildable": False,
187                },
188                "libxml2": {
189                    "externals": [{"spec": "libxml2@2.12.5", "prefix": "/usr"}],
190                    "buildable": False,
191                },
192                "ncurses": {
193                    "externals": [{"spec": "ncurses@6.4", "prefix": "/usr"}],
194                    "buildable": False,
195                },
196                "readline": {
197                    "externals": [{"spec": "readline@8.2", "prefix": "/usr"}],
198                    "buildable": False,
199                },
200                "sqlite": {
201                    "externals": [{"spec": "sqlite@3.46.1", "prefix": "/usr"}],
202                    "buildable": False,
203                },
204                # Step 4 adds the external tar package here.
205                "util-linux-uuid": {
206                    "externals": [{"spec": "util-linux-uuid@2.40.2", "prefix": "/usr"}],
207                    "buildable": False,
208                },
209                "xz": {
210                    "externals": [{"spec": "xz@5.6.2", "prefix": "/usr"}],
211                    "buildable": False,
212                },
213                "zstd": {
214                    "externals": [{"spec": "zstd@1.5.5", "prefix": "/usr"}],
215                    "buildable": False,
216                },
217                "gmake": {
218                    "externals": [{"spec": "gmake@4.4.1", "prefix": "/usr"}],
219                    "buildable": False,
220                },
221                "pigz": {
222                    "externals": [{"spec": "pigz@2.8.7", "prefix": "/usr"}],
223                    "buildable": False,
224                },
225                "libmd": {
226                    "externals": [{"spec": "libmd@1.2.0", "prefix": "/usr"}],
227                    "buildable": False,
228                },
229                "libbsd": {
230                    "externals": [{"spec": "libbsd@0.12.2", "prefix": "/usr"}],
231                    "buildable": False,
232                },
233                "python": {
234                    "externals": [{"spec": "python@3.12.12", "prefix": "/usr"}],
235                    "buildable": False,
236                },
237            }
238        }
239
240    def compute_software_section(self):
241        default_compiler = "gcc"
242        if self.spec.satisfies("compiler=llvm"):
243            default_compiler = "llvm"
244        return {
245            "software": {
246                "packages": {
247                    "default-compiler": {"pkg_spec": default_compiler},
248                    "compiler-gcc": {"pkg_spec": "gcc"},
249                    "default-mpi": {"pkg_spec": "mpich"},
250                }
251            }
252        }

1. Add Another Target Architecture

The starter definition supports the amd64 architecture. Adding arm64 requires a resource mapping and a corresponding value in the instance_type variant.

Replace the first Step 1 placeholder in id_to_resources with:

# In id_to_resources:
        "arm64": {"cpu_arch": "arm64"},

Replace the second Step 1 placeholder in the instance_type variant with:

# In the instance_type values tuple:
            "arm64",

2. Set Runtime and Resource Attributes

The system initializer specifies how Benchpark runs workloads and allocates resources. Replace the Step 2 placeholder in __init__() with:

# In __init__():
        self.programming_models = [OpenMPCPUOnlySystem()]

        self.scheduler = "flux"
        setattr(self, "sys_cores_per_node", 4)
        setattr(self, "sys_mem_per_node_GB", 1)
        setattr(self, "n_nodes", 1)
        attrs = self.id_to_resources.get(self.spec.variants["instance_type"][0])
        for k, v in attrs.items():
            setattr(self, k, v)

3. Add Clang

The compiler variant exposes the compiler choice in the system spec. Replace the first Step 3 placeholder in its values tuple with:

# In the compiler values tuple:
            "clang",

compute_compilers_section() tells Spack which LLVM installation and Clang executables are available. Replace the second Step 3 placeholder, immediately before return cfg, with:

# In compute_compilers_section():
        if self.spec.satisfies("compiler=clang"):
            cfg = compiler_section_for(
                "clang",
                [
                    compiler_def(
                        "llvm@20.1.8",
                        "/usr/lib64/ccache/",
                        {"c": "clang", "cxx": "clang++"},
                    )
                ],
            )

4. Add the Tar Package

compute_packages_section() records software already installed on the system. Replace the Step 4 placeholder with the external tar package definition:

# In the packages dictionary:
                "tar": {
                    "externals": [{"spec": "tar@1.35", "prefix": "/usr"}],
                    "buildable": False,
                },

Initialize the system to validate the definition:

$ benchpark system init --dest=fluxtainer fluxtainer

For the complete system authoring reference, see Adding a System.

Next Step