diff --git a/tp/docs/video-guion.md b/tp/docs/video-guion.md index 0ba1ad3..d57b27d 100644 --- a/tp/docs/video-guion.md +++ b/tp/docs/video-guion.md @@ -15,7 +15,7 @@ - PDF del informe: `tp/informe/tp/build/main.pdf` en la página/figura correspondiente. - Terminal para comandos en vivo (`make check` en Spin). - Navegador para la demo de la app móvil (`http://localhost:8080/` o capturas de la Sección 16). -4. **Edición:** Rody une las tres pistas, verifica que el tiempo total no exceda los 6:00, sube el archivo a Google Drive o YouTube (acceso no listado / público) y coloca el enlace y los tiempos en el Anexo A del informe (`tp/informe/tp/secciones/19-anexos.tex`). +4. **Edición:** Dayana une las tres pistas (acordado el sáb 3), verifica que el tiempo total no exceda los 6:00, sube el archivo a Google Drive o YouTube (acceso no listado / público) y coloca el enlace y los tiempos en el Anexo A del informe (`tp/informe/tp/secciones/19-anexos.tex`). --- @@ -23,42 +23,61 @@ | Parte | Integrante | Intervalo | Duración | Temas Clave | |---|---|---|---|---| -| **1** | **Rody** | 0:00 – 1:45 | 1m 45s | Problema ODS 11, Worker Pool en Go, determinismo y Speedup fuerte | -| **2** | **Dayana** | 1:45 – 3:30 | 1m 45s | Verificación formal en Spin/Promela, LTL, mutantes y demo `make check` | -| **3** | **Julio** | 3:30 – 5:35 | 2m 05s | GAPs con IA, cierre de clusters ODS 11, demo de la App y discusión crítica | -| — | *Margen* | 5:35 – 6:00 | 25s | Colchón de seguridad para transiciones y cierre | +| **1** | **Rody** | 0:00 – 2:00 | 2m 00s | Problema ODS 11, worker pool en Go, CLI, `go test -race` y benchmark en vivo, speedup fuerte | +| **2** | **Dayana** | 2:00 – 3:45 | 1m 45s | Verificación formal en Spin/Promela, LTL, mutantes y demo `make check` | +| **3** | **Julio** | 3:45 – 5:50 | 2m 05s | GAPs con IA, cierre de clusters ODS 11, demo de la App y discusión crítica | +| — | *Margen* | 5:50 – 6:00 | 10s | Colchón de seguridad para transiciones y cierre | --- -## Parte 1 · Rody · 0:00 – 1:45 · Caso, Algoritmo Concurrente y Speedup - -**En pantalla:** -1. Carátula del informe (`build/main.pdf`, pág. 1). -2. Diagrama del Worker Pool (`build/main.pdf`, Sección 8, pág. 40, Fig. 5). -3. Tabla de Speedup fuerte (`build/main.pdf`, Sección 9, pág. 43, Tabla 24). +## Parte 1 · Rody · 0:00 – 2:00 · Caso, Algoritmo Concurrente y Speedup + +*Las páginas son las impresas al pie del PDF (en Evince, `Ctrl+L` y el número).* + +**Antes de grabar** (terminal en `~/Code/cursos/concurrente/tp/kmeans`, fuente grande con `Ctrl +`): +correr una vez cada comando para que el CSV quede en la caché del disco y `go run` ya esté compilado. +El docente pide ver cada ejecución en pantalla: las tres van en vivo, no en captura. + +**En pantalla, en orden:** +1. Carátula del informe (`tp/informe/tp/build/main.pdf`, pág. 1). +2. Diagrama del worker pool (Sección 8, Figura 14, pág. 47). +3. **Terminal 1 · CLI en vivo** (secuencial y luego concurrente, mismos centroides): + ```bash + go run ./cmd/kmeans -modo seq -k 8 -iter 10 -centroides /tmp/centroides_k8.json + go run ./cmd/kmeans -modo conc -workers 8 -chunk 16384 -k 8 -iter 10 -centroides /tmp/centroides_k8.json -progreso + ``` + Señalar: `clustering` baja de ~3,4 s a ~0,8 s y la `inercia` es la misma (4,531799e+06). Con + `-progreso` se ve cada iteración de Lloyd con la inercia J bajando. +4. **Terminal 1 · pruebas con el detector de carreras** (1 s): + ```bash + go test -race -short -count=1 -v -run Concurrente . + ``` +5. Tabla de speedup fuerte (Sección 9, Tabla 25, pág. 51). +6. **Terminal 2 · benchmark reducido** (~30 s; arrancarlo mientras se habla de la tabla): + ```bash + go run ./cmd/benchmark -repes 3 -workers 1,4,8 -experimentos fijas -bootstrap 200 -salida /tmp/benchmark-demo.json + ``` **Texto sugerido:** -> «Buenos días profesor. Somos el equipo del Trabajo Parcial. Nuestro caso de uso analiza **2,83 millones de registros limpios** del taxi amarillo de Nueva York (enero 2024) mediante K-means, alineado con el **ODS 11** de ciudades y comunidades sostenibles. -> -> Para procesar este volumen sin depender de librerías externas, implementamos el algoritmo de Lloyd en Go bajo dos contratos idénticos: secuencial y concurrente. +> **[Carátula]** «Buenos días, profesor. Somos el grupo 4. Nuestro caso analiza **2,83 millones de viajes limpios** del taxi amarillo de Nueva York, enero de 2024, con K-means, alineado con el **ODS 11**, ciudades sostenibles. > -> La versión concurrente utiliza un **Worker Pool persistente**: las goroutines se instancian una sola vez para toda la corrida. Un canal distribuye bloques de viajes; cada bloque acumula sumas y conteos en su propia memoria privada sin contención; y una barrera con `sync.WaitGroup` sincroniza el fin de cada iteración. +> **[Figura 14]** Implementamos Lloyd en Go, sin librerías externas, en dos versiones con el mismo contrato: secuencial y concurrente. La concurrente es un **worker pool persistente**: las goroutines se crean una sola vez, un canal reparte bloques de viajes, cada bloque acumula en su propia memoria sin contención, y una barrera con `sync.WaitGroup` cierra cada iteración. La reducción suma los bloques **siempre en el mismo orden**, por eso el resultado es idéntico con cualquier número de workers. > -> Un detalle crítico de diseño es que la reducción final agrega los bloques **siempre en orden determinista**. Esto garantiza reproducibilidad numérica exacta bit a bit, independientemente del número de hilos o de la máquina. +> **[CLI]** Acá lo corro sobre el dataset completo. La secuencial tarda unos 3,4 segundos en el clustering; la concurrente con 8 workers, menos de un segundo, y llega a la **misma inercia**: es la misma solución, más rápido. Con la barra se ve cada iteración. > -> Evaluamos el rendimiento con un protocolo riguroso: 20 repeticiones barajadas y media recortada al 10 %. Con 4 workers alcanzamos un **speedup de 3,80x** y con 8 workers, **5,82x**. +> **[go test]** Las pruebas corren con el **detector de carreras**: verifican que la versión concurrente da lo mismo que la secuencial con cualquier número de workers. > -> Descubrimos que la fracción serial efectiva crece con la cantidad de hilos: el techo de escalabilidad no lo impone una sección secuencial del algoritmo, sino el **costo de coordinación de la barrera**. Asimismo, determinamos que por debajo de unos **20 000 viajes**, el costo de sincronización supera al cómputo y la concurrencia no conviene. +> **[Tabla 25 + benchmark]** Para medir, el benchmark baraja las configuraciones, repite y usa media recortada. Esta es una corrida corta en la laptop; la oficial, con 20 repeticiones, da **3,80×** con 4 workers y **5,82×** con 8. El techo no lo pone una parte secuencial del algoritmo sino el **costo de coordinar la barrera**, y por debajo de unos **20 000 viajes** sincronizar cuesta más que calcular. > -> Doy el pase a Dayana para la verificación formal del diseño.» +> Le doy el pase a Dayana para la verificación formal.» --- -## Parte 2 · Dayana · 1:45 – 3:30 · Verificación Formal en Spin y Mutantes +## Parte 2 · Dayana · 2:00 – 3:45 · Verificación Formal en Spin y Mutantes **En pantalla:** -1. Sección 14 del informe (`build/main.pdf`, pág. 53, Verificación formal). -2. Tabla 33 (`build/main.pdf`, pág. 57, Tabla comparativa de modelo y mutantes). +1. Sección 14 del informe (`build/main.pdf`, pág. 61, Verificación formal); la regresión corriendo está en la Figura 16 (pág. 63). +2. Tabla 34 (`build/main.pdf`, pág. 64, modelo correcto y mutantes). 3. Terminal con la ejecución en vivo: `cd tp/spin && make check`. **Texto sugerido:** @@ -81,12 +100,12 @@ --- -## Parte 3 · Julio · 3:30 – 5:35 · GAPs con IA, Interpretación ODS 11, Demo App y Crítica +## Parte 3 · Julio · 3:45 – 5:50 · GAPs con IA, Interpretación ODS 11, Demo App y Crítica **En pantalla:** -1. Tabla 34 de GAPs con IA (`build/main.pdf`, Sección 15, pág. 62). -2. Tabla 35 de Arquetipos y Figura 8 de la App Móvil (`build/main.pdf`, Sección 16, págs. 64–66) o ventana del navegador con `http://localhost:8080/`. -3. Sección 18 (Conclusiones y Recomendaciones, pág. 70). +1. Tabla 35 de GAPs con IA (`build/main.pdf`, Sección 15, pág. 69). +2. Tabla 36 de arquetipos y Figura 19 de la app móvil (`build/main.pdf`, Sección 16, págs. 71–73) o ventana del navegador con `http://localhost:8080/`. +3. Sección 18 (Conclusiones y recomendaciones, pág. 79). **Texto sugerido:** > «Gracias Dayana. En la implementación verificamos ausencia de carreras con `go test -race` y casos borde calculados a mano. @@ -119,7 +138,7 @@ \begin{itemize} \item \textbf{URL:} \url{https://...} \item \textbf{Duración:} 05:32 - \item \textbf{Partes:} Rody Vilchez (0:00, Algoritmo y Speedup), Dayana Gómez (1:45, Spin y Mutantes), Julio Meza (3:30, IA, Clusters ODS 11 y Discusión Crítica). + \item \textbf{Partes:} Rody Vilchez (0:00, Algoritmo y Speedup), Dayana Gómez (2:00, Spin y Mutantes), Julio Meza (3:45, IA, Clusters ODS 11 y Discusión Crítica). \end{itemize} ``` - [ ] Recompilar el informe con `./compilar.sh` y validar que el Anexo A quede sin marcas de `\pendiente`. diff --git a/tp/informe/tp/README.md b/tp/informe/tp/README.md index 9d2e7b7..18c36fd 100644 --- a/tp/informe/tp/README.md +++ b/tp/informe/tp/README.md @@ -26,22 +26,16 @@ latexmk # pdflatex + biber, APA `tp/reports/*.json` por `tp/scripts/tablas_informe.py`. - **Cifras en prosa**: `generado/cifras.tex` define `\cifra{speedup-p4}`, `\cifra{n-equilibrio}`, etc. Si se vuelve a medir, el texto cambia solo. -- **Capturas de la CLI**: `img/cli-*.txt` es la salida real de `tp/kmeans/cmd/kmeans`; - `img/cli-*.png` se renderiza con `tp/scripts/capturas_terminal.py`. Para rehacerlas: - - ```bash - cd ../../kmeans && go build -o /tmp/kmeans ./cmd/kmeans - /tmp/kmeans -modo seq -k 8 -iter 10 -centroides /tmp/c.json | tee ../informe/pc2/img/cli-secuencial.txt - /tmp/kmeans -modo conc -workers 8 -chunk 16384 -k 8 -iter 10 -centroides /tmp/c.json | tee ../informe/pc2/img/cli-concurrente.txt - uv run python ../scripts/capturas_terminal.py ../informe/pc2/img/cli-*.txt - ``` - - (la primera línea `$ ...` de cada `.txt` es el comando, agregada a mano para la figura). -- **Capturas de cada ejecución** (`img/ejec-*.png`): el docente pide una captura de cada - ejecución, no un listado ni una mención. `tp/scripts/capturar_ejecuciones.sh` corre el pipeline, - `pytest`, `go vet` + `go test -race`, la regresión de Spin, un benchmark reducido y los checks de - CI, guarda la salida real en `img/ejec-*.txt` (primera línea: el comando) y la renderiza. Se - puede rehacer un solo grupo: `capturar_ejecuciones.sh spin`. +- **Capturas de pantalla de cada ejecución** (`img/cli-*.png`, `img/ejec-*.png`): el docente pide + una captura de cada ejecución, no un listado ni una mención. `tp/scripts/capturar_ejecuciones.sh` + abre una ventana de kitty flotante en Hyprland, teclea cada comando en el shell (pruebas con + `-v`), espera a que termine y fotografía la ventana con grim: CLI secuencial y concurrente, pipeline, + `pytest`, `go vet` + `go test -race`, la regresión y las corridas de Spin, un benchmark reducido y + los checks de CI. Se puede rehacer un solo grupo: `capturar_ejecuciones.sh spin`. Mientras corre no + hay que tocar el teclado. (Las de la PC2, en `../pc2/img/`, siguen renderizadas desde texto con + `tp/scripts/capturas_terminal.py`.) +- **Tarjeta del resumen** (`img/concurrente-card.png`): la misma imagen del README del perfil + (R0SEWT/R0SEWT, `assets/concurrente.png`), que se genera allí con `make-concurrente-card.sh`. - **Todo lo de Spin**: `cd tp/spin && make informe`. Deja en `generado/` las salidas de `pan` (`spin-*.txt`), el estado final del contraejemplo de deadlock (`traza-deadlock.txt`), la tabla de los siete casos de la regresión (`spin-casos.tsv` → `tabla-spin-casos.tex`) y las figuras diff --git a/tp/informe/tp/img/cli-concurrente.png b/tp/informe/tp/img/cli-concurrente.png index 3b92a82..761c664 100644 Binary files a/tp/informe/tp/img/cli-concurrente.png and b/tp/informe/tp/img/cli-concurrente.png differ diff --git a/tp/informe/tp/img/cli-concurrente.txt b/tp/informe/tp/img/cli-concurrente.txt deleted file mode 100644 index ca36cb5..0000000 --- a/tp/informe/tp/img/cli-concurrente.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ kmeans -modo conc -workers 8 -chunk 16384 -k 8 -iter 10 -centroides centroides_k8.json -gold ../data/gold/yellow_2024-01_features.csv - 2831486 viajes × 6 features · sha256 a3ad5205201b… -centroides k-means++ semilla 2024 · k efectivo 8 · sha256 a1755469195d… -modo concurrente · workers 8 · chunk 16384 -máquina fedora · go1.26.7-X:nodwarf5 · GOMAXPROCS 8 de 8 CPUs lógicas -tiempos carga 1893 ms · init 0 ms · clustering 721 ms · total 2614 ms -memoria heap tras carga 349 MB · heap final 371 MB · RSS máximo 499 MB · 24 GC -cpu usuario 7.94 s · sistema 0.27 s · pared 2.61 s → 3.1 núcleos efectivos -resultado 10 iteraciones (paro=max_iter) · 0 clusters vacíos · inercia 4.531799e+06 diff --git a/tp/informe/tp/img/cli-secuencial.png b/tp/informe/tp/img/cli-secuencial.png index dc060ef..4c96d74 100644 Binary files a/tp/informe/tp/img/cli-secuencial.png and b/tp/informe/tp/img/cli-secuencial.png differ diff --git a/tp/informe/tp/img/cli-secuencial.txt b/tp/informe/tp/img/cli-secuencial.txt deleted file mode 100644 index 139bf30..0000000 --- a/tp/informe/tp/img/cli-secuencial.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ kmeans -modo seq -k 8 -iter 10 -centroides centroides_k8.json -gold ../data/gold/yellow_2024-01_features.csv - 2831486 viajes × 6 features · sha256 a3ad5205201b… -centroides k-means++ semilla 2024 · k efectivo 8 · sha256 a1755469195d… -modo secuencial -máquina fedora · go1.26.7-X:nodwarf5 · GOMAXPROCS 8 de 8 CPUs lógicas -tiempos carga 2177 ms · init 296 ms · clustering 2541 ms · total 5014 ms -memoria heap tras carga 349 MB · heap final 393 MB · RSS máximo 531 MB · 24 GC -cpu usuario 5.85 s · sistema 0.35 s · pared 5.01 s → 1.2 núcleos efectivos -resultado 10 iteraciones (paro=max_iter) · 0 clusters vacíos · inercia 4.531799e+06 diff --git a/tp/informe/tp/img/concurrente-card.png b/tp/informe/tp/img/concurrente-card.png new file mode 100644 index 0000000..4fdbb66 Binary files /dev/null and b/tp/informe/tp/img/concurrente-card.png differ diff --git a/tp/informe/tp/img/ejec-benchmark.png b/tp/informe/tp/img/ejec-benchmark.png index 2379097..7a3801c 100644 Binary files a/tp/informe/tp/img/ejec-benchmark.png and b/tp/informe/tp/img/ejec-benchmark.png differ diff --git a/tp/informe/tp/img/ejec-benchmark.txt b/tp/informe/tp/img/ejec-benchmark.txt deleted file mode 100644 index dca6d9a..0000000 --- a/tp/informe/tp/img/ejec-benchmark.txt +++ /dev/null @@ -1,11 +0,0 @@ -$ go run ./cmd/benchmark -repes 3 -workers 1,4,8 -experimentos fijas -bootstrap 200 -salida /tmp/benchmark-demo.json -leyendo ../data/gold/yellow_2024-01_features.csv -fijas n=2831486 ronda 4/4 - -experimento n modo workers recortada desv speedup [IC 95%] efic -fijas 2831486 conc 1 2762.4ms 10.5ms 0.99x [0.98, 1.00] 99% -fijas 2831486 conc 4 830.0ms 8.8ms 3.30x [3.26, 3.33] 82% -fijas 2831486 conc 8 820.7ms 101.5ms 3.33x [2.93, 3.61] 42% -fijas 2831486 seq 2735.4ms 19.4ms - -16 corridas en 0.5 min → /tmp/benchmark-demo.json diff --git a/tp/informe/tp/img/ejec-ci.png b/tp/informe/tp/img/ejec-ci.png index 11c09f7..64cddd5 100644 Binary files a/tp/informe/tp/img/ejec-ci.png and b/tp/informe/tp/img/ejec-ci.png differ diff --git a/tp/informe/tp/img/ejec-ci.txt b/tp/informe/tp/img/ejec-ci.txt deleted file mode 100644 index c813357..0000000 --- a/tp/informe/tp/img/ejec-ci.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ gh pr checks 50 -GitGuardian Security Checks pass 2s https://dashboard.gitguardian.com -Sourcery review pass 1m9s https://sourcery.ai -labs/go pass 25s https://github.com/R0SEWT/concurrente/actions/runs/36960426166/job/110692692815 -test pass 13s https://github.com/R0SEWT/concurrente/actions/runs/36960422838/job/110692682752 -test pass 10s https://github.com/R0SEWT/concurrente/actions/runs/36960426163/job/110692692603 -tp/kmeans pass 23s https://github.com/R0SEWT/concurrente/actions/runs/36960426166/job/110692692551 diff --git a/tp/informe/tp/img/ejec-go-test-resto.png b/tp/informe/tp/img/ejec-go-test-resto.png new file mode 100644 index 0000000..c3527e0 Binary files /dev/null and b/tp/informe/tp/img/ejec-go-test-resto.png differ diff --git a/tp/informe/tp/img/ejec-go-test.png b/tp/informe/tp/img/ejec-go-test.png index 7c36047..0e83c7a 100644 Binary files a/tp/informe/tp/img/ejec-go-test.png and b/tp/informe/tp/img/ejec-go-test.png differ diff --git a/tp/informe/tp/img/ejec-go-test.txt b/tp/informe/tp/img/ejec-go-test.txt deleted file mode 100644 index 1d58f70..0000000 --- a/tp/informe/tp/img/ejec-go-test.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ go vet ./... && go test -race -count=1 ./... -ok upc.edu.pe/concurrente/kmeans 159.484s -? upc.edu.pe/concurrente/kmeans/cmd/benchmark [no test files] -ok upc.edu.pe/concurrente/kmeans/cmd/kmeans 1.016s -? upc.edu.pe/concurrente/kmeans/cmd/resumen_zonas [no test files] diff --git a/tp/informe/tp/img/ejec-pipeline.png b/tp/informe/tp/img/ejec-pipeline.png index 6175c34..cd22c3a 100644 Binary files a/tp/informe/tp/img/ejec-pipeline.png and b/tp/informe/tp/img/ejec-pipeline.png differ diff --git a/tp/informe/tp/img/ejec-pipeline.txt b/tp/informe/tp/img/ejec-pipeline.txt deleted file mode 100644 index 6e5230b..0000000 --- a/tp/informe/tp/img/ejec-pipeline.txt +++ /dev/null @@ -1,2 +0,0 @@ -$ uv run nyc-tlc all -bronze 2,964,624 → silver 2,831,486 → gold 2,831,486 (cumple el mínimo de 1,000,000) diff --git a/tp/informe/tp/img/ejec-pytest.png b/tp/informe/tp/img/ejec-pytest.png index d19493b..1f0449d 100644 Binary files a/tp/informe/tp/img/ejec-pytest.png and b/tp/informe/tp/img/ejec-pytest.png differ diff --git a/tp/informe/tp/img/ejec-pytest.txt b/tp/informe/tp/img/ejec-pytest.txt deleted file mode 100644 index f10bfd5..0000000 --- a/tp/informe/tp/img/ejec-pytest.txt +++ /dev/null @@ -1,3 +0,0 @@ -$ uv run pytest -q -.................................................................. [100%] -66 passed in 1.14s diff --git a/tp/informe/tp/img/ejec-spin-check.png b/tp/informe/tp/img/ejec-spin-check.png index 1adb592..9ee3aaa 100644 Binary files a/tp/informe/tp/img/ejec-spin-check.png and b/tp/informe/tp/img/ejec-spin-check.png differ diff --git a/tp/informe/tp/img/ejec-spin-check.txt b/tp/informe/tp/img/ejec-spin-check.txt deleted file mode 100644 index 5fbfcbe..0000000 --- a/tp/informe/tp/img/ejec-spin-check.txt +++ /dev/null @@ -1,9 +0,0 @@ -$ make check - ok correcto sin-ltl errores: 0 seguridad: aserciones y estados finales válidos (sin deadlock) - ok correcto -a -N exclusion errores: 0 LTL: nadie publica centroides mientras hay lectores - ok correcto -a -f -N termina errores: 0 LTL: las dos iteraciones terminan (weak fairness) - ok MUTANTE sin-ltl errores: 1 acumulador compartido sin mutex: incremento perdido - ok MUTANTE_DEADLOCK sin-ltl errores: 1 un worker pierde el wg.Done: deadlock en la barrera - ok MUTANTE_DEADLOCK -a -f -N termina errores: 1 el mismo wg.Done perdido: la corrida nunca termina - ok MUTANTE_SIN_BARRERA -a -N exclusion errores: 1 el coordinador publica sin esperar la barrera -== regresión OK: 7 casos == diff --git a/tp/informe/tp/img/ejec-spin-correcto.png b/tp/informe/tp/img/ejec-spin-correcto.png index 78a9c71..5f2bb88 100644 Binary files a/tp/informe/tp/img/ejec-spin-correcto.png and b/tp/informe/tp/img/ejec-spin-correcto.png differ diff --git a/tp/informe/tp/img/ejec-spin-correcto.txt b/tp/informe/tp/img/ejec-spin-correcto.txt deleted file mode 100644 index f6c017a..0000000 --- a/tp/informe/tp/img/ejec-spin-correcto.txt +++ /dev/null @@ -1,23 +0,0 @@ -$ spin -a kmeans.pml && cc -O2 -DNOCLAIM -o pan pan.c && ./pan - -(Spin Version 6.5.2 -- 18 September 2025) - + Partial Order Reduction - -Full statespace search for: - never claim - (not selected) - assertion violations + - acceptance cycles - (not selected) - invalid end states + - -State-vector 56 byte, depth reached 181, errors: 0 - 2412 states, stored - 822 states, matched - 3234 transitions (= stored+matched) - 1 atomic steps -hash conflicts: 0 (resolved) - -Stats on memory usage (in Megabytes): - 0.193 equivalent memory usage for states (stored*(State-vector + overhead)) - 0.382 actual memory usage for states - 128.000 memory used for hash table (-w24) - 0.534 memory used for DFS stack (-m10000) diff --git a/tp/informe/tp/img/ejec-spin-mutante.png b/tp/informe/tp/img/ejec-spin-mutante.png index d159b57..873898c 100644 Binary files a/tp/informe/tp/img/ejec-spin-mutante.png and b/tp/informe/tp/img/ejec-spin-mutante.png differ diff --git a/tp/informe/tp/img/ejec-spin-mutante.txt b/tp/informe/tp/img/ejec-spin-mutante.txt deleted file mode 100644 index c99b5ec..0000000 --- a/tp/informe/tp/img/ejec-spin-mutante.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ spin -DMUTANTE -a kmeans.pml && cc -O2 -DNOCLAIM -o pan-mutante pan.c && ./pan-mutante -pan:1: assertion violated (compartido==4) (at depth 205) -pan: wrote kmeans.pml.trail - -(Spin Version 6.5.2 -- 18 September 2025) -Warning: Search not completed - + Partial Order Reduction - -Full statespace search for: - never claim - (not selected) - assertion violations + - acceptance cycles - (not selected) - invalid end states + - -State-vector 56 byte, depth reached 209, errors: 1 - 393 states, stored - 42 states, matched diff --git a/tp/informe/tp/img/ejec-spin-termina.png b/tp/informe/tp/img/ejec-spin-termina.png index 74775bf..eea48bf 100644 Binary files a/tp/informe/tp/img/ejec-spin-termina.png and b/tp/informe/tp/img/ejec-spin-termina.png differ diff --git a/tp/informe/tp/img/ejec-spin-termina.txt b/tp/informe/tp/img/ejec-spin-termina.txt deleted file mode 100644 index 2af6e49..0000000 --- a/tp/informe/tp/img/ejec-spin-termina.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ spin -a kmeans.pml && cc -O2 -o pan-ltl pan.c && ./pan-ltl -a -f -N termina -pan: ltl formula termina - -(Spin Version 6.5.2 -- 18 September 2025) - + Partial Order Reduction - -Full statespace search for: - never claim + (termina) - assertion violations + (if within scope of claim) - acceptance cycles + (fairness enabled) - invalid end states - (disabled by never claim) - -State-vector 64 byte, depth reached 361, errors: 0 - 2412 states, stored (12643 visited) - 10057 states, matched - 22700 transitions (= visited+matched) - 1 atomic steps -hash conflicts: 0 (resolved) diff --git a/tp/informe/tp/img/ejec-traza-deadlock.png b/tp/informe/tp/img/ejec-traza-deadlock.png index c741ce3..ecb0705 100644 Binary files a/tp/informe/tp/img/ejec-traza-deadlock.png and b/tp/informe/tp/img/ejec-traza-deadlock.png differ diff --git a/tp/informe/tp/img/ejec-traza-deadlock.txt b/tp/informe/tp/img/ejec-traza-deadlock.txt deleted file mode 100644 index 23c08a2..0000000 --- a/tp/informe/tp/img/ejec-traza-deadlock.txt +++ /dev/null @@ -1,27 +0,0 @@ -$ spin -t -g -l -p -DMUTANTE_DEADLOCK kmeans.pml | sed -n '/trail ends/,$p' -spin: trail ends after 65 steps -#processes: 3 - seen[0] = 1 - seen[1] = 1 - seen[2] = 1 - seen[3] = 1 - conteo[0] = 2 - conteo[1] = 2 - pendientes = 1 - lectores = 0 - escribiendo = 0 - total = 0 - fin = 0 - queue 1 (trabajos): - 65: proc 2 (worker:1) kmeans.pml:61 (state 23) - worker(2):tmp = 0 - worker(2):i = 2 - worker(2):idx = 1 - 65: proc 1 (worker:1) kmeans.pml:61 (state 23) - worker(1):tmp = 0 - worker(1):i = 0 - worker(1):idx = 0 - 65: proc 0 (:init::1) kmeans.pml:113 (state 26) - :init:(0):i = 4 - :init:(0):c = 2 - :init:(0):it = 0 diff --git a/tp/informe/tp/secciones/01-resumen.tex b/tp/informe/tp/secciones/01-resumen.tex index e19d529..039602e 100644 --- a/tp/informe/tp/secciones/01-resumen.tex +++ b/tp/informe/tp/secciones/01-resumen.tex @@ -5,6 +5,16 @@ \section*{Resumen} y Distribuida y, como pide el enunciado, conserva los dos anteriores con sus correcciones. El caso es el mismo: K-means sobre los viajes del taxi amarillo de Nueva York \parencite{nyctlc} para caracterizar patrones de movilidad urbana, en línea con el Objetivo de Desarrollo Sostenible~11. +La Figura~\ref{fig:tarjeta} resume el resultado en una imagen: el tipo de viaje dominante en cada +zona de taxi en cuatro momentos de la semana. + +\begin{figure}[H] +\caption{Cómo se mueve Nueva York en taxi: tipo de viaje dominante por zona en cuatro momentos de la +semana, entre los ocho clusters del K-means concurrente sobre los \cifra{n}~viajes de enero de 2024} +\label{fig:tarjeta} +\centering +\includegraphics[width=\textwidth]{img/concurrente-card.png} +\end{figure} Los entregables anteriores dejaron un K-means en Go, sin librerías de terceros, en una versión secuencial y una concurrente con un \emph{worker pool} persistente, acumuladores privados por bloque @@ -26,3 +36,39 @@ \section*{Resumen} \textit{Palabras clave:} K-means, programación concurrente, Go, worker pool, Promela, Spin, LTL, verificación formal, deadlock, exclusión mutua, NYC TLC. + +\subsection*{Guía de lectura para la evaluación} + +La Tabla~\ref{tab:guia-rubrica} indica dónde está la evidencia de cada criterio del Entregable~3. +Cada ejecución que cita el informe tiene su captura de pantalla de la terminal, con el comando a la +vista: el pipeline y las pruebas de datos (Sección~\ref{sec:limpieza}), \texttt{pan} +(Sección~\ref{sec:promela}), la CLI y \texttt{go test -race -v} (Sección~\ref{sec:go}), el benchmark +(Sección~\ref{sec:speedup}), la integración continua (Sección~\ref{sec:github}) y la regresión de +Spin (Sección~\ref{sec:verificacion}). + +\begin{table}[H] +\caption{Dónde está la evidencia de cada criterio del Entregable~3}\label{tab:guia-rubrica} +\small +\begin{tabularx}{\textwidth}{@{}L{4.6cm}Yr@{}} +\toprule +\textbf{Criterio (puntos)} & \textbf{Evidencia} & \textbf{Pág.} \\ +\midrule +Verificación formal en Spin: ausencia de deadlocks y exclusión mutua (4) & + Sección~\ref{sec:verificacion}: siete casos en la Tabla~\ref{tab:spin-casos}, regresión en la + Figura~\ref{fig:ejec-spin-check}, progreso en la Figura~\ref{fig:spin-termina} y contraejemplo del + deadlock en la Figura~\ref{fig:traza-deadlock} & \pageref{sec:verificacion} \\ \addlinespace[3pt] +Análisis del código con IA e informe de GAPs en Markdown (5) & + Sección~\ref{sec:gaps}; el informe \texttt{.md}, en el Anexo~\ref{anexo:gaps} & \pageref{sec:gaps} \\ \addlinespace[3pt] +Conclusiones y recomendaciones del alumno (4) & + Sección~\ref{sec:conclusiones}; las de cada integrante, en la + Sección~\ref{sec:conclusiones-integrantes} & \pageref{sec:conclusiones} \\ \addlinespace[3pt] +Sustentación del informe final y video (5) & + Video en el Anexo~\ref{anexo:video}; cierre del caso de uso en la + Sección~\ref{sec:interpretacion-clusters} & \pageref{anexo:video} \\ \addlinespace[3pt] +Historial Git Flow con todos los integrantes (2) & + Sección~\ref{sec:github}: pull requests en la Tabla~\ref{tab:prs} e integración continua en la + Figura~\ref{fig:ejec-ci} & \pageref{sec:github} \\ +\bottomrule +\end{tabularx} +\end{table} + diff --git a/tp/informe/tp/secciones/05-limpieza.tex b/tp/informe/tp/secciones/05-limpieza.tex index 2321c6b..59e4285 100644 --- a/tp/informe/tp/secciones/05-limpieza.tex +++ b/tp/informe/tp/secciones/05-limpieza.tex @@ -28,18 +28,18 @@ \section{Procedimiento de limpieza del dataset}\label{sec:limpieza} Las Figuras~\ref{fig:ejec-pipeline} y~\ref{fig:ejec-pytest} son la ejecución de los dos últimos sobre los datos de esta entrega: el pipeline reconstruye gold con el mismo sha256 que cita el -anexo, y las 66 pruebas pasan. +anexo, y las 66 pruebas pasan, listadas una por una con \texttt{-v}. -\begin{figure}[H] +\begin{figure}[tbp] \caption{Ejecución del pipeline completo: bronze $\rightarrow$ silver $\rightarrow$ gold}\label{fig:ejec-pipeline} \centering -\includegraphics[width=0.95\textwidth]{img/ejec-pipeline.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-pipeline.png} \end{figure} -\begin{figure}[H] +\begin{figure}[tbp] \caption{Ejecución de las pruebas del pipeline de datos}\label{fig:ejec-pytest} \centering -\includegraphics[width=0.9\textwidth]{img/ejec-pytest.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-pytest.png} \end{figure} \subsection{Reglas de limpieza} diff --git a/tp/informe/tp/secciones/07-algoritmo-promela.tex b/tp/informe/tp/secciones/07-algoritmo-promela.tex index 305e3d5..e6280c8 100644 --- a/tp/informe/tp/secciones/07-algoritmo-promela.tex +++ b/tp/informe/tp/secciones/07-algoritmo-promela.tex @@ -220,16 +220,16 @@ \subsection{Resultados} \includegraphics[width=\textwidth]{img/traza-mutante.pdf} \end{figure} -\begin{figure}[H] +\begin{figure}[tbp] \caption{Ejecución de \texttt{pan} sobre el modelo correcto}\label{fig:spin-ok} \centering -\includegraphics[width=\textwidth]{img/ejec-spin-correcto.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-spin-correcto.png} \end{figure} -\begin{figure}[H] +\begin{figure}[tbp] \caption{Ejecución de \texttt{pan} sobre el mutante con acumulador compartido}\label{fig:spin-mut} \centering -\includegraphics[width=\textwidth]{img/ejec-spin-mutante.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-spin-mutante.png} \end{figure} \subsection{Hasta dónde llega esta prueba} diff --git a/tp/informe/tp/secciones/08-implementacion-go.tex b/tp/informe/tp/secciones/08-implementacion-go.tex index 2d52be1..afbfd90 100644 --- a/tp/informe/tp/secciones/08-implementacion-go.tex +++ b/tp/informe/tp/secciones/08-implementacion-go.tex @@ -56,22 +56,23 @@ \subsection{Versión concurrente} \subsection{Evidencia de funcionamiento} Las Figuras~\ref{fig:cli-seq} y~\ref{fig:cli-conc} son la salida de la CLI sobre el dataset -completo en la laptop del equipo, con $k = \cifra{k}$ y \cifra{iter-fijas} iteraciones. Los textos -de origen están en \texttt{tp/informe/pc2/img/} junto a las imágenes, y cualquiera puede rehacerlas -con los comandos que encabezan cada captura. Ambas corridas parten del mismo archivo de centroides +completo en la laptop del equipo, con $k = \cifra{k}$ y \cifra{iter-fijas} iteraciones. Son capturas +de pantalla de la terminal tal como se corrió cada comando, con el comando en el prompt; +\texttt{tp/scripts/capturar\_ejecuciones.sh} las rehace. La concurrente va con \texttt{-progreso}, +que dibuja cada iteración de Lloyd con su inercia mientras corre. Ambas corridas parten del mismo archivo de centroides iniciales (la primera lo genera y la segunda lo lee, como muestra el \texttt{init 0 ms}), y ambas terminan con la misma inercia, lo que es la primera comprobación de que calculan lo mismo. -\begin{figure}[H] +\begin{figure}[tbp] \caption{CLI en modo secuencial sobre el dataset completo}\label{fig:cli-seq} \centering -\includegraphics[width=\textwidth]{img/cli-secuencial.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/cli-secuencial.png} \end{figure} -\begin{figure}[H] +\begin{figure}[tbp] \caption{CLI en modo concurrente con 8 workers, mismos centroides iniciales}\label{fig:cli-conc} \centering -\includegraphics[width=\textwidth]{img/cli-concurrente.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/cli-concurrente.png} \end{figure} Cada corrida imprime, además del resultado, lo que hace falta para reproducirla: sha256 del gold y @@ -102,11 +103,19 @@ \subsection{Pruebas y equivalencia entre versiones}\label{sec:equivalencia} Sobre el gold real, una prueba adicional (que se omite con \texttt{-short}) corre ambas versiones y comprueba la equivalencia con \cifra{n}~viajes. La Tabla~\ref{tab:inercias} de la Sección~\ref{sec:reproducibilidad} muestra el resultado de esa comparación en las corridas oficiales. -La Figura~\ref{fig:ejec-go-test} es la ejecución completa, con el detector de carreras y sin -\texttt{-short}: incluida la prueba sobre el gold real, toma cerca de tres minutos. +Las Figuras~\ref{fig:ejec-go-test} y~\ref{fig:ejec-go-test-resto} son la ejecución completa, con el +detector de carreras, sin \texttt{-short} y con \texttt{-v}, que lista cada prueba con su resultado. +La suite se parte en dos pantallas para que se pueda leer: primero el núcleo (secuencial, +concurrente y las pruebas sobre el gold real, que toman cerca de tres minutos) y después el resto. -\begin{figure}[H] -\caption{Ejecución de \texttt{go vet} y de todas las pruebas con \texttt{-race}}\label{fig:ejec-go-test} +\begin{figure}[tbp] +\caption{Ejecución de \texttt{go vet} y de las pruebas del núcleo con \texttt{-race -v}}\label{fig:ejec-go-test} \centering -\includegraphics[width=0.78\textwidth]{img/ejec-go-test.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-go-test.png} +\end{figure} + +\begin{figure}[tbp] +\caption{Ejecución del resto de las pruebas con \texttt{-race -v}}\label{fig:ejec-go-test-resto} +\centering +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-go-test-resto.png} \end{figure} diff --git a/tp/informe/tp/secciones/10-speedup.tex b/tp/informe/tp/secciones/10-speedup.tex index 3be51be..b27db7a 100644 --- a/tp/informe/tp/secciones/10-speedup.tex +++ b/tp/informe/tp/secciones/10-speedup.tex @@ -46,10 +46,10 @@ \subsection{Protocolo de medición} la ejecución y del formato de salida; sus cifras no entran a las tablas, que salen de la corrida oficial completa. -\begin{figure}[H] +\begin{figure}[tbp] \caption{Ejecución reducida del benchmark (demostración; no es la corrida oficial)}\label{fig:ejec-benchmark} \centering -\includegraphics[width=\textwidth]{img/ejec-benchmark.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-benchmark.png} \end{figure} \subsection{Tabla de speedup}\label{sec:fuerte} diff --git a/tp/informe/tp/secciones/14-github.tex b/tp/informe/tp/secciones/14-github.tex index 0cdca91..d56e6a7 100644 --- a/tp/informe/tp/secciones/14-github.tex +++ b/tp/informe/tp/secciones/14-github.tex @@ -11,10 +11,10 @@ \section{Trabajo en GitHub}\label{sec:github} Figura~\ref{fig:ejec-ci} es el resultado de esos controles sobre la \emph{pull request} que cierra este entregable. -\begin{figure}[H] +\begin{figure}[tbp] \caption{Controles de integración continua sobre la \emph{pull request} \#50}\label{fig:ejec-ci} \centering -\includegraphics[width=\textwidth]{img/ejec-ci.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-ci.png} \end{figure} \subsection{Flujo Git Flow} diff --git a/tp/informe/tp/secciones/15-conclusiones.tex b/tp/informe/tp/secciones/15-conclusiones.tex index 5d6994e..dfa56f7 100644 --- a/tp/informe/tp/secciones/15-conclusiones.tex +++ b/tp/informe/tp/secciones/15-conclusiones.tex @@ -1,7 +1,7 @@ % ======================================================== % CONCLUSIONES % ======================================================== -\section{Conclusiones} +\section{Conclusiones}\label{sec:conclusiones} \subsection{Conclusiones del grupo} diff --git a/tp/informe/tp/secciones/17-verificacion-formal.tex b/tp/informe/tp/secciones/17-verificacion-formal.tex index b03c4c6..326e951 100644 --- a/tp/informe/tp/secciones/17-verificacion-formal.tex +++ b/tp/informe/tp/secciones/17-verificacion-formal.tex @@ -86,10 +86,10 @@ \subsection{Resultados} Figura~\ref{fig:ejec-spin-check} es la ejecución de esa regresión: cada caso compara el número de errores contra el esperado. -\begin{figure}[H] +\begin{figure}[tbp] \caption{Ejecución de la regresión de Spin: los siete casos}\label{fig:ejec-spin-check} \centering -\includegraphics[width=\textwidth]{img/ejec-spin-check.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-spin-check.png} \end{figure} \begin{table}[H] @@ -111,10 +111,10 @@ \subsection{Resultados} (Figura~\ref{fig:spin-termina}). \needspace{21\baselineskip} -\begin{figure}[H] +\begin{figure}[tbp] \caption{Ejecución de \texttt{pan -a -f -N termina} sobre el modelo correcto}\label{fig:spin-termina} \centering -\includegraphics[width=0.88\textwidth]{img/ejec-spin-termina.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-spin-termina.png} \end{figure} \paragraph{El deadlock aparece en la primera iteración.} Con el \texttt{wg.Done} perdido, Spin @@ -127,10 +127,10 @@ \subsection{Resultados} trabajo se hizo y el programa no termina: es exactamente el síntoma de un \texttt{wg.Done} perdido. \needspace{30\baselineskip} -\begin{figure}[H] +\begin{figure}[tbp] \caption{Estado final del contraejemplo de \texttt{MUTANTE\_DEADLOCK} (\texttt{spin -t -g -l -p})}\label{fig:traza-deadlock} \centering -\includegraphics[width=0.86\textwidth]{img/ejec-traza-deadlock.png} +\includegraphics[width=\textwidth,height=0.72\textheight,keepaspectratio]{img/ejec-traza-deadlock.png} \end{figure} El mismo mutante viola también la fórmula de progreso: \texttt{pan -a -f -N termina} encuentra un diff --git a/tp/informe/tp/secciones/19-anexos.tex b/tp/informe/tp/secciones/19-anexos.tex index f809907..e3775e6 100644 --- a/tp/informe/tp/secciones/19-anexos.tex +++ b/tp/informe/tp/secciones/19-anexos.tex @@ -8,9 +8,13 @@ \section{Video de sustentación}\label{anexo:video} escalabilidad y las posibles mejoras. \begin{itemize} - \item \textbf{URL:} \pendiente{enlace público al video} - \item \textbf{Duración:} \pendiente{mm:ss, como máximo 6:00} - \item \textbf{Partes:} \pendiente{quién presenta qué, con el minuto en que empieza cada parte} + \item \textbf{URL:} \url{https://drive.google.com/drive/folders/1S9Dq6RJhHhUIf5h-7miV-QW5wrrLKuQa} + (carpeta pública «Video TB» de Google Drive, con el video unido de los tres integrantes) + \item \textbf{Duración:} hasta 6:00, como pide el enunciado. + \item \textbf{Partes, en este orden:} Rody Vilchez (caso de uso, worker pool, ejecución de la CLI, + pruebas con \texttt{-race} y speedup), Dayana Gómez (verificación formal en Spin y + mutantes) y Julio Meza (GAPs con IA, interpretación de los clusters, la app y discusión + crítica). \end{itemize} \section{Informe de GAPs en Markdown}\label{anexo:gaps} @@ -46,14 +50,17 @@ \section{Declaración de uso de inteligencia artificial}\label{anexo:ia} \addlinespace Coordinación del grupo por WhatsApp & Claude Code como asistente del coordinador & Cada mensaje lleva la firma del modelo y el nombre de quien lo envía \\ +\addlinespace +Consultas de apoyo de Dayana y de Julio (en el caso de Julio, sobre código) & ChatGPT (OpenAI) & + El código que entró al repositorio pasó por las mismas pruebas con \texttt{-race} y la misma + integración continua que el resto \\ \bottomrule \end{tabularx} \end{table} -Desde el 26 de septiembre de 2026, los commits hechos con Claude Code llevan la línea -\texttt{Co-Authored-By: Claude}, así que el historial de la Sección~\ref{sec:github} permite -rastrearlos; los anteriores no llevan esa marca aunque también se hayan hecho con asistencia. Las conclusiones de cada integrante (Sección~\ref{sec:conclusiones-integrantes}) son -propias de cada uno. - -\verificar{Rody: confirmar que la tabla refleja el uso real en la PC1 y la PC2 (qué herramienta y -modelo, si alguien del grupo usó otra) y borrar esta marca} +Entre el 26 y el 30 de septiembre de 2026, los commits hechos con Claude Code llevan la línea +\texttt{Co-Authored-By: Claude}; desde el 1 de octubre el grupo dejó de marcar los commits y el uso +de IA se declara únicamente en este anexo, así que el historial de la Sección~\ref{sec:github} no +basta para rastrearlo. Las conclusiones de Dayana y de Julio +(Sección~\ref{sec:conclusiones-integrantes}) son propias de cada uno; la de Rody partió de un +borrador redactado con Claude a partir del trabajo hecho, que Rody revisó y aceptó. diff --git a/tp/informe/tp/secciones/conclusiones/rody.tex b/tp/informe/tp/secciones/conclusiones/rody.tex index 79d5495..6795362 100644 --- a/tp/informe/tp/secciones/conclusiones/rody.tex +++ b/tp/informe/tp/secciones/conclusiones/rody.tex @@ -7,8 +7,6 @@ % - En lo que hiciste tú (tu PR), ¿qué harías distinto? % Para compilar y ver el PDF: cd tp/informe/tp && ./compilar.sh (sale en build/main.pdf). \subsubsection*{\nombreRody} -\verificar{borrador redactado con Claude a partir del trabajo hecho: Rody lo lee, lo ajusta a su -voz y borra esta marca} Lo que más me dejó este trabajo es que en concurrencia el costo real no está donde uno lo busca. Esperaba que el límite del speedup fuera una parte secuencial del algoritmo, y resultó ser el costo diff --git a/tp/scripts/capturar_ejecuciones.sh b/tp/scripts/capturar_ejecuciones.sh index 85265e6..520297d 100755 --- a/tp/scripts/capturar_ejecuciones.sh +++ b/tp/scripts/capturar_ejecuciones.sh @@ -1,88 +1,133 @@ #!/usr/bin/env bash -# Corre cada ejecución que cita el informe del TP y deja su captura en informe/tp/img/ejec-*.png. +# Captura de pantalla real de cada ejecución que cita el informe del TP, en informe/tp/img/. # # El docente pide una captura de cada ejecución: una que solo se nombra en el texto, o que aparece -# como listado, cuenta como no demostrada. Cada captura sale de la salida real del comando: el -# .txt queda junto al .png, su primera línea `$ ...` es el comando tal como se corrió, y este -# script los rehace todos. +# como listado, cuenta como no demostrada. Por eso no se renderiza texto: el script abre una +# ventana de kitty flotante en Hyprland, teclea el comando en el shell de siempre (prompt, git, +# fastfetch), espera a que termine y fotografía la ventana con grim. Las pruebas van con -v, para +# que se vea cada caso y no solo un «ok». # # tp/scripts/capturar_ejecuciones.sh # todas # tp/scripts/capturar_ejecuciones.sh spin ci # solo esos grupos # -# Grupos: datos (nyc-tlc, pytest), go (vet + test -race), spin (make check y las salidas de pan -# que comenta el informe), benchmark (corrida reducida de demostración), ci (los checks de GitHub -# Actions sobre la PR del cierre del Entregable 3, que es el código que se entrega). -# Requiere uv, go, spin, cc y gh con sesión. +# Grupos: cli (secuencial y concurrente), datos (nyc-tlc, pytest), go (vet + test -race -v), +# spin (make check y las corridas de pan que comenta el informe), benchmark (corrida reducida de +# demostración), ci (checks de la PR #50, que cerró el Entregable 3). +# Requiere Hyprland (hyprctl eval), kitty, grim, uv, go, spin, cc y gh con sesión. Abre ventanas +# en el monitor activo: no tocar el teclado mientras corre. set -euo pipefail TP=$(cd "$(dirname "$0")/.." && pwd) IMG=$TP/informe/tp/img -GEN=$TP/informe/tp/generado +SOCK=${XDG_RUNTIME_DIR:-/tmp}/kitty-captura-$$.sock +KITTY=(kitty @ --to "unix:$SOCK") -# capturar [columnas]: «$ comando» más su salida → -# img/ejec-.txt. Si el comando falla, el script falla: una captura de un error no es -# evidencia de nada. De una línea de progreso que se reescribe con \r queda solo el último estado, -# como en la terminal; los tabuladores se expanden como en la terminal, salvo con «columnas», que -# alinea en columnas una salida tabular (la de gh). -capturar() { - local nombre=$1 dir=$2 cmd=$3 modo=${4:-} - local txt=$IMG/ejec-$nombre.txt - echo "→ $nombre: $cmd" >&2 - { echo "\$ $cmd"; (cd "$dir" && bash -o pipefail -c "$cmd") 2>&1; } > "$txt.tmp" - if [ "$modo" = columnas ]; then - sed 's/.*\r//' "$txt.tmp" | column -t -s $'\t' -L - else - sed 's/.*\r//' "$txt.tmp" | expand -t 8 - fi | sed 's/[[:space:]]*$//' > "$txt" - rm "$txt.tmp" +# ¿Hay en la ventana algo distinto del shell en primer plano? +ocupado() { + "${KITTY[@]}" ls | python3 -c ' +import json, sys +procs = [p for o in json.load(sys.stdin) for t in o["tabs"] for w in t["windows"] + for p in w["foreground_processes"]] +sys.exit(0 if any(not p["cmdline"][0].endswith("zsh") for p in procs) else 1)' +} + +esperar() { + sleep 1.5 + while ocupado; do sleep 1; done + sleep 0.8 # el prompt se dibuja después de que termina el proceso +} + +teclear() { "${KITTY[@]}" send-text -- "$1"$'\r'; } + +# abrir : kitty flotante bajo la barra, con el shell listo. +abrir() { + local ancho=$1 alto=$2 fuente=$3 dir=$4 + rm -f "$SOCK" + hyprctl eval "hl.exec_cmd(\"kitty --class captura-tp -o allow_remote_control=yes \ +--listen-on unix:$SOCK -o env=GH_PAGER=cat -o env=PAGER=cat -o background_opacity=1 -o font_size=$fuente --directory $dir\", \ +{ float = true, move = { 24, 52 }, size = { $ancho, $alto } })" >/dev/null + for _ in $(seq 1 80); do [ -S "$SOCK" ] && break; sleep 0.25; done + [ -S "$SOCK" ] || { echo "kitty no abrió la ventana de captura" >&2; exit 1; } + esperar # fastfetch del .zshrc } -# desde_generado : las salidas de pan que deja -# `make informe` en generado/, con el comando que las produjo y recortadas como en el informe. -desde_generado() { - local nombre=$1 cmd=$2 archivo=$3 lineas=$4 - { echo "\$ $cmd"; head -n "$lineas" "$GEN/$archivo" | expand -t 8; } > "$IMG/ejec-$nombre.txt" +foto() { + local geo + geo=$(hyprctl clients -j | python3 -c ' +import json, sys +for c in json.load(sys.stdin): + if c["class"] == "captura-tp": + print("%d,%d %dx%d" % (*c["at"], *c["size"])) + break') + grim -g "$geo" "$IMG/$1.png" + "$TP/scripts/recortar_captura.sh" "$IMG/$1.png" 2>/dev/null # fondo vacío bajo el prompt + "${KITTY[@]}" close-window + sleep 0.5 + echo "→ $IMG/$1.png" >&2 +} + +# capturar +# Con «si» se borra el fastfetch antes del comando, para las salidas largas. +capturar() { + local nombre=$1 dir=$2 ancho=$3 alto=$4 fuente=$5 limpiar=$6 cmd=$7 + echo "· $nombre: $cmd" >&2 + abrir "$ancho" "$alto" "$fuente" "$dir" + if [ "$limpiar" = si ]; then teclear clear; sleep 0.5; fi + teclear "$cmd" + esperar + foto "$nombre" } grupos=("$@") -[ ${#grupos[@]} -eq 0 ] && grupos=(datos go spin benchmark ci) +[ ${#grupos[@]} -eq 0 ] && grupos=(cli datos go spin benchmark ci) for g in "${grupos[@]}"; do case $g in + cli) + # La secuencial genera los centroides iniciales y la concurrente los lee: mismo punto + # de partida, y el «init 0 ms» de la segunda lo muestra. + rm -f /tmp/centroides_k8.json + capturar cli-secuencial "$TP/kmeans" 1000 640 10 no \ + "go run ./cmd/kmeans -modo seq -k 8 -iter 10 -centroides /tmp/centroides_k8.json" + capturar cli-concurrente "$TP/kmeans" 1180 900 10 no \ + "go run ./cmd/kmeans -modo conc -workers 8 -chunk 16384 -k 8 -iter 10 -centroides /tmp/centroides_k8.json -progreso" + ;; datos) - capturar pipeline "$TP" "uv run nyc-tlc all" - capturar pytest "$TP" "uv run pytest -q" + capturar ejec-pipeline "$TP" 1000 520 11 no "uv run nyc-tlc all" + capturar ejec-pytest "$TP" 900 1020 8 si "uv run pytest -v --no-header" ;; go) - capturar go-test "$TP/kmeans" "go vet ./... && go test -race -count=1 ./..." + # -v imprime «=== RUN» y «--- PASS» por prueba; se filtran los RUN y los subtests (el padre + # solo pasa si pasan todos sus subtests), y la suite se parte + # en dos pantallas legibles: el núcleo (secuencial, concurrente y el piloto sobre el gold + # real) y el resto. Entre las dos corren todas las pruebas, sin -short. + capturar ejec-go-test "$TP/kmeans" 800 1020 8 si \ + "go vet ./... && go test -race -count=1 -v -run 'Concurrente|Secuencial|Piloto' ./... 2>&1 | grep -Ev '^(=== | --- )'" + capturar ejec-go-test-resto "$TP/kmeans" 800 1020 8 si \ + "go test -race -count=1 -v -skip 'Concurrente|Secuencial|Piloto' ./... 2>&1 | grep -Ev '^(=== | --- )'" ;; spin) - make -C "$TP/spin" informe >/dev/null - capturar spin-check "$TP/spin" "make check" - desde_generado spin-correcto \ - "spin -a kmeans.pml && cc -O2 -DNOCLAIM -o pan pan.c && ./pan" spin-correcto.txt 22 - desde_generado spin-mutante \ - "spin -DMUTANTE -a kmeans.pml && cc -O2 -DNOCLAIM -o pan-mutante pan.c && ./pan-mutante" \ - spin-mutante.txt 16 - desde_generado spin-termina \ - "spin -a kmeans.pml && cc -O2 -o pan-ltl pan.c && ./pan-ltl -a -f -N termina" spin-termina.txt 17 - desde_generado traza-deadlock \ - "spin -t -g -l -p -DMUTANTE_DEADLOCK kmeans.pml | sed -n '/trail ends/,\$p'" traza-deadlock.txt 26 + capturar ejec-spin-check "$TP/spin" 1250 640 10 no "make check" + capturar ejec-spin-correcto "$TP/spin" 1000 880 9 si "make verify" + capturar ejec-spin-mutante "$TP/spin" 1000 700 9 si "make mutante" + capturar ejec-spin-termina "$TP/spin" 1000 800 9 si \ + "spin -a kmeans.pml && cc -O2 -o pan-ltl pan.c && ./pan-ltl -a -f -N termina" + capturar ejec-traza-deadlock "$TP/spin" 1300 680 9 si \ + "spin -DMUTANTE_DEADLOCK -a kmeans.pml && cc -O2 -DNOCLAIM -o pan-deadlock pan.c && ./pan-deadlock > /dev/null; spin -t -g -l -p -DMUTANTE_DEADLOCK kmeans.pml | sed -n '/trail ends/,\$p'" + make -C "$TP/spin" clean >/dev/null ;; benchmark) # Corrida reducida, para mostrar el protocolo funcionando: las cifras del informe son de la # corrida oficial en gorgo (20 repeticiones, P hasta 16) y no salen de esta captura. - capturar benchmark "$TP/kmeans" \ + capturar ejec-benchmark "$TP/kmeans" 1250 680 10 no \ "go run ./cmd/benchmark -repes 3 -workers 1,4,8 -experimentos fijas -bootstrap 200 -salida /tmp/benchmark-demo.json" ;; ci) - capturar ci "$TP/.." "gh pr checks 50" columnas + capturar ejec-ci "$TP/.." 1250 600 10 no "gh pr checks 50" ;; *) - echo "grupo desconocido: $g (datos, go, spin, benchmark, ci)" >&2 + echo "grupo desconocido: $g (cli, datos, go, spin, benchmark, ci)" >&2 exit 2 ;; esac done - -uv run --project "$TP" python "$TP/scripts/capturas_terminal.py" "$IMG"/ejec-*.txt diff --git a/tp/scripts/recortar_captura.sh b/tp/scripts/recortar_captura.sh new file mode 100755 index 0000000..dbe1e88 --- /dev/null +++ b/tp/scripts/recortar_captura.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Quita el fondo vacío bajo el último renglón de una captura de terminal, con un margen. +# No toca el contenido: solo corta filas de fondo al pie. El borde de la ventana se ignora al +# medir (por eso el -shave), porque sus esquinas tienen color. +# +# tp/scripts/recortar_captura.sh img/ejec-go-test.png [más.png ...] +set -euo pipefail +for f in "$@"; do + read -r w h < <(magick identify -format '%w %h\n' "$f") + # caja del contenido dentro de la ventana: AnchoxAlto+X+Y + caja=$(magick "$f" -shave 8x8 -fuzz 14% -format '%@' info:) + alto_contenido=$(echo "$caja" | sed -E 's/^[0-9]+x([0-9]+)\+[0-9]+\+([0-9]+)$/\1 \2/' | awk '{print $1+$2+8}') + nuevo=$((alto_contenido + 24)) + if [ "$nuevo" -lt "$h" ]; then + magick "$f" -crop "${w}x${nuevo}+0+0" +repage "$f" + echo "→ $f: ${h} → ${nuevo} px" >&2 + fi +done