Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 28 additions & 25 deletions workloads/linux/spec2006/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
# SPEC CPU2006 Linux workload

`workloads/linux/spec2006` now builds SPEC CPU2006 workloads with the original
SPEC tools (`runspec`) against an external SPEC installation.
SPEC tools (`runspec`) from a prepared workspace installed from a SPEC ISO.

## Build one case

Either point `SPEC` at the SPEC tree:
Point `SPEC2006_ISO` at the SPEC ISO:

```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
make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN
```

`BENCH` may also be a full case name from `spec06.json`:

```sh
make linux/spec2006 BENCH=astar_biglakes SPEC=/path/to/cpu2006 -jN
make linux/spec2006 BENCH=astar_biglakes SPEC2006_ISO=/path/to/cpu2006.iso -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
1. Run `make spec2006-prepare SPEC2006_ISO=/path/to/cpu2006.iso` to install a build-local
writable SPEC workspace under `build/linux-workloads/spec2006/spec-src`.
2. Generate a build-local SPEC cfg copy under the case build directory.
3. Inject `output_root` into that cfg so SPEC build artifacts stay under this
repository instead of modifying the prepared SPEC workspace.
4. Run `runspec --action build` inside the prepared workspace.
5. Export the built SPEC ELF, package the benchmark plus input files into the
Linux rootfs, and produce:

```text
Expand All @@ -41,15 +37,15 @@ build/linux-workloads/spec2006/<case>/fw_payload.bin
Export all selected cases to `build/images/spec2006`:

```sh
make spec2006-images SPEC=/path/to/cpu2006 -jN
make spec2006-images SPEC2006_ISO=/path/to/cpu2006.iso -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
make spec2006-images SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=test -jN
make spec2006-images SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=all -jN
```

Selected SPEC cases are built one by one to avoid concurrent `runspec`
Expand All @@ -76,7 +72,7 @@ Override the destination with `SPEC2006_IMAGE_DIR=/path/to/image`.
Build one case without packaging it into the Linux rootfs:

```sh
make spec2006-elf BENCH=astar INPUT=biglakes SPEC=/path/to/cpu2006 -jN
make spec2006-elf BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN
```

This writes:
Expand All @@ -88,17 +84,17 @@ build/linux-workloads/spec2006/<case>/elf/<case>.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
make spec2006-elfs SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=ref -jN
make spec2006-elfs SPEC2006_ISO=/path/to/cpu2006.iso 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
make -f rules.mk spec2006-elf BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN
make -f rules.mk spec2006-elfs SPEC2006_ISO=/path/to/cpu2006.iso SPEC2006_INPUT=all -jN
```

## Configuration
Expand All @@ -113,7 +109,7 @@ Override it with:

```sh
make linux/spec2006 BENCH=bzip2_source \
SPEC=/path/to/cpu2006 \
SPEC2006_ISO=/path/to/cpu2006.iso \
SPEC2006_CFG=/path/to/other.cfg \
-jN
```
Expand Down Expand Up @@ -170,7 +166,14 @@ SPEC2006 builds keep console output concise. Detailed logs are written to:

## Notes

- The original SPEC tree is used read-only for sources and input data.
- The original SPEC ISO is used read-only as installation media.
- `runspec` is never executed against the original ISO contents; it only sees the
prepared workspace under `build/linux-workloads/spec2006/spec-src`.
- The prepared workspace is installed into a writable build directory before
any SPEC tools are executed.
- Installation staging uses a temporary local filesystem; override
`SPEC2006_PREPARE_TMPDIR` if `/tmp` is not suitable.
- `xorriso` is required to extract the SPEC ISO during `spec2006-prepare`.
- 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;
Expand Down
54 changes: 54 additions & 0 deletions workloads/linux/spec2006/prepare-spec-workspace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
set -euo pipefail

source_spec_iso="$(realpath "$1")"
prepared_spec_root="$(realpath -m "$2")"

prepare_dir="$(dirname "$prepared_spec_root")"
mkdir -p "$prepare_dir"
chmod -R u+rwX "$prepared_spec_root" 2>/dev/null || true
rm -rf "$prepared_spec_root"

temp_root=""
cleanup() {
if [ -n "$temp_root" ]; then
chmod -R u+rwX "$temp_root" 2>/dev/null || true
rm -rf "$temp_root" 2>/dev/null || true
fi
}
trap cleanup EXIT

if ! command -v xorriso >/dev/null 2>&1; then
echo "xorriso is required to extract $source_spec_iso" >&2
exit 1
fi

tmp_parent="${SPEC2006_PREPARE_TMPDIR:-${TMPDIR:-/tmp}}"
mkdir -p "$tmp_parent"
temp_root="$(mktemp -d "$tmp_parent/spec-prepare.XXXXXX")"

media_root="$temp_root/media"
staged_spec_root="$temp_root/spec-src"
mkdir -p "$media_root"

xorriso -osirrox on -indev "$source_spec_iso" -extract / "$media_root" >/dev/null

if ! [ -f "$media_root/install.sh" ]; then
echo "install.sh not found in $source_spec_iso" >&2
exit 1
fi

(
cd "$media_root"
env -u SPEC sh ./install.sh -f -d "$staged_spec_root"
)

mkdir -p "$prepared_spec_root"
cp -R "$staged_spec_root"/. "$prepared_spec_root"/
chmod -R u+rwX "$prepared_spec_root"

(
cd "$prepared_spec_root"
. ./shrc >/dev/null
bin/relocate >/dev/null
)
56 changes: 31 additions & 25 deletions workloads/linux/spec2006/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ 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_SOURCE_SPEC_ISO := $(SPEC2006_ISO)
SPEC2006_PREPARED_SPEC_ROOT := $(SPEC2006_BUILD_DIR)/spec-src
SPEC2006_SOURCE_SPEC_HASH := $(shell printf '%s\n' "$(SPEC2006_SOURCE_SPEC_ISO)" | sha256sum | cut -d ' ' -f 1)
SPEC2006_PREPARE_STAMP := $(SPEC2006_BUILD_DIR)/spec-src.$(SPEC2006_SOURCE_SPEC_HASH).prepared
SPEC2006_PREPARE_SCRIPT := $(SPEC2006_WORKLOAD_DIR)/prepare-spec-workspace.sh
SPEC2006_CROSS_COMPILE ?= riscv64-unknown-linux-gnu-
SPEC2006_COMPILER_ROOT ?=
SPEC2006_GNU_TOOLCHAIN_ROOT ?=
Expand Down Expand Up @@ -40,19 +44,14 @@ SPEC2006_DEFAULT_DTB_STAMP := $(SPEC2006_BUILD_DIR)/dtb.$(shell printf '%s\n' "$

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"; \
spec2006-check-spec-iso:
@if [ -z "$(SPEC2006_SOURCE_SPEC_ISO)" ]; then \
echo "SPEC2006_ISO is required, for example:"; \
echo " make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -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"; \
if ! [ -f "$(SPEC2006_SOURCE_SPEC_ISO)" ]; then \
echo "SPEC ISO path does not exist: $(SPEC2006_SOURCE_SPEC_ISO)"; \
exit 1; \
fi; \
if ! [ -f "$(SPEC2006_CFG)" ]; then \
Expand All @@ -68,6 +67,13 @@ spec2006-check-spec-dir:
*) echo "SPEC2006_INPUT must be one of: ref, train, test, all"; exit 1 ;; \
esac

spec2006-prepare: $(SPEC2006_PREPARE_STAMP)

$(SPEC2006_PREPARE_STAMP): $(SPEC2006_PREPARE_SCRIPT) $(SPEC2006_SOURCE_SPEC_ISO) | spec2006-check-spec-iso
@printf '$(SPEC2006_PROGRESS_PREFIX) Preparing SPEC workspace at $(SPEC2006_PREPARED_SPEC_ROOT)\n'
@bash "$(SPEC2006_PREPARE_SCRIPT)" "$(SPEC2006_SOURCE_SPEC_ISO)" "$(SPEC2006_PREPARED_SPEC_ROOT)"
@touch "$@"

$(SPEC2006_DEFAULT_DTB_STAMP):
@mkdir -p "$(@D)"
@rm -f "$(SPEC2006_BUILD_DIR)"/dtb.*
Expand All @@ -78,7 +84,7 @@ $(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)
$(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: $(SPEC2006_PREPARE_STAMP) $$(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))" \
Expand All @@ -87,7 +93,7 @@ $(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: spec2006-check-spec-dir $$(SPEC2006_HEL
SPEC2006_PROGRESS_K="$$(SPEC2006_PROGRESS_K)" \
SPEC2006_PROGRESS_N="$$(SPEC2006_PROGRESS_N)" \
SPEC2006_CASE="$(1)" \
SPEC2006="$$(SPEC2006_SPEC_ROOT)" \
SPEC2006="$$(SPEC2006_PREPARED_SPEC_ROOT)" \
SPEC2006_CASE_CONFIG="$$(abspath $$(SPEC2006_CASE_CONFIG))" \
SPEC2006_CFG="$$(abspath $$(SPEC2006_CFG))" \
SPEC2006_COMPILER_ROOT="$$(SPEC2006_COMPILER_ROOT)" \
Expand All @@ -98,12 +104,12 @@ $(SPEC2006_BUILD_DIR)/$(1)/elf/$(1).elf: spec2006-check-spec-dir $$(SPEC2006_HEL
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
$(SPEC2006_BUILD_DIR)/$(1)/rootfs.cpio: $(SPEC2006_PREPARE_STAMP) $$(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="$$(SPEC2006_PREPARED_SPEC_ROOT)" \
SPEC2006_CASE_CONFIG="$$(abspath $$(SPEC2006_CASE_CONFIG))" \
SPEC2006_CFG="$$(abspath $$(SPEC2006_CFG))" \
SPEC2006_COMPILER_ROOT="$$(SPEC2006_COMPILER_ROOT)" \
Expand Down Expand Up @@ -145,23 +151,23 @@ endef

$(foreach case,$(SPEC2006_ALL_CASES),$(eval $(call add_spec2006_case,$(case))))

linux/spec2006: spec2006-check-spec-dir
linux/spec2006: spec2006-check-spec-iso
@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"; \
echo "Usage: make linux/spec2006 BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \
echo " or: make linux/spec2006 BENCH=astar_biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \
exit 1; \
fi
@$(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" GCPT_DEFAULT_DTB="$(SPEC2006_DEFAULT_DTB)" $(SPEC2006_BUILD_DIR)/$(SPEC2006_CASE)/fw_payload.bin

spec2006-elf: spec2006-check-spec-dir
spec2006-elf: spec2006-check-spec-iso
@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"; \
echo "Usage: make spec2006-elf BENCH=astar INPUT=biglakes SPEC2006_ISO=/path/to/cpu2006.iso -jN"; \
echo " or: make spec2006-elf BENCH=astar_biglakes SPEC2006_ISO=/path/to/cpu2006.iso -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
spec2006-elfs: spec2006-check-spec-iso
@if [ -z "$(SPEC2006_SELECTED_CASES)" ]; then \
echo "No SPEC2006 cases selected by SPEC2006_INPUT=$(SPEC2006_INPUT)"; \
exit 1; \
Expand All @@ -170,7 +176,7 @@ spec2006-elfs: spec2006-check-spec-dir
$(MAKE) --no-print-directory -f "$(SPEC2006_RECURSE_MAKEFILE)" "$(SPEC2006_BUILD_DIR)/$$case/elf/$$case.elf" || exit $$?; \
done

spec2006-images: spec2006-check-spec-dir
spec2006-images: spec2006-check-spec-iso
@if [ -z "$(SPEC2006_IMAGE_CASES)" ]; then \
echo "No SPEC2006 cases selected by SPEC2006_INPUT=$(SPEC2006_INPUT)"; \
exit 1; \
Expand All @@ -183,4 +189,4 @@ spec2006-images: spec2006-check-spec-dir
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
.PHONY: linux/spec2006 spec2006-check-spec-iso spec2006-prepare spec2006-elf spec2006-elfs spec2006-images
Loading