Skip to content

Commands

The k4bench console script is the primary interface. This page walks the flags with examples. For a terse table, see the Configuration reference; for how flags interact, see Configuration.

Synopsis

k4bench --xml PATH
        [--list-detectors]
        [--sweep | --sweep-detectors DET... | --include-only DET... | --exclude-only DET...]
        [--events N]
        [--ddsim-args="..."]
        [--output-file PATH]
        [--output-dir DIR]
        [--pickle FILENAME]
        [--verbose | -v]

Only --xml is required.

Geometry

--xml PATH (required)

The top-level DD4hep compact XML for the geometry under test. May be absolute or relative; environment variables like $K4GEO are expanded by your shell before k4bench sees the path.

k4bench --xml $K4GEO/FCCee/ALLEGRO/compact/ALLEGRO_o1_v03/ALLEGRO_o1_v03.xml \
        --ddsim-args="--enableGun --gun.particle e-"

The XML's stem (ALLEGRO_o1_v03) becomes the default output directory name.

--list-detectors

Print the subdetector names found in --xml, one per line, and exit — no simulation is run and no other flags are needed. Use it to discover valid names for --sweep-detectors/--include-only/--exclude-only before running a sweep.

k4bench --xml ALLEGRO_o1_v03.xml --list-detectors
# InnerTracker
# OuterTracker
# ECalBarrel
# HCalBarrel
# ...

Exits 0 with the names on stdout, or 1 with a message on stderr if the geometry has no <detector> elements.

Sweep selection

These four are mutually exclusive. With none, k4bench does a single baseline run. See Sweep modes for full semantics.

--sweep

Run the baseline, then one run per discovered subdetector with that detector removed.

k4bench --xml ALLEGRO_o1_v03.xml --sweep \
        --ddsim-args="--enableGun --gun.particle e- --gun.distribution uniform"

--sweep-detectors DETECTOR [DETECTOR ...]

Like --sweep, but the removal sweep is restricted to the named detectors: the baseline plus one no_<Name> run per name. Handy when a full sweep would take too long — e.g. in CI. Unknown names are warned and skipped.

k4bench --xml ALLEGRO_o1_v03.xml \
        --sweep-detectors ECalBarrel HCalBarrel \
        --ddsim-args="--enableGun --gun.particle e- --gun.distribution uniform"
# labels: baseline, no_ECalBarrel, no_HCalBarrel

--include-only DETECTOR [DETECTOR ...]

A single run keeping only the named detectors active; all others are removed. No baseline. Useful to isolate a small subsystem.

k4bench --xml ALLEGRO_o1_v03.xml \
        --include-only ECalBarrel HCalBarrel \
        --ddsim-args="--enableGun --gun.particle e-"
# label: only_ECalBarrel_HCalBarrel

--exclude-only DETECTOR [DETECTOR ...]

A single run with the named detectors removed and all others active. The mirror image of --include-only.

k4bench --xml ALLEGRO_o1_v03.xml \
        --exclude-only DRcaloTubes \
        --ddsim-args="--enableGun --gun.particle e-"
# label: no_DRcaloTubes

Long detector lists get a hashed label

When you name more than five detectors, the label is truncated to a stable hash suffix (e.g. only_8_detectors_1a2b3c4d) so filenames stay sane. The full list is printed to the run's log.

Simulation

--events N

Events to simulate per run. Default 2. Injected as --numberOfEvents and used to compute events_per_sec.

k4bench --xml ALLEGRO_o1_v03.xml --events 500 --ddsim-args="--enableGun --gun.particle e-"

--ddsim-args="ARGS"

Additional arguments passed verbatim to ddsim, as one quoted string. This is where all physics configuration goes. Always use the = form.

--ddsim-args="--enableGun --gun.particle e- --gun.distribution uniform --gun.energy '10*GeV'"

See Configuration → passthrough rules.

--output-file PATH

The temporary EDM4hep ROOT output (default /tmp/k4bench_out.edm4hep.root), injected as --outputFile. Overwritten each run; only its size is recorded.

Output

--output-dir DIR

Directory for logs and results. Defaults to logs/<xml-stem>/. Created if absent.

--pickle FILENAME

Also serialise the full list[RunResult] to <output-dir>/<FILENAME>:

k4bench --xml ALLEGRO_o1_v03.xml --sweep --pickle results.pkl \
        --ddsim-args="--enableGun --gun.particle e-"

Reload later:

import pickle
results = pickle.loads(open("logs/ALLEGRO_o1_v03/results.pkl", "rb").read())

--verbose, -v

Stream ddsim output to your terminal live (it is always captured to the .log regardless).

Benchmarking a k4run job

k4bench k4run benchmarks any Gaudi job run with k4run, reconstruction for example, instead of ddsim. k4Bench appends the k4BenchAuditor's options file after the job's own, so every algorithm and service is measured per event, preloads the auditor's allocation counter, so the measurements include heap allocations, and injects --num-events. Everything else the job needs goes in --k4run-args. The counter forwards to glibc's allocator, so when LD_PRELOAD already names another one (jemalloc, tcmalloc, ...) or a sanitizer runtime (ASan, TSan, ...) it is not preloaded and the job runs on its own allocator without allocation counts. When the job has a setup_script, LD_PRELOAD is checked after the script is sourced, so the allocators it preloads count too. An allocator the job links rather than preloads is not detected, and is replaced by glibc's while the counter is preloaded.

k4bench k4run CLDReconstruction.py \
    --stage-dir $CLDCONFIG/share/CLDConfig \
    --events 30 \
    --k4run-args="--inputFiles $PWD/sim.edm4hep.root --compactFile $K4GEO/FCCee/CLD/compact/CLD_o2_v09/CLD_o2_v09.xml" \
    --variant truth_tracking=--truthTracking
# labels: baseline, variant_truth_tracking

Each run starts in a fresh working directory: a writable copy of --stage-dir (CLDConfig must run from its own directory) or an empty one. It is removed after the run, so the job's outputs never land in your directory, and paths in --k4run-args must be absolute. Each --variant NAME=ARGS is one more run with ARGS appended. Before each run, the same job runs for one event, unmeasured and discarded, so the measured run finds what it reads from CVMFS already cached; on a cold cache, fetching the software can take longer than initializing the job (--no-warm-up skips it). A warm-up that fails leaves its log as <label>_warm-up.log. Next to the usual log and results CSV, every label gets <label>_events.json, <label>_components.json and <label>_joboptions.opts. With --memory-events N, each run is followed by its job again for N events, untimed, which records the heap each component holds into <label>_heap.json; a pass that fails leaves its log as <label>_heap.log instead. See File formats and the configuration reference.

Exit codes

Code Meaning
0 All runs succeeded (returncode == 0 for every run).
1 A configuration error (bad arguments, no valid detectors) or one or more ddsim runs failed.

On failure, k4bench prints which runs failed by label and (for config errors) an Error: ... message on stderr. A sweep always runs to completion even if some configurations fail — you keep the partial results and the overall exit code still reflects the failure.

3 run(s) failed: ['no_ECalBarrel', 'no_HCalBarrel', 'no_Muon']

Interrupting a run

Press Ctrl+C to stop. k4bench catches KeyboardInterrupt, sends SIGTERM to the entire ddsim process group, waits up to 5 seconds, then escalates to SIGKILL if needed — so you don't leave orphaned ddsim/Geant4 processes behind. The interrupt then propagates and k4bench exits. See run_ddsim.

Built-in help

k4bench --help

prints the argparse help, including the usage examples embedded in the k4bench.cli module docstring.