#!/bin/sh # Quiet-host, one-axis BQ8/BK64 versus BQ8/BK128 operator gate. set -eu [ "$#" -eq 1 ] || { echo "usage: $0 OUTPUT_DIRECTORY" >&2 exit 2 } output=$1 build_dir=${GEM_BQ8_GATE_BUILD:-build} profile="$build_dir/gem-long-attention-profile" counter_info="$build_dir/gem-metal-counter-info" max_load_per_cpu=${GEM_BQ8_GATE_MAX_LOAD_PER_CPU:-1.0} max_short_window_busy_cpu=${GEM_BQ8_GATE_MAX_SHORT_WINDOW_BUSY_CPU_PERCENT:-10.0} repetitions=10 warmup=10 [ ! -e "$output" ] || { echo "gem: output already exists: $output" >&2; exit 2; } [ -x "$profile" ] || { echo "gem: required profiler is missing: $profile" >&2; exit 2; } [ -x "$counter_info" ] || { echo "gem: required Metal inventory tool is missing: $counter_info" >&2 exit 2 } case $max_load_per_cpu in ''|*[!0-9.]*) echo "gem: invalid maximum load per CPU" >&2; exit 2 ;; esac awk -v maximum="$max_load_per_cpu" 'BEGIN {exit !(maximum > 0)}' || { echo "gem: maximum load per CPU must be positive" >&2 exit 2 } awk -v maximum="$max_short_window_busy_cpu" 'BEGIN {exit !(maximum > 0)}' || { echo "gem: maximum short-window busy CPU must be positive" >&2 exit 2 } if [ "$(uname -s)" != Darwin ] || ! command -v sysctl >/dev/null 2>&1 || ! command -v pmset >/dev/null 2>&1 || ! command -v caffeinate >/dev/null 2>&1 || ! command -v top >/dev/null 2>&1; then echo "gem: BK128 performance gate requires macOS host-state tools" >&2 exit 2 fi if command -v pgrep >/dev/null 2>&1 && pgrep -f 'build/gem serve' >/dev/null 2>&1; then echo "gem: refusing to overlap a production server Metal workload" >&2 exit 1 fi mkdir -p "$output" date -u '+%Y-%m-%dT%H:%M:%SZ' > "$output/run-start-utc.txt" sw_vers > "$output/macos-version.txt" shasum -a 256 "$profile" "$counter_info" src/metal.m src/long_attention_profile.c \ scripts/run-bq8-bk128-gate.sh scripts/analyze-bq8-bk128-gate.sh \ > "$output/sha256.txt" otool -L "$profile" "$counter_info" > "$output/native-linkage.txt" if grep -Eiq 'lib(llama|ggml)' "$output/native-linkage.txt"; then echo "gem: profiler unexpectedly links llama/ggml" >&2 exit 1 fi "$counter_info" > "$output/metal-device.json" jq -e ' .schema_version == 1 and .workload == "metal-counter-info" and .device.name == "Apple M4 Max" and .device.has_unified_memory == true and .device.gpu_families.apple9 == true and .device.max_threadgroup_memory_bytes >= 20544 ' "$output/metal-device.json" >/dev/null jq -n --arg build_dir "$build_dir" --argjson maximum "$max_load_per_cpu" \ --argjson max_short_window_busy_cpu "$max_short_window_busy_cpu" \ --argjson repetitions "$repetitions" --argjson warmup "$warmup" \ '{schema_version: 2, engine: "gem-native-c-metal", axis: {name: "cache_tile_width", baseline: 64, candidate: 128}, positions: [4064, 65504, 131040], rows: 32, kv_type: "f32", repetitions: $repetitions, warmup: $warmup, seed_prefix: true, max_load_per_logical_cpu: $maximum, max_short_window_busy_cpu_percent: $max_short_window_busy_cpu, requires_ac_power: true, requires_no_thermal_warning: true, build_directory: $build_dir}' \ > "$output/gate-config.json" host_receipt() { phase=$1 tokens=$2 destination="$output/host-$phase-$tokens.json" timestamp=$(date -u '+%Y-%m-%dT%H:%M:%SZ') load_average=$(sysctl -n vm.loadavg) load_1m=$(printf '%s\n' "$load_average" | awk '{print $2}') logical_cpus=$(sysctl -n hw.logicalcpu) load_per_cpu=$(awk -v load="$load_1m" -v cpus="$logical_cpus" \ 'BEGIN {printf "%.6f", load / cpus}') recent_process_cpu_percent=$(ps -Ao pcpu= | awk '{sum += $1} END {printf "%.3f", sum}') short_window_busy_cpu=$(LC_ALL=C top -l 2 -s 1 -n 0 -stats pid,cpu,command | awk -F'[:,%]' '/^CPU usage:/ {idle=$6} END { gsub(/^[[:space:]]+|[[:space:]]+$/, "", idle) if (idle !~ /^[0-9]+([.][0-9]+)?$/) exit 1 printf "%.3f", 100 - idle }') || { echo "gem: could not sample short-window macOS CPU state" >&2 return 1 } power_state=$(LC_ALL=C pmset -g batt 2>&1 || true) thermal_state=$(LC_ALL=C pmset -g therm 2>&1 || true) ac_power=false case $power_state in *"Now drawing from 'AC Power'"*) ac_power=true ;; esac no_thermal_warning=false if printf '%s\n' "$thermal_state" | grep -Fq 'No thermal warning level has been recorded' && printf '%s\n' "$thermal_state" | grep -Fq 'No performance warning level has been recorded'; then no_thermal_warning=true elif printf '%s\n' "$thermal_state" | grep -Eq 'CPU_Scheduler_Limit[[:space:]]*=[[:space:]]*100' && printf '%s\n' "$thermal_state" | grep -Eq 'CPU_Speed_Limit[[:space:]]*=[[:space:]]*100'; then no_thermal_warning=true fi status=pass awk -v actual="$load_per_cpu" -v maximum="$max_load_per_cpu" \ 'BEGIN {exit !(actual <= maximum)}' || status=fail awk -v actual="$short_window_busy_cpu" -v maximum="$max_short_window_busy_cpu" \ 'BEGIN {exit !(actual <= maximum)}' || status=fail [ "$ac_power" = true ] || status=fail [ "$no_thermal_warning" = true ] || status=fail assertions=$(pmset -g assertions 2>&1 || true) top_processes=$(ps -Ao pid,pcpu,pmem,etime,comm -r | sed -n '1,24p') jq -n --arg timestamp "$timestamp" --arg phase "$phase" --arg status "$status" \ --arg load_average "$load_average" --argjson load_1m "$load_1m" \ --argjson logical_cpus "$logical_cpus" --argjson load_per_cpu "$load_per_cpu" \ --argjson maximum "$max_load_per_cpu" --arg power_state "$power_state" \ --argjson recent_process_cpu_percent "$recent_process_cpu_percent" \ --argjson short_window_busy_cpu "$short_window_busy_cpu" \ --argjson max_short_window_busy_cpu "$max_short_window_busy_cpu" \ --argjson ac_power "$ac_power" \ --argjson no_thermal_warning "$no_thermal_warning" \ --arg thermal_state "$thermal_state" --arg assertions "$assertions" \ --arg top_processes "$top_processes" \ '{schema_version: 2, timestamp_utc: $timestamp, phase: $phase, status: $status, load_average: $load_average, load_1m: $load_1m, logical_cpus: $logical_cpus, load_per_logical_cpu: $load_per_cpu, max_load_per_logical_cpu: $maximum, power_state: $power_state, ac_power: $ac_power, recent_aggregate_process_cpu_percent: $recent_process_cpu_percent, short_window_busy_cpu_percent: $short_window_busy_cpu, max_short_window_busy_cpu_percent: $max_short_window_busy_cpu, thermal_state: $thermal_state, no_thermal_warning: $no_thermal_warning, assertions: $assertions, top_processes: $top_processes}' > "$destination" [ "$status" = pass ] } for tokens in 4096 65536 131072; do position=$((tokens - 32)) if ! host_receipt preflight "$tokens"; then echo "gem: BK128 gate rejected busy host before $tokens-token screen" >&2 exit 1 fi temporary="$output/seeded-$tokens.json.tmp" caffeinate -i "$profile" --shape 31b-full --position "$position" --rows 32 \ --repetitions "$repetitions" --warmup "$warmup" --seed-prefix \ --variant compare-bq8-bk128 > "$temporary" jq -e --argjson position "$position" --argjson capacity "$tokens" ' .schema_version == 1 and .engine == "gem-native-c-metal" and .shape == "31b-full" and .kv_type == "f32" and .position == $position and .rows == 32 and .cache_capacity == $capacity and .repetitions == 10 and .warmup == 10 and .seed_prefix == true and (.variants["online-bq8"].samples | length) == 10 and (.variants["online-bq8-bk128"].samples | length) == 10 ' "$temporary" >/dev/null mv "$temporary" "$output/seeded-$tokens.json" if ! host_receipt postflight "$tokens"; then echo "gem: BK128 gate rejected changed host after $tokens-token screen" >&2 exit 1 fi done scripts/analyze-bq8-bk128-gate.sh "$output" "$output/decision.json" jq . "$output/decision.json"