#!/usr/bin/env bash
# PUBPUB blind client dispatcher — picks the backend and runs one a-range.
#   client <sources.bin> <a0> <a1> [--backend auto|hsass|sass|ptx|cpu] [--hits out.txt]
# Backend auto: HSASS (hand-tuned RCAsm cubin, ~2.2x, sm_89) > SASS (nvcc native, sm_89) >
#               PTX (JITs anywhere) > CPU. All emit identical "H a i j k glv"; orchestrator re-verifies exactly.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
SRC="${1:?sources.bin}"; A0="${2:?a0}"; A1="${3:?a1}"; shift 3
BACKEND=auto; HITS=/dev/stdout; PIV=""
while [ $# -gt 0 ]; do case "$1" in
  --backend) BACKEND="$2"; shift 2;;
  --hits)    HITS="$2";    shift 2;;
  --pivlo)   PIV="$PIV --pivlo $2"; shift 2;;   # pivot-tile range (swarm); forwarded to hsass/cpu backends
  --pivhi)   PIV="$PIV --pivhi $2"; shift 2;;
  *) shift;;
esac; done

cc_present(){ command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi -L >/dev/null 2>&1; }
cc_cap(){ nvidia-smi --query-gpu=compute_cap --format=csv,noheader 2>/dev/null | head -1 | tr -d '.' ; }

choose(){
  if [ "$BACKEND" != auto ]; then echo "$BACKEND"; return; fi
  # RULE: GPU==sm_89 -> hand-SASS (hsass); any OTHER GPU -> portable PTX; no GPU -> CPU (last resort).
  if cc_present; then
    cap="$(cc_cap || true)"
    if [ "${cap:-0}" = "89" ] && [ -x "$HERE/crosscheck_hsass" ] && [ -x "$HERE/xcross_host" ] && [ -f "$HERE/kernel_xcross_fpt_sm89.cubin" ]; then echo hsass; return; fi
    if [ -x "$HERE/crosscheck_gpu.ptx" ]; then echo ptx; return; fi    # non-sm_89 GPU (or hsass missing)
    echo cpu; return
  fi
  echo cpu
}

B="$(choose)"
case "$B" in
  hsass)[ -x "$HERE/crosscheck_hsass" ] && [ -x "$HERE/xcross_host" ] || { echo "client: hsass backend not built, falling back to sass" >&2; B=sass; }; ;;
esac
case "$B" in
  sass) [ -x "$HERE/crosscheck_gpu.sass" ] || { echo "client: sass backend not built, falling back to cpu" >&2; B=cpu; }; ;;
  ptx)  [ -x "$HERE/crosscheck_gpu.ptx"  ] || { echo "client: ptx backend not built, falling back to cpu"  >&2; B=cpu; }; ;;
esac
echo "client: backend=$B  a∈[$A0,$A1)  src=$SRC" >&2
case "$B" in
  hsass)exec "$HERE/crosscheck_hsass"     --xcheck "$SRC" "$A0" "$A1" --hits "$HITS" $PIV;;
  sass) exec "$HERE/crosscheck_gpu.sass" --xcheck "$SRC" "$A0" "$A1" --hits "$HITS";;   # nvcc: no pivot-tiling
  ptx)  exec "$HERE/crosscheck_gpu.ptx"  --xcheck "$SRC" "$A0" "$A1" --hits "$HITS";;   # nvcc: no pivot-tiling
  cpu)  exec "$HERE/crosscheck_cpu"       "$SRC" "$A0" "$A1" --hits "$HITS" $PIV;;
  *) echo "client: unknown backend '$B'" >&2; exit 2;;
esac
