$Id$ | Latest: www.spec.org/hpc2021/Docs/ |
---|
A. What is a config file? B. Benchmark selection C. Five consumers |
D. Syntax 1. Sections and scope 2. Comments 3. Whitespace 4. Quoting 5. Line continuation 6. Included files 7. Section markers E. Section merging |
F. Variables 1. Defining variables 2. $[square] substitution 3. Useful $[variables] 4. ${curly} interpolation 5. Useful ${variables} 6. Unsetting "%undef%" 7. Debug tips |
All variable types $(MAKEVAR)\$SHELLVAR $[startup] ${during_run}/$during_run %{macro} %{ENV_var} New with SPEChpc 2021 |
II. Config file options for runhpc
A. Precedence: config file vs. runhpc command line
B. Options
action allow_label_override backup_config basepeak bind check_version command_add_redirect delay deletework difflines enable_monitor env_vars expand_notes expid fail fail_build fail_run flagsurl force_monitor http_proxy http_timeout ignore_errors ignore_sigint info_wrap_columns iterations keeptmp line_width label locking log_line_width log_timestamp mail_reports mailcompress mailmethod mailport mailserver mailto make make_no_clobber makeflags mean_anyway minimize_builddirs minimize_rundirs no_input_handler no_monitor nobuild notes_wrap_columns notes_wrap_indent output_format output_root pmodel New preenv ranks rebuild reportable runlist save_build_files section_specifier_fatal setprocgroup showtimer New size src.alt strict_rundir_verify table teeout threads tune use_submit_for_speed verbose verify_binaries version_url
III. Config file options for specmake
A. Commonly used Make variables
CC, CXX, FC |
B. Parallel Model Selection C. Creating your own Make variables D. += is available but use with caution E. Using buildsetup to create a sandbox F. About Automatic Rebuilds |
|
{C|CXX|F}C_VERSION_OPTION New and required with SPEChpc 2021 |
IV. Config file options for the shell
A. \$SHELLVAR variable substitution B. Options bench_post_setup build_pre_bench build_post_bench mointor_X post_setup submit |
C. Using submit 1. Basic usage 2. Using scripts with submit for thread binding 3. Reporting |
V. Config file options for human readers
VII. The config file preprocessor
A. Introduction 1. Example: Picking Model 2. Syntax Basics B. Defining macros 1. In a config file 2. On the command line 3. Predefined macros: endian, hostname...
4. Example: Adjusting the Environment 5. Redefinition |
C. Un-doing macro definition D. Using macros E. Conditionals 1. %ifdef .. %endif 2. %ifndef .. %endif 3. %if .. %endif 4. %else 5. %elif |
F. Informational directives 1. %warning 2. %error 3. %info New with SPEChpc 2021 4. %dumpmacros New with SPEChpc 2021 |
VII. Output files - and how they relate to your config file
A. Help, I've got too many config files! B. The log file 1. Useful Search Strings 2. About Temporary Debug Logs 3. Verbosity levels |
D. Help, I've got too many log files! E. Finding the build directory F. Files in the build directory G. For more information |
A. Other benchmark sets
B. Obsolete features
I.A. What is a config file?A SPEChpc config file is a file that defines how to build, run, and report on the SPEChpc benchmarks in a particular environment. It defines how SPEChpc 2021 interacts with your test environment, and lets you describe that environment in human-readable form. A config file provides detailed control of testing, including:
Using your customized options, the SPEChpc tools automatically create Makefiles, build the benchmarks, run them, generate reports, and write log files. Because they collect your options into one place, config files are key to result reproducibility. For example, if a vendor publishes SPEChpc 2021 results for the SuperHero Model 42 at the SPEC web site www.spec.org/hpc2021, it is expected that a customer can demonstrate similar performance using only 3 ingredients:
|
q. This document looks big and intimidating. Where do I start? a. Don't start here. Start with the Overview and Using SPEC SPEChpc 2021 - the 'runhpc' Command. After that, please read section I.C carefully, which explains that config files contain options for five (5) different consumers. You need to recognize which options are for which consumers. Please notice that config files have 3 kinds of sections. You need to know how named sections work. From that point on, you can probably skip around among topics as they may interest you. Tip: Most topics can be found by adding '#topic' to the URL for this document. Examples: #consumers #shell #readers #sw_c_compiler Still lost? The config file directory contains several example config files (Prefixed as "Example_"). Copy the example that best matches the compiler version you're using to a new config file, and edit from there. The "Example_SUT.inc" file includes an example for the system description fields which you can either copy into your config file, or copy it to a new include file for your particular system. |
In a config file, you can reference: One or more individual benchmarks, such as 605.lbm_s, or entire suites, using the Short Tags in the table below.
Short Tag |
Suite | Contents | Metrics | How many ranks? What do Higher Scores Mean? |
Tiny | SPEChpc 2021 Tiny Workload | 9 benchmarks | SPEChpc 2021_tny_base SPEChpc 2021_tny_peak |
The Tiny workloads use up to 60GB of memory and are
intended for use on a single node using between 1 and 256 ranks. More nodes and ranks may be used however higher rank counts may see lower scaling as MPI communication becomes more dominant.
Higher scores indicate that less time is needed. |
Small | SPEChpc 2021 Small Workload | 9 benchmarks | SPEChpc 2021_sml_base SPEChpc 2021_sml_peak |
The Small workloads use up to 480GB of memory and are intended for use on one or more nodes using between 64 and 1024 ranks. More ranks may be used however higher rank counts may see lower scaling as MPI communication becomes more dominant.
Higher scores indicate that less time is needed. |
Medium | SPEChpc 2021 Medium Workload | 6 benchmarks | SPEChpc 2021_med_base SPEChpc 2021_med_peak |
The Medium workloads use up to 4TB of memory and are intended for use on a mid-size cluster using between 256 and 4096 ranks. More ranks may be used however higher rank counts may see lower scaling as MPI communication becomes more dominant.
Higher scores indicate that less time is needed. |
Large | SPEChpc 2021 Large Workload | 6 benchmarks | SPEChpc 2021_lrg_base SPEChpc 2021_lrg_peak |
The Large workloads use up to 14.5TB of memory and are intended for use on a larger clusters using between 2048 and 32,768 ranks. More ranks may be used however higher rank counts may see lower scaling as MPI communication becomes more dominant.
Higher scores indicate that less time is needed. |
The "Short Tag" is the canonical abbreviation for use with runhpc, where context
is defined by the tools. In a published document, context may not be clear.
To avoid ambiguity in published documents, the Suite Name or the Metrics should be spelled as shown above. |
A config file has content for five (5) distinct consumers, as shown in the table.
To understand a config file, you must understand which consumer is addressed at any given
point.
Column 3 below provides a few examples for each; click the roman numerals in column 2 for many more.
Consumer | List of options |
Examples | Brief description |
runhpc | II |
ranks
output_format reportable threads pmodel |
Options that change how runhpc itself works. Many should be familiar from Using SPEChpc 2021. output_format = text,csv tune = base reportable = yes ranks = 2048 pmodel = MPI runlist = medium then the defaults for the runhpc command would change as shown. Both of these would do the same thing: runhpc --config=jimmy --output=text,csv --tune=base --reportable --pmodel=MPI -ranks 2048 medium |
---|---|---|---|
specmake | III |
OPTIMIZE
PORTABILITY |
Make variables, to control benchmark builds via specmake.
Commonly used specmake variables: section III
|
shell | IV |
post_setup submit |
Commands to be executed by the Unix shell (/bin/sh)
submit = mpirun -np $ranks --bind-to none $[top]/bind.sh $command Above, the mpirun command will use a user supplied "bind.sh" shell script to perform binding per rank.
Warning: SPEChpc config files can execute arbitrary
shell commands.
|
readers | V | hw_model
notes100 sw_compiler |
System Under Test (SUT) description, with enough detail so that the reader can understand what was tested and can reproduce your results. If a SPEChpc 2021 result is published (whether at SPEC or independently) it must be fully described. |
preprocessor | VII | %define
%ifdef |
Preprocessing directives and definitions to adjust your config file prior to use. All preprocessor directives begin in column 1. Example: %if %{model} eq 'openacc' % define model_define -DSPEC_OPENACC %endif OPTIMIZE = -O3 %{model_define} |
A config file contains: a header section, named sections, and a HASH section.
Scope: Every line is considered to be within the scope of one of these three. Lines prior to the first section marker are in the scope of the header section. All other lines are either in the scope of the most recently preceding section marker or in the HASH section.
Sections | Description | Example |
header section |
The header section is the first section, prior to the any named section. Most attempts to address runhpc itself are done in the header section. In the example, lines 1 through 6 are in the header section. |
$ cat -n hiroshi.cfg 1 flagsurl = $[top]/config/flags/gcc.xml 2 iterations = 1 3 output_format = text 4 runlist = 605.lbm_s 5 size = ref 6 tune = peak 7 small=peak: 8 CC_VERSION_OPTION = -v 9 CC = mpicc 10 OPTIMIZE = -O2 11 605.lbm_s=peak: 12 OPTIMIZE = -O3 13 14 __HASH__ 15 605.lbm_s=peak=none: 16 # Last updated 2021-02-06 14:29:40 17 opthash=ff6059d6d9ec9577f7f49d05178c58688f31004089 18 baggage= 19 compiler_version=\ 20 @eNo1jbEOgjAYhPc+RUcdaFEJIWwGHEhQjBLjRn7LLzapLWkL8 21 kpP9OCqkdX070hmtk0bTjMUspiuhQA9RFgfDki3brEkLdkCf0y 22 0NO36VHldDROLqTSzoNS2JfS5pT/DqUAH54cv4tAsjDEC6M9au 23 FuH/CZ+c5Q+pyRd+tUlX 24 compile_options=\ 25 @eNp1T11PgzAUfe+vaPrOMjNfJGMJlLqhQBtLX3xptHYGBWoKM 26 vNp93Vjs3obadX2I+sHXZtD+0D3VXr9bX+8/InJBEMAeKBFZLq 27 KgWj06epUADLlCVqe+rFquJaKiHumJSaC1YWAuOAr/DPWvfu4I 28 mALF6zzeSpj96+RITFhJd3rG/dMaQTzEIJYV2T0DJl8RlGfl7Z 29 hjyd8vw+D9MirnY6z5LRW9NOC1yNkc/OfAJtxnuD 30 exehash=5290fe504238c6de1a13e275ab8ca11e035fbb4e7e 31 $ |
---|---|---|
or default: |
Options for the header section may also be entered in section default=default=default: or a shorter spelling thereof, such as default: This can be helpful if you need to effectively return to the header section, perhaps when using include. Tip: Nevertheless, it is usually easier to maintain a config files that keeps all runhpc options near the top, preferably in alphabetical order. |
|
Named sections |
A named section is a portion of the config file that follows a line that contains a section marker. Briefly, a section marker is a 1-to-3 part string with equals signs in the middle and a colon at the end; see detail below. The example has 2 named sections, delimited by 2 section markers on lines 7 and 11. Notice that the example sets OPTIMIZE in both of the named sections. To understand which one gets used, see the precedence rules, which describe how sections interact. |
|
HASH section |
The HASH Section is the final, automatically-generated section. It starts with __HASH__ and contains checksums. The example starts the HASH section at line 14. (For readability, the lines are truncated on the right.) The automatically-updated checksums ensure that binaries match their config file. You can optionally disable checking, but doing so is strongly discouraged. See verify_binaries. Config files printed by --output_format=config do not include the HASH section. |
Comments begin with '#'. There are two types:
Syntax | Type | Saved? | Detail |
---|---|---|---|
# | Regular | Yes | Regular comments can be full-line or trailing. A copy of your config file is saved with the test results. If you submit your results to SPEC for publication, the regular comments can be read by anyone. |
#> | Protected | No | A full-line comment that begins with #> is a protected comment and will not be saved with your results. You can use protected comments for proprietary information, for example: #> I didn't use the C++ beta because of Bob's big back-end bug. |
Both types of comments are ignored when processing the config file.
Full-line comments: If # is the first non-blank item on a line, then the whole line is a comment. Comment lines can be placed anywhere in a config file.
Trailing comments: If a line has non-blank items, you can (usually) add regular comments. You cannot write a protected trailing comment. If you try to use a protected comment after some other element, it is treated as a regular comment.
All comments below will be saved except the one that says 'NOT saved'.
# New optimizers. default=base: # Most optimizers go up to ten. OPTIMIZE = -O11 # These go to eleven. #> This comment is NOT saved COPTIMIZE = -std #> This comment is saved
Not a comment: These instances of # do not start a comment:
\# To use a # without starting a comment, put a backslash in front of it:
hw_model = MegaCorp's \#1 Semi-Autonomous Unit
notesN...# Config file notes are printed in reports as entered, including any instances of #
#notes100 = This note will not be printed, because # was the first item on the line.T notes110 = This note will be printed in reports. All of it. # Even this part.
Blank lines can be placed anywhere in a config file. They are ignored.
Spaces at the beginning of lines are ignored, with the exception that preprocessor directives always begin with a percent sign (%) in the first column. You can put spaces after the percent sign, if you wish (example).
Spaces within a line are usually ignored. Don't try to break up a section marker, and you can't break up a single word (say 'OPTIMIZE' not 'OPT I MIZE'). If multiple spaces separate line elements, it is as if there were only one space. Each of these have the same meaning:
OPTIMIZE=-O2 -noalias OPTIMIZE = -O2 -noalias
One place where spaces are considered significant is in notes, where you can use spaces to line up your comments. Notes are printed in a fixed-width font.
Trailing spaces and tabs are ignored, unless they are preceded by a backslash.
If you use double (") or single (') quotes within a config file, runhpc leaves them alone. The assumption is that you put them there because one of the consumers (such as a shell) needs them. The quotes are not significant to runhpc but may be highly significant to the consumer. See the section on quote traps.
If you use a backslash (\) it is usually not significant. The exceptions are:
Many fields, including most reader fields, can be continued by adding a number:
node_compute_hw_tcache000= 256 MB I+D on chip per chip node_compute_hw_tcache001 = 16 MB shared / 4 cores node_compute_sw_os1 = SUSE Linux Enterprise Linux Server 12 node_compute_sw_os2 = 4.12.14-94.41-default
The fields which cannot be continued are the ones that are expecting a simple integer, such as node_hw_nchips and license_num; and the ones that expect a date, such as hw_avail. You can pick your own style of numbering, as in the examples above. (Note: the stored results from your test always use three-digit numbers, and have slightly different syntax, as discussed in utility.html.)
Shell-style "here documents" with double angle brackets and a delimiter word (e.g. <<EOT) can be used to set multi-line values. Backslash-continued lines are also supported. For example:
$ cat continued_lines.cfg expand_notes = 1 output_format = text output_root = /tmp/fake_lines runlist = 605.lbm_s here_continued = <<EOT + This is + + a test + EOT backslash_continued = + So is +\ + this + notes1 = ${here_continued} notes2 = ${backslash_continued} $ cat continued_lines.sh runhpc --config=continued_lines --fakereport | grep txt grep '+' /tmp/fake_lines/result/hpc2021_sml*txt $ ./continued_lines.sh format: Text -> /tmp/fake_lines/result/hpc2021_sml.001.small.ref.txt + This is + + a test + + So is + + this + $
You can include other files in your config file using include:
Multiple files may be included.
Included files may use macros (and you can use configpp to check the effect).
Included files may write to arbitrary sections, including
(effectively) the header section.
Example: a config file is developed on one system, and applied on a different System Under Test (SUT). The compilers are, of course, installed on the development system. They might not be present on the SUT.
The compiler is described in the main config file on lines 10-12.
$ cat -n include.cfg 1 iterations = 1 2 output_format = text 3 output_root = /tmp/example 4 runlist = 605.lbm_s 5 size = test 6 test_sponsor = Turboblaster 7 tester = Turboblaster 8 include: SUT.inc 9 default: 10 CC = mpicc 11 CC_VERSION_OPTION = -V 12 sw_compiler000 = C/C++/Fortran: Version 9.2.0 of 13 sw_compiler001 = GNU Compiler Collection 14 sw_avail = Aug-2019 15 sw_mpi_library = OpenMPI Version 3.1.5 $ Note the software date (sw_avail) on line 14 above.
$ cp Turboblaster.inc SUT.inc $ cat Turboblaster.inc default: node_compute_label = TurboBlaster 5000 node_compute_order = 1 node_compute_count = 2 node_compute_purpose = compute node_compute_hw_vendor = Mega Technology node_compute_hw_model = Turblaster 5000 node_compute_hw_cpu_name = Turbo CPU node_compute_hw_ncpuorder = 1 chips hw_avail = Feb-2018 $ Note the hardware date (hw_avail) in the include file.
$ cat include.sh runhpc --config=include | grep txt grep avail /tmp/example/result/*txt $ ./include.sh format: Text -> /tmp/example/result/hpc2021_sml.001.small.test.txt Test sponsor: Turboblaster Hardware availability: Feb-2018 Tested by: Turboblaster Software availability: Aug-2019 $ I.D.7. Section markers and Named sectionsA named section begins with a section marker and continues until the next section marker or the HASH section is
reached.
A section marker is a one- to three-part string of the form: benchmark[,...]=tuning[,...]=label[,...]: The three parts of a section marker are called the section specifiers, with allowed values:
Trailing default section specifiers may be omitted from a section marker. In the pairs below, in each case, the second line is equivalent to the first: small=default=default: 605.lbm_s=base=default: default=default=default: small: 605.lbm_s=base: default: I.E. Section merging and precedence rulesBy constructing section markers, you determine how you would like your options applied. Benchmarks are built according
to instructions in the sections that they match, subject to rules for combining sections and resolving conflicts among them.
Sections are combined using these rules.
I.F. Variables and Variable Substitution
I.F.1. Defining variablesYou can create your own runhpc variables using a line of the form name = value The name may contain only letters, digits, and underscores (a hyphen is NOT allowed).
Exception: preprocessor macros are different on all of the above. Hyphens are allowed, use %define name value and the % must appear in column 1. You can indent after the % if you wish. Conventions: Although not required, certain conventions are usually followed:
Examples of the above (in the same order) %ifndef processorNumaControl % define processorNumaControl firstTouch # macro %endif default: my_submit_cmd = numactl -C $BIND # runhpc variable MYTUNE = -O2 --math=SIMD # make variable ENV_LD_LIBRARY_PATH = /opt/lib # environment variable The remainder of this section I.F is about runhpc variables -- the $[square] and ${curly} rows from the table at the top. I.F.2. $[square] substitution at startupImmediately after preprocessing, variables that are delimited by $[square
brackets] are substituted.
flagsurl01 = $[top]/config/compiler.xml flagsurl02 = $[top]/config/platform.xml EXTRA_LIBS = $[top]/mylibs preENV_LIBRARY_PATH = $[top]/lib64:$[top]/lib Traps for the unwary: In some cases it may be obvious to the human which value to use, but the tools aren't as smart as you.
Square substitution is done early. That comes in handy if you need a variable right away, for example, in order to use it with preENV. $ cat EarlySub.cfg SW_DIR = /opt/path/to/compilers preENV = 1 preENV_LD_LIBRARY_PATH = $[SW_DIR]/lib $ cat EarlySub.sh runhpc --config=EarlySub --fake 605.lbm_s | grep '^LD' | uniq $ ./EarlySub.sh LD_LIBRARY_PATH=/opt/path/to/compilers/lib $ The example below uses variables defined in several named sections. The sections are delimited by section markers default: (line 8), default=base: (line 11), and default=peak: (line 15). $ cat -n square.cfg 1 expand_notes = 1 2 iterations = 1 3 output_format = text 4 output_root = /tmp/square 5 runlist = 605.lbm_s 6 size = test 7 tune = base,peak 8 default: 9 CC = mpicc 10 CC_VERSION_OPTION = -v 11 default=base: 12 the_system = STAR 13 OPTIMIZE = -O1 14 notes_base_100 = base tuning uses '$[CC]' '$[OPTIMIZE]' on system '$[the_system]' 15 default=peak: 16 OPTIMIZE = -O2 17 notes_peak_100 = peak tuning uses '$[CC]' '$[OPTIMIZE]' on system '$[the_system]' 18 $ cat square.sh runhpc --config=square | grep txt grep tuning /tmp/square/result/hpc2021.001.small.test.txt $ ./square.sh format: Text -> /tmp/square/result/hpc2021.001.small.test.txt base tuning uses 'mpicc' '-O1' on system 'STAR' peak tuning uses 'mpicc' '-O2' on system '' $ Note that line 14 finds all three variables that it is looking for, but line 17 does not. If it is not clear why this happens, please see the descriptions of named sections and precedence above. I.F.3. Useful $[square] variablesUseful $[variables] include:
You can access the initial value of most options that you can enter into a config file, including:
action, allow_label_override,
backup_config, basepeak, check_version, command_add_redirect, copies, delay, deletework, difflines, env_vars,
expand_notes, expid, fake, flagsurl, http_proxy, http_timeout, ignore_errors, ignore_sigint, info_wrap_columns,
iterations, label, line_width, locking, log_line_width, mail_reports, mailcompress, mailmethod, mailport, mailserver,
mailto, make, make_no_clobber, makeflags, mean_anyway, minimize_builddirs, minimize_rundirs, no_input_handler, no_monitor,
notes_wrap_columns, notes_wrap_indent, output_format, output_root, plain_train, rawformat, rebuild, reportable, runlist,
section_specifier_fatal, setprocgroup, size, strict_rundir_verify, sysinfo_program, table, teeout,
train_single_thread, tune, use_submit_for_speed, username, verbose, verify_binaries,
version_url.
I.F.4. ${curly} substitution (interpolation) during a run
|
During a run, variables that are delimited by ${curly brackets} are substituted: | ${command} |
Usually, variables can be spelled with or without the curlies: | $command or ${command} |
Exception 1: curlies are required if the variable is adjacent to other text | ${command}s |
runhpc uses perl interpolation.
Only scalars (not: perl arrays and hashes) can be interpolated.
Example: on the notes100 line, you could optionally add say either ${lognum} or $lognum, but don't try taking the curly brackets away from ${size}.
$ cat just.cfg expand_notes = 1 notes100 = Just ${size}ing, in run $lognum output_root = /tmp/just runlist = 605.lbm_s size = test CC = mpicc CC_VERSION_OPTION = -v $ $ cat just.sh runhpc -c just | grep txt grep Just /tmp/just/result/hpc2021.001.small.test.txt $ $ ./just.sh format: Text -> /tmp/just/result/hpc2021.001.small.test.txt Just testing, in run 001 $
Traps for the unwary
Timing: Some variables are only defined at certain times, and a line that uses it might be interpolated at a different time. Therefore interpolation won't always do what you might wish. In particular, notes are not expanded in the context of a particular benchmark run, and therefore variables such as ${tune} are not useful within them.
output_root:
You cannot set an output_root that depends on a runhpc variable.
You can set one that uses a macro:
output_root=$[top]/my/path # wrong output_root=${top}/my/path # wrong output_root=%{ENV_SPEC}/my/path # right
These variables may be of interest:
${baseexe} | The first part of the executable name, which is <baseexe>_<tune>.<label>. For example, in "lbm_base.foo", baseexe is "lbm". |
---|---|
${benchmark} | The number and name of the benchmark currently being run, for example 605.lbm_s |
${benchname} | The name of the benchmark currently being run, for example lbm |
${benchnum} | The number of the benchmark currently being run, for example 605 |
${benchtop} | The top directory for the benchmark currently being run, for example /spec/hpc2021/benchspec/HPC/605.lbm_s |
${command} | The shell command line to run the current benchmark, for example ../run_base_test_sticky.0000/weather_base.sticky output6.ref.txt 24000 10000 3000 1250 600 100 6 |
${commandexe} | The executable for the current command, for example ../run_base_test_none.0000/weather_base.sticky |
${label} | The label for the benchmark being run |
${iter} | The current iteration number |
${logname} | The complete log file name, for example /spec/hpc2021/result/hpc2021.168.log |
${lognum} | The log file number, for example 168 |
${tune} | The tuning for the benchmark being run (base or peak) |
${workload} | The current workload number (within the iteration) |
For a complete list of the available variables relative to the current config file, set
expand_notes = 1 verbose = 35 # or higher
Then, do a run that causes a command substitution to happen.
In the log, you will find many lines of the
form:
- Variables available for interpolation that have changed since the last list: (From config) $runmode = "speed" (From config) $size = "test" - Variables available for interpolation that have changed since the last list: (From config) $size = "ref"
It is sometimes useful to undo the setting of a variable that would otherwise be included from another section. This can be accomplished using the special value %undef%. In the example, line 14 undefines COPTIMIZE when compiling peak:
$ cat -n dave.cfg 1 flagsurl = $[top]/config/flags/gcc.xml 2 iterations = 1 3 output_format = text 4 output_root = /tmp/undef 5 runlist = 605.lbm_s 6 size = test 7 tune = base,peak 8 default: 9 CC_VERSION_OPTION = -v 10 CC = mpicc 11 OPTIMIZE = -O2 12 COPTIMIZE = -fno-tree-pre 13 605.lbm_s=peak: 14 COPTIMIZE = %undef% 15 $ runhpc --config=dave | grep txt format: Text -> /tmp/undef/result/hpc2021.001.small.test.txt $ cd /tmp/undef/benchspec/HPC/605.lbm_r/build $ grep OPTIMIZE build_base_none.0000/Makefile.spec COPTIMIZE = -fno-tree-pre OPTIMIZE = -O2 $ grep OPTIMIZE build_peak_none.0000/Makefile.spec COPTIMIZE = OPTIMIZE = -O2 $
Notice that in the build directory, COPTIMIZE is present for base and absent for peak.
When debugging a config file that uses runhpc variables, try:
iterations = 1 minimize_rundirs = 0 reportable = 0 runlist = (one or two benchmarks) size = test verbose = 40
Using --fake will probably be informative. Look inside the log for the (case-sensitive) word 'From'.
This section documents options that control the operation of runhpc itself.
In the list that follows, some items are linked to the document Using SPEChpc 2021 - the 'runhpc' Command because they can be specified either in a config file, or on the runhpc command line.
New with SPEChpc 2021, If an option is specified in both places, the command line wins.
In the table that follows, if an option is documented as accepting the values "no" and "yes", these may also be specified as "false" and "true", or as "0" and "1".
The "Use In" column indicates where the option can be used:
H | use only in header section |
N | use in a named section. |
H,N | can be used in both the header section and in named sections. The item can therefore be applied on a global basis, and/or can be applied to individual benchmarks. |
Option | Use In | Default | Meaning | ||||||||
action | H | validate | What to do. The available actions are defined in the runhpc
document. See also the buildsetup example in the section on specmake . |
||||||||
allow_label_override | H | no | The runhpc command can use --label to select sections that apply to a specific label. If the label mentioned on the runhpc command does not occur in any section marker:
|
||||||||
backup_config | H | yes | When updating the hashes in the config file, make a backup copy first. Highly recommended to defend against full-file-system errors, system crashes, or other unfortunate events. | ||||||||
basepeak | H,N | no | Use base binary and/or base result for peak. If applied to the whole suite then only base is run, and its results are reported for both the base and peak metrics. If applied to a single benchmark, the same binary will be used for both base and peak runs, and the base results will be reported for both. (The reason for running the binary during both base and peak is to remove the possibility that skipping a benchmark altogether might somehow change the performance of some other benchmark.) | ||||||||
check_version | H | no (yes for reportable runs) |
When set, before doing a reportable run, runhpc will download a small file (~15 bytes) from www.spec.org containing the current version of the suite and the date it was released, and check your copy vs. that file. In this way, you can be notified if the version of the suite that you're using is out-of-date. Setting this variable to no will disable this check. If you'd like to check a local file instead, you can modify version_url to point to your internal copy. If you would like to check your version for a NON-reportable run, you will need to add --check_version to your command line. Setting check_version=yes in the config file only causes the check for reportable runs. |
||||||||
command_add_redirect | H | no | If set, the generated ${command} will include redirection operators (stdout, stderr), which are passed along to the shell that executes the command. If this variable is not set, specinvoke does the redirection. This option is commonly used with submit. When used with submit, the command_add_redirect feature lets you choose whether
redirection operators (such as <this_benchmark.in or >that_benchmark.out) are
applied to your entire modified submit command (the default) or just to the portion that has ${command}.
The above is only pseudo-code; see the section on Using Submit for real examples. |
Option | Use In | Default | Meaning |
delay | H,N | 0 | Insert a delay of the specified number of seconds before and after benchmark execution. This delay does not contribute to the measured runtime of the benchmark. This delay is also not available in a reportable run. |
deletework | H,N | no | If set to yes, always delete existing benchmark working directories. An extra-careful person might want to set this to ensure no unwanted leftovers from previous benchmark runs, but the tools are already trying to enforce that property. |
difflines | H,N | 10 | Number of lines of differences to print when comparing results. |
enable_monitor | H,N | yes | If this variable is set to no, then all of the monitoring hooks are disabled. This can be overridden by setting force_monitor. force_monitor is new with SPEChpc 2021 |
env_vars or envvars |
H,N | no | If set to yes, environment settings can be changed using ENV_* options in the config file. Note that you cannot change OMP_NUM_THREADS or ACC_NUM_CORES using this feature. Use threads. |
Example: Consider the config file below, which sets the LD_LIBRARY_PATH to the location of the compiler runtime libraries for an alternate mpicc thats not used for the base. size = test tune = peak label = srini +env_vars = 1 # 605.lbm_s=peak: + ENV_LD_LIBRARY_PATH = /tmp/compiler/lib64:%{ENV_LD_LIBRARY_PATH} CC = alt_mpicc CC_VERSION_OPTION = -v OPTIMIZE = -O1
|
|||
expand_notes | H | no | If set, will expand variables in notes. This capability is limited because notes are NOT processed by specmake, so you cannot do repeated substitutions. |
expid | H | If set to a non-empty value, will cause executables, run directories, results, and log files to be put in a subdirectory (with the same name as the value set) in their normal directories. For example, setting expid = CDS will cause benchmark binaries to end up in exe/CDS, run directories to end up in run/CDS, and results and logs in $SPEC/result/CDS. | |
fail | H,N | no | If set, will cause a build or run to fail. |
fail_build | H,N | 0 | If set, will cause a build to fail. For example, you could say something like this: 605.lbm_s=default: #> I am posting this config file for use by others in the #> company, but am forcing it to fail here because #> I want to force users to review this section. #> #> Once you find your way here, you should test whether #> bug report 234567 has been fixed, by using the first #> line below. If it has not been fixed, then use the #> second. In either case, you'll need to remove the #> fail_build. #> #> - Pney Guvaxre #> Boomtime, the 66th day of Confusion in the YOLD 3172 OPTIMIZE = -Osuperduper # OPTIMIZE = -Omiddling fail_build = yes In the example above, the build is forced to fail until the user examines and modifies that section of the config file. Notice that Pney has used protected comments to cause the comments about the internal bug report to disappear if the config file were to be published as part of a reportable run. |
fail_run | H,N | no | If set, will cause a run to fail. |
Option | Use In | Default | Meaning | ||||
flagsurl | H | none | If set, retrieve the named URL or filename and use that as the "user" flags file. If the special value "noflags" is used, runhpc will not use any file and (if formatting previously run results) will remove any stored file. Automated processing of flags is explained in flag-description.html. If you want to list more than one flagsfile, the recommended method is by using numbered continuation lines, for example: flagsurl1 = mycompiler.xml flagsurl2 = myplatform.xml Using other methods (such as backslash continuation) to specify multiple flags files may appear to work, but may result in unexpected differences between the original config file and the config file as written by output format config. Multiple flags files will typically be needed, because flags files are separated into two types, "compiler", and "platform". |
||||
force_monitor | H,N | no | If this variable is set to yes, then all of the monitoring hooks are enabled, regardless of settings that would otherwise turn them off. This means that every invocation of specinvoke will be subject to monitor_specrun_wrapper, and all command invocations will be subject to monitor_wrapper. This includes things that would normally not be subject to monitoring, such as FDO training runs, input generation commands, and commands used for validating benchmark output such as specdiff. force_monitor is new with SPEChpc 2021. |
||||
http_proxy | H | In some cases, such as when doing version checks and loading flag description files, runhpc will use HTTP to fetch a file. If you need to specify the URL of a proxy server, this is the variable to use. By default, no proxy is used. Note that this setting will override the value of the http_proxy environment variable. For example, one might set: http_proxy = http://webcache.tom.spokewrenchdad.com:8080 |
|||||
http_timeout | H | 30 | This is the amount of time (in seconds) to wait while attempting to fetch a file via HTTP. If the connection cannot be established in this amount of time, the attempt will be aborted. | ||||
ignore_errors | H | no | Ignore certain errors which would otherwise cause the run to stop. Very useful when debugging a new compiler and new set of options: with this option set, you'll find out about all the benchmarks that have problems, instead of only finding out about the first one. | ||||
ignore_sigint | H | no | Ignore SIGINT. If this is set, runhpc will attempt to continue running when you interrupt one of its child processes by pressing ^C (assuming that you have ^C mapped in the common way). Note that this does NOT cause runhpc itself to ignore SIGINT. | ||||
info_wrap_columns | H | 50 | When set to a value greater than 0, attempts to split non-notes informational lines such that they are no longer than info_wrap_columns columns wide. Lines are split on whitespace, and newly created lines are guaranteed to have at least the same indentation as the original line. If a line contains an item that is longer than info_wrap_columns, a warning is logged and the original line is left unchanged. | ||||
iterations | H | 3 | Number of iterations to run. | ||||
keeptmp | H | no | Whether or not to keep various temporary files. If you leave keeptmp at its default setting, temporary files will be automatically deleted after a successful run. If not, temporary files may accumulate at a prodigious rate, and you should be prepared to clean them by hand. Temporary files include:
|
||||
label | H | none | An arbitrary tag for executables, build directories, and run directories.
label=jun12.old.CC label=jun12.new.CC label=jun14-flagday label=jun15-robert.wants.yet.another.test If a label is used as a section specifier, it can be referenced from the runhpc command line. runhpc --label=sandra [...] ERROR: The label 'sandra' defines no settings in the config file! The error can be disabled if you set allow_label_override=yes. |
||||
|
Option | Use In | Default | Meaning |
line_width | H | 0 | Line wrap width for screen. If left at the default, 0, then lines will not be wrapped and may be arbitrarily long. |
locking | H | yes | Try to use file locking to avoid race conditions, e.g. if more than one copy of runhpc is in use. Although performance tests are typically done with only one copy of runhpc active, it can be handy to run multiple copies if you are just testing for correctness, or if you are compiling the benchmarks. |
log_line_width | H | 0 | Line wrap width for logfiles. If your editor complains about lines being too long when you look at logfiles, try setting this to some reasonable value, such as 80 or yes. If left at the default, yes, then lines will not be wrapped and may be arbitrarily long. |
log_timestamp | H | no | Whether or not to prepend time stamps to log file lines. |
mailcompress | H | no | When using the 'mail' output format, turning this on will cause the various report attachments to be compressed with gzip. |
mailmethod | H | smtp | When using the 'mail' output format, this specifies the method that should be used to send the mail. On UNIX and
UNIX-like systems, there are three choices: 'smtp' (communicate directly with an SMTP server over the network), 'sendmail'
(try invoking sendmail directly from locations where it is commonly installed), and 'qmail' (try invoking
qmail-inject from locations where it is commonly installed).
Using a sendmail or qmail-inject program from a non-standard location is possible only by setting the PERL_MAILER environment variable. See the Mail::Mailer documentation for details. |
mailport | H | 25 | When using the 'mail' output format, and when the mailmethod is 'smtp', this specifies the port to use on the mail server. The default is the standard SMTP port and should not be changed. |
mailserver | H | 127.0.0.1 | When using the 'mail' output format, and when the mailmethod is 'smtp', this specifies the IP address or hostname of the mailserver through which to send the results. |
mailto | H | '' | The address or addresses to which results should be sent when using the 'mail' output format. If multiple addresses are specified, they should be separated by commas or whitespace. Each address should consist only of the name@domain part (i.e. no "full name" type info). The addresses are not checked for correct formatting; if a mistake is made, the results may be sent to an unknown location. Think: comp.arch. OK, probably not there, but seriously be careful about security on this one. Config files as posted at www.spec.org/hpc2021 will not include whatever you put on this line (thus, spambots will not see the contents of this field). Note that to get your reports mailed to you, you need to specify both mail as an output_format and an address to which they should be mailed. For example: mailto=fast.guy@welovebenchmarks.org output_format=text,mail If no addresses are specified, no mail will be sent. |
mail_reports | H | all | The list of report types to mail. The format and possible values are the same as for output_format, with the addition of log, which will cause the
current log file to be sent. The default is for all files associated with the run to be mailed (so, this will include
what you listed as your desired output_format plus log (the log file) and rsf (the
rawfile). You can cut your email down to the bare essentials with something like this:
mailto=fast.guy@welovebenchmarks.org output_format=text,mail mail_reports=textIf none of the requested report types were generated, no mail will be sent. |
make | H,N | specmake | Name of make executable. Note that the tools will enforce use of specmake for reportable results. |
make_no_clobber | H,N | no | Don't delete directories when building executables. The default is no, meaning "clobber". The "yes" option, meaning "avoid clobbering", should only be used for troubleshooting a problematic compile. The tools will not allow you to use this option when building binaries for a reportable result. Note that you could issue multiple successive runhpc commands with this option set (either in the config file, or with the --make_no_clobber switch), and the build directories will be preserved. But once you remove make_no_clobber (allowing it to default back to no), then the tools will attempt a normal build with a fresh build directory. |
makeflags | H,N | '' | Extra flags for make (such as -j). Set this to -j n where n is the number of concurrent processes to run during a build. Omitting n or setting it to zero unlimits the number of jobs that will be run in parallel. Use with care! Make flags should be used here only if you are familiar with GNU make. (The program specmake is GNU Make under another name to ensure no accidental conflicts with other Make utilities you might have. The GNU Make Manual can be consulted, and you can also say specmake --help.) Note that requesting a parallel build with makeflags = -j N causes multiple processors to be used at build time. It has no effect on whether multiple processors are used at run time, and so does not affect how you report on parallelism. |
Option | Use In | Default | Meaning | |||||||||||
mean_anyway | H | no | Calculate mean even if invalid. DANGER: this will write a mean to all reports even if no valid mean can be computed (e.g. half the benchmarks failed). A mean from an invalid run is not "reportable" (that is, it cannot be represented in public as the SPEC metric). | |||||||||||
minimize_rundirs | H | no | During a run, try to keep working disk size down. Cannot be used in a reportable run. | |||||||||||
minimize_builddirs | H | no | Try to keep working disk size down during builds. | |||||||||||
nobuild | H | no | Do not attempt to build benchmarks. Useful to prevent attempts to rebuild benchmarks that cannot be built. Also comes in handy when testing whether proposed config file options would potentially force an automatic rebuild. | |||||||||||
no_monitor | H,N | '' | Exclude the listed workloads from monitoring via the various monitor_* hooks. | |||||||||||
no_input_handler | H,N | close | Method to use to simulate an empty input. Choices are:
Normally, this option should be left at the default; it was actually added to the tools for the benefit of a different SPEC suite that needed the feature. If a reportable run for SPEChpc 2021 uses this feature, an explanation should be provided as to why it was used. |
|||||||||||
notes_wrap_columns | H | 0 | When set to a value greater than 0, attempts to split notes lines such that they are no longer than notes_wrap_columns columns wide. Lines are split on whitespace, and newly created lines are guaranteed to have at least the same indentation as the original line. If a line contains an item that is longer than notes_wrap_columns, a warning is logged and the original line is left unchanged. | |||||||||||
notes_wrap_indent | H | ' ' | When line wrapping is enabled (see notes_wrap_columns), this is the string that will be prepended to newly created lines after the indentation from the original line is applied. The default is four spaces, but it can be set to any arbitrary string. | |||||||||||
output_format | H | all | Format for reports. Valid options are listed at runhpc.html under --output_format; major options include txt (ASCII text), html, pdf, and ps. You might prefer to set this to txt if you're going to be doing lots of runs, and only create the pretty reports at the end of the series. See also the information in runhpc.html about --rawformat. | |||||||||||
output_root | H |
If set to a non-empty value, all output files will be rooted under
the named directory, instead of under $SPEC (or %SPEC%).
You can navigate a rooted directory with ogo.
|
||||||||||||
|
Option | Use In | Default | Meaning | ||||||||||
pmodel | N | MPI | Optionally select the node level parallel model to use for each benchmark. If not set, the default is to build with MPI only.
Important! This option only sets the appropriate macro define flag for the model's directives to be visible in the post-processed
source. You must also set the appropriate compiler option to enable the use of the model (ex. "-fopenmp") in
OPTIMIZE. Also, not all models are supported by all compilers. Please consult your compiler's documentation
for the appropriate options and which models they support.
|
||||||||||
preenv or pre_env |
H | yes | Use preENV_ lines in the config file. When this option is set (the default), lines of the form preENV_<variable> = <value> will cause runhpc to set the specified environment variable to value and re-exec runhpc to perform the run. The restart is done in order to ensure that the entire run takes place with the new settings. You can set preENV_SOME_VARIABLE = value only in the header section or a section using one these benchmark specifiers: default: tiny: small: medium: large: Any attempt to use preENV_ in other sections is silently
ignored.
Example: Above, the section on env_vars showed how a library path can be adjusted for a single
benchmark.
preENV_LD_LIBRARY_PATH = %{ENV_SPEC}/libraries:%{ENV_LD_LIBRARY_PATH} |
||||||||||
ranks | H | yes | The number of ranks to be used to run each benchmark. The value is required to be set, either in the config file or on the runhpc command line, so the reports will be formatted correctly. Use $ranks to pass the count to the MPI driver, as shown in the submit section. | ||||||||||
reportable | H | yes | Strictly follow reporting rules, to the extent that it is practical to enforce them by automated means. The tester remains responsible for ensuring that the runs are rule compliant. You must set reportable to generate a valid run suitable for publication and/or submission to SPEC. | ||||||||||
rebuild | H | no | Rebuild binaries even if they exist. | ||||||||||
runlist | H | none | Benchmarks or sets to run. Names can be abbreviated, just as on the command line. See the long discussion of run order in runhpc.html. | ||||||||||
save_build_files | H,N | none | After a build is finished, files matching any of the space-delimited wildcard patterns in this variable will be gathered up and saved. When a non-reportable run is being set up, those files will be unpacked into the run directory when the executable is copied in. The auxiliary file package is ignored when setting up reportable runs. The save_build_files feature is new with SPEChpc 2021. |
||||||||||
section_specifier_fatal | H | yes | While parsing the config file, if a section specifier is found that refers to an unknown benchmark or benchset, an error is output and the run stops. Set section_specifier_fatal=no in the header section of your config file to convert this error into a warning and allow the run to continue. The ability to convert section specifier errors into warnings is probably of use only for benchmark developers. |
||||||||||
setprocgroup | H | yes | Set the process group. On Unix-like systems, improves the chances that ^C gets the whole run, not just one of the children. | ||||||||||
showtimer | H | 0 | Display the internal timer information in the reports. | ||||||||||
size | H | ref | Size of input set: test or ref
You might choose to use runhpc --size=test while debugging a new set of compilation options. Reportable runs only invoke the ref workload |
Option | Use In | Default | Meaning |
src.alt | N | none | Name of a SPEC-approved alternate source.
|
About alternate sources: Sometimes a portability issue may require use of different source code for a benchmark, and SPEC may issue a src.alt, which is a compressed tar file containing modifications, created by makesrcalt. To use a src.alt, see the instructions posted with it at
www.spec.org/hpc2021/src.alt.
$ cd $SPEC $ specxz -dc nnn.benchmark.FixMumble.tar.xz | spectar -xvf - $ cat README.nnn.benchmark.src.alt.FixMumble.txt The README will explain what to add to your config file and any other instructions that are needed. After you unpack it, a directory is created under under <benchmark>/src/src.alt/ and a set of patches are stored there. You can look at the patches using dumpsrcalt, but it may be easier to just apply the src.alt and look at a build directory. Example: This config file builds with or without a src.alt, depending on the runhpc setting for the --label. $ cat testme.cfg action = buildsetup runlist = nnn.benchmark tune = base default: CC = mpicc CC_VERSION_OPTION = -v nnn.benchmark=base=without: OPTIMIZE = -O2 nnn.benchmark=base=with: OPTIMIZE = -O2 srcalt = FixMumble To populate build directories: runhpc --label=without --config=testme runhpc --label=with --config=testme Then, if you visit benchspec/CPU/nnn.benchmark/build you can compare the directories. |
Option | Use In | Default | Meaning |
strict_rundir_verify | H | yes | When set, the tools will verify that the file contents in existing run directories match the expected checksums. Normally, this should always be on, and reportable runs will force it to be on. Turning it off might make the setup phase go a little faster while you are tuning the benchmarks. Developer notes: setting strict_rundir_verify=no might be useful when prototyping a change to a workload or testing the effect of differing workloads. Note, though, that once you start changing your installed tree for such purposes it is easy to get lost; you might as well keep a pristine tree without modifications, and use a second tree that you convert_to_development. |
table | H | yes | In ASCII reports, include information about each execution of the benchmark. |
teeout | H | no | Run output through tee so you can see it on the screen. Primarily affects builds, but also provides some information about progress of runtime, by showing you the specinvoke commands. |
threads | H,N | 1 | Value to be set for OMP_NUM_THREADS or ACC_NUM_CORES when benchmarks are run.
If you have set these in your environment prior to using runhpc, that setting will be ignored. To use multiple benchmark threads, you must use either this config file field or the corresponding option runhpc --threads=N. |
tune | H | base | default tuning level. In a reportable run, must be either all or base. |
verbose | H | 5 | Verbosity level. Select level 1 through 99 to control how much debugging info runhpc prints out. For more information, see the section on log files, below. |
verify_binaries | H | yes | runhpc uses checksums to verify that executables match the config file that invokes them, and if they do not, runhpc forces a recompile. You can turn that feature off by setting verify_binaries=no. Warning: It is strongly recommended that you keep this option at its default, yes (that is, enabled). If you disable this feature, you effectively say that you are willing to run a benchmark even if you don't know what you did or how you did it -- that is, you lack information as to how it was built! The feature can be turned off because it may be useful to do so sometimes when debugging (for an example, see env_vars), but it should not be routinely disabled. Since SPEC requires that you disclose how you build benchmarks, reportable runs (using the command-line switch --reportable or config file setting reportable=yes) will cause verify_binaries to be automatically enabled. For SPEChpc 2021, this field replaces the field check_md5 |
version_url | H | http:// www. spec.org/ hpc2021/ current_ version |
If version checking is enabled, this specifies the location from which the version information should be fetched. |
For SPEChpc you do not write Makefiles. Instead, you set Make variables in the config file, which are sent to a SPEC-supplied copy of GNU Make, known as specmake. Variables with a dollar sign and parentheses, aka "round brackets", are substituted by specmake. For example:
COMPILER_DIR = /usr/local/bin/ CC = $(COMPILER_DIR)cc CXX = $(COMPILER_DIR)c++ FC = $(COMPILER_DIR)f90
See below for more information on syntax of variables that you create and reference.
The following Make variables are frequently useful. When selecting where to put a flag, please bear in mind that the run rules require that portability flags must use PORTABILITY variables.
CC | How to invoke your C compiler. |
CXX | How to invoke your C++ compiler. |
FC | How to invoke your Fortran compiler. |
CC_VERSION_OPTION CXX_VERSION_OPTION FC_VERSION_OPTION |
New with SPEChpc 2021: You must specify how to ask each compiler "Please tell me your version" because the method varies from compiler to compiler. The version information is recorded contemporaneously with the build. You must specify the option for all compilers that you use.
|
PORTABILITY EXTRA_PORTABILITY |
Portability flags to be applied no matter what the compiler. |
{C|CXX|F}PORTABILITY EXTRA_{C|CXX|F}PORTABILITY |
Portability flags to be applied to modules of the designated language (For example, CXXPORTABILITY is for the C++ modules). |
OPTIMIZE EXTRA_OPTIMIZE | Optimization flags to be applied for all compilers. |
{C|CXX|F}OPTIMIZE EXTRA_{C|CXX|F}OPTIMIZE |
Optimization flags to be applied to modules of the designated language. |
EXTRA_{C|CXX|F}FLAGS | Flags that are neither optimization nor portability |
LIBS | Libraries to add to the link line |
Many more | See chart in document Make Variables |
By default, the SPEChpc benchmarks use only MPI parallelism. However, you may also enable either OpenACC or OpenMP directives to enable node-level parallelism. The benchmark will then be hybrid MPI+OpenACC or MPI+OpenMP.
For OpenMP, you may select either "traditional" OpenMP using CPU task/threads, or "Target" OpenMP which includes OpenMP 5.0 'target' constructs that may use to target a host CPU or offload to accelerator device.
Note if you choose to use a node-level parallel model, the same model must be used for all benchmarks in base. For peak, you may select the model on a per benchmark basis.
To enable a node-level parallel mode, use the appropriate 'pmodel' setting. The tools then set the appropriate preprocessor define flag which makes the directives visible in the source. Note that not all compilers support all models and the compiler flag that enables the model must be set in your OPTIMIZE variable in the config file. Please consult your compiler's documentation for the supported models and options.
pmodel setting | Model | Define flag implicitly added |
---|---|---|
MPI | MPI-Only (default) | None. |
ACC | MPI+OpenACC | -DSPEC_OPENACC |
OMP | MPI+OpenMP using CPU task/threads | -DSPEC_OPENMP |
TGT | MPI+OpenMP using Target constructs | -DSPEC_OPENMP_TARGET |
Note that using the define flags directly in you OPTIMIZE or PORTABILITY flags will cause the tools to error. This is to help reduce the possibiltiy of setting the pmodel to one model but then accidently enabling a different model.
The config file fragment below demonstrates how to conditionally include a parallel model selected via runhpc --define option:
% cat -n config/pmodel.cfg 1 # If model is not set use Only MPI 2 %ifndef %{model} 3 pmodel=MPI 4 %endif 5 6 # Compiler flags applied to all models 7 default: 8 CC = mpicc 9 OPTIMIZE = -O3 10 CXXPORTABILITY = --c++14 11 submit = mpirun --bind-to none -mp $ranks $command 12 13 # OpenACC flags 14 %if %{model} eq 'acc' 15 pmodel = ACC 16 OPTIMIZE += -acc 17 %endif 18 19 # OpenMP (CPU Threaded) flags 20 %if %{model} eq 'omp' 21 pmodel = OMP 22 OPTIMIZE += -mp 23 %endif 24 25 # OpenMP (Target) flags 26 %if %{model} eq 'omptgt' 27 pmodel=TGT 28 OPTIMIZE += -mp=gpu 29 %endif 30 31 605.lbm_s=peak: 32 pmodel = ACC 33 OPTIMIZE = -acc -fast 34 35 # This will error since the model define flags 36 # should only be set by the tools 37 705.lbm_m=peak: 38 OPTIMIZE = -mp -fast -DSPEC_OPENMP 39 % runhpc -c pmodel --fake -ranks=4 605.lbm_s | grep lbm.c mpicc -c -o lbm.o -DSPEC -DNDEBUG -O3 lbm.c % runhpc -c pmodel --fake -ranks=4 --define model=acc 605.lbm_s | grep lbm.c mpicc -c -o lbm.o -DSPEC -DNDEBUG -O3 -acc -DSPEC_OPENACC lbm.c % runhpc -c pmodel --fake -ranks=4 --define model=omp 605.lbm_s | grep lbm.c mpicc -c -o lbm.o -DSPEC -DNDEBUG -O3 -mp -DSPEC_OPENMP lbm.c % runhpc -c pmodel --fake -ranks=4 --define model=omptgt 605.lbm_s | grep lbm.c mpicc -c -o lbm.o -DSPEC -DNDEBUG -O3 -mp=gpu -DSPEC_OPENMP_TARGET lbm.c % runhpc -c pmodel --fake -ranks=4 --tune peak 605.lbm_s | grep lbm.c mpicc -c -o lbm.o -DSPEC -DNDEBUG -acc -fast -DSPEC_OPENACC lbm.c
Note for peak only OpenACC is used from 605.lbm_s since it's not guarded by the define.
Using a pmodel's define flag in the config will cause the following error:
% runhpc -c pmodel --fake -ranks=4 --tune peak 705.lbm_m SPEC HPC(r) 2021 Benchmark Suites Copyright 1995-2021 Standard Performance Evaluation Corporation (SPEC) runhpc v.unknown Using 'linux-x86_64' tools Reading file manifests... read 16870 entries from 2 files in 0.08s (200294 files/s) ... cut ... Compiling Binaries ERROR: pmodel define flag "-DSPEC_OPENMP" may only be set by the tools. Please remove it from the following line of your config file. OPTIMIZE = -acc -fast -DSPEC_OPENMP ... cut ...
Variables with a dollar sign and parentheses, aka "round brackets", are substituted by specmake.
Deprecated feature alert: Although it is also possible to pass information to specmake using curly brackets: ${COMPILER_DIR}, this is not recommended. Instead, you should consistently use curly brackets to address runhpc and round brackets to address specmake. It is possible that a future version of runhpc may insist on interpolating curly brackets itself, rather than allowing specmake to do so.
Example:
$ cat makevar.cfg action = build runlist = 605.lbm_s default: DEBUG_SYMBOLS = --debug:symbols=expanded_info_level:42 EXTRA_FFLAGS = $(GEE) small=base: GEE = -g $(DEBUG_SYMBOLS) small=peak: GEE = -g $ cat makevar.sh runhpc --config=makevar --fake --tune=base | grep COMP: runhpc --config=makevar --fake --tune=peak | grep COMP: $ ./makevar.sh COMP: "cc -c -o lbm.o -g --debug:symbols=expanded_info_level:42 <source>" COMP: "cc -c -o lbm.o -g <source>" $
The config file above creates two variables options (DEBUG_SYMBOLS and GEE). Both are passed to specmake, which interprets them. The results are shown above using the runhpc --fake option.
For an extensive example of variable substitution handled by specmake, see the SPEC CPU®2000 example at www.spec.org/cpu2000/docs/example-advanced.cfg. Search that file for LIBS, and note the long comment which provides a walk-through of a complex substitution handled by specmake.
The operator "+=" adds to specmake variables. It may be convenient; it also may cause hard-to-diagnose bugs. Example:
$ cat tmp.cfg action = build runlist = 605.lbm_s tune = peak default: OPTIMIZE = -O1 fprate=default: OPTIMIZE += --unroll default=peak: OPTIMIZE += --inner_unroll 605.lbm_s=peak: OPTIMIZE += --outer_unroll default=default=breakfast: OPTIMIZE = --jelly_roll $ runhpc --fake --config=tmp | grep lbm.c cc -c -o lbm.o -DSPEC -DSPEC_CPU -DNDEBUG -O1 --inner_unroll --unroll --outer_unroll lbm.c $
Note that the options accumulate.
Caution: although the += operator adds flexibility, it may introduce hard-to-predict behavior, depending on precedence of section specifiers, the order of your config file, and other features, such as include files. Instead of using '+=' try picking different make variables for different purposes. For an example of hard-to-predict behavior, what will happen if you add --label=breakfast to the above runhpc command? (Try it.)
Recommendations:
Avoid += to prevent surprises.
Keep it simple.
Pick different makevars for different purposes.
Create conventions for your config files and write them down, in config file comments.
If you must use += review its effects carefully (--fake is your friend).
When debugging a set of build options, it is often useful to create a "sandbox" - that is, a directory where you can play with the benchmark and its options. This example creates a build sandbox with action buildsetup.
$ cat sandbox.cfg action = buildsetup label = fast output_root = /tmp/demo_buildsetup runlist = 605.lbm_s tune = peak default=peak: OPTIMIZE = -fast $ cat sandbox.sh runhpc --config=sandbox | grep log grep Makefile.spec /tmp/demo_buildsetup/result/hpc2021.001.log $ ./sandbox.sh The log for this run is in /tmp/demo_buildsetup/result/hpc2021.001.log Wrote to makefile '/tmp/demo_buildsetup/benchspec/HPC/605.lbm_s/build/build_peak_fast.0000/Makefile.spec':
The action causes a directory to be created
There, the Makefile can be examined, used in a dry run, or modified as part of a testing effort.
$ cd /tmp/demo_buildsetup/benchspec/HPC/605.lbm_s/build/build_peak_fast.0000/ $ grep OPTIMIZE Makefile.spec OPTIMIZE = -fast $ specmake --dry-run cc -c -o lbm.o -DSPEC -DNDEBUG -fast lbm.c cc -c -o main.o -DSPEC -DNDEBUG -fast main.c cc -c -o specrand/specrand.o -DSPEC -DNDEBUG -fast specrand/specrand.c cc -fast lbm.o main.o specrand/specrand.o -lm -o lbm
See also the chapter on specmake in SPEChpc 2021 Utilities and the sandbox examples in Avoiding runhpc.
The SPEChpc tools try to keep config files and binaries synchronized with each other.(*)
Edits to a config file may cause binaries to be rebuilt, sometimes to the surprise(**) of testers.
Testing option sensitivity: The first thing that happens in a rebuild is to delete the old binary.
If that is a
potential problem (perhaps it takes a long time to build), you can test whether a config file change will cause a
rebuild:
The command:
No binaries are harmed.
Notes:
(*) Unless you change verify_binaries. Recommendation: Don't change it.
(**) Recent implementations surprise less often. For detail, see the CPU2006 version of this section.
Some options in your config file cause commands to be executed by your shell (/bin/sh).
Substitution by the shell uses backslash dollar sign.
The backslash protects the variables from interpretation by runhpc.
Example: This config file runs 605.lbm_s twice, with base and peak options. Only peak uses backslashes:
$ cat tmp.cfg expand_notes = 1 iterations = 1 runlist = 605.lbm_s size = test tune = base,peak default: CC = mpicc CC_VERSION_OPTION = -v default=base: submit = echo home=$HOME, spec=$SPEC > /tmp/chan; ${command} default=peak: submit = echo home=\$HOME, spec=\$SPEC > /tmp/nui; ${command} $ runhpc --config=tmp | grep txt format: Text -> /Users/bo/spec/hpc2021/result/hpc2021.697.small.test.txt $ cd /tmp $ cat chan nui home=, spec= home=/Users/chris, spec=/Users/chris/spec/hpc2021 $In base, $HOME and $SPEC are gobbled up by runhpc, which obediently retuns their values: nothing at all.
In peak, backslashes prevent runhpc from interpreting the variables, and the shell provides their values.
Warning: SPEChpc config files can execute arbitrary
shell commands.
Read a config file before using it.
Don't be root.
Don't run as Administrator.
Turn privileges off.
These options cause commands to be executed:
bench_post_setup | Command to be executed after each benchmark's run directory setup phase. The rules say that this feature may be used to cause data to be written to stable storage (e.g. sync). The command must be the same for all benchmarks. It will be run after each benchmark is setup, and for all workloads (test/train/ref). It is not affected by the setting of parallel_test. Use the header section for bench_post_setup. |
|
build_pre_bench
build_post_bench |
Commands for benchmark monitoring, described in the document on the Monitoring Facility. | |
monitor_X | Commands that allow benchmark monitoring, described in the document on the Monitoring Facility. | |
post_setup | Command to be executed after all benchmark run directories have been set up. The rules say that this feature may be used to cause data to be written to stable storage (e.g. sync). Notes:
|
|
submit | Modified command to actually run a benchmark. The default is in ${command}, which the rules allow you to supplement, for example by including the mpiexec command or batch scheduler command. |
The config file feature submit allows you specify the command needed to launch your MPI command as well as include and process to core bindings. This section provides examples to demonstrate how submit works with several other config file features. You might also want to search published results at www.spec.org/hpc2021 for systems that are similar to your system.
You can use submit to specify the MPI or batch scheduler command used to launch your MPI jobs.
The example below runs 4 ranks using OpenMPI's "-bind-to cores" option to bind ranks to cores.
$ cat submitmpi.cfg ranks = 4 runlist = 605.lbm_s submit = mpirun --bind-to cores -np ${ranks} ${command} $ cat submitmpi.sh runhpc --fake --config=submitmpi | grep '^mpirun' | cut -b 1-75 $ ./submitmpi.sh mpirun --bind-to cores -np 4 ../run_base_ref_none.0000/lbm_base.none $
You can use scripts with submit to specify the thread binding for individual MPI ranks. While setting environment variables such as OMP_PLACES in your config's environment setting or using utilities such as numactl work fine when there's a single rank per node, using these with multiple ranks would cause the threads from each rank to be bound to the same core. Several MPI and batch schedulers will perform this binding correctly for you. However in cases where it doesn't, you can provide a script to perform the binding.
The example below runs 8 ranks with each running 16 OpenMP threads. The example uses a perl script to determine the local rank number via OpenMPI's OMPI_COMM_WORLD_LOCAL_RANK environment variable, and then bind the rank's threads via the numactl. Note: please check your MPI distribution's documentation for the equivalent environment variable.
The sample for a two socket system with 128 cores with 8 NUMA nodes. You would need to modify the script for different systems.
$ cat bind8.pl use strict; my %bind; $bind{0} = "0-15"; $bind{1} = "16-31"; $bind{2} = "32-47"; $bind{3} = "48-63"; $bind{4} = "64-79"; $bind{5} = "80-95"; $bind{6} = "96-111"; $bind{7} = "112-127"; my %mem; $mem{0} = "0"; $mem{1} = "1"; $mem{2} = "2"; $mem{3} = "3"; $mem{4} = "4"; $mem{5} = "5"; $mem{6} = "6"; $mem{7} = "7"; my $rank = $ENV{OMPI_COMM_WORLD_LOCAL_RANK}; my $cmd = "numactl -C $bind{$rank} -m $mem{$rank} "; #my $cmd = "taskset -c $bind{$rank} "; while (my $arg = shift) { $cmd .= "$arg "; } my $rc = system($cmd); exit($rc);
Assuming the bind8.pl is copied to the top directory in your SPEChpc installation, you would then use the following submit command to execute it:
$ cat config/submitmpi2.cdf ranks = 8 runlist = 605.lbm_s submit = mpirun --bind-to cores -np ${ranks} perl $[top]/bind8.pl ${command}
If you use the submit feature, a notes section will automatically be created to indicate that you have done so.
Submit Notes ------------ The config file option 'submit' was used.
You can add notes to that section, or customize it as you wish, by creating lines with notes_submit_NNN. The phrase The config file option 'submit' was used must appear somewhere in your customized notes. You can vary the capitalization of the phrase, you can even break it across multiple lines; it just needs to be present. If it is not, it will automatically be added. If you used scripts in your submit command, the full text of the script should be listed in the submit notes.
Whether or not you send your result to SPEC, you should fully disclose how you achieved the result. If it requires the installation of the GoFastLinker, you should say so. By setting the appropriate fields in the config file, you can cause information about the GoFastLinker to appear in the reports that are intended for humans.
Here are the fields that you can set to describe your testbed to readers:
license_num | The SPEC license number for either the tester or the test_sponsor. | ||||||
prepared_by | Is never output. If you wish, you could set this to your own name, so that the rawfile will be tagged with your name but not the formal reports. | ||||||
hw_avail | The availability date of the system hardware. | ||||||
system_name | The name assigned to the kind of system. Usually this name collectively describes the key components of the system, e.g. SGI Altix 4700 Cluster (4 nodes at 1600 MHz) with NumaLink4, but in some cases the name may not derive from its components: Our Super Duper Cluster Computer. | ||||||
system_vendor | The Vendor of the particular system. Usually this is the same as the manufacturer of the node used, but a system may also be constructed from 3rd-party commodity boards and the Vendor is the manufacturer of the integrated system rather than the component boards. | ||||||
system_class | The type of compute system:
|
||||||
sw_avail | The availability date of the system software. | ||||||
tester | The entity actually carrying out the tests. An optional field; if not specified, defaults to test_sponsor. An example is given in the test_sponsor section. | ||||||
test_date | When the tests were run. Note that the test date will be automatically set by runhpc. | ||||||
test_sponsor | The entity sponsoring this test. An optional field; if not specified, defaults to system_vendor. For example, suppose that the Genius Compiler Company wants to show off their new compiler on the TurboBlaster 9000 computer, but does not happen to own a maxed-out system with eight thousand processors. Meanwhile, the Pawtuckaway State College Engineering department has just taken delivery of such a system. In this case, the compiler company could contract with the college to test their compiler on the big machine. The fields could be set as: test_sponsor = Genius Compilers tester = Pawtuckaway State College system_vendor = TurboBlaster |
The second set of parameters can be continued to multiple lines by repeating the variable name multiple times with different suffixes:
sw_c_compiler | Name and version of the C compiler. |
sw_cxx_compiler | Name and version of the C++ compiler. |
sw_f_compiler | Name and version of the Fortran compiler. |
sw_mpi_library | The type and version of the MPI library used. |
sw_mpi_other | Other information on the MPI implementation or settings. |
sw_other | Any other performance-relevant non-compiler software used, including third-party libraries, accelerators, pre-processors, etc. |
A system running MPI may be a standalone SMP or a cluster of nodes with dedicated file servers. The SPEChpc 2021 reporting conventions allow you to describe highly heterogeneous systems by specifying the attributes of multiple kinds of nodes, interconnects and file servers.
The output report will contain a separate section describing each of these components. Each one of these sections consists of a formatted table derived from the fixed-field entries in the config-file, followed by free-form notes derived from the notes entries of the config-file.
Each component is described with a prefix that defines its type, followed by the field to be assigned:
node_IBM655_label = IBM 655 Server # This system has only one kind of node node_IBM655_count = 16 # and uses 16 of them. node_IBM655_count = compute,fileserver # One of the nodes is also the file server. node_IBM655_notes = Node 0 is the file server for the cluster. node_HP2000_label = HP 2000 Server node_HP3000_label = HP 3000 Server # This system has two kinds of nodes node_HP2000_count = 12 # with different numbers of each. node_HP3000_count = 20 node_HP2000_purpose = compute node_HP3000_purpose = compute interconnect_GBEthernet_data_rate = 1Gb/sec # Details of the GB Ethernet interconnect. interconnect_InfiniBand_data_rate = 1Gb/sec # Details of the InfiniBand interconnect. node_SUN1000_label = SUN 1000 Disk Array Server # Details of the SUN 1000 file server. node_SUN1000_count = 1 # Only one of them. node_SUN1000_purpose = fileserver
If you don't declare any components of a given type, no subsection will appear in the report. For example, on an SMT system there will be only one kind of node, and no file server, since the node uses its own local file system. The interconnect is neither replaceable nor configurable so there are no details to report, either.
An SMP system consists of one node of one type. A heterogeneous cluster may consist of many nodes of several types. Most nodes are used for computation but others may act as file servers or provide other utilities. The fields in this section describe the hardware and software configuration of a given node, and are assigned as follows:
node_HP2000_vendor = Hewlett-Packard Corporation
The available fixed-format fields are as follows:
node_tag_label | The name of the node type. | ||||||||
node_tag_order | The output report contains a subsection for each component in the system. The node_order parameter specifies the position of this subsection relative to the others in the report. | ||||||||
node_tag_count | The number of nodes in the system, of this type. | ||||||||
node_tag_hw_vendor | The hardware vendor. An example of usage of this and related fields is given in the test_sponsor section. | ||||||||
node_tag_hw_model | The model of the node type. | ||||||||
node_tag_purpose | What the node is used for:
|
||||||||
node_tag_hw_cpu_name | Manufacturer-determined formal processor name. | ||||||||
node_tag_hw_ncores | Number of CPU cores configured/enabled in the node. See the discussion of CPU counting in the run rules. | ||||||||
node_tag_hw_ncoresorder | Valid number of processor cores orderable for this model of node, including a unit. For example: 2, 4, 6, or 8 chips. | ||||||||
node_tag_hw_ncoresperchip | The number of processor cores per CPU chip. | ||||||||
node_tag_hw_nchips | Number of CPU chips configured. See the discussion of CPU counting in the run rules. | ||||||||
node_tag_hw_nthreadspercore | Number of hardware threads per core. See the discussion of CPU counting in the run rules. | ||||||||
node_tag_hw_cpu_char | Technical characteristics to help identify the processor. (You'll find more information about the intended use of hw_cpu_name vs. hw_cpu_char in the run rules.) | ||||||||
node_tag_hw_cpu_mhz | Speed of the CPUs, in MHz. | ||||||||
node_tag_hw_fpu | Floating point unit. | ||||||||
node_tag_hw_pcache | 1st level (primary) cache. | ||||||||
node_tag_hw_scache | 2nd level cache. | ||||||||
node_tag_hw_tcache | 3rd level cache. | ||||||||
node_tag_hw_ocache | 4th level or other form of cache. | ||||||||
node_tag_hw_memory | Size of main memory (and other performance-relevant information about memory, as discussed in the run rules.) | ||||||||
node_tag_sw_os | Operating system name and version. | ||||||||
node_tag_sw_state | Multi-user, single-user, default, etc. |
Continuable fields:
node_tag_hw_disk | Disk subsystem for the SPEC run directories. Three important Notes:
|
node_tag_sw_local_file | Local file space, used perhaps to store intermediate data files. Local file systems are not usually described since (a) the SPEC run-directory must be shared, and (b) file systems other than the SPEC run directory are usually not a performance-relevant variable. |
node_tag_sw_shared_file | File system (ntfs, ufs, nfs, etc) for the SPEC run directories. Three important Notes:
|
node_tag_sw_other | Any other performance-relevant software to describe for the node. (Note that compiler and library details are covered in the Benchmark (REFERENCE) section). |
node_tag_hw_other | Any other performance-relevant hardware to describe for the node. |
node_tag_notes | Free-form notes describing other details of the node type. Note that you can use the continuation convention to separate this into node_notes_hw, node_notes_os, etc. |
Included as part of the node description, the following fields describe the accelerator used. The fields may be left blank or set to "Not Applicable" if no accelerator was used.
node_tag_accel_count | The number of accelerators included per node. |
node_tag_accel_connect | Describes how the accelerator is connected to the system under test. Possible values include but not limited to integrated, PCIe, none. |
node_tag_accel_desc | Provide further details about he accelerator that are important to performance. Things that might be of interest include memory sizes, number of cores, number of vectors, etc. |
node_tag_accel_driver | The name and version of the software driver used to control the accelerator. |
node_tag_accel_ecc | This is a Yes or No field stating if the accelerator uses ECC for its memory. |
node_tag_accel_model | The model name of the accelerator. If multiple different accelerators are used, use a comma delimited list with the count of each type. |
node_tag_accel_name | The name of the accelerator. If multiple different accelerators are used, use a comma delimited list. |
node_tag_accel_type | The type of accelerator. Possible values include, but not limited to: GPU, APU, CPU, etc. |
node_tag_accel_vendor | The company/vendor of the accelerator. |
The nodes in a compute-cluster use adaptors to attach to the available interconnects. The disclosure convention provides the following fields to declare multiple adaptors of different kinds for each given node type, using a second level of tags
node_HPCX_hw_adaptor_InfiniBand_model = PCI-Express DDR InfiniBand HCA node_HPCX_hw_adaptor_InfiniBand_count = 1
node_tag1_hw_adaptor_tag2_model | Adaptor model and vendor. |
node_tag1_hw_adaptor_tag2_slot_type | PCIe x8, HTX, etc. |
node_tag1_hw_adaptor_tag2_data_rate | Per port nominal data-rate and units, e.g. 1Gb/sec. |
node_tag1_hw_adaptor_tag2_count | Number of tag2 adaptors attached to nodes of type tag1. |
node_tag1_hw_adaptor_tag2_ports_used | Number fo cables connecting this kind of adaptor to the interconnect switches. |
node_tag1_hw_adaptor_tag2_driver | Adaptor driver. |
node_tag1_hw_adaptor_tag2_firmware | Adaptor firmware. |
The nodes of a compute-cluster are joined via one or more interconnects that will transmit various kinds of data communication. The report will contain one section for each interconnect. An SMT system with no external file server will not use an interconnect for communication and file transfers, so none of the below fields will be filles in and the report will not contain any interconnect sections. The attributes of each interconnect are prefixed as follows:
interconnect_GBEthernet_label = Gigabit Ethernet # If more than one interconnect. interconnect_mpiComm_label = MPI traffic interconnect # It may be named by what it's used for.
First, the fixed-format fields:
interconnect_tag_label | The name of this interconnect type. |
interconnect_tag_order | The output report contains a subsection for each component in the system. The interconnect_order parameter specifies the position of this subsection relative to the others in the report. |
interconnect_tag_hw_vendor | The hardware vendor. An example of usage of this and related fields is given in the test_sponsor section. |
interconnect_tag_hw_model | The model of the interconnect type. |
interconnect_tag1_hw_switch_tag2_count | Number of switches of this type in the interconnect. |
interconnect_tag1_hw_switch_tag2_ports | Ports per switch of this type. |
interconnect_tag1_hw_switch_tag2_data_rate | Descriptive phrase for switch port speed. |
Continuable fields..
interconnect_tag_hw_switch_tag2 | The vendor and model of the internal aggregation or leaf switch(es) composing this interconnect. |
interconnect_tag_hw_topo | Description of the interconnect arrangement. |
interconnect_tag1_sw_switch_tag2_firmware | Switch firmware version. |
interconnect_tag_purpose | Major use for this interconnect. |
interconnect_tag_notes | Free-form notes describing interconnect details. |
Fields can appear and disappear based upon scope. For example, if your Small runs used two Fortran compilers (which is allowed for peak), you could construct a config file that adjusts the fields accordingly:
$ cat tmp.cfg expand_notes = 1 test_sponsor = Turboblaster, Inc. output_format = text output_root = /tmp/fake default: hw_avail = Feb-2021 sw_avail = Jan-2021 sw_compiler1 = C: V42.0 of TurboBlaster C/C++ sw_compiler2 = Fortran: V42.2 of TurboBlaster Fortran small: sw_avail = Apr-2021 sw_compiler3 = Fortran: V9.2.0 of gfortran notes_comp_100 = In base, all benchmarks use Turboblaster Fortran notes_comp_110 = In peak, some benchmarks use Turboblaster Fortran and some notes_comp_120 = benchmarks use gfortran, as noted in the report. $ runhpc --fakereportable --config=tmp small medium | grep .txt format: Text -> /tmp/fake/result/hpc2021_sml.001.small.txt format: Text -> /tmp/fake/result/hpc2021_med.001.medium.txt $ cd /tmp/fake/result $ grep avail hpc2021_sml.001.small.txt Test sponsor: Turboblaster, Inc. Hardware availability: Feb-2021 Tested by: Turboblaster, Inc. Software availability: Apr-2021 $ grep avail hpc2021_med.001.medium.txt Test sponsor: Turboblaster, Inc. Hardware availability: Feb-2021 Tested by: Turboblaster, Inc. Software availability: Jan-2021 $ grep ortran hpc2021_sml.001.small.txt Fortran: V42.2 of TurboBlaster Fortran Fortran: V9.2.0 of gfortran In base, all benchmarks use Turboblaster Fortran In peak, some benchmarks use Turboblaster Fortran and some benchmarks use gfortran, as noted in the report. $ grep ortran hpc2021_med.001.medium.txt Fortran: V42.2 of TurboBlaster Fortran $
In the above example, notice that both the compiler information and the availability date changed in the report, depending on the metric.
In addition to the pre-defined fields, you can write as many notes as you wish. These notes are printed in the report, using a fixed-width font. For example, you can use notes to describe software or hardware information with more detail beyond the predefined fields:
notes_os_001 = The operating system used service pack 2 plus patches notes_os_002 = 31415, 92653, and 58979. At installation time, the notes_os_003 = optional "Numa Performance Package" was selected.
There are various notes sections. If there are no notes in a particular section, it is not output, so you don't need to worry about making sure you have something in each section.
The sections, in order of appearance, are as follows:
Notes about the submit command are described above, with the description of the submit option.
Start your notes with the name of the notes section where you want the note to appear, and then add numbers to define the order of the lines. Within a section, notes are sorted by line number. The NNN above is not intended to indicate that you are restricted to 3 digits; you can use a smaller or larger number of digits as you wish, and you can skip around as you like: for example, ex-BASIC programmers might naturally use line numbers 100, 110, 120... But note that if you say notes_plat782348320742972403 you just might encounter the dreaded (and highly unusual) "out of memory" error, so don't do that.
You can optionally include an underscore just before the number, but beware: if you say both notes_plat_105 and notes_plat105, both are considered to be the same line. The last one mentioned will replace the first, and it will be the only one output.
For all sections you can add an optional additional tag of your choosing before the numbers. Notes will be organized within the tags.
The intent of the feature is that it may allow you to organize your system information in a manner that better suits your own categories for describing it.
For example:
$ cat notes_tags.cfg iterations = 1 output_format = text output_root = /tmp/notes_tags runlist = 605.lbm_s size = test small=base: CC = mpicc CC_VERSION_OPTION = -V notes_part_greeting_011 = ++ how notes_part_greeting_20 = ++ you? notes_part_greeting_012 = ++ are notes_part_aname_1 = ++ Veronica, notes_part_080 = ++ hi $ cat notes_tags.sh runhpc --config=notes_tags --fakereport 605.lbm_s | grep txt grep '++' /tmp/notes_tags/result/hpc2021_sml.001.small.test.txt $ ./notes_tags.sh format: Text -> /tmp/notes_tags/result/hpc2021_sml.001.small.test.txt ++ hi ++ Veronica, ++ how ++ are ++ you? $
You can mention URLs in your notes section, and html reports will correctly render them as hyperlinks. For example:
notes_plat_001 = Additional detail may be found at notes_plat_002 = http://www.turboblaster.com/servers/big/green/
If you like, you can use descriptive text for the link by preceding it by the word LINK and adding the descriptive text in square brackets:
LINK url AS [descriptive text]
The brackets may be omitted if your descriptive text is a single word, without blanks.
For example:
notes_plat_001 = Additional detail may be found at notes_plat_002 = LINK http://www.turboblaster.com/servers/big/green/ AS [TurboBlaster Servers]
When the above appears in an html report, it is rendered as:
Additional detail may be found at TurboBlaster Servers
And in a text report, it appears as:
Platform Notes -------------- Additional detail may found at TurboBlaster Servers (http://www.turboblaster.com/servers/big/green/)
Since the text report is not a context in which the reader can click on a link, it is spelled out instead. Note that because the text report spells the link out, the text line is wider than in HTML, PS, and PDF reports. When deciding where to break your notes lines, you'll have to pick whether to plan line widths for text (which may result in thin-looking lines elsewhere) or plan your line widths for HTML/PS/PDF (which may result in lines that fall of the right edge with text). The feature notes_wrap_columns won't help you here, since it is applied before the link is spelled out.
The SPEChpc tools include a configuration file macro preprocessor. This section introduces preprocessor examples, and then discusses a few basics of syntax.
In this example, the user is testing several configurations, and wants to pick an appropriate pmodel.
$ cat -n preprocessor_example1.cfg 1 505.lbm_t,605.lbm_s,705.lbm_m,805.lbm_l: 2 %if %{model} eq "openacc" 3 pmodel=ACC 4 %elif %{model} eq "openmp" 5 % if %{usegpu} == 1 6 pmodel=TGT 7 % else 8 pmodel=OMP 9 % endif 10 %endif
Lines that start with percent (%) are preprocessor directives. The percent (%) character must be in column 1.
The config file preprocessor is called a macro processor because it allows you to define macros, which are brief abbreviations for longer constructs. In the example above, two macros are used: (%{model}, and %{usegpu}). Macro values are tested, and hunks of config file are included or excluded, using the conditionals %if (lines 2 and 5), and %elif (line 4). One of the conditionals includes an %else clause (line 7).
The preprocessor is automatically run whenever you use runhpc, and macros may be set on the runhpc command line. Or, you can run it separately, as configpp:
% specperl bin/harness/configpp -c preprocessor_example1.cfg --define model=openacc | grep -e lbm -e pmodel 505.lbm_t,605.lbm_s,705.lbm_m,805.lbm_l: pmodel=ACC % specperl bin/harness/configpp -c preprocessor_example1.cfg --define model=openmp | grep -e lbm -e pmodel 505.lbm_t,605.lbm_s,705.lbm_m,805.lbm_l: pmodel=OMP % specperl bin/harness/configpp -c preprocessor_example1.cfg -S model=openmp -S usegpu=1 | grep -e lbm -e pmodel 505.lbm_t,605.lbm_s,705.lbm_m,805.lbm_l: pmodel=TGT
Notice above that preprocessor variables can be set on the command line, using either --define or '-S'.
Emphasis: Column 1. Always punch column 1.
All preprocessor directives begin with the percent sign (%) in column 1. You can -- and probably should -- use indenting, but keep the percent sign on the far left. Any amount of spaces or tabs may separate the percent from the directive. The following are okay:
%define foo % define bar % undef hello!
The following are not okay:
%define foo Space in the first column %define foo Tab in the first column #define foo <--wrong!
Did you catch why the last one is wrong? This isn't CPP - use percent, not hash!
One line per directive
The macro preprocessor does NOT follow the same quoting rules described elsewhere for config files. In particular, you may not use line continuation, line appending, or block quotes. You may have a value of arbitrary length, but in the interests of config file readability and maintainability, please keep them relatively short.
Macro names may only be composed of alphanumeric characters, underscores, and hyphens, and they ARE case-sensitive.
Macros can be defined in a config file or on the command line. Both ways are equivalent.
Macros set on the command-line are defined first; therefore, it is not possible to use the command line to override a macro definition that occurs in the config file itself. If you want the command line to "win", see the notes below about redefinition.
A macro that has not been defined will not be substituted.
A macro that has been defined, but not given a value,
See the example in the next section.
Having no value is not the same as having an empty string as the value. The following are NOT equivalent:
--define FOO="" | FOO is defined, is false, and behaves as an empty string in a string context. |
---|---|
--define FOO | FOO is defined, is true, and behaves as an empty string in a string context. |
See the table about Truth and definition, below.
To define a macro in a config file, use the %define preprocessor directive. Note that no quoting is necessary when specifying the names of macros or their values.
# Define a simple macro %define foo bar # Now the macro called 'foo' has the value 'bar' # It's not necessary for a macro to have a value to be useful %define baz # Now the macro called 'baz' is defined, but it has no value.
Above, the macro baz has been defined, but has not been assigned a value.
Nevertheless, if you use it in an expression, it will behave as if it has the value 1.
$ cat macroDefinedButNoValue.cfg %define baz %ifdef %{baz} % info baz is defined. In text contexts, it looks like this: "%{baz}". %endif %if %{baz} % info In a logical context, it behaves as if it were 1 (i.e. true) %endif %if %{baz} + 3 == 4 % info In a numeric context, it behaves as if it were 1. %endif $ cat macroDefinedButNoValue.sh specperl bin/harness/configpp --config=macroDefinedButNoValue | grep INFO $ ./macroDefinedButNoValue.sh INFO: baz is defined. In text contexts, it looks like this: "". INFO: In a logical context, it behaves as if it were 1 (i.e. true) INFO: In a numeric context, it behaves as if it were 1. $
Macros can also be defined on the command line, using the --define switch. You may find it convenient to abbreviate that switch, if you prefer. The following are entirely equivalent:
$ runhpc --define mymacro=something $ runhpc -S mymacro=something
Some useful macros are predefined, as shown in the table below. New with SPEChpc 2021: The config file preprocessor can do environment variable substitution. Environment variables to be substituted use a percent sign and curly brackets, and the name is prefixed with the string "ENV_", as %{ENV_variable_name}.
%{configfile} | The name of the config file specified on the command line (possibly not including directory path) |
---|---|
%{endian} | Indicator of endian characteristics, for example '12345678' indicating a little-endian system |
%{hostname} | System Under Test name |
%{runhpc} | Your original runhpc command |
%{top_config_file} | The name of the top-level config file (likely the same as %{configfile}, one may have the full path and the other not) |
%{current_config_file} | The name of the config file currently being read (same as %{configfile} unless reading an included config file) |
%{parent_config_file} | The name of the config file that included the config file currently being read (empty for the top-level config file) |
%{config_nesting_level} | The number of nested includes in effect (0 for the top-level config file) |
%{ENV_variable} | Any of your environment variables. |
For a complete list, see dumpmacros. |
Automating output_root: You can automatically bring an output_root into your config file using %{ENV_GO} and navigate around it, as shown in the example for the ogo utility.
Notice that %{ENV_variable_name} brings an environment variable into your config file; what if you want to push it back out to affect other things? In that case, you will also need the feature preenv, which causes runhpc to re-invoke itself with your requested variable in the environment.
For example, you could set up paths for your compiler using something like this:
$ cat -n test.cfg 1 action = build 2 output_root = /tmp/me 3 rebuild = 1 4 runlist = 605.lbm_s 5 verbose = 99 6 7 %define tentop /SW/compilers/GCC/Linux/x86_64/gcc-10.1.0 8 %define ninetop /SW/compilers/GCC/Linux/x86_64/gcc-9.2.0 9 10 %ifdef %{wantGcc9} 11 preENV_PATH = %{ninetop}/bin:%{ENV_PATH} 12 preENV_LD_LIBRARY_PATH = %{ninetop}/lib64:%{ENV_LD_LIBRARY_PATH} 13 % else 14 preENV_PATH = %{tentop}/bin:%{ENV_PATH} 15 preENV_LD_LIBRARY_PATH = %{tentop}/lib64:%{ENV_LD_LIBRARY_PATH} 16 %endif 17 18 default: 19 CC = mpicc 20 CC_VERSION_OPTION = -v 21 $
The config file above builds a single benchmark, 605.lbm_s, using the local paths for GCC 9.2 or 10.1. Notice that in both cases, the desired path is added to the existing path: for example, on line 12, the right side accesses the existing setting via %{ENV_LD_LIBRARY_PATH} and the left side applies it to the build, via preENV_LD_LIBRARY_PATH. On line 5, the config file sets verbose=99, so that runhpc will print all possible detail and we will be able to confirm the adjusted variables.
You will receive a warning if a previously defined macro is re-defined. In the example below, the first config file just sets a macro; the second one tests before acting.
$ cat preproc.symbol.just_define.cfg %define build_ncpus 20 makeflags = -j%{build_ncpus} $ $ cat preproc.symbol.test_first.cfg %ifndef %{build_ncpus} % define build_ncpus 20 %endif makeflags = -j%{build_ncpus} $
A run script uses both config files with and without a definition on the runhpc command line:
$ cat preproc.symbol.sh JUST_DEFINE="configpp --config=preproc.symbol.just_define.cfg" TEST_FIRST="configpp --config=preproc.symbol.test_first.cfg" GREP_IT='grep -e WARNING -e makeflags' echo original: $JUST_DEFINE --define build_ncpus=8 | $GREP_IT $JUST_DEFINE | $GREP_IT echo echo test1st: $TEST_FIRST --define build_ncpus=8 | $GREP_IT $TEST_FIRST | $GREP_IT $
Result: testing first with ifndef avoids a warning and does a better job of respecting the user's wishes.
$ ./preproc.symbol.sh original: WARNING: Redefinition of preprocessor macro 'build_ncpus' on line 1 makeflags = -j20 makeflags = -j20 test1st: makeflags = -j8 makeflags = -j20 $
Sometimes you want to make the preprocessor forget about a macro that you taught it. This is easily accomplished.
Macros can be undefined in two ways:
%define foo bar # Now the macro called 'foo' has the value 'bar' %undef foo # Now it doesn't
Note that no quoting is necessary when specifying the names of macros.
Like macro definition, the undefinition requests can't affect macros set in the config file because
those definitions effectively happen after the un-definition. For this reason, command-line undefinition is basically
useless; it can only undo macros also set on the command line.
So why was such a useless ability added to the tools?
The writer likes orthogonality.
By now you're probably over that initial euphoric rush that comes from wantonly defining and undefining macros, and you're looking for something more. This is it!
When you want to use the value of a macro, you refer to it by name. Unfortunately, the syntax for this is not as simple as you might hope. It's not too complicated, though; to have the preprocessor expand the macro 'foo', just write
%{foo}
in the place where you'd like it to appear. Given the following config file snippet:
%define foo Hello_ %define bar baz %define foobar Huh? %define foobaz What? %define Hello_baz Please don't do this
Here's a handy table to see the various ways you can reference these values:
Macro reference | Value |
---|---|
%{foo} | Hello_ |
%{bar} | baz |
%{foobar} | Huh? |
%{foobaz} | What? |
%{Hello_baz} | Please don't do this |
Easy, right? The following is also possible:
%{foo%{bar}} | What? |
%{%{foo}%{bar}} | Please don't do this |
Because macro values can only be one line long, it's not possible to use the preprocessor to macro-ize large chunks of your config file at once, as may be common practice for advanced users of CPP.
A macro that has not been defined will not be substituted. Note the mention of %{FOO} on the last line of this config file.
$ cat macroDef.cfg action = build output_format = text output_root = /tmp/mDef rebuild = 1 runlist = 605.lbm_s size = test teeout = 1 intspeed=base: CXX = mpicc CXX_VERSION_OPTION = -v OPTIMIZE = %{FOO} $
The failure for the first test below is expected: the GNU C compiler does not know what to do with ${FOO}.
$ cat macroDef1.sh runhpc --config=macroDef | grep -e lbm.o -e ^Error -e uccess $ ./macroDef1.sh mpicc -c -o lbm.o -DSPEC -DNDEBUG -I. %{FOO} lbm.c Error with make 'specmake --output-sync build': check file "/tmp/mDef/benchspec/HPC/605.lbm_s/build/build_base_none.0000/make.out" $ cat /tmp/mDef/benchspec/HPC/605.lbm_s/build/build*/make.out mpicc -c -o lbm.o -DSPEC -DNDEBUG -I. %{FOO} lbm.c gcc: error: %{FOO}: No such file or directory $
If you want to substitute an empty string, then assign it one.
$ cat macroDef2.sh runhpc --config=macroDef --define FOO="" | grep -e lbm.o -e ^Error -e uccess $ ./macroDef2.sh mpicc -c -o lbm.o -DSPEC -DNDEBUG -I. lbm.c Build successes for small: 605.lbm_s(base) $
Defining, undefining, and expanding macros is quite an enjoyable activity in and of itself, and can even be useful on occasion. However, conditionals add an entirely new dimension to config file processing: the ability to include and exclude entire sections of text based on macros and their values.
The %ifdef conditional provides a way to determine whether or not a particular macro has been defined. If the named macro has been defined, the conditional is true, and the text to the matching %endif is included in the text of the config file as evaluated by runhpc. Note that the matching %endif may not necessarily be the next %endif; conditionals may be nested.
For example, given the following section of a config file:
%define foo %ifdef %{foo} This text will be included %endif %ifdef %{bar} This text will not be included %endif
The preprocessor would produce the following output:
This text will be included
Note especially the quoting used for the macro names in the conditional; the only time macro name quoting may be omitted is when defining or undefining it.
The %ifndef conditional is the converse of %ifdef; If the named macro has not been defined, the conditional is true, and the text to the matching %endif is included in the text of the config file as evaluated by runhpc. Note that the matching %endif may not necessarily be the next %endif; conditionals may be nested.
Given a slightly modified version of the example from earlier:
%define foo %ifndef %{foo} Now THIS text will not be included %endif %ifndef %{bar} This text WILL be included %endif
The preprocessor would produce the following output:
This text WILL be included
Checking whether or not a macro is defined is quite useful, but it's just a subset of the more general conditional facility available. This general form is
%if expression ... %endif
The expression is evaluated using a subset of the Perl interpreter, so the possibilities for testing values are fairly broad. For example,
%ifdef %{foo} ... %endif
is exactly equivalent to
%if defined(%{foo}) ... %endif
Likewise,
%ifndef %{foo} ... %endif
is exactly equivalent to
%if !defined(%{foo}) ... %endif
Using the general form, it's possible to string conditionals together:
%if defined(%{foo}) && !defined(%{bar}) || %{baz} == 0 ... %endif
To compare versus a string value, you must supply quotes:
%if %{foo} eq 'Hello, Dave.' ... %endif
You may perform basic math on macro values:
%if %{foo} * 2004 > 3737 ... %endif
You can do basic regular expression matching, as shown in the example for %info.
More precisely, the Perl operations allowed are the :base_core and :base_math bundles, with the ability to dereference and modify variables disallowed. For more details, see the source code for config.pl (the eval_pp_conditional subroutine) and Perl's own Opcode documentation.
Truth and definition
%ifdef %{v} and %if defined(%{v}) vs. %if %{v} |
Conditional expressions are evaluated using perl's rules for Truth and Falsehood.
$ cat test_define.cfg %ifdef %{a} OPTIMIZE = -a %endif %if defined(%{b}) LDOPTIMIZE = -b %endif %if %{c} COPTIMIZE = -c %endif $ specperl bin/harness/configpp --config=test_define -S a=1 -S b=1 -S c=1 | grep OPT OPTIMIZE = -a LDOPTIMIZE = -b COPTIMIZE = -c $ specperl bin/harness/configpp --config=test_define -S a=0 -S b=0 -S c=0 | grep OPT OPTIMIZE = -a LDOPTIMIZE = -b |
It's possible to get by without the "else" part of the classic "if .. then .. else" trio, but it's not any fun. It works as you'd expect:
%define foo %ifndef %{foo} This text will not be included %else This text WILL be included (from the else clause) %endif
The preprocessor would produce the following output:
This text WILL be included (from the else clause)
Only one %else per conditional is allowed.
%elif is another convenience that's been added. For those not familiar with CPP, it's an "else if" construct. You may have as many of these as you'd like. Given:
%define foo Hello! %if !defined(%{foo}) This text will not be included %elif defined(%{bar}) This text won't be included either %elif '%{foo}' eq 'Hello!' This text WILL be included (from the second elif clause) %else Alas, the else here is left out as well. %endif
The preprocessor would produce the following output:
This text WILL be included (from the second elif clause)
It's often helpful to be able to warn or exit on certain conditions. Perhaps there's a macro that must be set to a particular value, or maybe it's just very highly recommended.
%warning does just what you'd expect; when the preprocessor encounters this directive, it prints the text following to stdout and the current log file, along with its location within the file being read, and continues on.
$ cat warning.cfg %if !defined(%{somewhat_important_macro}) % warning You have not defined somewhat_important_macro! %endif $ $ cat warning.sh specperl bin/harness/configpp --config=warning | grep -C2 WARNING $ $ ./warning.sh *** WARNING: You have not defined somewhat_important_macro! (From line 2 of /hpc2021/config/warning.cfg.) $
Like %warning, %error logs an error to stderr and the log file. Unlike %warning, though, it then stops the run.
Consider a slightly modified version of the previous example:
$ cat error.cfg %if !defined(%{REALLY_important_macro}) % error You have not defined REALLY_important_macro! %endif $ $ cat error.sh specperl bin/harness/configpp --config=error > /tmp/out echo runhpc exit code: $? grep -C2 ERROR /tmp/out $ ./error.sh runhpc exit code: 1 ************************************************************************ ERROR: You have not defined REALLY_important_macro! (From line 2 of /hpc2021/config/error.cfg.) $
Unlike a warning, the error will be close to the last thing output. As you can see from the output of echo $? above, runhpc exited with an error code 1.
The %info directive prints a message preceded by the word INFO:. For example,
$ cat -n info.cfg 1 %if !defined(%{chip}) || %{chip} !~ m/(sparc|x86)/ 2 % error Please use --define chip=sparc or --define chip=x86 3 %endif 4 5 %if %{chip} eq "sparc" 6 % define default_build_ncpus 64 7 %elif %{chip} eq "x86" 8 % define default_build_ncpus 20 9 %endif 10 %ifndef %{build_ncpus} 11 % define build_ncpus %{default_build_ncpus} 12 %endif 13 14 %info Preprocessor selections: 15 %info . build_ncpus %{build_ncpus} 16 %info . chip %{chip} 17 18 make = specmake --jobs=%{build_ncpus} --load-average=%{build_ncpus} $ $ specperl bin/harness/configpp -c info --define chip=sparc | grep -e make -e INFO INFO: Preprocessor selections: INFO: . build_ncpus 64 INFO: . chip sparc make = specmake --jobs=64 --load-average=64 $
Note in the example above:
The %dumpmacros prints the values of all macros currently defined at the point where it appears. Each macro value is preceded by the word 'DBG:'. For example,
$ cat -n dumpmacros.cfg 1 %if !defined(%{chip}) || %{chip} !~ m/(sparc|x86)/ 2 % error Please use --define chip=sparc or --define chip=x86 3 %endif 4 5 %if %{chip} eq "sparc" 6 % define default_build_ncpus 64 7 %elif %{chip} eq "x86" 8 % define default_build_ncpus 20 9 %endif 10 %ifndef %{build_ncpus} 11 % define build_ncpus %{default_build_ncpus} 12 %endif 13 14 %dumpmacros $ $ specperl bin/harness/configpp -c dumpmacros --define chip=sparc | grep -e DBG DBG: build_ncpus: '%{default_build_ncpus}' DBG: chip: 'sparc' DBG: default_build_ncpus: '64' DBG: runhpc: 'configpp -c dumpmacros --define chip=sparc' $
The %dumpmacros directive is new with SPEChpc 2021.
This section describes how the location and contents of several kinds of output files are influenced by your config file.
It was mentioned above that the HASH section of the config file is written automatically by the tools. Each time your config file is updated, a backup copy is made. Thus your config directory may soon come to look like this:
$ cd $SPEC/config $ ls tune.cfg* tune.cfg tune.cfg.2021-02-05T124831 tune.cfg.2021-02-05T125733 tune.cfg.2021-02-05T120242 tune.cfg.2021-02-05T125557 tune.cfg.2021-02-05T125738 tune.cfg.2021-02-05T122021 tune.cfg.2021-02-05T125603 tune.cfg.2021-02-05T125744 tune.cfg.2021-02-05T122026 tune.cfg.2021-02-05T125608 tune.cfg.2021-02-05T125749 tune.cfg.2021-02-05T124215 tune.cfg.2021-02-05T125614 tune.cfg.2021-02-05T125756 tune.cfg.2021-02-05T124222 tune.cfg.2021-02-05T125620 tune.cfg.2021-02-05T125802 tune.cfg.2021-02-05T124728 tune.cfg.2021-02-05T125626 tune.cfg.2021-02-05T125807 tune.cfg.2021-02-05T124739 tune.cfg.2021-02-05T125632 tune.cfg.2021-02-05T125812 tune.cfg.2021-02-05T124821 tune.cfg.2021-02-05T125727 $
If this feels like too much clutter, you can disable the backup mechanism, as described under backup_config. Note that doing so may leave you with a risk of losing the config file in case of a filesystem overflow or system crash. A better idea may be to periodically remove just portions of the clutter, with selective removal of older version; or sweep them to a wastebasket every now and then:
$ cd $SPEC/config $ mkdir wastebasket $ mv *cfg.2021* wastebasket/ $
$SPEC/result (Unix) or %SPEC%\result (Windows) contains reports and log files. When you are doing a build, you will probably find that you want to pay close attention to the log files such as hpc2021.001.log. Depending on the verbosity level that you have selected, it will contain detailed information about how your build went.
The SPEChpc 2021 tool suite provides for varying amounts of output about its actions during a run. These levels range from the bare minimum of output (level 0) to copious streams of information that are probably useful only to tools developers (level 99). Selecting one output level gives you the output from all lower levels, which may cause you to wade through more output than you might like.
When you are trying to find your way through a log file, you will probably find these (case-sensitive) search strings useful:
runhpc: | The runhpc command for this log. |
---|---|
Running | Printed at the top of a run of a benchmark. |
# | Printed at the top of a run of a benchmark for runs with multiple iterations. Useful for finding the ref workloads in reportable runs. |
runtime | Printed at the end of a benchmark run. |
Building | Printed at the beginning of a benchmark compile. |
Elapsed compile | Printed at the end of a benchmark compile. |
There are also temporary debug logs, such as hpc2021.001.log.debug. A debug log contains very detailed debugging output from the SPEC tools, as if --verbose 99 had been specified.
For a successful run, the debug log will be removed automatically, unless you specify "--keeptmp" on the command line, or "keeptmp=yes" in your config file.
For a failed run, the debug log is kept. The debug log may seem overwhelmingly wordy, repetitive, detailed, redundant, repetitive, and long-winded, and therefore useless. Suggestion: after a failure, try looking in the regular log first, which has a default verbosity level of 5. If your regular log doesn't have as much detail as you wish, then you can examine the additional detail in the debug log.
If you file a support request, you may be asked to send in the debug log.
The 'level' referred to in the table below is selected either in the config file verbose option or in the runhpc command as in 'runhpc --verbose n'.
Levels higher than 99 are special; they are always output to your log file. You can also see them on the screen if you set verbosity to the specified level minus 100. For example, the default log level is 5. This means that on your screen you will get messages at levels 0 through 5, and 100 through 105. In your log file, you'll find the same messages, plus the messages at levels 106 through 199.
Level | What you get |
0 | Basic status information, and most errors. These messages can not be turned off. |
1 | List of the benchmarks which will be acted upon. |
2 | A list of possible output formats, as well as notification when beginning and ending each phase of operation (build, setup, run, reporting). |
3 | A list of each action performed during each phase of operation (e.g. "Building 605.lbm_s", "Setting up 635.weather_s") |
4 | Notification of benchmarks excluded |
5 (default) | Notification if a benchmark somehow was built but nevertheless is not executable. |
6 | Time spent doing automatic flag reporting. |
7 | Actions to update SPEC-supplied flags files. |
10 | Information on basepeak operation. |
12 | Errors during discovery of benchmarks and output formats. |
15 | Information about certain updates to stored config files |
24 | Notification of additions to and replacements in the list of benchmarks. |
30 | A list of options which are included in the hash of options used to determine whether or not a given binary needs to be recompiled. |
35 | A list of key=value pairs that can be used in command and notes substitutions, and results of env_var settings. |
40 | A list of 'submit' commands for each benchmark.
Note: If you would like to see all of the submit commands for every copy and every benchmark invocation, with all your variables (such as $BIND) resolved, try runhpc --verbose=40 --fake, or go to the run directory and use specinvoke -n (dry run). |
70 | Information on selection of median results. |
89 | Progress comparing run directory checksum for executables. |
90 | Time required for various internal functions in the tools. |
95, 96, 97, 98 | Flag parsing progress during flag reporting (progressively more detail) |
99 | Gruesome detail of comparing hashes of files being copied during run directory setup. |
Messages at the following levels will always appear in your log files | |
100 | Various config file errors, such as bad preprocessor directives, bad placement of certain options, illegal characters... |
102 | Information about output formats that could not be loaded. |
103 | A tally of successes and failures during the run broken down by benchmark. |
106 | A list of runtime and calculated ratio for each benchmark run. |
107 | Dividers to visually block each phase of the run. |
110 | Elapsed time for each portion of a workload (if an executable is invoked more than once). |
120 | Messages about which commands are being issued for which benchmarks. |
125 | A listing of each individual child processes' start, end, and elapsed times. |
130 | A nice header with the time of the runhpc invocation and the command line used. Information about what happened with your sysinfo program |
140 | General information about the settings for the current run. |
145 | Messages about file comparisons. |
150 | List of commands that will be run, and details about the settings used for comparing output files. Also the contents of the makefile written. |
155 | Start, end, and elapsed times for benchmark run. |
160 | Start, end, and elapsed times for benchmark compilation. |
180 | stdout and stderr from commands run |
190 | Start and stop of delays |
191 | Notification of command line used to run specinvoke. |
If you do many builds and runs, you may find that your result directory gets too cluttered. Within a result directory, all output formats other than .rsf can be regenerated from your .rsf files. Therefore, you could reduce clutter by deleting HTML, PDF, and other reports. You can delete old .debug logs unless you plan to submit a support request.
Still feel cluttered? A simple solution is to move your result directory aside, giving it a new name.
Don't worry about creating a new directory; runhpc will do so automatically. You should be careful to ensure
no surprises for any currently-running users.
If you move result directories, it is a good idea to also clean temporary directories at the same time.
Example:
cd $SPEC
mv result old-result
rm -Rf tmp/
cd output_root # (If you use an output_root)
rm -Rf tmp/
As described under "About Disk Usage" in runhpc.html, the SPEChpc 2021 tools do the actual builds and runs in newly created directories. The benchmark sources are never modified in the src directory.
The build directories for a benchmark are located underneath that benchmarks' top-level directory, typically $SPEC/benchspec/HPC/nnn.benchmark/build (Unix)
(If you are using the output_root feature, then the first part of that path will change to be your requested root instead of SPEC.)
The build directories have logical names, typically of the form build_<tune>_<label>.0000.
If the directory build_<tune>_<label>.0000 already exists when a new build is attempted for the same tuning and label, the directory will be re-used, unless:
In such cases, the 0000 will be incremented until a name is generated that is available. You can find locked directories by searching for lock=yes in the file $SPEC/benchspec/HPC/<nnn.benchmark>/run/list (Unix)
When more than one build directory has been created for a given tuning and label, you may need to trace the directory back to the specific build attempt that created it. You can do so by searching for the directory name in the log files:
$ grep build_peak_blue271.0000 *log | grep Building hpc2021.838.log: Building 605.lbm_s peak blue271: (build_peak_blue271.0000) [2021-02-14 05:26:09] $
In the above example, the grep command locates log #838 as the log that corresponds to this run directory.
A variety of files are output to the build directory. Here are some of the key files which can usefully be examined:
Makefile.spec | The components for make that were generated for the current config file with the current set of runhpc options. |
make.out | For 1 pass compile: detailed commands generated. |
For more information about how the run directories work, see the descriptions of specinvoke, specmake, and specdiff in utility.html.
When something goes wrong, here are some things to check:
Are there any obvious clues in the log file? Search for the word "Building". Keep searching until you hit the next benchmark AFTER the one that you are interested in. Now scroll backward one screen's worth of text.
Did your desired switches get applied? Go to the build directory, and look at options*out.
Did the tools or your compilers report any errors? Look in the build directory at *err.
What happens if you try the build by hand? See the section on specmake in utility.html.
If an actual run fails, what happens if you invoke the run by hand? See the information about "specinvoke -n" in utility.html
Do you understand what is in your path, and why? Sometimes confusion can be greatly reduced by ensuring that you have only what is needed, avoiding, in particular, experimental and non-standard versions of standard utilities.
Note: on Windows systems, SPEC recommends that Windows/Unix compatibility products should be removed from the %PATH% prior to invoking runhpc, in order to reduce the probability of certain difficult-to-diagnose error messages.
Try asking the tools to leave more clues behind, with keeptmp.