From 23e2a217226f73cb405cd2ae7936cb883ddee403 Mon Sep 17 00:00:00 2001 From: Jeff Nye Date: Mon, 30 Jun 2025 13:56:50 -0500 Subject: [PATCH] rescind spike_stf support --- traces/README.md | 315 +------------------------------------ traces/dhrystone_opt1.zstf | Bin 3367 -> 0 bytes traces/dhrystone_opt2.zstf | Bin 2827 -> 0 bytes traces/dhrystone_opt3.zstf | Bin 2827 -> 0 bytes 4 files changed, 6 insertions(+), 309 deletions(-) delete mode 100644 traces/dhrystone_opt1.zstf delete mode 100644 traces/dhrystone_opt2.zstf delete mode 100644 traces/dhrystone_opt3.zstf diff --git a/traces/README.md b/traces/README.md index 031e27b6..12807b72 100644 --- a/traces/README.md +++ b/traces/README.md @@ -1,27 +1,5 @@ # Generating Input for Olympia -## Table of Contents - -1. [Introduction](#introduction) -1. [JSON Inputs](#json-inputs) -1. [STF Inputs](#stf-inputs) -1. [Instrumenting Source for Tracing](#instrumenting-source-for-tracing) -1. [Generating Baremetal Traces](#generating-baremetal-traces) - 1. [Build Spike-STF](#build-spike-stf) - 1. [Generating the Baremetal Dhrystone Traces](#generating-the-baremetal-dhrystone-traces) -1. [Generating Linux Traces](#generating-linux-traces) - 1. [Building the Linux Dhrystone Elfs](#building-the-linux-dhrystone-elfs) - 1. [Building the Linux Collateral](#building-the-linux-collateral) - 1. [Booting Linux on Spike-STF](#booting-linux-on-spike-stf) - 1. [Updating the Root File System](#updating-the-root-file-system) - 1. [Invoke Linux and Generate the Traces](#invoke-linux-and-generate-the-traces) - 1. [Sample Session](#sample-session) -1. [Generating an STF Trace with Dromajo](#generating-an-stf-trace-with-dromajo) - 1. [Build an STF Capable Dromajo](#build-an-stf-capable-dromajo) - 1. [Instrument a Workload for Tracing](#instrument-a-workload-for-tracing) - -## Introduction - Olympia can take input in two formats: JSON and [STF](https://github.com/sparcians/stf_spec). @@ -33,16 +11,6 @@ STF format is the preferred format to represent a workload to run on Olympia. STFs are typically created by a RISC-V functional model that has been instrumented to generate one. -Two functional models which generate STFs are documented. -[Spike-STF](https://github.com/jeffnye-gh/cpm.riscv-isa-sim) - is the latest model, -[Dromajo](https://github.com/chipsalliance/dromajo) also generates -STFs. - -Spike-STF ISA suport is more recent. Spike-STF adds other features such as BBV generation. - -Documentation for trace generation is provided for both functional models. - ## JSON Inputs JSON inputs are typically generated by hand. There are no automated @@ -125,290 +93,18 @@ cd build Using the [stf_lib]() in the [Sparcians](https://github.com/sparcians) repo, Olympia is capable of reading a RISC-V STF trace generated from -a functional simulator. Included in Olympia (in this directory) are several trace files - -``` - - traces/dhrystone_opt1.zstf 1000 iterations of a baremetal Dhrystone - run with optimization set for 'Ground Rules'. - - traces/dhrystone_opt2.zstf 1000 iterations of a baremetal Dhrystone - run with optimization allowing in-lining. - - traces/dhrystone_opt3.zstf 1000 iterations of baremetal Dhrystone - run with optimization allowing in-lining - and LT. Baremetal - - - traces/core_riscv.zstf Hot spot of Coremark generated by Dromajo - - traces/dhrystone.zstf Hot spot of Dhrystone generated by Dromajo - - traces/core_riscv.zstf Hot spot of Coremark generated by Dromajo -``` +a functional simulator. Included in Olympia (in this directory) is a +trace of the "hot spot" of Dhrystone generated from the Dromajo +simulator. This directory also contains a trace of Coremark generated +similarly. -To run an STF file, provide the path to olympia: +To run the STF file, just provide it to olympia: ``` cd build -./olympia ../traces/dhrystone_opt1.zstf -./olympia ../traces/dhrystone_opt2.zstf -./olympia ../traces/dhrystone_opt3.zstf ./olympia ../traces/dhrystone.zstf ./olympia ../traces/core_riscv.zstf ``` -## Instrumenting Source for Tracing - -There are multiple ways to trigger tracing. The macro tracing scheme -instruments source code with trace boundary macros. These -macros are nops with known operand encodings comprehended by -the functional models. The macro tracing scheme supports baremetal and -linux application tracing. - -The source code is instrumented by insertion of `START_TRACE` and `STOP_TRACE`. - -For example: -``` main() { - // ... init code - - START_TRACE; - // Dhrystone benchmark code - STOP_TRACE; - - // ... teardown - } - -``` -The `START_TRACE` and `STOP_TRACE` macros are defined in `traces/stf_trace_gen/trace_macros.h`. - -Instructions between the macros will be recorded in the trace output. - -Spike-STF supports other tracing modes. Both Dromajo and Spike-STF support -the macro tracing mode. - ---------------------------------------------------------- -## Generating Baremetal Traces - -### Build Spike-STF -The first step to generating an STF with Spike-STF is to clone and build -the Spike-STF [repo](https://github.com/jeffnye-gh/cpm.riscv-isa-sim.git). - -This example uses the `riscv-perf-model/traces` directory as a working -directory. - -The steps are: clone the repo, download and add the baremetal compiler to your -path, and build/regress/install Spike-STF. - -The compiler steps are optional if you have `riscv64-unknown-elf-gcc` in -your path. - -```bash -cd riscv-perf-model/traces -git clone https://github.com/jeffnye-gh/cpm.riscv-isa-sim.git --recursive - -cd cpm.riscv-isa-sim -bash scripts/download-bm-compiler.sh -export PATH=`pwd`/riscv-embecosm-embedded-ubuntu2204-20250309/bin:$PATH -``` -Exit the conda environment, if enabled, before compiling Spike-STF. -``` -conda deactivate -conda deactivate - -mkdir -p build install && cd build -../configure --prefix=`pwd`/../install -make -j$(nproc) -make regress -make install -``` - -The regress target executes the [riscv-tests](https://github.com/riscv-software-src/riscv-tests) test suite. Pass/fail is reported. - -The compiler is a prebuilt RISC-V cross compiler from [Embecosm](https://embecosm.com/). - -There is detailed information in the Spike-STF repo, -[README_FORK.mk](https://github.com/jeffnye-gh/cpm.riscv-isa-sim/blob/spike_stf/README_FORK.md) and [USAGE.md](https://github.com/jeffnye-gh/cpm.riscv-isa-sim/blob/spike_stf/USAGE.md). - -### Generating the Baremetal Dhrystone Traces - -When Spike-STF is initially configured the dhrystone ELFs are created. If they need to be re-created: - -```bash -cd riscv-perf-model/traces/cpm.riscv-isa-sim -make -C dhrystone -``` - -This creates 3 versions of the dhrystone elf with 3 different levels of -optimization running 1000 iterations. The source code has been modified to -add the trace macros and to allow simplified execution under baremetal with -limited syscall support. - -A discussion of the 3 optimization levels is available in [USAGE.md](https://github.com/jeffnye-gh/cpm.riscv-isa-sim/blob/spike_stf/USAGE.md#dhrystone-optimization-discussion). - -Once the ELFs are built, traces are generated by: - -``` -cd riscv-perf-model/traces/cpm.riscv-isa-sim - -bash scripts/run-spike-stf.sh dhrystone/bin/dhrystone_opt1.1000.gcc.bare.riscv \ - dhrystone_opt1.zstf -bash scripts/run-spike-stf.sh dhrystone/bin/dhrystone_opt2.1000.gcc.bare.riscv \ - dhrystone_opt2.zstf -bash scripts/run-spike-stf.sh dhrystone/bin/dhrystone_opt3.1000.gcc.bare.riscv \ - dhrystone_opt3.zstf -``` - -The compressed trace outputs can then be run on olympia by - -``` - - -./olympia ../traces/cpm.riscv-isa-sim/trace_out/dhrystone_opt1.zstf -./olympia ../traces/cpm.riscv-isa-sim/trace_out/dhrystone_opt2.zstf -./olympia ../traces/cpm.riscv-isa-sim/trace_out/dhrystone_opt3.zstf -``` -## Generating Linux Traces - -### Building the Linux Dhrystone Elfs - -In order to compile applications for linux, you must have riscv64-unknown-linux-gnu-gcc in your path. - -``` -cd riscv-perf-model/traces/cpm.riscv-isa-sim -bash scripts/download-lnx-compiler.sh -export PATH=`pwd`/riscv64-embecosm-linux-gcc-ubuntu2204-20240407/bin:$PATH -``` - -To build the linux version of the Dhrystone benchmarks: -``` -cd riscv-perf-model/traces/cpm.riscv-isa-sim -make -C dhrystone bin-linux -``` - -Directory dhrystone/bin will contain: -``` -dhrystone/bin/dhrystone_opt1.1000.gcc.linux.riscv -dhrystone/bin/dhrystone_opt2.1000.gcc.linux.riscv -dhrystone/bin/dhrystone_opt3.1000.gcc.linux.riscv -``` - -### Building the Linux Collateral - -In order to generate linux based traces a linux environment is required as well as a linux cross compiler in your path. See above for the compiler. - -A linux environment consists of a bootloader, the linux kernel and a -root file system. - -The process to clone and build these components is contained in a script. -This is a lengthy process. - -```bash -cd riscv-perf-model/traces/cpm.riscv-isa-sim -bash scripts/build-linux-collateral.sh -``` - -Once complete, the directory `riscv-perf-model/traces/cpm.riscv-isa-sim/riscv-linux` will contain the files necessary to boot linux. -``` -fw_jump.elf -rootfs.cpio -Image -``` - -### Booting Linux on Spike-STF -With the linux components built, boot linux using the helper script: -``` -cd riscv-perf-model/traces/cpm.riscv-isa-sim -bash scripts/boot-linux.sh -``` -The credentials are root/root. - -Hitting control-c a few times will exit the simulator. Depending on what is -running under linux it is sometimes necessary to kill the spike PID. - -### Updating the Root File System -To trace applications under linux it is necessary to add them to the root -file system. This makes them available from the spike/linux console. - -In this example the 3 versions of dhrystone linux are built into the root -file system. - -This script builds the `dhrystone_optN.1000.gcc.linux.riscv` elfs, adds them to -the buildroot source tree, rebuilds rootfs, and copies the image to riscv-linux -for use in the next section. - -``` -cd riscv-perf-model/traces/cpm.riscv-isa-sim -bash scripts/build-trace-rootfs.sh -``` - -This script performs basic checking, and copies the dhrystone linux ELFS to -a location in the buildroot tree. - -``` -${BUILDROOT}/output/target/root/trace_elfs -``` - -This location ensures access to the elfs once the root file system has been recompiled and linux has been booted. - -### Invoke Linux and Generate the Traces - - -Once the new rootfs is built we boot linux on spike with tracing enabled from the -command line. We use the boot-linux.sh script with two additional -arguments. The first specifes the new rootfs and the second specifies the path -for the STF trace output. - -``` -cd riscv-perf-model/traces/cpm.riscv-isa-sim -bash scripts/boot-linux.sh --rootfs ./riscv-linux/trace_rootfs.cpio \ - --trace ./trace_out/linux_trace.zstf -``` -Once linux boots, enter the root/root credentials, then from the ash shell -cd to `trace_elfs and run the dhrystone_opt3.1000.gcc.bare.riscv.zstf - -### Sample Session - -A sample session: - -``` -Welcome to Buildroot -buildroot login: root -root -Password: root - -# cd trace_elfs -cd trace_elfs -# ls -ls -dhrystone_opt1.1000.gcc.linux.riscv dhrystone_opt3.1000.gcc.linux.riscv -dhrystone_opt2.1000.gcc.linux.riscv -# ./dhrystone_opt3.1000.gcc.linux.riscv - -...snip... --I: traced 241546 instructions -...snip... -Str_2_Loc: DHRYSTONE PROGRAM, 2'ND STRING - should be: DHRYSTONE PROGRAM, 2'ND STRING - -Measured time too small to obtain meaningful results -Please increase number of runs - -# -# ^C(spike) quit -``` - -Once you have exited spike and are returned to the main o/s, the trace_out -directory will hold the trace file. -``` --rw-r--r-- 1 random agroup 12097 Jan 1 00:00 linux_trace.zstf -``` - -Note _any_ trace-enabled ELF you run while in spike linux will be added to the -same trace file. - -This is useful in cases. - -For other use cases, check the USAGE.md file in the Spike-STF repo for -instructions on how to use initd to automate linux based trace generation. - -See [Automating Linux Tracing with INIT.d](https://github.com/jeffnye-gh/cpm.riscv-isa-sim/blob/spike_stf/USAGE.md#Automating-linux-tracing-with-initd) - - ------------------------------------------------------ ### Generating an STF Trace with Dromajo #### Build an STF-Capable Dromajo @@ -555,5 +251,6 @@ Now, run that trace on olympia: % ./olympia ../traces/stf_trace_gen/dromajo/run/dhry_riscv.zstf Running... olympia: STF file input detected + ... ``` diff --git a/traces/dhrystone_opt1.zstf b/traces/dhrystone_opt1.zstf deleted file mode 100644 index 9d1748bdf0a5723e1cf6c69e82f95b8bfe4844a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3367 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 diff --git a/traces/dhrystone_opt2.zstf b/traces/dhrystone_opt2.zstf deleted file mode 100644 index 38b4827916bf6e65bcfa4fbe1a0a903a92dc6f7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2827 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