#!/usr/bin/env bash
# La tarjeta, y quien la esta usando.
#
# Va la primera porque es la que explica los fallos de las demas. En 4 GB no
# caben el verde y el naranja a la vez: si el naranja esta cargado, el verde
# dara "cudaMalloc failed" y parecera que el modelo esta roto cuando lo que
# pasa es que no hay sitio.
#
# El caso que mas ha costado en este proyecto es whisper-server: lo lanza
# flatpak-spawn --host, vive FUERA del sandbox y no se entera de que la app
# cerro. Cada reinicio deja uno agarrado a ~850 MiB. Dos o tres y ya no cabe
# nada. Por eso se cuentan, no solo se mira si hay alguno.

cd "$(dirname "$0")" && . ./comun.sh

titulo "La tarjeta"

USADA=$(vram)
if [ -z "$USADA" ]; then
    echo "  $(rojo FALLO) no hay nvidia-smi: esto necesita la grafica"
    exit 1
fi

TOTAL=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader | tr -d ' MiB')
nota "$USADA MiB usados de $TOTAL"
nvidia-smi --query-compute-apps=used_memory,process_name --format=csv,noheader 2>/dev/null \
    | sed 's/^/        /'

titulo "Nadie compitiendo por ella"

# pgrep -c YA imprime 0 cuando no encuentra nada, y ademas devuelve 1. Un
# "|| echo 0" detras parece prudente y lo que hace es imprimir DOS ceros, que
# no son iguales a "0" y hacen fallar una prueba que en realidad pasa.
cuantos()   { local n; n=$(pgrep -cf "$1" 2>/dev/null); echo "${n:-0}"; }
cuantos_x() { local n; n=$(pgrep -cx "$1" 2>/dev/null); echo "${n:-0}"; }

# dataset.py genera pares con el NARANJA: mientras corra, ollama recarga el
# modelo naranja en segundos aunque se le haga stop. No es un fallo de ollama.
comprueba "dataset.py no esta corriendo" "$(cuantos 'entrena/dataset.py')" "0"

comprueba "el nucleo naranja no esta corriendo" "$(cuantos 'nucleo/jarvis.py')" "0"

comprueba "sin whisper-server huerfanos" "$(cuantos_x whisper-server)" "0"

CARGADO=$(curl -fsS --max-time 5 "$OLLAMA/api/ps" 2>/dev/null | python3 -c "
import json, sys
try: m = json.load(sys.stdin).get('models', [])
except Exception: m = []
print(','.join(x['name'] for x in m) or 'ninguno')
" 2>/dev/null)
nota "en ollama ahora: $CARGADO"

case "$CARGADO" in
    *"$NARANJA"*)
        echo "  $(rojo FALLO) el naranja esta cargado: no cabe el verde encima"
        echo "        $(gris "ollama stop $NARANJA")"
        _fallo=$((_fallo + 1)) ;;
    *)
        echo "  $(verde OK) el naranja no ocupa la tarjeta"
        _ok=$((_ok + 1)) ;;
esac

# Sitio para el verde: 2795 MiB medidos el 16 ago a num_ctx 65536 con 16 de 32
# capas en GPU. La cifra anterior (3301) era la del modelo a 24576 con las 32
# capas dentro, que Hermes rechaza por su suelo de 64k.
#
# Si el modelo ya esta dentro, la comprobacion no aplica: el hueco ya se uso.
case "$CARGADO" in
    *"$MODELO"*) nota "el verde ya esta cargado, no hace falta hueco" ;;
    *)           mayor_que "queda hueco para el verde (MiB libres)" \
                     "$((TOTAL - USADA))" 2800 ;;
esac

resumen
