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.