Skip to content

Fix ARM64 corpus exec-time coverage #16

Fix ARM64 corpus exec-time coverage

Fix ARM64 corpus exec-time coverage #16

name: ARM64 Baseline Benchmark
on:
workflow_dispatch:
permissions:
contents: read
jobs:
baseline:
timeout-minutes: 120
runs-on: ubuntu-24.04-arm
env:
BPFTOOL_BIN: micro/build/vendor/bpftool/bpftool
MICRO_OUTPUT: micro/results/arm64_pure_jit.json
MICRO_LLVMBPF_FALLBACK: micro/results/arm64_pure_jit_llvmbpf_only.json
MICRO_KERNEL_FALLBACK: micro/results/arm64_pure_jit_kernel_only.json
CORPUS_RESULTS_DIR: corpus/results/arm64
CORPUS_CODE_SIZE_OUTPUT: corpus/results/arm64/real_world_code_size_libbpf_bootstrap_arm64.json
CORPUS_CODE_SIZE_REPORT: corpus/results/arm64/real_world_code_size_libbpf_bootstrap_arm64.md
CORPUS_EXEC_OUTPUT: corpus/results/arm64/real_world_exec_time_libbpf_bootstrap_arm64.json
CORPUS_EXEC_REPORT: corpus/results/arm64/real_world_exec_time_libbpf_bootstrap_arm64.md
PREFLIGHT_DIR: artifacts/arm64-baseline/preflight
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Update required submodules
run: |
git submodule sync -- vendor/llvmbpf vendor/libbpf vendor/bpftool
git submodule update --init --depth 1 \
vendor/llvmbpf \
vendor/libbpf \
vendor/bpftool
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
binutils-dev \
build-essential \
clang \
cmake \
libbpf-dev \
libcap-dev \
libelf-dev \
libyaml-cpp-dev \
llvm \
llvm-dev \
pkg-config \
python3-pyelftools \
python3-yaml \
zlib1g-dev \
libzstd-dev
- name: Build micro runner, BPF programs, and vendored bpftool
run: |
make -C micro micro_exec
make -C micro programs
make -C micro vendor_bpftool
- name: Record runner environment
run: |
mkdir -p "${PREFLIGHT_DIR}"
{
echo "date=$(date -u --iso-8601=seconds)"
echo "uname=$(uname -a)"
echo "machine=$(uname -m)"
echo "clang=$(clang --version | head -n 1)"
echo "cmake=$(cmake --version | head -n 1)"
echo "python=$(python3 --version)"
echo "bpftool=$("${BPFTOOL_BIN}" version | head -n 1)"
if [ -e /sys/kernel/btf/vmlinux ]; then
echo "kernel_btf=/sys/kernel/btf/vmlinux"
else
echo "kernel_btf=missing"
fi
if [ -r /proc/sys/net/core/bpf_jit_enable ]; then
echo "bpf_jit_enable=$(cat /proc/sys/net/core/bpf_jit_enable)"
else
echo "bpf_jit_enable=unavailable"
fi
} | tee "${PREFLIGHT_DIR}/environment.txt"
- name: Preflight compile-only backend checks
run: |
mkdir -p "${PREFLIGHT_DIR}"
micro/build/runner/micro_exec list-programs \
--program micro/programs/simple.bpf.o \
> "${PREFLIGHT_DIR}/simple_program_inventory.json"
micro/build/runner/micro_exec run-llvmbpf \
--program micro/programs/simple.bpf.o \
--program-name simple_xdp \
--io-mode staged \
--input-size 64 \
--repeat 1 \
--compile-only \
> "${PREFLIGHT_DIR}/simple_llvmbpf_compile_only.json"
sudo -n micro/build/runner/micro_exec run-kernel \
--program micro/programs/simple.bpf.o \
--program-name simple_xdp \
--io-mode packet \
--raw-packet \
--input-size 64 \
--repeat 1 \
--compile-only \
> "${PREFLIGHT_DIR}/simple_kernel_compile_only.json" \
2> "${PREFLIGHT_DIR}/simple_kernel_compile_only.stderr"
- name: Run micro pure-JIT baseline with llvmbpf and kernel
id: micro_full
continue-on-error: true
run: |
mkdir -p micro/results
python3 micro/driver.py suite \
--runtime llvmbpf \
--runtime kernel \
--iterations 5 \
--warmups 1 \
--repeat 200 \
--suite config/micro_pure_jit.yaml \
--output "${MICRO_OUTPUT}"
- name: Fallback micro llvmbpf-only run
if: always()
continue-on-error: true
run: |
if [ -s "${MICRO_OUTPUT}" ]; then
echo "Combined micro result exists; skipping llvmbpf-only fallback."
exit 0
fi
python3 micro/driver.py suite \
--runtime llvmbpf \
--iterations 5 \
--warmups 1 \
--repeat 200 \
--suite config/micro_pure_jit.yaml \
--output "${MICRO_LLVMBPF_FALLBACK}"
- name: Fallback micro kernel-only run
if: always()
continue-on-error: true
run: |
if [ -s "${MICRO_OUTPUT}" ]; then
echo "Combined micro result exists; skipping kernel-only fallback."
exit 0
fi
python3 micro/driver.py suite \
--runtime kernel \
--iterations 5 \
--warmups 1 \
--repeat 200 \
--suite config/micro_pure_jit.yaml \
--output "${MICRO_KERNEL_FALLBACK}"
- name: Fetch minimal corpus inputs
run: |
python3 corpus/fetch_real_world_corpus.py --repo libbpf-bootstrap
- name: Run corpus code-size baseline
id: corpus_code_size
continue-on-error: true
run: |
mkdir -p "${CORPUS_RESULTS_DIR}"
python3 corpus/run_real_world_code_size.py \
--bpftool "${BPFTOOL_BIN}" \
--repo libbpf-bootstrap \
--runtime llvmbpf \
--runtime kernel \
--output "${CORPUS_CODE_SIZE_OUTPUT}" \
--report "${CORPUS_CODE_SIZE_REPORT}"
- name: Run corpus exec-time baseline
if: always()
id: corpus_exec
continue-on-error: true
run: |
if [ ! -s "${CORPUS_CODE_SIZE_OUTPUT}" ]; then
echo "Corpus code-size output missing; skipping exec-time baseline."
exit 0
fi
python3 corpus/run_real_world_exec_time.py \
--input "${CORPUS_CODE_SIZE_OUTPUT}" \
--output "${CORPUS_EXEC_OUTPUT}" \
--report "${CORPUS_EXEC_REPORT}" \
--iterations 5 \
--repeat 200 \
--context-size 256
- name: Summarize outputs
if: always()
run: |
{
echo "## ARM64 baseline summary"
echo
echo "- Runner: \`$(uname -a)\`"
if [ -r /proc/sys/net/core/bpf_jit_enable ]; then
echo "- Host bpf_jit_enable: \`$(cat /proc/sys/net/core/bpf_jit_enable)\`"
fi
if [ -s "${MICRO_OUTPUT}" ]; then
echo "- Micro baseline: combined llvmbpf+kernel result present"
else
echo "- Micro baseline: combined result missing"
fi
if [ -s "${MICRO_LLVMBPF_FALLBACK}" ]; then
echo "- Micro fallback: llvmbpf-only result present"
fi
if [ -s "${MICRO_KERNEL_FALLBACK}" ]; then
echo "- Micro fallback: kernel-only result present"
fi
if [ -s "${CORPUS_CODE_SIZE_OUTPUT}" ]; then
echo "- Corpus code-size baseline: present"
else
echo "- Corpus code-size baseline: missing"
fi
if [ -s "${CORPUS_EXEC_OUTPUT}" ]; then
echo "- Corpus exec-time baseline: present"
else
echo "- Corpus exec-time baseline: missing"
fi
if [ -s "${CORPUS_EXEC_OUTPUT}" ]; then
python3 - <<'PY'
import json

Check failure on line 227 in .github/workflows/arm64-benchmark.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/arm64-benchmark.yml

Invalid workflow file

You have an error in your yaml syntax on line 227
import os
from pathlib import Path
path = Path(os.environ["CORPUS_EXEC_OUTPUT"])
payload = json.loads(path.read_text())
summary = payload.get("summary", {})
programs = summary.get("programs", {})
runtime_status = summary.get("runtime_status", {})
kernel_status = runtime_status.get("kernel", {})
llvmbpf_status = runtime_status.get("llvmbpf", {})
print(f"- Corpus exec-time any-runtime ok: `{programs.get('any_runtime_exec_ok', 0)}/{programs.get('paired_from_code_size', 0)}`")
print(f"- Corpus exec-time paired ok: `{programs.get('paired_exec_ok', 0)}/{programs.get('paired_from_code_size', 0)}`")
print(f"- Corpus exec-time kernel ok/skipped: `{kernel_status.get('ok', 0)}/{kernel_status.get('skipped', 0)}`")
print(f"- Corpus exec-time llvmbpf ok/error: `{llvmbpf_status.get('ok', 0)}/{llvmbpf_status.get('error', 0)}`")
PY
fi
} >> "${GITHUB_STEP_SUMMARY}"
- name: Validate required outputs
if: always()
run: |
test -s "${MICRO_OUTPUT}" \
|| test -s "${MICRO_LLVMBPF_FALLBACK}" \
|| test -s "${MICRO_KERNEL_FALLBACK}"
- name: Upload ARM64 baseline artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: arm64-baseline-results
path: |
micro/results/arm64*.json
corpus/results/arm64/*.json
corpus/results/arm64/*.md
artifacts/arm64-baseline/**
if-no-files-found: warn