161 lines
4.3 KiB
Bash
Executable File
161 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Common helpers for benchmark orchestrators.
|
|
# Usage: source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../scripts/common/lib.sh"
|
|
|
|
set -Eeuo pipefail
|
|
|
|
# Resolve repository root relative to this file.
|
|
_COMMON_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ROOT_DIR="$(cd "${_COMMON_LIB_DIR}/../.." && pwd)"
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Logging
|
|
# -----------------------------------------------------------------------------
|
|
|
|
LOG_FILE=""
|
|
|
|
log_init() {
|
|
local log_path="$1"
|
|
LOG_FILE="$log_path"
|
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
: > "$LOG_FILE"
|
|
}
|
|
|
|
log() {
|
|
local msg="[$(date --iso-8601=seconds)] $*"
|
|
echo "$msg"
|
|
if [[ -n "${LOG_FILE:-}" ]]; then
|
|
echo "$msg" >> "$LOG_FILE"
|
|
fi
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Result directories
|
|
# -----------------------------------------------------------------------------
|
|
|
|
ensure_result_root() {
|
|
local result_root="$1"
|
|
mkdir -p "${result_root}/logs"
|
|
mkdir -p "${result_root}/raw_outputs"
|
|
echo "$result_root"
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Server health check
|
|
# -----------------------------------------------------------------------------
|
|
|
|
health_check() {
|
|
local host="${1:-127.0.0.1}"
|
|
local port="${2:-30000}"
|
|
local max_wait="${3:-120}"
|
|
|
|
for ((i = 1; i <= max_wait; i++)); do
|
|
if curl --fail --silent --show-error --max-time 5 "http://${host}:${port}/health" >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Git metadata
|
|
# -----------------------------------------------------------------------------
|
|
|
|
git_commit() {
|
|
( cd "$ROOT_DIR" && git rev-parse --short HEAD 2>/dev/null || echo "unknown" )
|
|
}
|
|
|
|
git_dirty() {
|
|
(
|
|
cd "$ROOT_DIR" || exit 1
|
|
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
|
|
echo "dirty"
|
|
else
|
|
echo "clean"
|
|
fi
|
|
)
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# results.json metadata
|
|
# -----------------------------------------------------------------------------
|
|
|
|
write_metadata_json() {
|
|
local output_path="$1"
|
|
local experiment="$2"
|
|
local run_id="$3"
|
|
local model="$4"
|
|
local backend="$5"
|
|
local engine="$6"
|
|
local hardware="$7"
|
|
local accelerator="$8"
|
|
local chip="$9"
|
|
local script="${10}"
|
|
local env_path="${11:-}"
|
|
local description="${12:-}"
|
|
|
|
mkdir -p "$(dirname "$output_path")"
|
|
|
|
"${PYTHON:-python3}" - "$output_path" "$experiment" "$run_id" "$model" "$backend" "$engine" "$hardware" "$accelerator" "$chip" "$script" "$env_path" "$description" "$(date --iso-8601=seconds)" "$(git_commit)" "$(git_dirty)" <<'PY'
|
|
import json, sys
|
|
(out, experiment, run_id, model, backend, engine, hardware, accelerator,
|
|
chip, script, env_path, description, timestamp, git_commit,
|
|
git_dirty) = sys.argv[1:16]
|
|
data = {
|
|
"metadata": {
|
|
"experiment": experiment,
|
|
"run_id": run_id,
|
|
"timestamp": timestamp,
|
|
"model": model,
|
|
"backend": backend,
|
|
"engine": engine,
|
|
"hardware": hardware,
|
|
"accelerator": accelerator,
|
|
"chip": chip,
|
|
"script": script,
|
|
"env": env_path,
|
|
"git_commit": git_commit,
|
|
"git_dirty": git_dirty,
|
|
"description": description,
|
|
},
|
|
"config": {},
|
|
"scenarios": [],
|
|
}
|
|
with open(out, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
PY
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# JSON append helper (naive but sufficient for small result JSONs)
|
|
# -----------------------------------------------------------------------------
|
|
|
|
append_scenario_to_json() {
|
|
local json_path="$1"
|
|
local scenario_json="$2"
|
|
|
|
if [[ ! -f "$json_path" ]]; then
|
|
echo "ERROR: $json_path not found" >&2
|
|
return 1
|
|
fi
|
|
|
|
# Use Python for safe JSON manipulation.
|
|
"${PYTHON:-python3}" - "$json_path" "$scenario_json" <<'PY'
|
|
import json
|
|
import sys
|
|
|
|
json_path = sys.argv[1]
|
|
scenario_json = sys.argv[2]
|
|
|
|
with open(json_path, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
scenario = json.loads(scenario_json)
|
|
data["scenarios"].append(scenario)
|
|
|
|
with open(json_path, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
|
PY
|
|
}
|