From 304820584c2ac90957af55478738675d8563a6e2 Mon Sep 17 00:00:00 2001 From: Yinan Xu Date: Wed, 29 Apr 2026 18:01:59 +0800 Subject: [PATCH] feat(spec2006): add runspec-based SPEC2006 workload flow Add a SPEC2006 workload integration under workloads/linux/spec2006 that builds benchmarks from an external SPEC tree with runspec, stages the selected inputs into the Linux workload rootfs, and exports the resulting firmware, ELF, and raw binary artifacts under the build and image directories. The new helper scripts keep SPEC build output inside this repository, add ELF-only make targets, and record detailed build logs in per-case log files. --- scripts/build-firmware-linux.sh | 10 +- scripts/build-workload-linux.sh | 2 +- workloads/linux/spec2006/README.md | 177 ++ workloads/linux/spec2006/build.sh | 228 ++ workloads/linux/spec2006/riscv_gcc15_base.cfg | 195 ++ workloads/linux/spec2006/rules.mk | 180 ++ workloads/linux/spec2006/spec06.json | 2241 +++++++++++++++++ workloads/linux/spec2006/spec2006-package.py | 562 +++++ 8 files changed, 3589 insertions(+), 6 deletions(-) create mode 100644 workloads/linux/spec2006/README.md create mode 100644 workloads/linux/spec2006/build.sh create mode 100644 workloads/linux/spec2006/riscv_gcc15_base.cfg create mode 100644 workloads/linux/spec2006/rules.mk create mode 100644 workloads/linux/spec2006/spec06.json create mode 100644 workloads/linux/spec2006/spec2006-package.py diff --git a/scripts/build-firmware-linux.sh b/scripts/build-firmware-linux.sh index 219b0d2..77f59b7 100644 --- a/scripts/build-firmware-linux.sh +++ b/scripts/build-firmware-linux.sh @@ -47,8 +47,8 @@ if ! [ -f "$DEFAULT_DTB_FILE" ]; then echo "Default device tree not found: $DEFAULT_DTB_FILE" >&2 exit 1 fi -dd if="$STARTUP_FILE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" -dd if="$DEFAULT_DTB_FILE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$DTB_OFFSET_KB" conv=notrunc -dd if="$SBI_BUILD_DIR/build/platform/generic/firmware/fw_jump.bin" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$SBI_OFFSET_KB" conv=notrunc -dd if="$KERNEL_IMAGE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$MEGABYTE" seek="$KERNEL_OFFSET_MB" conv=notrunc -dd if="$CPIO_ARCHIVE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$MEGABYTE" seek="$INITRAMFS_OFFSET_MB" conv=notrunc +dd if="$STARTUP_FILE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" status=none +dd if="$DEFAULT_DTB_FILE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$DTB_OFFSET_KB" conv=notrunc status=none +dd if="$SBI_BUILD_DIR/build/platform/generic/firmware/fw_jump.bin" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$KILOBYTE" seek="$SBI_OFFSET_KB" conv=notrunc status=none +dd if="$KERNEL_IMAGE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$MEGABYTE" seek="$KERNEL_OFFSET_MB" conv=notrunc status=none +dd if="$CPIO_ARCHIVE" of="$WORKLOAD_BUILD_DIR/fw_payload.bin" bs="$MEGABYTE" seek="$INITRAMFS_OFFSET_MB" conv=notrunc status=none diff --git a/scripts/build-workload-linux.sh b/scripts/build-workload-linux.sh index 040002f..ee9df27 100644 --- a/scripts/build-workload-linux.sh +++ b/scripts/build-workload-linux.sh @@ -31,7 +31,7 @@ pack-cpio() { local cpio_file="$2" rm -f "$cpio_file" cd "$root_dir" - find . | fakeroot cpio -o -H newc > "$cpio_file" + find . | fakeroot cpio -o -H newc > "$cpio_file" 2>/dev/null } populate-src-dir diff --git a/workloads/linux/spec2006/README.md b/workloads/linux/spec2006/README.md new file mode 100644 index 0000000..e140e44 --- /dev/null +++ b/workloads/linux/spec2006/README.md @@ -0,0 +1,177 @@ +# SPEC CPU2006 Linux workload + +`workloads/linux/spec2006` now builds SPEC CPU2006 workloads with the original +SPEC tools (`runspec`) against an external SPEC installation. + +## Build one case + +Either point `SPEC` at the SPEC tree: + +```sh +make linux/spec2006 BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN +``` + +or pass `SPEC2006` explicitly: + +```sh +make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006=/path/to/cpu2006 -jN +``` + +`BENCH` may also be a full case name from `spec06.json`: + +```sh +make linux/spec2006 BENCH=astar_biglakes SPEC=/path/to/cpu2006 -jN +``` + +The build flow is: + +1. Generate a build-local SPEC cfg copy under the case build directory. +2. Inject `output_root` into that cfg so SPEC build artifacts stay under this + repository instead of modifying the original SPEC installation. +3. Run `runspec --action build`. +4. Export the built SPEC ELF, package the benchmark plus input files into the + Linux rootfs, and produce: + +```text +build/linux-workloads/spec2006//fw_payload.bin +``` + +## Build and export images + +Export all selected cases to `build/images/spec2006`: + +```sh +make spec2006-images SPEC=/path/to/cpu2006 -jN +``` + +By default, export builds only `ref` cases. Select another input set with +`SPEC2006_INPUT`; use `all` to export every configured case: + +```sh +make spec2006-images SPEC=/path/to/cpu2006 SPEC2006_INPUT=test -jN +make spec2006-images SPEC=/path/to/cpu2006 SPEC2006_INPUT=all -jN +``` + +Selected SPEC cases are built one by one to avoid concurrent `runspec` +instances contending on shared temporary state inside the SPEC tool tree. + +The export directory is organized as: + +```text +build/images/spec2006/ + bin/.fw_payload.bin + kernel/.Image + elf/.elf + gcpt/gcpt.elf + gcpt/gcpt.bin + cfg/ +``` + +`gcpt/` and `cfg/` are copied once per export tree, not once per case. + +Override the destination with `SPEC2006_IMAGE_DIR=/path/to/image`. + +## Build ELF only + +Build one case without packaging it into the Linux rootfs: + +```sh +make spec2006-elf BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN +``` + +This writes: + +```text +build/linux-workloads/spec2006//elf/.elf +``` + +Build every selected case as ELF only: + +```sh +make spec2006-elfs SPEC=/path/to/cpu2006 SPEC2006_INPUT=ref -jN +make spec2006-elfs SPEC=/path/to/cpu2006 SPEC2006_INPUT=all -jN +``` + +If you only want the standalone ELF build flow, you can run it from this +directory without the top-level Makefile: + +```sh +cd workloads/linux/spec2006 +make -f rules.mk spec2006-elf BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN +make -f rules.mk spec2006-elfs SPEC=/path/to/cpu2006 SPEC2006_INPUT=all -jN +``` + +## Configuration + +The default SPEC cfg is: + +```text +workloads/linux/spec2006/riscv_gcc15_base.cfg +``` + +Override it with: + +```sh +make linux/spec2006 BENCH=bzip2_source \ + SPEC=/path/to/cpu2006 \ + SPEC2006_CFG=/path/to/other.cfg \ + -jN +``` + +The default tuning level is `base`. Override it with `SPEC2006_TUNE=peak`. + +Case definitions remain in `spec06.json`; they describe the benchmark name, +required input files/directories, command-line arguments, and input set. + +## Toolchain and jemalloc + +The default cross prefix is: + +```text +riscv64-unknown-linux-gnu- +``` + +Override it with `SPEC2006_CROSS_COMPILE=/path/to/bin/riscv64-unknown-linux-gnu-`. + +The helper derives the toolchain root from `SPEC2006_CROSS_COMPILE` and exports +the env vars expected by `riscv_gcc15_base.cfg`: + +- `LLVM_INSTALL_PATH` +- `GNU_RISCV64_PATH` +- `JEMALLOC_INSTALL_PATH` + +If you need to override them directly, use: + +- `SPEC2006_COMPILER_ROOT` +- `SPEC2006_GNU_TOOLCHAIN_ROOT` +- `SPEC2006_JEMALLOC_ROOT` + +If the selected cfg references jemalloc and the library is missing, the build +automatically clones upstream jemalloc and installs it into: + +```text +build/linux-workloads/spec2006/jemalloc/install +``` + +Override the install prefix with `SPEC2006_JEMALLOC_ROOT` or +`JEMALLOC_INSTALL_PATH`. Override the jemalloc source/checkout with: + +- `SPEC2006_JEMALLOC_REPO` +- `SPEC2006_JEMALLOC_COMMIT` +- `SPEC2006_JEMALLOC_CONFIGURE_HOST` +- `SPEC2006_DOWNLOAD_RETRIES` + +## Logs + +SPEC2006 builds keep console output concise. Detailed logs are written to: + +- `build/linux-workloads/spec2006//logs/build.log` +- `build/linux-workloads/spec2006/jemalloc/build.log` + +## Notes + +- The original SPEC tree is used read-only for sources and input data. +- Build logs, copied cfg files, build directories, and built executables are + redirected into the case-local `runspec-output` directory via `output_root`. +- The source cfg in this repository is never passed to `runspec` directly; + `runspec` is allowed to rewrite only the generated local cfg copy. diff --git a/workloads/linux/spec2006/build.sh b/workloads/linux/spec2006/build.sh new file mode 100644 index 0000000..999991f --- /dev/null +++ b/workloads/linux/spec2006/build.sh @@ -0,0 +1,228 @@ +#!/usr/bin/env bash +set -euo pipefail + +: "${SPEC2006_CASE:?SPEC2006_CASE is required}" +: "${SPEC2006:?SPEC2006 is required}" +: "${SPEC2006_CASE_CONFIG:?SPEC2006_CASE_CONFIG is required}" +: "${SPEC2006_CFG:?SPEC2006_CFG is required}" +: "${CROSS_COMPILE:=riscv64-unknown-linux-gnu-}" +: "${SPEC2006_TUNE:=base}" +: "${SPEC2006_JOBS:=$(nproc)}" +: "${SPEC2006_JEMALLOC_REPO:=https://github.com/jemalloc/jemalloc.git}" +: "${SPEC2006_JEMALLOC_COMMIT:=da66aa391f853ccf2300845b3873cc8f1cf48f2d}" +: "${SPEC2006_DOWNLOAD_RETRIES:=3}" +: "${SPEC2006_ELF_ONLY:=false}" +: "${SPEC2006_LOG_DIR:=$WORKLOAD_BUILD_DIR/logs}" +: "${PKG_DIR:=$WORKLOAD_BUILD_DIR/package}" + +SPEC2006_JEMALLOC_ROOT="${SPEC2006_JEMALLOC_ROOT:-${JEMALLOC_INSTALL_PATH:-}}" + +jemalloc_lock_dir="" +cleanup() { + if [ -n "$jemalloc_lock_dir" ]; then + rmdir "$jemalloc_lock_dir" 2>/dev/null || true + fi +} +trap cleanup EXIT + +mkdir -p "$SPEC2006_LOG_DIR" + +spec2006_progress_prefix() { + local k="${SPEC2006_PROGRESS_K:-1}" + local n="${SPEC2006_PROGRESS_N:-1}" + printf '[spec2006 %s/%s]' "$k" "$n" +} + +status() { + printf '%s %s\n' "$(spec2006_progress_prefix)" "$*" +} + +show_log_tail() { + local log_file="$1" + if [ -f "$log_file" ]; then + echo "$(spec2006_progress_prefix) Last 40 lines from $log_file:" >&2 + tail -n 40 "$log_file" >&2 || true + fi +} + +retry() { + local attempt=1 + while true; do + if "$@"; then + return 0 + fi + if [ "$attempt" -ge "$SPEC2006_DOWNLOAD_RETRIES" ]; then + return 1 + fi + printf '%s Retrying failed command (%s/%s): %s\n' \ + "$(spec2006_progress_prefix)" \ + "$attempt" \ + "$SPEC2006_DOWNLOAD_RETRIES" \ + "$*" >&2 + sleep $((attempt * 2)) + attempt=$((attempt + 1)) + done +} + +retry_git_clone() { + local repo="$1" + local dest="$2" + local attempt=1 + while true; do + rm -rf "$dest" + if git clone "$repo" "$dest"; then + return 0 + fi + if [ "$attempt" -ge "$SPEC2006_DOWNLOAD_RETRIES" ]; then + return 1 + fi + printf '%s Retrying failed git clone (%s/%s): %s\n' \ + "$(spec2006_progress_prefix)" \ + "$attempt" \ + "$SPEC2006_DOWNLOAD_RETRIES" \ + "$repo" >&2 + sleep $((attempt * 2)) + attempt=$((attempt + 1)) + done +} + +prepare_git_checkout() { + local repo="$1" + local commit="$2" + local dest="$3" + local current_commit target_commit + + if [ ! -d "$dest/.git" ]; then + retry_git_clone "$repo" "$dest" + else + git -C "$dest" remote set-url origin "$repo" + fi + + if ! git -C "$dest" cat-file -e "$commit^{commit}" 2>/dev/null; then + retry git -C "$dest" fetch --tags origin + fi + + current_commit="$(git -C "$dest" rev-parse HEAD 2>/dev/null || true)" + target_commit="$(git -C "$dest" rev-parse "$commit")" + if [ "$current_commit" != "$target_commit" ]; then + git -C "$dest" checkout --detach "$commit" + fi +} + +is_true() { + case "$1" in + 1|true|yes|on) return 0 ;; + *) return 1 ;; + esac +} + +cfg_requires_jemalloc() { + grep -Eq 'JEMALLOC_PATH|-ljemalloc' "$SPEC2006_CFG" +} + +resolve_jemalloc_root() { + if [ -n "$SPEC2006_JEMALLOC_ROOT" ]; then + realpath -m "$SPEC2006_JEMALLOC_ROOT" + else + realpath -m "$(dirname "$WORKLOAD_BUILD_DIR")/jemalloc/install" + fi +} + +resolve_jemalloc_host() { + if [ -n "${SPEC2006_JEMALLOC_CONFIGURE_HOST:-}" ]; then + printf '%s\n' "$SPEC2006_JEMALLOC_CONFIGURE_HOST" + else + "${CROSS_COMPILE}gcc" -dumpmachine + fi +} + +prepare_jemalloc() { + local base_dir source_dir prefix host log_file + base_dir="$(realpath -m "$(dirname "$WORKLOAD_BUILD_DIR")/jemalloc")" + source_dir="$base_dir/source" + prefix="$(resolve_jemalloc_root)" + host="$(resolve_jemalloc_host)" + log_file="$base_dir/build.log" + + if [ -f "$prefix/lib/libjemalloc.a" ]; then + SPEC2006_JEMALLOC_ROOT="$prefix" + export SPEC2006_JEMALLOC_ROOT + status "Using cached jemalloc: $prefix" + return + fi + + jemalloc_lock_dir="$base_dir/.lock" + mkdir -p "$base_dir" + while ! mkdir "$jemalloc_lock_dir" 2>/dev/null; do + sleep 1 + done + + if [ -f "$prefix/lib/libjemalloc.a" ]; then + rmdir "$jemalloc_lock_dir" + jemalloc_lock_dir="" + SPEC2006_JEMALLOC_ROOT="$prefix" + export SPEC2006_JEMALLOC_ROOT + status "Using cached jemalloc: $prefix" + return + fi + + status "Preparing jemalloc (log: $log_file)" + : > "$log_file" + + if ! { + echo "# jemalloc repo: $SPEC2006_JEMALLOC_REPO" + echo "# jemalloc commit: $SPEC2006_JEMALLOC_COMMIT" + echo "# install prefix: $prefix" + echo "# configure host: $host" + prepare_git_checkout "$SPEC2006_JEMALLOC_REPO" "$SPEC2006_JEMALLOC_COMMIT" "$source_dir" + + ( + cd "$source_dir" + CC="${CROSS_COMPILE}gcc" \ + CXX="${CROSS_COMPILE}g++" \ + AR="${CROSS_COMPILE}ar" \ + LD="${CROSS_COMPILE}ld" \ + RANLIB="${CROSS_COMPILE}ranlib" \ + STRIP="${CROSS_COMPILE}strip" \ + ./autogen.sh --prefix="$prefix" --host="$host" + make -j"$SPEC2006_JOBS" + make install + ) + } >>"$log_file" 2>&1; then + echo "$(spec2006_progress_prefix) jemalloc build failed; see $log_file" >&2 + show_log_tail "$log_file" + return 1 + fi + + rmdir "$jemalloc_lock_dir" + jemalloc_lock_dir="" + + SPEC2006_JEMALLOC_ROOT="$prefix" + export SPEC2006_JEMALLOC_ROOT + status "jemalloc ready: $prefix" +} + +if cfg_requires_jemalloc; then + prepare_jemalloc +fi + +python_args=() +if is_true "$SPEC2006_ELF_ONLY"; then + python_args+=(--elf-only) +fi + +python3 "$WORKLOAD_DIR/spec2006-package.py" \ + --case "$SPEC2006_CASE" \ + --cases-config "$SPEC2006_CASE_CONFIG" \ + --spec "$SPEC2006" \ + --spec-config "$SPEC2006_CFG" \ + --pkg-dir "$PKG_DIR" \ + --out-dir "$WORKLOAD_BUILD_DIR" \ + --cross-compile "$CROSS_COMPILE" \ + --compiler-root "${SPEC2006_COMPILER_ROOT:-}" \ + --gnu-toolchain-root "${SPEC2006_GNU_TOOLCHAIN_ROOT:-}" \ + --jemalloc-root "${SPEC2006_JEMALLOC_ROOT:-}" \ + --log-dir "$SPEC2006_LOG_DIR" \ + --tune "$SPEC2006_TUNE" \ + --jobs "$SPEC2006_JOBS" \ + "${python_args[@]}" diff --git a/workloads/linux/spec2006/riscv_gcc15_base.cfg b/workloads/linux/spec2006/riscv_gcc15_base.cfg new file mode 100644 index 0000000..e44394d --- /dev/null +++ b/workloads/linux/spec2006/riscv_gcc15_base.cfg @@ -0,0 +1,195 @@ +#################################################################### +# RISC-V Config file for SPEC CPU2006 + +# Please see http://www.spec.org/cpu2006/Docs/config.html (also available in +# the Docs directory of your SPEC tree) for details on config file setup. The +# config.html page has a list of all of the fields required for a full +# publication ofresults. + +##################################################################### +# System Under Test (SUT) Section + +# If it affects performance, you need to describe it, either in the +# pre-defined fields or by adding it to the notes section. Replace the +# setting below with the ones that match your machine. + +####################################################################### + +# Tester Description +test_sponsor = OpenXiangShan +tester = OpenXiangShan + +# System Description +hw_model = XiangShan Kunminghu +hw_memory = 2 GiB DDR +hw_disk = None +hw_vendor = Institute of Computing Technology, Chinese Academy of Sciences +hw_other = N/A +hw_avail = Dec-9999 + +# CPU description +# See http://www.spec.org/cpu2006/Docs/runrules.html#cpucount +# for a discussion of these fields + +hw_cpu_name = XiangShan Kunminghu +hw_cpu_char = +hw_cpu_mhz = 3000 +hw_fpu = Integrated +hw_nchips = 1 +hw_ncores = 1 +hw_ncoresperchip = 1 +hw_nthreadspercore = 1 +hw_ncpuorder = N/A + +# Cache description + +hw_pcache = N/A +hw_scache = N/A +hw_tcache = N/A +hw_ocache = N/A + +# Tester description + +license_num = 0 + +# Operating system, file system + +sw_os = Linux with OpenSBI firmware boot +sw_file = initramfs rootfs +sw_state = Single-user +sw_other = None + +## SW config +sw_compiler = gcc, g++ 15.2.0 +sw_avail = Apr-2026 +sw_base_ptrsize = 64-bit +sw_peak_ptrsize = 64-bit + +####################################################################### +# End of SUT section +# If this config file were to be applied to several SUTs, edits would +# be needed only ABOVE this point. +###################################################################### + +ignore_errors = yes +tune = base +basepeak = no +ext = riscv_gcc15_base +teeout = yes +teerunout = yes +output_format = asc, csv, html +makeflags = -j64 + +reportable = yes + +default=default=default=default: +##################################################################### +# +# Compiler selection +# +##################################################################### + +COMPILER_PATH = ${LLVM_INSTALL_PATH} +JEMALLOC_PATH = ${JEMALLOC_INSTALL_PATH} +GCC_TOOLCHAIN_PATH = ${GNU_RISCV64_PATH} + +JEMALLOC_LIBS = -L$(JEMALLOC_PATH)/lib -ljemalloc -lm +# jemalloc also exports C++ operator new/delete. Some SPEC C++ benchmarks +# define replaceable allocation symbols in their own objects, so keep +# muldefs enabled for the final static link. +STATIC_LDFLAGS = -z muldefs -static + +CC = $(COMPILER_PATH)/bin/riscv64-unknown-linux-gnu-gcc -std=gnu89 +CXX = $(COMPILER_PATH)/bin/riscv64-unknown-linux-gnu-g++ +FC = $(COMPILER_PATH)/bin/riscv64-unknown-linux-gnu-gfortran + +##################################################################### +# Optimization +##################################################################### + +int=base=default: + COPTIMIZE = -static -O3 -march=rv64gc_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=off -fno-tree-vectorize -fno-tree-loop-vectorize -fno-strict-aliasing + CXXOPTIMIZE = -static -O3 -march=rv64gc_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=off -std=c++98 -fno-tree-vectorize -fno-tree-loop-vectorize -fno-strict-aliasing + + EXTRA_LIBS = $(JEMALLOC_LIBS) + EXTRA_LDFLAGS = $(STATIC_LDFLAGS) + +fp=base=default: + COPTIMIZE = -static -O3 -march=rv64gc_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=fast -fno-tree-vectorize -fno-tree-loop-vectorize -fno-strict-aliasing + CXXOPTIMIZE = -static -O3 -march=rv64gc_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=fast -std=c++98 -fno-tree-vectorize -fno-tree-loop-vectorize -fno-strict-aliasing + FOPTIMIZE = -static -O3 -march=rv64gc_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=fast -fno-tree-vectorize -fno-tree-loop-vectorize -fno-strict-aliasing + + EXTRA_LIBS = $(JEMALLOC_LIBS) + EXTRA_LDFLAGS = $(STATIC_LDFLAGS) + +int=peak=default: + COPTIMIZE = -static -O3 -march=rv64gcv_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=off -ftree-vectorize -ftree-loop-vectorize -fno-strict-aliasing + CXXOPTIMIZE = -static -O3 -march=rv64gcv_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=off -std=c++98 -ftree-vectorize -ftree-loop-vectorize -fno-strict-aliasing + + EXTRA_LIBS = $(JEMALLOC_LIBS) + EXTRA_LDFLAGS = $(STATIC_LDFLAGS) + +fp=peak=default: + COPTIMIZE = -static -O3 -march=rv64gcv_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=fast -ftree-vectorize -ftree-loop-vectorize -fno-strict-aliasing + CXXOPTIMIZE = -static -O3 -march=rv64gcv_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=fast -std=c++98 -ftree-vectorize -ftree-loop-vectorize -fno-strict-aliasing + FOPTIMIZE = -static -O3 -march=rv64gcv_zba_zbb_zbs_zbc -ffast-math -flto -ffp-contract=fast -ftree-vectorize -ftree-loop-vectorize -fno-strict-aliasing + + EXTRA_LIBS = $(JEMALLOC_LIBS) + EXTRA_LDFLAGS = $(STATIC_LDFLAGS) + + +##################################################################### +# 32/64 bit Portability Flags - all +##################################################################### + +default=default=default=default: +PORTABILITY = -DSPEC_CPU_LP64 + +##################################################################### +# Portability Flags +##################################################################### + +400.perlbench=default=default=default: +CPORTABILITY = -DSPEC_CPU_LINUX_X64 -std=gnu89 + +401.bzip2=default=default=default: +CPORTABILITY = -std=gnu89 + +416.gamess=default=default=default: +CPORTABILITY = -funconstrained-commons +FPORTABILITY = -std=legacy -funconstrained-commons -fno-strict-aliasing + +436.cactusADM=default=default=default: +CPORTABILITY = -std=gnu17 + +462.libquantum=default=default=default: +CPORTABILITY = -DSPEC_CPU_LINUX + +464.h264ref=default=default=default: +CPORTABILITY = -fsigned-char + +482.sphinx3=default=default=default: +CPORTABILITY = -fsigned-char + +483.xalancbmk=default=default=default: +CXXPORTABILITY = -DSPEC_CPU_LINUX -include cstring -Wno-c++11-narrowing -Wno-template-body + +453.povray=base=default=default: +CXXOPTIMIZE = -static -O3 -march=rv64gc_zba_zbb_zbs_zbc -flto -ffp-contract=fast -std=c++98 -fno-tree-vectorize -fno-tree-loop-vectorize -fno-strict-aliasing + +453.povray=peak=default=default: +CXXOPTIMIZE = -static -O3 -march=rv64gcv_zba_zbb_zbs_zbc -flto -ffp-contract=fast -std=c++98 -ftree-vectorize -ftree-loop-vectorize -fno-strict-aliasing + +481.wrf=default=default=default: +CPORTABILITY = -DSPEC_CPU_CASE_FLAG -DSPEC_CPU_LINUX +FPORTABILITY = -std=legacy -fallow-argument-mismatch + +447.dealII=default=default=default: +CXXPORTABILITY = -fpermissive -include cstring -std=c++11 + +450.soplex=default=default=default: +CXXPORTABILITY = -std=gnu++98 + +##################################################################### +# Notes +##################################################################### diff --git a/workloads/linux/spec2006/rules.mk b/workloads/linux/spec2006/rules.mk new file mode 100644 index 0000000..d889bff --- /dev/null +++ b/workloads/linux/spec2006/rules.mk @@ -0,0 +1,180 @@ +SPEC2006_WORKLOAD_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +SPEC2006_REPO_ROOT := $(abspath $(SPEC2006_WORKLOAD_DIR)/../../..) +SPEC2006_SELF_MAKEFILE := $(SPEC2006_WORKLOAD_DIR)/rules.mk +SPEC2006_ROOT_MAKEFILE := $(SPEC2006_REPO_ROOT)/Makefile +SPEC2006_RECURSE_MAKEFILE := $(if $(filter $(SPEC2006_ROOT_MAKEFILE),$(abspath $(firstword $(MAKEFILE_LIST)))),$(SPEC2006_ROOT_MAKEFILE),$(SPEC2006_SELF_MAKEFILE)) +SPEC2006_SCRIPTS_DIR := $(SPEC2006_REPO_ROOT)/scripts +SPEC2006_DTS_DIR := $(SPEC2006_REPO_ROOT)/dts +SPEC2006_BUILD_DIR ?= $(SPEC2006_REPO_ROOT)/build/linux-workloads/spec2006 +SPEC2006_CASE_CONFIG := $(SPEC2006_WORKLOAD_DIR)/spec06.json +SPEC2006_CFG ?= $(SPEC2006_WORKLOAD_DIR)/riscv_gcc15_base.cfg +SPEC2006_HELPER := $(SPEC2006_WORKLOAD_DIR)/spec2006-package.py +SPEC2006_IMAGE_DIR ?= $(SPEC2006_REPO_ROOT)/build/images/spec2006 +SPEC2006_SPEC_ROOT := $(if $(SPEC2006),$(SPEC2006),$(SPEC)) +SPEC2006_CROSS_COMPILE ?= riscv64-unknown-linux-gnu- +SPEC2006_COMPILER_ROOT ?= +SPEC2006_GNU_TOOLCHAIN_ROOT ?= +SPEC2006_JEMALLOC_ROOT ?= +SPEC2006_DEFAULT_DTB ?= xiangshan-fpga-noAIA +SPEC2006_TUNE ?= base +SPEC2006_JOBS ?= $(shell nproc) +SPEC2006_INPUT ?= ref +SPEC2006_PROGRESS_K ?= 1 +SPEC2006_PROGRESS_N ?= 1 +SPEC2006_PROGRESS_PREFIX := [spec2006 $(SPEC2006_PROGRESS_K)/$(SPEC2006_PROGRESS_N)] +SPEC2006_BUILDROOT_DIR ?= $(if $(BUILDROOT_DIR),$(BUILDROOT_DIR),$(SPEC2006_REPO_ROOT)/build/buildroot) +SPEC2006_LINUX_IMAGE ?= $(if $(LINUX_IMAGE),$(LINUX_IMAGE),$(SPEC2006_BUILDROOT_DIR)/output/images/Image) +SPEC2006_GCPT_ELF ?= $(if $(GCPT_ELF),$(GCPT_ELF),$(SPEC2006_REPO_ROOT)/build/LibCheckpointAlpha/build/gcpt) +SPEC2006_GCPT_BIN ?= $(if $(GCPT_BIN),$(GCPT_BIN),$(SPEC2006_REPO_ROOT)/build/LibCheckpointAlpha/build/gcpt.bin) +SPEC2006_SBI_BUILD_DIR ?= $(if $(SBI_BUILD_DIR),$(SBI_BUILD_DIR),$(SPEC2006_REPO_ROOT)/build/opensbi) +SPEC2006_SBI_BIN ?= $(if $(SBI_BIN),$(SBI_BIN),$(SPEC2006_SBI_BUILD_DIR)/build/platform/generic/firmware/fw_jump.bin) +SPEC2006_BUILDROOT_CROSS_COMPILE ?= $(SPEC2006_BUILDROOT_DIR)/output/host/bin/riscv64-linux- +SPEC2006_DTC ?= $(SPEC2006_BUILDROOT_DIR)/output/host/bin/dtc +SPEC2006_CASE := $(if $(INPUT),$(BENCH)_$(INPUT),$(BENCH)) +SPEC2006_ALL_CASES := $(shell python3 $(SPEC2006_HELPER) --cases-config $(SPEC2006_CASE_CONFIG) --list-cases 2>/dev/null) +SPEC2006_SELECTED_CASES := $(shell python3 $(SPEC2006_HELPER) --cases-config $(SPEC2006_CASE_CONFIG) --list-cases --input-set $(SPEC2006_INPUT) 2>/dev/null) +SPEC2006_IMAGE_CASES := $(SPEC2006_SELECTED_CASES) +SPEC2006_ELF_TARGETS := $(foreach case,$(SPEC2006_SELECTED_CASES),$(SPEC2006_BUILD_DIR)/$(case)/elf/$(case).elf) +SPEC2006_DTS_SOURCES := $(shell find $(SPEC2006_DTS_DIR) -type f 2>/dev/null) + +WORKLOAD_DIRS += $(SPEC2006_BUILD_DIR) + +spec2006-check-spec-dir: + @if [ -z "$(SPEC2006_SPEC_ROOT)" ]; then \ + echo "SPEC or SPEC2006 is required, for example:"; \ + echo " make linux/spec2006 BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN"; \ + echo " make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006=/path/to/cpu2006 -jN"; \ + exit 1; \ + fi; \ + if ! [ -d "$(SPEC2006_SPEC_ROOT)" ]; then \ + echo "SPEC path does not exist or is not a directory: $(SPEC2006_SPEC_ROOT)"; \ + exit 1; \ + fi; \ + if ! [ -x "$(SPEC2006_SPEC_ROOT)/bin/runspec" ]; then \ + echo "runspec not found under $(SPEC2006_SPEC_ROOT)/bin/runspec"; \ + exit 1; \ + fi; \ + if ! [ -f "$(SPEC2006_CFG)" ]; then \ + echo "SPEC2006 cfg does not exist: $(SPEC2006_CFG)"; \ + exit 1; \ + fi; \ + if ! [ -f "$(SPEC2006_CASE_CONFIG)" ]; then \ + echo "SPEC2006 case config does not exist: $(SPEC2006_CASE_CONFIG)"; \ + exit 1; \ + fi; \ + case "$(SPEC2006_INPUT)" in \ + ref|train|test|all) ;; \ + *) echo "SPEC2006_INPUT must be one of: ref, train, test, all"; exit 1 ;; \ + esac + +define add_spec2006_case +$(SPEC2006_BUILD_DIR)/$(1)/download/sentinel: + @mkdir -p $$(@D) + @touch $$@ + +$(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: spec2006-check-spec-dir $$(SPEC2006_HELPER) $$(SPEC2006_WORKLOAD_DIR)/build.sh $$(SPEC2006_CASE_CONFIG) $$(SPEC2006_CFG) + @mkdir -p "$$(dir $$@)" + @WORKLOAD_DIR="$$(abspath $$(SPEC2006_WORKLOAD_DIR))" \ + WORKLOAD_BUILD_DIR="$$(abspath $(SPEC2006_BUILD_DIR)/$(1))" \ + PKG_DIR="$$(abspath $(SPEC2006_BUILD_DIR)/$(1)/package)" \ + CROSS_COMPILE="$$(SPEC2006_CROSS_COMPILE)" \ + SPEC2006_PROGRESS_K="$$(SPEC2006_PROGRESS_K)" \ + SPEC2006_PROGRESS_N="$$(SPEC2006_PROGRESS_N)" \ + SPEC2006_CASE="$(1)" \ + SPEC2006="$$(SPEC2006_SPEC_ROOT)" \ + SPEC2006_CASE_CONFIG="$$(abspath $$(SPEC2006_CASE_CONFIG))" \ + SPEC2006_CFG="$$(abspath $$(SPEC2006_CFG))" \ + SPEC2006_COMPILER_ROOT="$$(SPEC2006_COMPILER_ROOT)" \ + SPEC2006_GNU_TOOLCHAIN_ROOT="$$(SPEC2006_GNU_TOOLCHAIN_ROOT)" \ + SPEC2006_JEMALLOC_ROOT="$$(SPEC2006_JEMALLOC_ROOT)" \ + SPEC2006_TUNE="$$(SPEC2006_TUNE)" \ + SPEC2006_JOBS="$$(SPEC2006_JOBS)" \ + SPEC2006_ELF_ONLY=1 \ + bash "$$(abspath $$(SPEC2006_WORKLOAD_DIR))/build.sh" + +$(SPEC2006_BUILD_DIR)/$(1)/rootfs.cpio: spec2006-check-spec-dir $$(SPEC2006_HELPER) $$(SPEC2006_WORKLOAD_DIR)/build.sh $$(SPEC2006_CASE_CONFIG) $$(SPEC2006_CFG) $(SPEC2006_BUILD_DIR)/$(1)/download/sentinel $$(SPEC2006_SCRIPTS_DIR)/build-workload-linux.sh + @CROSS_COMPILE="$$(SPEC2006_CROSS_COMPILE)" \ + SPEC2006_PROGRESS_K="$$(SPEC2006_PROGRESS_K)" \ + SPEC2006_PROGRESS_N="$$(SPEC2006_PROGRESS_N)" \ + SPEC2006_CASE="$(1)" \ + SPEC2006="$$(SPEC2006_SPEC_ROOT)" \ + SPEC2006_CASE_CONFIG="$$(abspath $$(SPEC2006_CASE_CONFIG))" \ + SPEC2006_CFG="$$(abspath $$(SPEC2006_CFG))" \ + SPEC2006_COMPILER_ROOT="$$(SPEC2006_COMPILER_ROOT)" \ + SPEC2006_GNU_TOOLCHAIN_ROOT="$$(SPEC2006_GNU_TOOLCHAIN_ROOT)" \ + SPEC2006_JEMALLOC_ROOT="$$(SPEC2006_JEMALLOC_ROOT)" \ + SPEC2006_TUNE="$$(SPEC2006_TUNE)" \ + SPEC2006_JOBS="$$(SPEC2006_JOBS)" \ + bash "$$(SPEC2006_SCRIPTS_DIR)/build-workload-linux.sh" "$$(SPEC2006_WORKLOAD_DIR)" "$(SPEC2006_BUILD_DIR)/$(1)" + +$(SPEC2006_BUILD_DIR)/$(1)/fw_payload.bin: $$(SPEC2006_DTS_SOURCES) $$(SPEC2006_GCPT_BIN) $$(SPEC2006_SCRIPTS_DIR)/build-firmware-linux.sh $(SPEC2006_BUILD_DIR)/$(1)/rootfs.cpio $$(SPEC2006_LINUX_IMAGE) $$(SPEC2006_SBI_BIN) + @printf '$(SPEC2006_PROGRESS_PREFIX) Assembling firmware for $(1)\n' + @CROSS_COMPILE="$$(SPEC2006_BUILDROOT_CROSS_COMPILE)" \ + DTC="$$(SPEC2006_DTC)" \ + DEFAULT_DTB="$$(SPEC2006_DEFAULT_DTB)" \ + SPEC2006_PROGRESS_K="$$(SPEC2006_PROGRESS_K)" \ + SPEC2006_PROGRESS_N="$$(SPEC2006_PROGRESS_N)" \ + bash "$$(SPEC2006_SCRIPTS_DIR)/build-firmware-linux.sh" "$$(SPEC2006_GCPT_BIN)" "$$(SPEC2006_SBI_BUILD_DIR)" "$$(SPEC2006_DTS_DIR)" "$$(SPEC2006_LINUX_IMAGE)" "$(SPEC2006_BUILD_DIR)/$(1)" + +linux/$(1): $(SPEC2006_BUILD_DIR)/$(1)/fw_payload.bin + +WORKLOAD_PHONY_TARGETS += linux/$(1) + +$(SPEC2006_IMAGE_DIR)/bin/$(1).fw_payload.bin: $(SPEC2006_BUILD_DIR)/$(1)/fw_payload.bin $(SPEC2006_LINUX_IMAGE) + @printf '$(SPEC2006_PROGRESS_PREFIX) Exporting $(1) artifacts to $(SPEC2006_IMAGE_DIR)\n' + @mkdir -p "$(SPEC2006_IMAGE_DIR)/bin" "$(SPEC2006_IMAGE_DIR)/kernel" "$(SPEC2006_IMAGE_DIR)/elf" "$(SPEC2006_IMAGE_DIR)/cfg" "$(SPEC2006_IMAGE_DIR)/gcpt" + @if [ ! -f "$(SPEC2006_IMAGE_DIR)/cfg/$(notdir $(SPEC2006_CFG))" ]; then \ + printf '$(SPEC2006_PROGRESS_PREFIX) Exporting spec2006 cfg to $(SPEC2006_IMAGE_DIR)/cfg\n'; \ + cp "$(SPEC2006_CFG)" "$(SPEC2006_IMAGE_DIR)/cfg/$(notdir $(SPEC2006_CFG))"; \ + fi + @if [ ! -f "$(SPEC2006_IMAGE_DIR)/gcpt/gcpt.elf" ] || [ ! -f "$(SPEC2006_IMAGE_DIR)/gcpt/gcpt.bin" ]; then \ + printf '$(SPEC2006_PROGRESS_PREFIX) Exporting gcpt artifacts to $(SPEC2006_IMAGE_DIR)/gcpt\n'; \ + cp "$(SPEC2006_GCPT_ELF)" "$(SPEC2006_IMAGE_DIR)/gcpt/gcpt.elf"; \ + cp "$(SPEC2006_GCPT_BIN)" "$(SPEC2006_IMAGE_DIR)/gcpt/gcpt.bin"; \ + fi + @cp $(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf $(SPEC2006_IMAGE_DIR)/elf/$(1).elf + @cp $(SPEC2006_LINUX_IMAGE) $(SPEC2006_IMAGE_DIR)/kernel/$(1).Image + @cp $(SPEC2006_BUILD_DIR)/$(1)/fw_payload.bin $(SPEC2006_IMAGE_DIR)/bin/$(1).fw_payload.bin +endef + +$(foreach case,$(SPEC2006_ALL_CASES),$(eval $(call add_spec2006_case,$(case)))) + +linux/spec2006: spec2006-check-spec-dir + @if [ -z "$(BENCH)" ]; then \ + echo "Usage: make linux/spec2006 BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN"; \ + echo " or: make linux/spec2006 BENCH=astar_biglakes SPEC=/path/to/cpu2006 -jN"; \ + exit 1; \ + fi + @$(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" $(SPEC2006_BUILD_DIR)/$(SPEC2006_CASE)/fw_payload.bin + +spec2006-elf: spec2006-check-spec-dir + @if [ -z "$(BENCH)" ]; then \ + echo "Usage: make spec2006-elf BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN"; \ + echo " or: make spec2006-elf BENCH=astar_biglakes SPEC=/path/to/cpu2006 -jN"; \ + exit 1; \ + fi + @$(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" $(SPEC2006_BUILD_DIR)/$(SPEC2006_CASE)/elf/$(SPEC2006_CASE).elf + +spec2006-elfs: spec2006-check-spec-dir + @if [ -z "$(SPEC2006_SELECTED_CASES)" ]; then \ + echo "No SPEC2006 cases selected by SPEC2006_INPUT=$(SPEC2006_INPUT)"; \ + exit 1; \ + fi; \ + for case in $(SPEC2006_SELECTED_CASES); do \ + $(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" "$(SPEC2006_BUILD_DIR)/$$case/elf/$$case.elf" || exit $$?; \ + done + +spec2006-images: spec2006-check-spec-dir + @if [ -z "$(SPEC2006_IMAGE_CASES)" ]; then \ + echo "No SPEC2006 cases selected by SPEC2006_INPUT=$(SPEC2006_INPUT)"; \ + exit 1; \ + fi; \ + total="$(words $(SPEC2006_IMAGE_CASES))"; \ + i=0; \ + for case in $(SPEC2006_IMAGE_CASES); do \ + i=$$((i + 1)); \ + SPEC2006_PROGRESS_K="$$i" SPEC2006_PROGRESS_N="$$total" $(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" "$(SPEC2006_IMAGE_DIR)/bin/$$case.fw_payload.bin" || exit $$?; \ + done + @printf '[spec2006 %s/%s] Output written to %s\n' "$(words $(SPEC2006_IMAGE_CASES))" "$(words $(SPEC2006_IMAGE_CASES))" "$(abspath $(SPEC2006_IMAGE_DIR))" + +.PHONY: linux/spec2006 spec2006-check-spec-dir spec2006-elf spec2006-elfs spec2006-images diff --git a/workloads/linux/spec2006/spec06.json b/workloads/linux/spec2006/spec06.json new file mode 100644 index 0000000..1faa7c0 --- /dev/null +++ b/workloads/linux/spec2006/spec06.json @@ -0,0 +1,2241 @@ +{ + "astar_biglakes": { + "base_name": "astar", + "files": [ + "astar/BigLakes2048.bin", + "astar/BigLakes2048.cfg" + ], + "args": [ + "BigLakes2048.cfg" + ], + "type": [ + "int", + "ref" + ] + }, + "astar_rivers": { + "base_name": "astar", + "files": [ + "astar/rivers.bin", + "astar/rivers.cfg" + ], + "args": [ + "rivers.cfg" + ], + "type": [ + "int", + "ref" + ] + }, + "bwaves": { + "base_name": "bwaves", + "files": [ + "bwaves/bwaves.in" + ], + "args": [], + "type": [ + "fp", + "ref" + ] + }, + "bzip2_chicken": { + "base_name": "bzip2", + "files": [ + "bzip2/chicken.jpg" + ], + "args": [ + "chicken.jpg", + "30" + ], + "type": [ + "int", + "ref" + ] + }, + "bzip2_combined": { + "base_name": "bzip2", + "files": [ + "bzip2/input.combined" + ], + "args": [ + "input.combined", + "200" + ], + "type": [ + "int", + "ref" + ] + }, + "bzip2_html": { + "base_name": "bzip2", + "files": [ + "bzip2/text.html" + ], + "args": [ + "text.html", + "280" + ], + "type": [ + "int", + "ref" + ] + }, + "bzip2_liberty": { + "base_name": "bzip2", + "files": [ + "bzip2/liberty.jpg" + ], + "args": [ + "liberty.jpg", + "30" + ], + "type": [ + "int", + "ref" + ] + }, + "bzip2_program": { + "base_name": "bzip2", + "files": [ + "bzip2/input.program" + ], + "args": [ + "input.program", + "280" + ], + "type": [ + "int", + "ref" + ] + }, + "bzip2_source": { + "base_name": "bzip2", + "files": [ + "bzip2/input.source" + ], + "args": [ + "input.source", + "280" + ], + "type": [ + "int", + "ref" + ] + }, + "cactusADM": { + "base_name": "cactusADM", + "files": [ + "cactusADM/benchADM.par" + ], + "args": [ + "benchADM.par" + ], + "type": [ + "fp", + "ref" + ] + }, + "calculix": { + "base_name": "calculix", + "files": [ + "calculix/hyperviscoplastic.inp" + ], + "args": [ + "-i", + "hyperviscoplastic" + ], + "type": [ + "fp", + "ref" + ] + }, + "dealII": { + "base_name": "dealII", + "files": [ + "dealII/DummyData" + ], + "args": [ + "23" + ], + "type": [ + "fp", + "ref" + ] + }, + "gamess_cytosine": { + "base_name": "gamess", + "files": [ + "gamess/cytosine.2.config", + "gamess/cytosine.2.inp" + ], + "args": [ + "<", + "cytosine.2.config" + ], + "type": [ + "fp", + "ref" + ] + }, + "gamess_gradient": { + "base_name": "gamess", + "files": [ + "gamess/h2ocu2+.gradient.config", + "gamess/h2ocu2+.gradient.inp" + ], + "args": [ + "<", + "h2ocu2+.gradient.config" + ], + "type": [ + "fp", + "ref" + ] + }, + "gamess_triazolium": { + "base_name": "gamess", + "files": [ + "gamess/triazolium.config", + "gamess/triazolium.inp" + ], + "args": [ + "<", + "triazolium.config" + ], + "type": [ + "fp", + "ref" + ] + }, + "gcc_166": { + "base_name": "gcc", + "files": [ + "gcc/166.in" + ], + "args": [ + "166.in", + "-o", + "166.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_200": { + "base_name": "gcc", + "files": [ + "gcc/200.in" + ], + "args": [ + "200.in", + "-o", + "200.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_cpdecl": { + "base_name": "gcc", + "files": [ + "gcc/cp-decl.in" + ], + "args": [ + "cp-decl.in", + "-o", + "cp-decl.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_expr2": { + "base_name": "gcc", + "files": [ + "gcc/expr2.in" + ], + "args": [ + "expr2.in", + "-o", + "expr2.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_expr": { + "base_name": "gcc", + "files": [ + "gcc/expr.in" + ], + "args": [ + "expr.in", + "-o", + "expr.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_g23": { + "base_name": "gcc", + "files": [ + "gcc/g23.in" + ], + "args": [ + "g23.in", + "-o", + "g23.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_s04": { + "base_name": "gcc", + "files": [ + "gcc/s04.in" + ], + "args": [ + "s04.in", + "-o", + "s04.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_scilab": { + "base_name": "gcc", + "files": [ + "gcc/scilab.in" + ], + "args": [ + "scilab.in", + "-o", + "scilab.s" + ], + "type": [ + "int", + "ref" + ] + }, + "gcc_typeck": { + "base_name": "gcc", + "files": [ + "gcc/c-typeck.in" + ], + "args": [ + "c-typeck.in", + "-o", + "c-typeck.s" + ], + "type": [ + "int", + "ref" + ] + }, + "GemsFDTD": { + "base_name": "GemsFDTD", + "files": [ + "GemsFDTD/ref.in", + "GemsFDTD/sphere.pec", + "GemsFDTD/yee.dat" + ], + "args": [], + "type": [ + "fp", + "ref" + ] + }, + "gobmk_13x13": { + "base_name": "gobmk", + "files": [ + "gobmk/13x13.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "13x13.tst" + ], + "type": [ + "int", + "ref" + ] + }, + "gobmk_nngs": { + "base_name": "gobmk", + "files": [ + "gobmk/nngs.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "nngs.tst" + ], + "type": [ + "int", + "ref" + ] + }, + "gobmk_score2": { + "base_name": "gobmk", + "files": [ + "gobmk/score2.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "score2.tst" + ], + "type": [ + "int", + "ref" + ] + }, + "gobmk_trevorc": { + "base_name": "gobmk", + "files": [ + "gobmk/trevorc.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "trevorc.tst" + ], + "type": [ + "int", + "ref" + ] + }, + "gobmk_trevord": { + "base_name": "gobmk", + "files": [ + "gobmk/trevord.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "trevord.tst" + ], + "type": [ + "int", + "ref" + ] + }, + "gromacs": { + "base_name": "gromacs", + "files": [ + "gromacs/gromacs.tpr" + ], + "args": [ + "-silent", + "-deffnm", + "gromacs.tpr", + "-nice", + "0" + ], + "type": [ + "fp", + "ref" + ] + }, + "h264ref_foreman.baseline": { + "base_name": "h264ref", + "files": [ + "h264ref/foreman_ref_encoder_baseline.cfg", + "h264ref/foreman_qcif.yuv" + ], + "args": [ + "-d", + "foreman_ref_encoder_baseline.cfg" + ], + "type": [ + "int", + "ref" + ] + }, + "h264ref_foreman.main": { + "base_name": "h264ref", + "files": [ + "h264ref/foreman_ref_encoder_main.cfg", + "h264ref/foreman_qcif.yuv" + ], + "args": [ + "-d", + "foreman_ref_encoder_main.cfg" + ], + "type": [ + "int", + "ref" + ] + }, + "h264ref_sss": { + "base_name": "h264ref", + "files": [ + "h264ref/sss_encoder_main.cfg", + "h264ref/sss.yuv" + ], + "args": [ + "-d", + "sss_encoder_main.cfg" + ], + "type": [ + "int", + "ref" + ] + }, + "hmmer_nph3": { + "base_name": "hmmer", + "files": [ + "hmmer/nph3.hmm", + "hmmer/swiss41" + ], + "args": [ + "nph3.hmm", + "swiss41" + ], + "type": [ + "int", + "ref" + ] + }, + "hmmer_retro": { + "base_name": "hmmer", + "files": [ + "hmmer/retro.hmm" + ], + "args": [ + "--fixed", + "0", + "--mean", + "500", + "--num", + "500000", + "--sd", + "350", + "--seed", + "0", + "retro.hmm" + ], + "type": [ + "int", + "ref" + ] + }, + "lbm": { + "base_name": "lbm", + "files": [ + "lbm/100_100_130_ldc.of", + "lbm/lbm.in" + ], + "args": [ + "3000", + "reference.dat", + "0", + "0", + "100_100_130_ldc.of" + ], + "type": [ + "fp", + "ref" + ] + }, + "leslie3d": { + "base_name": "leslie3d", + "files": [ + "leslie3d/leslie3d.in" + ], + "args": [ + "<", + "leslie3d.in" + ], + "type": [ + "fp", + "ref" + ] + }, + "libquantum": { + "base_name": "libquantum", + "files": [], + "args": [ + "1397", + "8" + ], + "type": [ + "int", + "ref" + ] + }, + "mcf": { + "base_name": "mcf", + "files": [ + "mcf/inp.in" + ], + "args": [ + "inp.in" + ], + "type": [ + "int", + "ref" + ] + }, + "milc": { + "base_name": "milc", + "files": [ + "milc/su3imp.in" + ], + "args": [ + "<", + "su3imp.in" + ], + "type": [ + "fp", + "ref" + ] + }, + "namd": { + "base_name": "namd", + "files": [ + "namd/namd.input" + ], + "args": [ + "--input", + "namd.input", + "--iterations", + "38", + "--output", + "namd.out" + ], + "type": [ + "fp", + "ref" + ] + }, + "omnetpp": { + "base_name": "omnetpp", + "files": [ + "omnetpp/omnetpp.ini" + ], + "args": [ + "omnetpp.ini" + ], + "type": [ + "int", + "ref" + ] + }, + "perlbench_checkspam": { + "base_name": "perlbench", + "files": [ + "perlbench/cpu2006_mhonarc.rc", + "perlbench/checkspam.pl", + "perlbench/checkspam.in", + "dir lib perlbench/lib", + "dir rules perlbench/rules" + ], + "args": [ + "-I./lib", + "checkspam.pl", + "2500", + "5", + "25", + "11", + "150", + "1", + "1", + "1", + "1" + ], + "type": [ + "int", + "ref" + ] + }, + "perlbench_diffmail": { + "base_name": "perlbench", + "files": [ + "perlbench/cpu2006_mhonarc.rc", + "perlbench/diffmail.pl", + "perlbench/diffmail.in", + "dir lib perlbench/lib", + "dir rules perlbench/rules" + ], + "args": [ + "-I./lib", + "diffmail.pl", + "4", + "800", + "10", + "17", + "19", + "300" + ], + "type": [ + "int", + "ref" + ] + }, + "perlbench_splitmail": { + "base_name": "perlbench", + "files": [ + "perlbench/cpu2006_mhonarc.rc", + "perlbench/splitmail.pl", + "perlbench/splitmail.in", + "dir lib perlbench/lib", + "dir rules perlbench/rules" + ], + "args": [ + "-I./lib", + "splitmail.pl", + "1600", + "12", + "26", + "16", + "4500" + ], + "type": [ + "int", + "ref" + ] + }, + "povray": { + "base_name": "povray", + "files": [ + "dir . povray" + ], + "args": [ + "SPEC-benchmark-ref.ini" + ], + "type": [ + "fp", + "ref" + ] + }, + "sjeng": { + "base_name": "sjeng", + "files": [ + "sjeng/ref.txt" + ], + "args": [ + "ref.txt" + ], + "type": [ + "int", + "ref" + ] + }, + "soplex_pds-50": { + "base_name": "soplex", + "files": [ + "soplex/pds-50.mps" + ], + "args": [ + "-s1", + "-e", + "-m45000", + "pds-50.mps" + ], + "type": [ + "fp", + "ref" + ] + }, + "soplex_ref": { + "base_name": "soplex", + "files": [ + "soplex/ref.mps" + ], + "args": [ + "-m3500", + "ref.mps" + ], + "type": [ + "fp", + "ref" + ] + }, + "sphinx3": { + "base_name": "sphinx3", + "files": [ + "dir . sphinx3" + ], + "args": [ + "ctlfile", + ".", + "args.an4" + ], + "type": [ + "fp", + "ref" + ] + }, + "tonto": { + "base_name": "tonto", + "files": [ + "tonto/stdin" + ], + "args": [], + "type": [ + "fp", + "ref" + ] + }, + "wrf": { + "base_name": "wrf", + "files": [ + "dir . wrf" + ], + "args": [], + "type": [ + "fp", + "ref" + ] + }, + "xalancbmk": { + "base_name": "xalancbmk", + "files": [ + "dir . xalancbmk" + ], + "args": [ + "-v", + "t5.xml", + "xalanc.xsl" + ], + "type": [ + "int", + "ref" + ] + }, + "zeusmp": { + "base_name": "zeusmp", + "files": [ + "zeusmp/zmp_inp" + ], + "args": [], + "type": [ + "fp", + "ref" + ] + }, + "gamess_exam29": { + "base_name": "gamess", + "files": [ + "gamess/exam29.config", + "gamess/exam29.inp" + ], + "args": [ + "<", + "exam29.config" + ], + "type": [ + "fp", + "test" + ] + }, + "perlbench_attrs": { + "base_name": "perlbench", + "files": [ + "perlbench/attrs.pl" + ], + "args": [ + "-I.", + "-I./lib", + "attrs.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_gv": { + "base_name": "perlbench", + "files": [ + "perlbench/gv.pl" + ], + "args": [ + "-I.", + "-I./lib", + "gv.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_makerand": { + "base_name": "perlbench", + "files": [ + "perlbench/makerand.pl" + ], + "args": [ + "-I.", + "-I./lib", + "makerand.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_pack": { + "base_name": "perlbench", + "files": [ + "perlbench/pack.pl", + "perlbench/test.pm" + ], + "args": [ + "-I.", + "-I./lib", + "pack.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_redef": { + "base_name": "perlbench", + "files": [ + "perlbench/redef.pl" + ], + "args": [ + "-I.", + "-I./lib", + "redef.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_ref": { + "base_name": "perlbench", + "files": [ + "perlbench/ref.pl" + ], + "args": [ + "-I.", + "-I./lib", + "ref.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_regmesg": { + "base_name": "perlbench", + "files": [ + "perlbench/regmesg.pl" + ], + "args": [ + "-I.", + "-I./lib", + "regmesg.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_test": { + "base_name": "perlbench", + "files": [ + "perlbench/test.pl", + "perlbench/test.pm", + "perlbench/re_tests", + "perlbench/append.t", + "perlbench/args.t", + "perlbench/arith.t", + "perlbench/array.t", + "perlbench/auto.t", + "perlbench/base_cond.t", + "perlbench/base_pat.t", + "perlbench/base_term.t", + "perlbench/bless.t", + "perlbench/bop.t", + "perlbench/bproto.t", + "perlbench/chars.t", + "perlbench/chop.t", + "perlbench/cmdopt.t", + "perlbench/cmp.t", + "perlbench/comp_term.t", + "perlbench/concat.t", + "perlbench/context.t", + "perlbench/decl.t", + "perlbench/defins.t", + "perlbench/delete.t", + "perlbench/die.t", + "perlbench/do.t", + "perlbench/each.t", + "perlbench/eval.t", + "perlbench/exists_sub.t", + "perlbench/exp.t", + "perlbench/fh.t", + "perlbench/grep.t", + "perlbench/hashwarn.t", + "perlbench/if.t", + "perlbench/inc.t", + "perlbench/index.t", + "perlbench/int.t", + "perlbench/join.t", + "perlbench/length.t", + "perlbench/lex.t", + "perlbench/list.t", + "perlbench/loopctl.t", + "perlbench/lop.t", + "perlbench/method.t", + "perlbench/my.t", + "perlbench/nothr5005.t", + "perlbench/oct.t", + "perlbench/op_cond.t", + "perlbench/op_pat.t", + "perlbench/ord.t", + "perlbench/override.t", + "perlbench/package.t", + "perlbench/pos.t", + "perlbench/push.t", + "perlbench/quotemeta.t", + "perlbench/range.t", + "perlbench/recurse.t", + "perlbench/regexp.t", + "perlbench/regexp_noamp.t", + "perlbench/repeat.t", + "perlbench/reverse.t", + "perlbench/rs.t", + "perlbench/sleep.t", + "perlbench/sort.t", + "perlbench/splice.t", + "perlbench/study.t", + "perlbench/sub_lval.t", + "perlbench/subst.t", + "perlbench/subst_amp.t", + "perlbench/subst_wamp.t", + "perlbench/tr.t", + "perlbench/undef.t", + "perlbench/unshift.t", + "perlbench/vec.t", + "perlbench/wantarray.t" + ], + "args": [ + "-I.", + "-I./lib", + "test.pl" + ], + "type": [ + "int", + "test" + ] + }, + "perlbench_diffmail_train": { + "base_name": "perlbench", + "files": [ + "perlbench/cpu2006_mhonarc.rc", + "perlbench/diffmail.pl", + "perlbench/diffmail.in", + "dir lib perlbench/lib", + "dir rules perlbench/rules" + ], + "args": [ + "-I./lib", + "diffmail.pl", + "4", + "800", + "10", + "17", + "19", + "300" + ], + "type": [ + "int", + "train" + ] + }, + "perlbench_perfect": { + "base_name": "perlbench", + "files": [ + "perlbench/perfect.pl", + "perlbench/perfect.in" + ], + "args": [ + "-I./lib", + "perfect.pl", + "b", + "3" + ], + "type": [ + "int", + "train" + ] + }, + "perlbench_splitmail_train": { + "base_name": "perlbench", + "files": [ + "perlbench/cpu2006_mhonarc.rc", + "perlbench/splitmail.pl", + "perlbench/splitmail.in", + "dir lib perlbench/lib", + "dir rules perlbench/rules" + ], + "args": [ + "-I./lib", + "splitmail.pl", + "1600", + "12", + "26", + "16", + "4500" + ], + "type": [ + "int", + "train" + ] + }, + "perlbench_scrabbl": { + "base_name": "perlbench", + "files": [ + "perlbench/scrabbl.pl", + "perlbench/scrabbl.in", + "perlbench/dictionary" + ], + "args": [ + "-I.", + "-I./lib", + "scrabbl.pl", + "<", + "scrabbl.in" + ], + "type": [ + "int", + "train" + ] + }, + "perlbench_suns": { + "base_name": "perlbench", + "files": [ + "perlbench/suns.pl", + "perlbench/WORDS" + ], + "args": [ + "-I.", + "-I./lib", + "suns.pl" + ], + "type": [ + "int", + "train" + ] + }, + "bzip2_dryer": { + "base_name": "bzip2", + "files": [ + "bzip2/dryer.jpg" + ], + "args": [ + "dryer.jpg", + "2" + ], + "type": [ + "int", + "test" + ] + }, + "bzip2_program_test": { + "base_name": "bzip2", + "files": [ + "bzip2/input.program" + ], + "args": [ + "input.program", + "5" + ], + "type": [ + "int", + "test" + ] + }, + "bzip2_byoudoin": { + "base_name": "bzip2", + "files": [ + "bzip2/byoudoin.jpg" + ], + "args": [ + "byoudoin.jpg", + "5" + ], + "type": [ + "int", + "train" + ] + }, + "bzip2_program_train": { + "base_name": "bzip2", + "files": [ + "bzip2/input.program" + ], + "args": [ + "input.program", + "10" + ], + "type": [ + "int", + "train" + ] + }, + "bzip2_combined_train": { + "base_name": "bzip2", + "files": [ + "bzip2/input.combined" + ], + "args": [ + "input.combined", + "80" + ], + "type": [ + "int", + "train" + ] + }, + "gcc_cccp": { + "base_name": "gcc", + "files": [ + "gcc/cccp.in" + ], + "args": [ + "cccp.in", + "-o", + "cccp.s" + ], + "type": [ + "int", + "test" + ] + }, + "gcc_integrate": { + "base_name": "gcc", + "files": [ + "gcc/integrate.in" + ], + "args": [ + "integrate.in", + "-o", + "integrate.s" + ], + "type": [ + "int", + "train" + ] + }, + "bwaves_test": { + "base_name": "bwaves", + "files": [ + "bwaves/bwaves.in" + ], + "args": [], + "type": [ + "fp", + "test" + ] + }, + "bwaves_train": { + "base_name": "bwaves", + "files": [ + "bwaves/bwaves.in" + ], + "args": [], + "type": [ + "fp", + "train" + ] + }, + "gamess_h2ocu2_energy": { + "base_name": "gamess", + "files": [ + "gamess/h2ocu2+.energy.config", + "gamess/h2ocu2+.energy.inp" + ], + "args": [ + "<", + "h2ocu2+.energy.config" + ], + "type": [ + "fp", + "train" + ] + }, + "mcf_test": { + "base_name": "mcf", + "files": [ + "mcf/inp.in" + ], + "args": [ + "inp.in" + ], + "type": [ + "int", + "test" + ] + }, + "mcf_train": { + "base_name": "mcf", + "files": [ + "mcf/inp.in" + ], + "args": [ + "inp.in" + ], + "type": [ + "int", + "train" + ] + }, + "milc_test": { + "base_name": "milc", + "files": [ + "milc/su3imp.in" + ], + "args": [ + "<", + "su3imp.in" + ], + "type": [ + "fp", + "test" + ] + }, + "milc_train": { + "base_name": "milc", + "files": [ + "milc/su3imp.in" + ], + "args": [ + "<", + "su3imp.in" + ], + "type": [ + "fp", + "train" + ] + }, + "zeusmp_test": { + "base_name": "zeusmp", + "files": [ + "zeusmp/zmp_inp" + ], + "args": [], + "type": [ + "fp", + "test" + ] + }, + "zeusmp_train": { + "base_name": "zeusmp", + "files": [ + "zeusmp/zmp_inp" + ], + "args": [], + "type": [ + "fp", + "train" + ] + }, + "gromacs_test": { + "base_name": "gromacs", + "files": [ + "gromacs/gromacs.tpr" + ], + "args": [ + "-silent", + "-deffnm", + "gromacs", + "-nice", + "0" + ], + "type": [ + "fp", + "test" + ] + }, + "gromacs_train": { + "base_name": "gromacs", + "files": [ + "gromacs/gromacs.tpr" + ], + "args": [ + "-silent", + "-deffnm", + "gromacs", + "-nice", + "0" + ], + "type": [ + "fp", + "train" + ] + }, + "cactusADM_test": { + "base_name": "cactusADM", + "files": [ + "cactusADM/benchADM.par" + ], + "args": [ + "benchADM.par" + ], + "type": [ + "fp", + "test" + ] + }, + "cactusADM_train": { + "base_name": "cactusADM", + "files": [ + "cactusADM/benchADM.par" + ], + "args": [ + "benchADM.par" + ], + "type": [ + "fp", + "train" + ] + }, + "leslie3d_test": { + "base_name": "leslie3d", + "files": [ + "leslie3d/leslie3d.in" + ], + "args": [ + "<", + "leslie3d.in" + ], + "type": [ + "fp", + "test" + ] + }, + "leslie3d_train": { + "base_name": "leslie3d", + "files": [ + "leslie3d/leslie3d.in" + ], + "args": [ + "<", + "leslie3d.in" + ], + "type": [ + "fp", + "train" + ] + }, + "namd_test": { + "base_name": "namd", + "files": [ + "namd/namd.input" + ], + "args": [ + "--input", + "namd.input", + "--iterations", + "1", + "--output", + "namd.out" + ], + "type": [ + "int", + "test" + ] + }, + "namd_train": { + "base_name": "namd", + "files": [ + "namd/namd.input" + ], + "args": [ + "--input", + "namd.input", + "--iterations", + "1", + "--output", + "namd.out" + ], + "type": [ + "int", + "train" + ] + }, + "dealII_test": { + "base_name": "dealII", + "files": [ + "dealII/DummyData" + ], + "args": [ + "8" + ], + "type": [ + "fp", + "test" + ] + }, + "dealII_train": { + "base_name": "dealII", + "files": [ + "dealII/DummyData" + ], + "args": [ + "10" + ], + "type": [ + "fp", + "train" + ] + }, + "soplex_test": { + "base_name": "soplex", + "files": [ + "soplex/test.mps" + ], + "args": [ + "-m10000", + "test.mps" + ], + "type": [ + "fp", + "test" + ] + }, + "soplex_pds-20": { + "base_name": "soplex", + "files": [ + "soplex/pds-20.mps" + ], + "args": [ + "-s1", + "-e", + "-m5000", + "pds-20.mps" + ], + "type": [ + "fp", + "train" + ] + }, + "soplex_train": { + "base_name": "soplex", + "files": [ + "soplex/train.mps" + ], + "args": [ + "-m1200", + "train.mps" + ], + "type": [ + "fp", + "train" + ] + }, + "povray_test": { + "base_name": "povray", + "files": [ + "povray/SPEC-benchmark-test.ini", + "povray/SPEC-benchmark-test.pov" + ], + "args": [ + "SPEC-benchmark-test.ini" + ], + "type": [ + "fp", + "test" + ] + }, + "povray_train": { + "base_name": "povray", + "files": [ + "povray/SPEC-benchmark-train.ini", + "povray/SPEC-benchmark-train.pov" + ], + "args": [ + "SPEC-benchmark-train.ini" + ], + "type": [ + "fp", + "train" + ] + }, + "calculix_test": { + "base_name": "calculix", + "files": [ + "calculix/beampic.inp" + ], + "args": [ + "-i", + "beampic" + ], + "type": [ + "fp", + "test" + ] + }, + "calculix_train": { + "base_name": "calculix", + "files": [ + "calculix/stairs.inp" + ], + "args": [ + "-i", + "stairs" + ], + "type": [ + "fp", + "train" + ] + }, + "hmmer_test": { + "base_name": "hmmer", + "files": [ + "hmmer/bombesin.hmm" + ], + "args": [ + "--fixed", + "0", + "--mean", + "325", + "--num", + "45000", + "--sd", + "200", + "--seed", + "0", + "bombesin.hmm" + ], + "type": [ + "fp", + "test" + ] + }, + "hmmer_train": { + "base_name": "hmmer", + "files": [ + "hmmer/leng100.hmm" + ], + "args": [ + "--fixed", + "0", + "--mean", + "425", + "--num", + "85000", + "--sd", + "300", + "--seed", + "0", + "leng100.hmm" + ], + "type": [ + "fp", + "train" + ] + }, + "sjeng_test": { + "base_name": "sjeng", + "files": [ + "sjeng/test.txt" + ], + "args": [ + "test.txt" + ], + "type": [ + "int", + "test" + ] + }, + "sjeng_train": { + "base_name": "sjeng", + "files": [ + "sjeng/train.txt" + ], + "args": [ + "train.txt" + ], + "type": [ + "int", + "train" + ] + }, + "GemsFDTD_test": { + "base_name": "GemsFDTD", + "files": [ + "GemsFDTD/sphere.pec", + "GemsFDTD/test.in", + "GemsFDTD/yee.dat" + ], + "args": [], + "type": [ + "fp", + "test" + ] + }, + "GemsFDTD_train": { + "base_name": "GemsFDTD", + "files": [ + "GemsFDTD/sphere.pec", + "GemsFDTD/train.in", + "GemsFDTD/yee.dat" + ], + "args": [], + "type": [ + "fp", + "train" + ] + }, + "tonto_test": { + "base_name": "tonto", + "files": [ + "tonto/stdin" + ], + "args": [], + "type": [ + "fp", + "test" + ] + }, + "tonto_train": { + "base_name": "tonto", + "files": [ + "tonto/stdin" + ], + "args": [], + "type": [ + "fp", + "train" + ] + }, + "lbm_test": { + "base_name": "lbm", + "files": [ + "lbm/100_100_130_cf_a.of", + "lbm/lbm.in" + ], + "args": [ + "20", + "reference.dat", + "0", + "1", + "100_100_130_cf_a.of" + ], + "type": [ + "fp", + "test" + ] + }, + "lbm_train": { + "base_name": "lbm", + "files": [ + "lbm/100_100_130_cf_b.of", + "lbm/lbm.in" + ], + "args": [ + "300", + "reference.dat", + "0", + "1", + "100_100_130_cf_b.of" + ], + "type": [ + "fp", + "train" + ] + }, + "omnetpp_test": { + "base_name": "omnetpp", + "files": [ + "omnetpp/omnetpp.ini" + ], + "args": [ + "omnetpp.ini" + ], + "type": [ + "int", + "test" + ] + }, + "omnetpp_train": { + "base_name": "omnetpp", + "files": [ + "omnetpp/omnetpp.ini" + ], + "args": [ + "omnetpp.ini" + ], + "type": [ + "int", + "train" + ] + }, + "astar_lake": { + "base_name": "astar", + "files": [ + "astar/lake.bin", + "astar/lake.cfg" + ], + "args": [ + "lake.cfg" + ], + "type": [ + "int", + "test" + ] + }, + "astar_biglakes1024": { + "base_name": "astar", + "files": [ + "astar/BigLakes1024.bin", + "astar/BigLakes1024.cfg" + ], + "args": [ + "BigLakes1024.cfg" + ], + "type": [ + "int", + "train" + ] + }, + "astar_rivers1": { + "base_name": "astar", + "files": [ + "astar/rivers.bin", + "astar/rivers1.cfg" + ], + "args": [ + "rivers1.cfg" + ], + "type": [ + "int", + "train" + ] + }, + "wrf_test": { + "base_name": "wrf", + "files": [ + "dir . wrf" + ], + "args": [], + "type": [ + "fp", + "test" + ] + }, + "wrf_train": { + "base_name": "wrf", + "files": [ + "dir . wrf" + ], + "args": [], + "type": [ + "fp", + "train" + ] + }, + "sphinx3_test": { + "base_name": "sphinx3", + "files": [ + "dir . sphinx3" + ], + "args": [ + "ctlfile", + ".", + "args.an4" + ], + "type": [ + "fp", + "test" + ] + }, + "sphinx3_train": { + "base_name": "sphinx3", + "files": [ + "dir . sphinx3" + ], + "args": [ + "ctlfile", + ".", + "args.an4" + ], + "type": [ + "fp", + "train" + ] + }, + "xalancbmk_test": { + "base_name": "xalancbmk", + "files": [ + "dir . xalancbmk" + ], + "args": [ + "-v", + "test.xml", + "xalanc.xsl" + ], + "type": [ + "int", + "test" + ] + }, + "xalancbmk_train": { + "base_name": "xalancbmk", + "files": [ + "dir . xalancbmk" + ], + "args": [ + "-v", + "allbooks.xml", + "xalanc.xsl" + ], + "type": [ + "int", + "train" + ] + }, + "h264ref_foreman.test": { + "base_name": "h264ref", + "files": [ + "h264ref/foreman_qcif.yuv", + "h264ref/foreman_test_encoder_baseline.cfg" + ], + "args": [ + "-d", + "foreman_test_encoder_baseline.cfg" + ], + "type": [ + "int", + "test" + ] + }, + "h264ref_foreman.train": { + "base_name": "h264ref", + "files": [ + "h264ref/foreman_qcif.yuv", + "h264ref/foreman_train_encoder_baseline.cfg" + ], + "args": [ + "-d", + "foreman_train_encoder_baseline.cfg" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_capture": { + "base_name": "gobmk", + "files": [ + "gobmk/capture.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "capture.tst" + ], + "type": [ + "int", + "test" + ] + }, + "gobmk_connect": { + "base_name": "gobmk", + "files": [ + "gobmk/connect.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "connect.tst" + ], + "type": [ + "int", + "test" + ] + }, + "gobmk_connect_rot": { + "base_name": "gobmk", + "files": [ + "gobmk/connect_rot.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "connect_rot.tst" + ], + "type": [ + "int", + "test" + ] + }, + "gobmk_connection": { + "base_name": "gobmk", + "files": [ + "gobmk/connection.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "connection.tst" + ], + "type": [ + "int", + "test" + ] + }, + "gobmk_connection_rot": { + "base_name": "gobmk", + "files": [ + "gobmk/connection_rot.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "connection_rot.tst" + ], + "type": [ + "int", + "test" + ] + }, + "gobmk_cutstone": { + "base_name": "gobmk", + "files": [ + "gobmk/cutstone.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "cutstone.tst" + ], + "type": [ + "int", + "test" + ] + }, + "gobmk_dniwog": { + "base_name": "gobmk", + "files": [ + "gobmk/dniwog.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "dniwog.tst" + ], + "type": [ + "int", + "test" + ] + }, + "gobmk_arb": { + "base_name": "gobmk", + "files": [ + "gobmk/arb.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "arb.tst" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_arend": { + "base_name": "gobmk", + "files": [ + "gobmk/arend.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "arend.tst" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_arion": { + "base_name": "gobmk", + "files": [ + "gobmk/arion.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "arion.tst" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_atari_atari": { + "base_name": "gobmk", + "files": [ + "gobmk/atari_atari.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "atari_atari.tst" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_blunder": { + "base_name": "gobmk", + "files": [ + "gobmk/blunder.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "blunder.tst" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_buzco": { + "base_name": "gobmk", + "files": [ + "gobmk/buzco.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "buzco.tst" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_nicklas2": { + "base_name": "gobmk", + "files": [ + "gobmk/nicklas2.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "nicklas2.tst" + ], + "type": [ + "int", + "train" + ] + }, + "gobmk_nicklas4": { + "base_name": "gobmk", + "files": [ + "gobmk/nicklas4.tst", + "dir games gobmk/games", + "dir golois gobmk/golois" + ], + "args": [ + "--quiet", + "--mode", + "gtp", + "<", + "nicklas4.tst" + ], + "type": [ + "int", + "train" + ] + } +} diff --git a/workloads/linux/spec2006/spec2006-package.py b/workloads/linux/spec2006/spec2006-package.py new file mode 100644 index 0000000..70ac9bf --- /dev/null +++ b/workloads/linux/spec2006/spec2006-package.py @@ -0,0 +1,562 @@ +#!/usr/bin/env python3 +import argparse +import hashlib +import json +import os +import shlex +import shutil +import subprocess +import sys +from collections import deque +from pathlib import Path + +INPUT_SETS = ("ref", "train", "test") + + +def format_cmd(cmd): + return " ".join(shlex.quote(str(part)) for part in cmd) + + +def progress_prefix(): + current = os.environ.get("SPEC2006_PROGRESS_K", "1") + total = os.environ.get("SPEC2006_PROGRESS_N", "1") + return f"[spec2006 {current}/{total}]" + + +def status(message): + print(f"{progress_prefix()} {message}", flush=True) + + +def read_log_tail(log_path, max_lines=40): + with open(log_path, "r", encoding="utf-8", errors="replace") as f: + lines = deque(f, maxlen=max_lines) + return "".join(lines).rstrip() + + +def maybe_read_log_tail(log_path, max_lines=40): + if log_path.is_file(): + tail = read_log_tail(log_path, max_lines=max_lines) + if tail: + return f"\nLast log lines from {log_path}:\n{tail}" + return "" + + +def run(cmd, *, env=None, cwd=None, log_path=None, summary=None): + command_text = format_cmd(cmd) + if summary: + status(summary) + + if log_path is None: + raise ValueError("log_path is required") + + log_path.parent.mkdir(parents=True, exist_ok=True) + with open(log_path, "a", encoding="utf-8") as log: + log.write(f"$ {command_text}\n") + if cwd is not None: + log.write(f"# cwd: {cwd}\n") + log.flush() + result = subprocess.run( + cmd, + cwd=cwd, + env=env, + check=False, + stdout=log, + stderr=subprocess.STDOUT, + text=True, + ) + log.write("\n") + + if result.returncode != 0: + tail = read_log_tail(log_path) + detail = f"\nLast log lines from {log_path}:\n{tail}" if tail else "" + raise RuntimeError(f"command failed: {command_text}\nSee {log_path}{detail}") + + +def load_cases(path): + with open(path, "r", encoding="utf-8") as f: + cases = json.load(f) + if not isinstance(cases, dict): + raise RuntimeError(f"case config must be a JSON object: {path}") + return cases + + +def file_sha256(path): + digest = hashlib.sha256() + with open(path, "rb") as f: + for chunk in iter(lambda: f.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def filter_cases(cases, input_set): + if input_set in (None, "", "all"): + return cases + if input_set not in INPUT_SETS: + choices = ", ".join((*INPUT_SETS, "all")) + raise RuntimeError(f"unknown SPEC2006 input set {input_set!r}; available: {choices}") + return { + name: case + for name, case in cases.items() + if input_set in case.get("type", []) + } + + +def input_set_for_case(case): + for name in INPUT_SETS: + if name in case.get("type", []): + return name + raise RuntimeError(f"case has no input set marker in type: {case.get('type')}") + + +def spec_env(spec_dir): + script = f"cd {shlex.quote(str(spec_dir))} && . ./shrc >/dev/null && env -0" + raw = subprocess.check_output(["bash", "-lc", script]) + env = {} + for item in raw.split(b"\0"): + if not item: + continue + key, value = item.split(b"=", 1) + env[key.decode()] = value.decode() + return env + + +def bench_dir_for_base(spec_dir, base_name): + root = spec_dir / "benchspec" / "CPU2006" + matches = [] + for path in root.iterdir(): + if not path.is_dir() or "." not in path.name: + continue + suffix = path.name.split(".", 1)[1] + if suffix == base_name: + matches.append(path.name) + if len(matches) != 1: + raise RuntimeError(f"cannot map base benchmark {base_name!r} to SPEC benchmark directory") + return matches[0] + + +def resolve_cross_compile(prefix): + gcc_name = prefix if prefix.endswith("gcc") else prefix + "gcc" + gcc_path = Path(gcc_name) + if not gcc_path.is_absolute(): + found = shutil.which(gcc_name) + if found is None: + raise RuntimeError(f"cannot locate compiler for CROSS_COMPILE={prefix!r}") + gcc_path = Path(found) + if not gcc_path.is_file(): + raise RuntimeError(f"compiler does not exist: {gcc_path}") + gcc_path = gcc_path.resolve() + if not gcc_path.name.endswith("gcc"): + raise RuntimeError(f"unexpected compiler name for CROSS_COMPILE={prefix!r}: {gcc_path.name}") + cross_compile = str(gcc_path)[: -len("gcc")] + toolchain_root = gcc_path.parent.parent + return cross_compile, toolchain_root + + +def copy_tree_contents(src, dst): + if not src.is_dir(): + return + dst.mkdir(parents=True, exist_ok=True) + for item in src.iterdir(): + target = dst / item.name + if item.is_dir(): + if target.exists(): + shutil.rmtree(target) + shutil.copytree(item, target, symlinks=True) + else: + shutil.copy2(item, target) + + +def stage_inputs(spec_dir, bench_dir, base_name, input_set, stage_root): + bench_data = spec_dir / "benchspec" / "CPU2006" / bench_dir / "data" + if stage_root.exists(): + shutil.rmtree(stage_root) + base_stage = stage_root / base_name + base_stage.mkdir(parents=True) + copy_tree_contents(bench_data / "all" / "input", base_stage) + copy_tree_contents(bench_data / input_set / "input", base_stage) + return stage_root + + +def install_case_files(case, stage_root, spec_root): + spec_root.mkdir(parents=True, exist_ok=True) + for entry in case.get("files", []): + parts = entry.split() + if len(parts) == 3 and parts[0] == "dir": + _, dest_name, rel_path = parts + src = stage_root / rel_path + if not src.is_dir(): + raise RuntimeError(f"missing SPEC input directory {src}") + if dest_name == ".": + copy_tree_contents(src, spec_root) + else: + dst = spec_root / dest_name + if dst.exists(): + shutil.rmtree(dst) + shutil.copytree(src, dst, symlinks=True) + elif len(parts) == 1: + src = stage_root / entry + if not src.is_file(): + raise RuntimeError(f"missing SPEC input file {src}") + shutil.copy2(src, spec_root / src.name) + else: + raise RuntimeError(f"unsupported SPEC file entry: {entry}") + + +def shell_command(binary_name, args): + before_redirect = [] + stdin_file = None + iterator = iter(args) + for arg in iterator: + if arg == "<": + try: + stdin_file = next(iterator) + except StopIteration as exc: + raise RuntimeError("input redirection without file") from exc + rest = list(iterator) + if rest: + raise RuntimeError(f"unsupported arguments after input redirection: {rest}") + break + before_redirect.append(arg) + + words = ["./" + binary_name] + before_redirect + cmd = " ".join(shlex.quote(x) for x in words) + if stdin_file is not None: + cmd += " < " + shlex.quote(stdin_file) + return cmd + + +def write_runtime_files(pkg_dir, case_name, binary_name, args): + spec_root = pkg_dir / "spec" + command = shell_command(binary_name, args) + run_sh = spec_root / "run.sh" + run_sh.write_text( + "\n".join( + [ + "#!/bin/sh", + "set -e", + "cd /spec", + f"echo '======== BEGIN {case_name} ========'", + f"md5sum ./{shlex.quote(binary_name)}", + "date -R || true", + f"spec_cmd={shlex.quote(command)}", + "echo \"CMD: $spec_cmd\"", + "set +e", + "sh -c \"$spec_cmd\"", + "status=$?", + "set -e", + "date -R || true", + f"echo '======== END {case_name} ========'", + "exit $status", + "", + ] + ), + encoding="utf-8", + ) + run_sh.chmod(0o755) + + etc = pkg_dir / "etc" + etc.mkdir(parents=True, exist_ok=True) + (etc / "inittab").write_text("::sysinit:nemu-exec /bin/sh /spec/run.sh\n", encoding="utf-8") + + +def export_elf_artifact(elf, case_name, out_dir): + elf_dir = out_dir / "elf" + elf_dir.mkdir(parents=True, exist_ok=True) + exported_elf = elf_dir / f"{case_name}.elf" + shutil.copy2(elf, exported_elf) + return exported_elf + + +def install_runtime_binary(elf, binary_name, pkg_dir): + spec_root = pkg_dir / "spec" + shutil.copy2(elf, spec_root / binary_name) + (spec_root / binary_name).chmod(0o755) + + +def build_local_config(template_cfg, generated_cfg, output_root, jobs): + text = template_cfg.read_text(encoding="utf-8") + filtered_lines = [] + for line in text.splitlines(): + stripped = line.lstrip() + if stripped.startswith("output_root") and "=" in line: + continue + if stripped.startswith("makeflags") and "=" in line: + continue + filtered_lines.append(line) + generated_cfg.parent.mkdir(parents=True, exist_ok=True) + generated_cfg.write_text( + "\n".join( + [ + "# Auto-generated by spec2006-package.py", + f"# Template: {template_cfg}", + f"output_root = {output_root}", + f"makeflags = -j{jobs}", + "", + *filtered_lines, + "", + ] + ), + encoding="utf-8", + ) + return generated_cfg + + +def shared_build_dir_for(out_dir, bench_dir, tune): + return out_dir.parent / "_bench-builds" / bench_dir / tune + + +def shared_build_metadata(spec_cfg, spec_dir, cross_compile, tune, compiler_root, gnu_toolchain_root, jemalloc_root): + return { + "spec_cfg_sha256": file_sha256(spec_cfg), + "spec_dir": str(spec_dir), + "cross_compile": cross_compile, + "tune": tune, + "compiler_root": str(compiler_root), + "gnu_toolchain_root": str(gnu_toolchain_root), + "jemalloc_root": str(jemalloc_root), + } + + +def load_json(path): + with open(path, "r", encoding="utf-8") as f: + return json.load(f) + + +def write_json(path, value): + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8") + + +def select_built_elf(exe_dir, tune): + if not exe_dir.is_dir(): + raise RuntimeError(f"runspec did not create exe directory: {exe_dir}") + candidates = [path for path in exe_dir.iterdir() if path.is_file() and not path.name.endswith(".md5")] + if not candidates: + raise RuntimeError(f"no executable produced by runspec under {exe_dir}") + preferred = [path for path in candidates if f"_{tune}." in path.name] + if preferred: + candidates = preferred + return max(candidates, key=lambda path: path.stat().st_mtime) + + +def explain_missing_elf(output_root, bench_dir, tune): + build_root = output_root / "benchspec" / "CPU2006" / bench_dir / "build" + if not build_root.is_dir(): + return "" + + build_dirs = sorted(path for path in build_root.iterdir() if path.is_dir()) + if not build_dirs: + return "" + + latest = max(build_dirs, key=lambda path: path.stat().st_mtime) + details = [f"Latest build directory: {latest}"] + for name in ("make.err", "make.out"): + tail = maybe_read_log_tail(latest / name) + if tail: + details.append(tail.lstrip("\n")) + break + return "\n" + "\n".join(details) + + +def cfg_requires_jemalloc(spec_cfg): + text = spec_cfg.read_text(encoding="utf-8") + return "JEMALLOC_PATH" in text or "-ljemalloc" in text + + +def build_elf(spec_dir, bench_dir, spec_cfg, out_dir, log_dir, cross_compile, tune, jobs, compiler_root, gnu_toolchain_root, jemalloc_root): + shared_dir = shared_build_dir_for(out_dir, bench_dir, tune) + output_root = shared_dir / "runspec-output" + generated_cfg = shared_dir / "runspec-config" / spec_cfg.name + shared_log_dir = shared_dir / "logs" + build_log = shared_log_dir / "build.log" + exe_dir = output_root / "benchspec" / "CPU2006" / bench_dir / "exe" + metadata_path = shared_dir / "build-meta.json" + metadata = shared_build_metadata( + spec_cfg, + spec_dir, + cross_compile, + tune, + compiler_root, + gnu_toolchain_root, + jemalloc_root, + ) + + if metadata_path.is_file(): + try: + cached_metadata = load_json(metadata_path) + except Exception: + cached_metadata = None + if cached_metadata == metadata: + try: + elf = select_built_elf(exe_dir, tune) + except Exception: + elf = None + if elf is not None: + status(f"Reusing {bench_dir} build from {shared_dir}") + return elf, build_log + + if output_root.exists(): + shutil.rmtree(output_root) + if generated_cfg.parent.exists(): + shutil.rmtree(generated_cfg.parent) + if shared_log_dir.exists(): + shutil.rmtree(shared_log_dir) + shared_log_dir.mkdir(parents=True, exist_ok=True) + + build_local_config(spec_cfg, generated_cfg, output_root, jobs) + status(f"Generated SPEC cfg: {generated_cfg}") + + env = os.environ.copy() + env.update(spec_env(spec_dir)) + env["SPEC"] = str(spec_dir) + env["LLVM_INSTALL_PATH"] = str(compiler_root) + env["GNU_RISCV64_PATH"] = str(gnu_toolchain_root) + env["JEMALLOC_INSTALL_PATH"] = str(jemalloc_root) + + runspec = spec_dir / "bin" / "runspec" + cmd = [ + str(runspec), + "--action", + "build", + "--config", + str(generated_cfg), + "--tune", + tune, + "--noreportable", + "--iterations", + "1", + bench_dir, + ] + run( + cmd, + cwd=spec_dir, + env=env, + log_path=build_log, + summary=f"Building {bench_dir} with runspec (log: {build_log})", + ) + + try: + elf = select_built_elf(exe_dir, tune) + except RuntimeError as exc: + detail = explain_missing_elf(output_root, bench_dir, tune) + raise RuntimeError(str(exc) + detail) from exc + write_json(metadata_path, metadata) + return elf, build_log + + +def package_case(args): + cases = load_cases(args.cases_config) + if args.case not in cases: + choices = " ".join(sorted(cases)) + raise RuntimeError(f"unknown SPEC2006 case {args.case!r}; available cases: {choices}") + + spec_dir = Path(args.spec).resolve() + spec_cfg = Path(args.spec_config).resolve() + pkg_dir = Path(args.pkg_dir).resolve() if args.pkg_dir else None + out_dir = Path(args.out_dir).resolve() + log_dir = Path(args.log_dir).resolve() if args.log_dir else out_dir / "logs" + + cross_compile, detected_toolchain_root = resolve_cross_compile(args.cross_compile) + compiler_root = Path(args.compiler_root).resolve() if args.compiler_root else detected_toolchain_root + gnu_toolchain_root = Path(args.gnu_toolchain_root).resolve() if args.gnu_toolchain_root else detected_toolchain_root + env_jemalloc_root = os.environ.get("SPEC2006_JEMALLOC_ROOT") or os.environ.get("JEMALLOC_INSTALL_PATH") + if args.jemalloc_root: + jemalloc_root = Path(args.jemalloc_root).resolve() + elif env_jemalloc_root: + jemalloc_root = Path(env_jemalloc_root).resolve() + else: + jemalloc_root = (out_dir.parent / "jemalloc" / "install").resolve() + + jemalloc_library = jemalloc_root / "lib" / "libjemalloc.a" + if cfg_requires_jemalloc(spec_cfg) and not jemalloc_library.is_file(): + raise RuntimeError( + f"jemalloc library not found: {jemalloc_library}; " + "set SPEC2006_JEMALLOC_ROOT or JEMALLOC_INSTALL_PATH to a valid install prefix" + ) + + case = cases[args.case] + base_name = case["base_name"] + bench_dir = bench_dir_for_base(spec_dir, base_name) + input_set = input_set_for_case(case) + + elf, build_log = build_elf( + spec_dir, + bench_dir, + spec_cfg, + out_dir, + log_dir, + cross_compile, + args.tune, + args.jobs, + compiler_root, + gnu_toolchain_root, + jemalloc_root, + ) + exported_elf = export_elf_artifact(elf, args.case, out_dir) + status(f"Exported ELF: {exported_elf}") + + if args.elf_only: + return + + stage_root = out_dir / "spec-stage" / args.case + status(f"Staging inputs for {args.case}") + stage_inputs(spec_dir, bench_dir, base_name, input_set, stage_root) + + if pkg_dir is None: + raise RuntimeError("--pkg-dir is required unless --elf-only is set") + if pkg_dir.exists(): + shutil.rmtree(pkg_dir) + (pkg_dir / "spec").mkdir(parents=True) + + status(f"Packaging rootfs for {args.case}") + install_case_files(case, stage_root, pkg_dir / "spec") + install_runtime_binary(elf, base_name, pkg_dir) + write_runtime_files(pkg_dir, args.case, base_name, case.get("args", [])) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--cases-config") + parser.add_argument("--list-cases", action="store_true") + parser.add_argument("--input-set", choices=(*INPUT_SETS, "all"), default="all") + parser.add_argument("--case") + parser.add_argument("--spec") + parser.add_argument("--spec-config") + parser.add_argument("--pkg-dir") + parser.add_argument("--out-dir") + parser.add_argument("--cross-compile", default="riscv64-unknown-linux-gnu-") + parser.add_argument("--compiler-root") + parser.add_argument("--gnu-toolchain-root") + parser.add_argument("--jemalloc-root") + parser.add_argument("--log-dir") + parser.add_argument("--tune", default="base") + parser.add_argument("--jobs", default=str(os.cpu_count() or 1)) + parser.add_argument("--elf-only", action="store_true") + args = parser.parse_args() + + if args.list_cases: + if not args.cases_config: + parser.error("--cases-config is required with --list-cases") + try: + cases = filter_cases(load_cases(args.cases_config), args.input_set) + except Exception as exc: + parser.error(str(exc)) + print(" ".join(cases.keys())) + return + + required = ["cases_config", "case", "spec", "spec_config", "out_dir", "cross_compile"] + if not args.elf_only: + required.append("pkg_dir") + missing = [name for name in required if getattr(args, name) in (None, "")] + if missing: + parser.error("missing required arguments: " + ", ".join("--" + x.replace("_", "-") for x in missing)) + + try: + package_case(args) + except Exception as exc: + print(f"{progress_prefix()} error: {exc}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + main()