Files
wehub-resource-sync 426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00

353 lines
14 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Repo root via git, not a fixed level count: native/ moved under
# plugins/plugin-local-inference/, so the old "$SCRIPT_DIR/../../.." resolved to
# plugins/ and "$REPO_ROOT/packages/app-core/..." became plugins/packages/... (ENOENT).
REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)"
cd "$SCRIPT_DIR"
ANDROID_API="${ANDROID_API:-28}"
TARGET="${ELIZA_MTP_TARGET:-android-arm64-vulkan}"
STATE_DIR="${ELIZA_STATE_DIR:-$HOME/.eliza}"
OUT_DIR="${ELIZA_MTP_TARGET_OUT_DIR:-$STATE_DIR/local-inference/bin/mtp/$TARGET}"
LLAMA_DIR="${ELIZA_MTP_LLAMA_DIR:-$HOME/.cache/eliza-mtp/android-vulkan-graph-llama-cpp}"
BIN_DIR="${ELIZA_MTP_VULKAN_BIN_DIR:-$OUT_DIR}"
REMOTE_DIR="${ELIZA_ANDROID_VULKAN_GRAPH_REMOTE_DIR:-/data/local/tmp/eliza-vulkan-graph}"
BUILD_DIR="${ELIZA_ANDROID_VULKAN_GRAPH_BUILD_DIR:-android-vulkan-graph-smoke}"
MTP_BUILD_JOBS="${ELIZA_MTP_JOBS:-1}"
ADB_HINT="${ADB:-adb}"
ALLOW_EMULATOR="${ELIZA_ALLOW_ANDROID_EMULATOR_VULKAN:-0}"
ALLOW_SOFTWARE="${ELIZA_ALLOW_SOFTWARE_VULKAN:-0}"
REPORT_DIR="${ELIZA_MTP_HARDWARE_REPORT_DIR:-$SCRIPT_DIR/hardware-results}"
EVIDENCE_PATH="${ELIZA_ANDROID_VULKAN_GRAPH_EVIDENCE_OUT:-$SCRIPT_DIR/vulkan-runtime-dispatch-evidence.json}"
mkdir -p "$REPORT_DIR"
REPORT_PATH="$REPORT_DIR/android-vulkan-graph-smoke-$(date -u +%Y%m%dT%H%M%SZ).log"
JSON_REPORT_PATH="${REPORT_PATH%.log}.json"
exec > >(tee "$REPORT_PATH") 2>&1
fail() {
local code="$1"
shift
echo "[android-vulkan-graph-smoke] FAIL: $*" >&2
echo "[android-vulkan-graph-smoke] evidence log: $REPORT_PATH" >&2
exit "$code"
}
resolve_ndk() {
local candidate sdk_root
for candidate in "${ANDROID_NDK_HOME:-}" "${ANDROID_NDK_ROOT:-}" "${ANDROID_NDK:-}"; do
if [[ -n "$candidate" && -f "$candidate/build/cmake/android.toolchain.cmake" ]]; then
printf '%s\n' "$candidate"
return 0
fi
done
for sdk_root in "${ANDROID_HOME:-}" "${ANDROID_SDK_ROOT:-}" "$HOME/Library/Android/sdk" "$HOME/Android/Sdk"; do
if [[ -n "$sdk_root" && -d "$sdk_root/ndk" ]]; then
find "$sdk_root/ndk" -mindepth 1 -maxdepth 1 -type d | sort | tail -n 1
return 0
fi
done
return 1
}
resolve_adb() {
local candidate
for candidate in \
"$ADB_HINT" \
"${ANDROID_HOME:-}/platform-tools/adb" \
"${ANDROID_SDK_ROOT:-}/platform-tools/adb" \
"$HOME/Library/Android/sdk/platform-tools/adb" \
"$HOME/Android/Sdk/platform-tools/adb"; do
[[ -z "$candidate" ]] && continue
if command -v "$candidate" >/dev/null 2>&1; then
command -v "$candidate"
return 0
fi
if [[ -x "$candidate" ]]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
adb_cmd() {
if [[ -n "${ADB_SERIAL:-}" ]]; then
"$ADB" -s "$ADB_SERIAL" "$@"
else
"$ADB" "$@"
fi
}
echo "[android-vulkan-graph-smoke] started=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "[android-vulkan-graph-smoke] evidence log: $REPORT_PATH"
echo "[android-vulkan-graph-smoke] host=$(uname -a)"
if [[ "$TARGET" != "android-arm64-vulkan" ]]; then
fail 2 "expected ELIZA_MTP_TARGET=android-arm64-vulkan, got $TARGET"
fi
NDK="$(resolve_ndk || true)"
if [[ -z "$NDK" || ! -d "$NDK/toolchains/llvm/prebuilt" ]]; then
fail 2 "Android NDK not found. Set ANDROID_NDK_HOME, ANDROID_HOME, or ANDROID_SDK_ROOT"
fi
HOST_TAG=""
for candidate in darwin-arm64 darwin-x86_64 linux-x86_64 windows-x86_64; do
if [[ -d "$NDK/toolchains/llvm/prebuilt/$candidate" ]]; then
HOST_TAG="$candidate"
break
fi
done
if [[ -z "$HOST_TAG" ]]; then
fail 2 "could not find NDK LLVM prebuilt under $NDK/toolchains/llvm/prebuilt"
fi
TOOLBIN="$NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin"
CC="$TOOLBIN/aarch64-linux-android${ANDROID_API}-clang"
CXX="$TOOLBIN/aarch64-linux-android${ANDROID_API}-clang++"
if [[ ! -x "$CC" || ! -x "$CXX" ]]; then
fail 2 "missing NDK clang tools for host tag $HOST_TAG"
fi
ADB="$(resolve_adb || true)"
if [[ -z "$ADB" ]]; then
fail 2 "adb not found. Set ADB=/path/to/adb, ANDROID_HOME, or ANDROID_SDK_ROOT"
fi
echo "[android-vulkan-graph-smoke] adb=${ADB}"
echo "[android-vulkan-graph-smoke] ndk=${NDK} host_tag=${HOST_TAG}"
echo "[android-vulkan-graph-smoke] target=${TARGET}"
echo "[android-vulkan-graph-smoke] llama_dir=${LLAMA_DIR}"
echo "[android-vulkan-graph-smoke] out_dir=${OUT_DIR}"
echo "[android-vulkan-graph-smoke] mtp_build_jobs=${MTP_BUILD_JOBS}"
ADB_DEVICES=()
ADB_LIST="$("$ADB" devices -l || true)"
printf '%s\n' "$ADB_LIST"
while read -r serial status rest; do
[[ -z "$serial" ]] && continue
if [[ "$status" == "device" ]]; then
ADB_DEVICES+=("$serial")
fi
done < <(printf '%s\n' "$ADB_LIST" | awk 'NR > 1 && NF >= 2 { print $1, $2 }')
if [[ -n "${ANDROID_SERIAL:-}" ]]; then
ADB_SERIAL="$ANDROID_SERIAL"
else
if [[ "${#ADB_DEVICES[@]}" -eq 1 ]]; then
ADB_SERIAL="${ADB_DEVICES[0]}"
echo "[android-vulkan-graph-smoke] auto-selected only attached device ${ADB_SERIAL}"
elif [[ "${#ADB_DEVICES[@]}" -eq 0 ]]; then
fail 2 "no adb devices in 'device' state"
else
fail 2 "multiple adb devices attached: ${ADB_DEVICES[*]}. Set ANDROID_SERIAL"
fi
fi
adb_cmd wait-for-device
SERIAL="$(adb_cmd get-serialno 2>/dev/null | tr -d '\r' || true)"
MANUFACTURER="$(adb_cmd shell getprop ro.product.manufacturer 2>/dev/null | tr -d '\r' || true)"
MODEL="$(adb_cmd shell getprop ro.product.model 2>/dev/null | tr -d '\r' || true)"
HARDWARE="$(adb_cmd shell getprop ro.hardware 2>/dev/null | tr -d '\r' || true)"
BOARD_PLATFORM="$(adb_cmd shell getprop ro.board.platform 2>/dev/null | tr -d '\r' || true)"
QEMU="$(adb_cmd shell getprop ro.kernel.qemu 2>/dev/null | tr -d '\r' || true)"
BOOT_QEMU="$(adb_cmd shell getprop ro.boot.qemu 2>/dev/null | tr -d '\r' || true)"
echo "[android-vulkan-graph-smoke] device serial=${SERIAL:-unknown} manufacturer=${MANUFACTURER:-unknown} model=${MODEL:-unknown} hardware=${HARDWARE:-unknown} board=${BOARD_PLATFORM:-unknown} qemu=${QEMU:-unknown}/${BOOT_QEMU:-unknown}"
if [[ "$QEMU" == "1" && "$ALLOW_EMULATOR" != "1" ]]; then
fail 3 "refusing emulator device. Connect a physical handset/tablet, or set ELIZA_ALLOW_ANDROID_EMULATOR_VULKAN=1 for diagnostics only"
fi
if [[ "$BOOT_QEMU" == "1" && "$ALLOW_EMULATOR" != "1" ]]; then
fail 3 "refusing emulator boot profile. Connect a physical handset/tablet, or set ELIZA_ALLOW_ANDROID_EMULATOR_VULKAN=1 for diagnostics only"
fi
VKJSON="$(adb_cmd shell cmd gpu vkjson 2>/dev/null || true)"
if [[ -n "$VKJSON" ]]; then
echo "[android-vulkan-graph-smoke] cmd gpu vkjson:"
printf '%s\n' "$VKJSON" | awk 'NR <= 120 { print }'
fi
if [[ -n "$VKJSON" ]] && [[ "$ALLOW_SOFTWARE" != "1" ]] && echo "$VKJSON" | grep -Eiq 'llvmpipe|lavapipe|swiftshader|software rasterizer'; then
fail 3 "refusing software Vulkan device. Set ELIZA_ALLOW_SOFTWARE_VULKAN=1 for diagnostics only"
fi
if [[ "${ELIZA_MTP_SKIP_BUILD:-0}" != "1" ]]; then
echo "[android-vulkan-graph-smoke] building patched fork target=${TARGET}"
rm -rf "$LLAMA_DIR/build/$TARGET"
ELIZA_MTP_ALLOW_UNVERIFIED_VULKAN_BUILD=1 \
ELIZA_MTP_SKIP_DRAFTER_ARCH_PATCH=1 \
node "$REPO_ROOT/packages/app-core/scripts/build-llama-cpp-mtp.mjs" \
--target "$TARGET" \
--cache-dir "$LLAMA_DIR" \
--jobs "$MTP_BUILD_JOBS"
else
[[ "${ELIZA_MTP_ALLOW_PREBUILT_VULKAN_SMOKE:-0}" == "1" ]] || \
fail 5 "ELIZA_MTP_SKIP_BUILD=1 requires ELIZA_MTP_ALLOW_PREBUILT_VULKAN_SMOKE=1"
fi
CAPABILITIES="$OUT_DIR/CAPABILITIES.json"
if [[ ! -f "$CAPABILITIES" ]]; then
fail 5 "CAPABILITIES.json not found at $CAPABILITIES"
fi
if [[ ! -f "$BIN_DIR/libggml-vulkan.so" ]]; then
fail 5 "libggml-vulkan.so not found under $BIN_DIR"
fi
if [[ ! -f "$LLAMA_DIR/ggml/include/ggml.h" ]]; then
fail 5 "ggml headers not found under $LLAMA_DIR"
fi
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
echo "[android-vulkan-graph-smoke] compiling graph-dispatch harness for arm64-v8a API ${ANDROID_API}"
"$CC" -O2 -Wall -Wextra -std=c11 -I../reference -c ../reference/turbo_kernels.c -o "$BUILD_DIR/turbo_kernels.o"
"$CC" -O2 -Wall -Wextra -std=c11 -I. -c qjl_polar_ref.c -o "$BUILD_DIR/qjl_polar_ref.o"
"$CXX" -O2 -Wall -Wextra -std=c++17 \
-I"$LLAMA_DIR/ggml/include" \
-I"$LLAMA_DIR/ggml/src" \
-I../reference -I. \
vulkan_dispatch_smoke.cpp "$BUILD_DIR/turbo_kernels.o" "$BUILD_DIR/qjl_polar_ref.o" \
-L"$BIN_DIR" -lggml-base -lggml-vulkan -lggml-cpu -lggml \
-Wl,-rpath,'$ORIGIN/lib' \
-static-libstdc++ -lvulkan -llog -landroid -ldl -latomic -lm \
-o "$BUILD_DIR/vulkan_dispatch_smoke"
LIBCXX_SHARED="$(find "$NDK" -path '*/libc++_shared.so' -type f | grep '/arm64-v8a/\|/aarch64-linux-android/' | head -n 1 || true)"
LIBOMP_SHARED="$(find "$NDK" -path '*/libomp.so' -type f | grep '/aarch64/' | head -n 1 || true)"
echo "[android-vulkan-graph-smoke] pushing harness and built fork libraries to ${REMOTE_DIR}"
adb_cmd shell "rm -rf '${REMOTE_DIR}' && mkdir -p '${REMOTE_DIR}/lib'"
adb_cmd push "$BUILD_DIR/vulkan_dispatch_smoke" "${REMOTE_DIR}/vulkan_dispatch_smoke" >/dev/null
adb_cmd push "$BIN_DIR"/lib*.so "${REMOTE_DIR}/lib/" >/dev/null
if [[ -n "$LIBCXX_SHARED" ]]; then
adb_cmd push "$LIBCXX_SHARED" "${REMOTE_DIR}/lib/libc++_shared.so" >/dev/null
fi
if [[ -n "$LIBOMP_SHARED" ]]; then
adb_cmd push "$LIBOMP_SHARED" "${REMOTE_DIR}/lib/libomp.so" >/dev/null
fi
adb_cmd shell "chmod 755 '${REMOTE_DIR}/vulkan_dispatch_smoke'"
echo "[android-vulkan-graph-smoke] running built-fork Vulkan graph dispatch on Android"
adb_cmd shell "cd '${REMOTE_DIR}' && LD_LIBRARY_PATH='${REMOTE_DIR}/lib' ELIZA_ALLOW_SOFTWARE_VULKAN='${ALLOW_SOFTWARE}' ./vulkan_dispatch_smoke"
node - "$REPORT_PATH" "$JSON_REPORT_PATH" "$EVIDENCE_PATH" "$CAPABILITIES" "$TARGET" "$SERIAL" "$MANUFACTURER" "$MODEL" "$HARDWARE" "$BOARD_PLATFORM" <<'NODE'
const fs = require("node:fs");
const [
reportPath,
jsonReportPath,
evidencePath,
capPath,
target,
serial,
manufacturer,
model,
hardware,
boardPlatform,
] = process.argv.slice(2);
const text = fs.readFileSync(reportPath, "utf8");
const cap = fs.existsSync(capPath) ? JSON.parse(fs.readFileSync(capPath, "utf8")) : {};
const routeMap = {
"GGML_OP_ATTN_SCORE_QJL": { key: "qjl", capability: "qjl_full", op: "GGML_OP_ATTN_SCORE_QJL" },
"GGML_OP_ATTN_SCORE_TBQ/turbo3": { key: "turbo3", capability: "turbo3", op: "GGML_OP_ATTN_SCORE_TBQ" },
"GGML_OP_ATTN_SCORE_TBQ/turbo4": { key: "turbo4", capability: "turbo4", op: "GGML_OP_ATTN_SCORE_TBQ" },
"GGML_OP_ATTN_SCORE_TBQ/turbo3_tcq": { key: "turbo3_tcq", capability: "turbo3_tcq", op: "GGML_OP_ATTN_SCORE_TBQ" },
"GGML_OP_ATTN_SCORE_POLAR/use_qjl=0": { key: "polar", capability: "polarquant", op: "GGML_OP_ATTN_SCORE_POLAR" },
"GGML_OP_ATTN_SCORE_POLAR/use_qjl=1": { key: "polar", capability: "polarquant", op: "GGML_OP_ATTN_SCORE_POLAR" },
"GGML_OP_FUSED_ATTN_QJL_TBQ": { key: "fused_attn_qjl_tbq", capability: "fused_attn_qjl_tbq", op: "GGML_OP_FUSED_ATTN_QJL_TBQ" },
};
const seen = new Map();
for (const match of text.matchAll(/\[vulkan_dispatch_smoke\] PASS ([^:]+): (\d+) (?:scores|outputs), max diff ([0-9.eE+-]+)/g)) {
const [, route, outputs, maxDiff] = match;
const meta = routeMap[route];
if (!meta) continue;
const current = seen.get(meta.key) ?? {
runtimeCapabilityKey: meta.capability,
status: "runtime-ready",
runtimeReady: true,
graphOp: meta.op,
smokeTarget: "android-vulkan-graph-smoke",
smokeCommand: "make -C packages/inference/verify android-vulkan-graph-smoke",
smokeOutputs: 0,
maxDiff: 0,
graphRoutes: [],
evidenceDate: new Date().toISOString().slice(0, 10),
};
current.smokeOutputs += Number(outputs);
current.maxDiff = Math.max(current.maxDiff, Number(maxDiff));
current.graphRoutes.push(route);
seen.set(meta.key, current);
}
const required = ["turbo3", "turbo4", "turbo3_tcq", "qjl", "polar", "fused_attn_qjl_tbq"];
const missing = required.filter((key) => !seen.has(key));
if (missing.length) {
console.error(`[android-vulkan-graph-smoke] cannot write runtime evidence; missing graph route(s): ${missing.join(", ")}`);
process.exit(1);
}
const payload = {
schemaVersion: 1,
backend: "vulkan",
platform: "android",
sourceOfTruth: "Runtime-ready means a built llama.cpp fork graph route selects the shipped Vulkan kernel and a numeric smoke test passes on Android. SPIR-V compilation and pipeline symbols are not enough.",
status: "runtime-ready",
runtimeReady: true,
generatedFrom: reportPath,
target,
device: {
serial,
manufacturer,
model,
hardware,
boardPlatform,
vulkanDescription: (text.match(/\[vulkan_dispatch_smoke\] device=(.+)/) ?? [null, "unknown"])[1],
},
atCommit: cap.forkCommit ?? "unknown",
smokeTarget: "android-vulkan-graph-smoke",
smokeCommand: "make -C packages/inference/verify android-vulkan-graph-smoke",
evidenceDate: new Date().toISOString().slice(0, 10),
kernels: Object.fromEntries([...seen.entries()].sort(([a], [b]) => a.localeCompare(b))),
};
fs.writeFileSync(jsonReportPath, JSON.stringify(payload, null, 2) + "\n");
let aggregate = {};
if (fs.existsSync(evidencePath)) {
try {
aggregate = JSON.parse(fs.readFileSync(evidencePath, "utf8"));
} catch {
aggregate = {};
}
}
const targets = {};
if (aggregate.targets && typeof aggregate.targets === "object") {
Object.assign(targets, aggregate.targets);
} else if (aggregate.target && aggregate.kernels) {
targets[aggregate.target] = aggregate;
}
targets[target] = payload;
const merged = {
schemaVersion: 2,
backend: "vulkan",
sourceOfTruth: "Runtime-ready is target-specific: each target needs a built llama.cpp fork graph route selecting the shipped Vulkan kernel and passing numeric smoke.",
status: "runtime-ready",
runtimeReady: Object.values(targets).every((entry) => entry && entry.runtimeReady === true),
updatedAt: new Date().toISOString(),
generatedFrom: reportPath,
targets: Object.fromEntries(Object.entries(targets).sort(([a], [b]) => a.localeCompare(b))),
};
fs.writeFileSync(evidencePath, JSON.stringify(merged, null, 2) + "\n");
console.log(`[android-vulkan-graph-smoke] wrote per-run evidence: ${jsonReportPath}`);
console.log(`[android-vulkan-graph-smoke] updated runtime dispatch evidence: ${evidencePath}`);
NODE
if [[ "${ELIZA_MTP_SKIP_REBUILD_WITH_EVIDENCE:-0}" != "1" && "${ELIZA_MTP_SKIP_BUILD:-0}" != "1" ]]; then
echo "[android-vulkan-graph-smoke] rebuilding target=${TARGET} with Android Vulkan runtime evidence recorded"
rm -rf "$LLAMA_DIR/build/$TARGET"
ELIZA_MTP_ALLOW_UNVERIFIED_VULKAN_BUILD=1 \
ELIZA_MTP_SKIP_DRAFTER_ARCH_PATCH=1 \
node "$REPO_ROOT/packages/app-core/scripts/build-llama-cpp-mtp.mjs" \
--target "$TARGET" \
--cache-dir "$LLAMA_DIR" \
--jobs "$MTP_BUILD_JOBS"
fi
echo "[android-vulkan-graph-smoke] PASS Android Vulkan built-fork graph dispatch"
echo "[android-vulkan-graph-smoke] evidence log: $REPORT_PATH"