This commit is contained in:
Carlos Gutierrez
2025-10-04 23:43:11 -04:00
parent e3663eb573
commit 878f03dd22
11 changed files with 234 additions and 18208 deletions

104
README.md
View File

@@ -3,19 +3,99 @@
This repo holds **all scripts, commands, and logs** for Phase 3.
## Order of operations
1) `scripts/00_env.sh` sets env vars used by all scripts
2) `scripts/10_run_one.sh` run a single experiment with clear args
3) `scripts/20_sweep.sh` run the full matrix
4) `scripts/30_extract_csv.sh` collect gem5 stats → CSV
5) `scripts/40_energy_post.py` compute Energy/Power/**EDP=J×s**
6) `scripts/50_plot_epi.py` / `scripts/51_plot_edp_tinyml.py` figures
7) `scripts/60_bundle_logs.sh` bundle terminal + stats excerpts
8) (optional) `scripts/70_diff_table.py` drowsy vs non-drowsy deltas
### 1. Setup Environment
```bash
sh scripts/env.sh
```
**Check logs**: `cat logs/env.txt` - Should show environment variables and "READY" message
### 2. Build Workloads
```bash
sh scripts/build_workloads.sh
```
**Check logs**: Look for "All workloads compiled successfully!" and verify binaries exist:
```bash
ls -la /home/carlos/projects/gem5/gem5-run/
```
### 3. Test Single Run
```bash
sh scripts/run_one.sh tinyml_kws big high 0 1MB
```
**Check logs**:
- Verify stats.txt has content: `ls -l /home/carlos/projects/gem5/gem5-data/SmartEdgeAI/results/tinyml_kws_big_high_l21MB_d0/stats.txt`
- Check simulation output: `cat logs/tinyml_kws_big_high_l21MB_d0.stdout.log`
- Check for errors: `cat logs/tinyml_kws_big_high_l21MB_d0.stderr.log`
### 4. Run Full Matrix
```bash
sh scripts/sweep.sh
```
**Check logs**: Monitor progress and verify all combinations complete:
```bash
ls -la /home/carlos/projects/gem5/gem5-data/SmartEdgeAI/results/
```
### 5. Extract Statistics
```bash
sh scripts/extract_csv.sh
```
**Check logs**: Verify CSV was created with data:
```bash
head -5 /home/carlos/projects/gem5/gem5-data/SmartEdgeAI/results/summary.csv
```
### 6. Compute Energy Metrics
```bash
python3 scripts/energy_post.py
```
**Check logs**: Verify energy calculations:
```bash
head -5 /home/carlos/projects/gem5/gem5-data/SmartEdgeAI/results/summary_energy.csv
```
### 7. Generate Plots
```bash
python3 scripts/plot_epi.py
python3 scripts/plot_edp_tinyml.py
```
**Check logs**: Verify plots were created:
```bash
ls -la /home/carlos/projects/gem5/gem5-data/SmartEdgeAI/results/fig_*.png
```
### 8. Bundle Logs
```bash
sh scripts/bundle_logs.sh
```
**Check logs**: Verify bundled logs:
```bash
cat logs/TERMINAL_EXCERPTS.txt
cat logs/STATS_EXCERPTS.txt
```
### 9. (Optional) Generate Delta Analysis
```bash
python3 scripts/diff_table.py
```
**Check logs**: Verify delta calculations:
```bash
head -5 results/phase3_drowsy_deltas.csv
```
## Paths assumed
- gem5 binary: `../../build/ARM/gem5.opt`
- config: `../../scripts/hetero_big_little.py`
- workloads: `../../gem5-run/{tinyml_kws,sensor_fusion,aes_ccm,attention_kernel}`
- gem5 binary: `/home/carlos/projects/gem5/build/ARM/gem5.opt`
- config: `scripts/hetero_big_little.py`
- workloads: `/home/carlos/projects/gem5/gem5-run/{tinyml_kws,sensor_fusion,aes_ccm,attention_kernel}`
All output is under `iot/results` and `iot/logs`.
## Output Locations
- **Results**: `/home/carlos/projects/gem5/gem5-data/SmartEdgeAI/results/` (mirrored to `results/`)
- **Logs**: `/home/carlos/projects/gem5/gem5-data/SmartEdgeAI/logs/` (mirrored to `logs/`)
## Troubleshooting
- **Empty stats.txt**: Check gem5 simulation logs for errors
- **Missing binaries**: Re-run `scripts/build_workloads.sh`
- **Permission errors**: Ensure scripts are executable: `chmod +x scripts/*.sh`
- **Path issues**: Verify `ROOT` variable in `scripts/env.sh` points to correct gem5 installation

View File

@@ -0,0 +1,29 @@
#!/bin/bash
set -eu
. "$(dirname "$0")/env.sh"
echo "[build_workloads] Compiling all workloads..."
# Compile tinyml_kws
echo "[build_workloads] Compiling tinyml_kws..."
arm-linux-gnueabihf-gcc -O2 -static -o "$RUN/tinyml_kws" \
"$(dirname "$0")/../workloads/tinyml_kws.c" -lm
# Compile sensor_fusion
echo "[build_workloads] Compiling sensor_fusion..."
arm-linux-gnueabihf-gcc -O2 -static -o "$RUN/sensor_fusion" \
"$(dirname "$0")/../workloads/sensor_fusion.c" -lm
# Compile aes_ccm
echo "[build_workloads] Compiling aes_ccm..."
arm-linux-gnueabihf-gcc -O2 -static -o "$RUN/aes_ccm" \
"$(dirname "$0")/../workloads/aes_ccm.c"
# Compile attention_kernel
echo "[build_workloads] Compiling attention_kernel..."
arm-linux-gnueabihf-gcc -O2 -static -o "$RUN/attention_kernel" \
"$(dirname "$0")/../workloads/attention_kernel.c" -lm
echo "[build_workloads] All workloads compiled successfully!"
echo "[build_workloads] Binaries created in $RUN/"
ls -la "$RUN/"

View File

@@ -6,22 +6,34 @@ TE="$LOG_DATA/TERMINAL_EXCERPTS.txt"
SE="$LOG_DATA/STATS_EXCERPTS.txt"
: > "$TE"; : > "$SE"
log_count=0
for f in "$LOG_DATA"/*.stdout.log; do
[ -f "$f" ] || continue
log_count=$((log_count + 1))
echo "===== $(basename "$f") =====" >> "$TE"
(head -n 20 "$f"; echo "..."; tail -n 20 "$f") >> "$TE"
echo >> "$TE"
done
if [ $log_count -eq 0 ]; then
echo "[bundle] WARNING: No stdout.log files found in $LOG_DATA"
fi
stats_count=0
for d in "$OUT_DATA"/*; do
[ -d "$d" ] || continue
S="$d/stats.txt"
[ -f "$S" ] || continue
stats_count=$((stats_count + 1))
echo "===== $(basename "$d") =====" >> "$SE"
awk '/^sim_seconds|^system\.cpu\.ipc|^system\.cpu0\.ipc|^system\.cpu\.numCycles|^system\.cpu0\.numCycles|^system\.cpu\.commit\.committedInsts|^system\.cpu0\.commit\.committedInsts|^system\.l2\.overall_miss_rate::total/' "$S" >> "$SE"
echo >> "$SE"
done
if [ $stats_count -eq 0 ]; then
echo "[bundle] WARNING: No stats.txt files found in $OUT_DATA"
fi
# mirror to repo
cp "$TE" "$LOG_IOT/TERMINAL_EXCERPTS.txt"
cp "$SE" "$LOG_IOT/STATS_EXCERPTS.txt"

View File

@@ -16,6 +16,10 @@ E_MEM_PJ = 600.0
DROWSY_SCALE = 0.85
rows = []
if not os.path.exists(src):
print(f"[energy] ERROR: Source file {src} does not exist")
exit(1)
with open(src) as f:
r = csv.DictReader(f)
for row in r:
@@ -43,6 +47,10 @@ with open(src) as f:
)
rows.append(row)
if not rows:
print(f"[energy] ERROR: No data found in {src}")
exit(1)
for path in (dst_data, dst_iot):
with open(path, "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=list(rows[0].keys()))

View File

@@ -12,7 +12,7 @@ for d in "$OUT_DATA"/*; do
W=$(echo "$base" | cut -d'_' -f1)
CORE=$(echo "$base" | cut -d'_' -f2)
DVFS=$(echo "$base" | cut -d'_' -f3)
L2=$(echo "$base" | sed -E 's/.*_l2([^_]+).*/\1/')
L2=$(echo "$base" | sed -E 's/.*l2([^_]+).*/\1/')
DROW=$(echo "$base" | sed -E 's/.*_d([01]).*/\1/')
S="$d/stats.txt"

View File

@@ -15,6 +15,8 @@ ap.add_argument("--mem", default="16GB")
ap.add_argument("--l2", default="1MB")
ap.add_argument("--dvfs", choices=["high","low"], default="high")
ap.add_argument("--drowsy", type=int, choices=[0,1], default=0)
ap.add_argument("--core", choices=["big","little","hybrid"], default="big")
ap.add_argument("--outdir", default="m5out")
args = ap.parse_args()
# -------------------------------
@@ -30,12 +32,15 @@ system = System(
)
# -------------------------------
# CPU cluster: 1 big + 2 little
# CPU cluster: Configure based on core type
# -------------------------------
big = O3CPU(cpu_id=0)
little1 = TimingSimpleCPU(cpu_id=1)
little2 = TimingSimpleCPU(cpu_id=2)
system.cpu = [big, little1, little2]
if args.core == "big":
system.cpu = [O3CPU(cpu_id=0)]
elif args.core == "little":
system.cpu = [TimingSimpleCPU(cpu_id=0)]
elif args.core == "hybrid":
# 1 big + 1 little
system.cpu = [O3CPU(cpu_id=0), TimingSimpleCPU(cpu_id=1)]
# -------------------------------
# Cache hierarchy
@@ -80,9 +85,20 @@ proc = Process()
proc.executable = args.cmd
proc.cmd = [args.cmd]
proc.env = {'GLIBC_TUNABLES': 'glibc.pthread.rseq=0'}
for c in system.cpu:
c.workload = proc
c.createThreads()
# Only assign workload to the first CPU (primary execution)
system.cpu[0].workload = proc
system.cpu[0].createThreads()
# Other CPUs remain idle
for i in range(1, len(system.cpu)):
system.cpu[i].workload = SEWorkload.init_compatible("hello")
system.cpu[i].createThreads()
# -------------------------------
# Stats configuration
# -------------------------------
m5.stats.addStatVisitor(m5.stats.TextStatsVisitor(args.outdir + "/stats.txt"))
# -------------------------------
# Instantiate and simulate

View File

@@ -1,8 +1,11 @@
cat > /home/carlos/projects/gem5/gem5-run/tinyml_kws << 'SH'
#!/bin/bash
# placeholder workload; swap later for your real binary
for i in $(seq 1 2000000); do :; done
echo "tinyml_kws: done"
SH
chmod +x /home/carlos/projects/gem5/gem5-run/tinyml_kws
set -eu
. "$(dirname "$0")/env.sh"
# Compile the actual tinyml_kws workload
echo "[tinyml_kws] Compiling workload..."
arm-linux-gnueabihf-gcc -O2 -static -o "$RUN/tinyml_kws" \
"$(dirname "$0")/../workloads/tinyml_kws.c" -lm
echo "[tinyml_kws] Binary created at $RUN/tinyml_kws"

18181
tree.log

File diff suppressed because it is too large Load Diff

21
workloads/aes_ccm.c Normal file
View File

@@ -0,0 +1,21 @@
#include <stdio.h>
#include <string.h>
int main() {
printf("[aes_ccm] Starting AES-CCM encryption workload...\n");
volatile unsigned char data[1024];
volatile unsigned char key[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
for (int round = 0; round < 1000000; round++) {
// Simulate AES-like operations
for (int i = 0; i < 1024; i++) {
data[i] = (data[i] ^ key[i % 16]) + (round & 0xFF);
}
if (round % 200000 == 0) {
printf("[aes_ccm] progress: %d rounds\n", round);
}
}
printf("[aes_ccm] Done! final byte=%d\n", data[0]);
return 0;
}

View File

@@ -0,0 +1,23 @@
#include <stdio.h>
#include <math.h>
int main() {
printf("[attention_kernel] Starting attention mechanism workload...\n");
volatile double attention[64][64];
volatile double sum = 0.0;
for (int iter = 0; iter < 500000; iter++) {
// Simulate attention computation
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 64; j++) {
attention[i][j] = sin(i * 0.1) * cos(j * 0.1) + iter * 0.001;
sum += attention[i][j];
}
}
if (iter % 100000 == 0) {
printf("[attention_kernel] progress: %d iterations\n", iter);
}
}
printf("[attention_kernel] Done! sum=%f\n", sum);
return 0;
}

15
workloads/sensor_fusion.c Normal file
View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include <math.h>
int main() {
printf("[sensor_fusion] Starting sensor fusion workload...\n");
volatile double sum = 0.0;
for (int i = 0; i < 15000000; i++) {
sum += sqrt(i * 0.001) * log(i + 1);
if (i % 3000000 == 0) {
printf("[sensor_fusion] progress: %d iterations\n", i);
}
}
printf("[sensor_fusion] Done! sum=%f\n", sum);
return 0;
}