Skip to content
Open
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
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
checkpoints
imgs/*.img
*.img
*.qcow2
__pycache__/
*.pyc
sim_outs
run_gen_snapshot.sh
gem5
bin
2 changes: 2 additions & 0 deletions Notion.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Find the Notion page for this project here with useful explanations for various aspects of the project:
https://www.notion.so/gem5-Checkpoint-Conversion-2af46d7f056e804d9dc0e3a1c4758184?source=copy_link
80 changes: 1 addition & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,2 @@
# QPoints
Please follow the instructions in this [README](https://www.notion.so/README-2ea46d7f056e80d1aeb5f644d6bb0204?source=copy_link) to run gem5 simulation using QFlex snapshots.

QPoints is a tool to generate a gem5 compatible checkpoints
using QEMU. This tool currently works for only ARM system.
This tool was created to reduce time spent in reaching
a state state of long running applcations.

### Requirements:
1. QEMU
2. Docker
3. Python3
- Jinja2 python module
4. gdb-multiarch
5. A disk image
6. (Optional) ARM Powered Apple Mac system. Needed this only to accelerate emulation.

### Setup:
1. Install docker, git, qemu-system packages on your host machine
```
sudo apt-get install git docker qemu-system
```
2. Run setup script which sets up directoris and builds a docker image
```
bash setup.sh
```
3. Download a disk image from Google Drive. Download script works in docker
environment. Follow below steps do get the image.
```
bash run_docker.sh
bash imgs/download_image.sh
exit
```
After running above set of commands `imgs` folder contains `ubuntu-arm.img` disk image.

Ubuntu image login user is `bgodala` and password is `1234`.

### Steps to create a checkpoint:
1. Launch QEMU emulation using the `run_ubuntu_linux.sh` file
```
bash run_docker.sh
bash run_ubuntu.sh
```
2. After reaching a steady state invoke the following command to create a checkpoint.
`gen_snapshot.sh` command works in the docker environment. Start the docker and then
invoke checkpoint generation command.
```
bash run_docker.sh
bash gen_snapshot.sh
exit
```

### Test Checkpoint:
1. To test checkpoint gem5 needs to be built. Use the following command to build gem5.

Start docker environment.
```
bash run_gem5_docker.sh
```
Build gem5.
```
cd gem5
scons -j8 build/ARM/gem5.opt
exit
```
If you encounter the following error while building gem5:
```
No such file or directory: "/qpoints/gem5/fatal: detected dubious ownership in repository at '/qpoints/gem5'\nTo add an exception for this directory, call:\n\n\tgit config --global --add safe.directory /qpoints/gem5/hooks"
```
You can fix this by following the information reported above:
```
git config --global --add safe.directory /qpoints/gem5
```


2. Run checkpoint in the docker environment.
```
bash run_gem5_docker.sh
bash run_gem5.sh
exit
```
File renamed without changes.
8 changes: 4 additions & 4 deletions docker/Dockerfile → archive/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#FROM arm64v8/ubuntu:latest
FROM ubuntu:latest
FROM ubuntu:24.04

# Update package lists
RUN apt-get update
Expand All @@ -8,10 +8,10 @@ RUN apt-get update
RUN apt-get install -y gdb-multiarch
RUN apt-get install -y python3
RUN apt-get install -y python3-pip
RUN apt-get install -y qemu
RUN apt-get install -y qemu-utils
RUN apt-get install -y qemu-system
RUN pip3 install jinja2
RUN pip3 install gdown
RUN apt-get install -y python3-jinja2
RUN pip3 install --break-system-packages gdown
RUN apt-get install -y vim

# Set the entrypoint to start a shell
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions archive/run_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# We don't need a separate docker. You the docker contrainer for qflex!
#docker run --rm --privileged --net host -v $(pwd):/qpoints -it qpoints:1.0
1 change: 1 addition & 0 deletions archive/run_gem5_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker run --volume $(pwd):/qpoints --rm -it cloudsuitetest/gem5-qpoints:1.0
3 changes: 2 additions & 1 deletion run_ubuntu_linux.sh → archive/run_ubuntu_linux.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ qemu-system-aarch64 -nographic -machine virt,gic-version=3 -m 16384M -cpu cortex
-snapshot \
-serial mon:stdio \
-qmp tcp:localhost:4444,server,nowait -monitor telnet::45454,server,nowait \
-drive file=imgs/ubuntu-arm.img,if=none,id=drive0,cache=writeback -device virtio-blk-device,indirect_desc=false,event_idx=false,drive=drive0,bootindex=0 \
-drive file=/qpoints/imgs/ubuntu-arm.img,if=none,id=drive0,cache=writeback -device virtio-blk-device,indirect_desc=false,event_idx=false,drive=drive0,bootindex=0 \
-nic none \
-bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd

#-kernel kernel_arm_built_img -append "root=/dev/vda2 ro splash quiet" \
#-initrd initrd.img \

File renamed without changes.
187 changes: 187 additions & 0 deletions run_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#!/usr/bin/env bash
set -euo pipefail

start_time="$(date +%s)"
report_timing() {
local exit_code=$?
local end_time
end_time="$(date +%s)"
local elapsed=$((end_time - start_time))
echo "[${snapshot:-unknown}] run_all.sh completed in ${elapsed}s (exit code: ${exit_code})"
}
trap report_timing EXIT

qemu_pid=""
cleanup_children() {
if [[ -n "$qemu_pid" ]]; then
kill "$qemu_pid" >/dev/null 2>&1 || true
fi
}
trap 'cleanup_children; exit 130' INT TERM

usage() {
cat <<'EOF'
Usage: run_all.sh --qflex-ckp-dir DIR --gem5-ckp-dir DIR --cores N --mem MB \
--base IMAGE --snapshot NAME [--ssh-host HOST] [--ssh-user USER] \
[--monitor-base PORT] [--qmp-base PORT] [--ssh-base PORT]

Example:
run_all.sh --qflex-ckp-dir qflex_checkpoints --gem5-ckp-dir gem5_checkpoints \
--cores 4 --mem 16384 --base web_search.qcow2 --snapshot snapshot_0
run_all.sh --qflex-ckp-dir qflex_checkpoints --gem5-ckp-dir gem5_checkpoints \
--cores 4 --mem 16384 --base web_search.qcow2 --snapshot snapshot_0 \
--ssh-host 127.0.0.1 --ssh-user ubuntu --monitor-base 45454 --qmp-base 4444 \
--ssh-base 2222
EOF
}

qflex_ckp_dir=""
gem5_ckp_dir=""
cores=""
mem=""
base=""
snapshot=""
ssh_host="127.0.0.1"
ssh_user="qflex"
monitor_base="45454"
qmp_base="4444"
ssh_base="2222"

while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--qflex-ckp-dir)
qflex_ckp_dir="${2:-}"
shift 2
;;
--gem5-ckp-dir)
gem5_ckp_dir="${2:-}"
shift 2
;;
--cores)
cores="${2:-}"
shift 2
;;
--mem)
mem="${2:-}"
shift 2
;;
--base)
base="${2:-}"
shift 2
;;
--snapshot)
snapshot="${2:-}"
shift 2
;;
--ssh-host)
ssh_host="${2:-}"
shift 2
;;
--ssh-user)
ssh_user="${2:-}"
shift 2
;;
--monitor-base)
monitor_base="${2:-}"
shift 2
;;
--qmp-base)
qmp_base="${2:-}"
shift 2
;;
--ssh-base)
ssh_base="${2:-}"
shift 2
;;
*)
echo "Unknown argument: $1" >&2
usage
exit 1
;;
esac
done

if [[ -z "$qflex_ckp_dir" || -z "$gem5_ckp_dir" || -z "$cores" || -z "$mem" || -z "$base" || -z "$snapshot" ]]; then
echo "Missing required arguments." >&2
usage
exit 1
fi

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
run_dir="${qflex_ckp_dir}/run"

snapshot_idx=0
if [[ "$snapshot" =~ _([0-9]+)$ ]]; then
snapshot_idx="${BASH_REMATCH[1]}"
fi

monitor_port=$((monitor_base + snapshot_idx))
qmp_port=$((qmp_base + snapshot_idx))
ssh_port=$((ssh_base + snapshot_idx))

if [[ ! -d "$run_dir" ]]; then
echo "[${snapshot}] run directory not found: $run_dir" >&2
exit 1
fi

if [[ ! -f "$run_dir/run_qemu_emu.sh" ]]; then
cp -u "$ROOT_DIR/scripts/qflex/run_qemu_emu.sh" "$run_dir/"
fi

chmod +x "$run_dir/run_qemu_emu.sh"
echo "[${snapshot}] start qemu in the background"
(
cd "$run_dir"
exec ./run_qemu_emu.sh "$cores" "$mem" "$base" "$snapshot" \
"$monitor_port" "$qmp_port" "$ssh_port" > "qemu_emu_${snapshot}.log" 2>&1
) &
qemu_pid=$!

# Wait for SSH to become available before proceeding.
while true; do
if SSHPASS="qflex" sshpass -e ssh -o ConnectTimeout=2 -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null -p "$ssh_port" "${ssh_user}@${ssh_host}" "true" \
>/dev/null 2>&1; then
break
fi
echo "[${snapshot}] waiting for vm ssh (${ssh_user}@${ssh_host}:${ssh_port})..."
sleep 0.5
done

img_dest_dir="${gem5_ckp_dir}/${snapshot}"
tmp_log="${run_dir}/gen_snapshot_${snapshot}.log"

echo "[${snapshot}] start generating gem5 checkpoint"
"$ROOT_DIR/gen_snapshot.sh" "$gem5_ckp_dir" "$snapshot" "" 0 "$cores" "$monitor_port" \
2> "$tmp_log"

if [[ -d "$img_dest_dir" ]]; then
mv "$tmp_log" "$img_dest_dir/gen_snapshot_${snapshot}.log"
else
echo "[${snapshot}] Destination directory does not exist: $img_dest_dir" >&2
exit 1
fi

if [[ ! -f "$run_dir/convert.sh" ]]; then
cp -u "$ROOT_DIR/scripts/qflex/convert.sh" "$run_dir/"
fi

(
cd "$run_dir"
chmod +x convert.sh
echo "[${snapshot}] start converting the disk image"
./convert.sh "$base" "$snapshot"
)

img_src="${run_dir}/${snapshot}.img"
if [[ -f "$img_src" ]]; then
echo "[${snapshot}] moving the raw disk image to the destination folder"
mv "$img_src" "$img_dest_dir/."
else
echo "[${snapshot}] Converted image not found: $img_src" >&2
exit 1
fi
Loading