Aggiunge documentazione e script per face KNN e face scan
This commit is contained in:
parent
867ed8d801
commit
17b4cf6cf5
7 changed files with 462 additions and 0 deletions
162
KNN-SCAN-flusso-shadow.md
Normal file
162
KNN-SCAN-flusso-shadow.md
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
# Flusso KNN Shadow — progetto s190js
|
||||||
|
|
||||||
|
## Panoramica
|
||||||
|
|
||||||
|
Il confronto KNN in modalità **shadow** viene eseguito lato **server Node.js**, non nel browser. Il flusso parte dal worker che aggiorna i prototipi facciali e arriva al binario nativo `face_knn`, passando attraverso il modulo di confronto, il runtime KNN e uno script shell.
|
||||||
|
|
||||||
|
```text
|
||||||
|
Server Node.js
|
||||||
|
└── tools/runPrototypeWorker.js
|
||||||
|
└── tools/runFaceKnnShadow.js
|
||||||
|
└── tools/faceKnnRuntime.js
|
||||||
|
└── native/face-knn/run-face-knn.sh
|
||||||
|
└── native/face-knn/bin/face_knn
|
||||||
|
```
|
||||||
|
|
||||||
|
Percorso del progetto usato negli esempi:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/home/nvme/dockerdata/prove/s190js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruolo dei componenti
|
||||||
|
|
||||||
|
### 1. `tools/runPrototypeWorker.js` — worker Node.js
|
||||||
|
|
||||||
|
È il processo server che gestisce i job di aggiornamento dei prototipi facciali.
|
||||||
|
|
||||||
|
In sintesi:
|
||||||
|
|
||||||
|
1. recupera un job in stato `pending`;
|
||||||
|
2. lo porta in elaborazione (`processing`);
|
||||||
|
3. esegue la procedura principale di selezione dei prototipi;
|
||||||
|
4. salva il risultato nel database;
|
||||||
|
5. dopo il salvataggio, avvia il confronto KNN shadow.
|
||||||
|
|
||||||
|
Il confronto shadow viene quindi eseguito **dopo** il salvataggio del risultato principale. Non è il componente che decide quali prototipi selezionare nella procedura ordinaria.
|
||||||
|
|
||||||
|
### 2. `tools/runFaceKnnShadow.js` — confronto KNN in modalità shadow
|
||||||
|
|
||||||
|
Questo modulo coordina il confronto tra i risultati KNN nativi e quelli di riferimento prodotti dall'esperimento.
|
||||||
|
|
||||||
|
Il suo compito è verificare e registrare eventuali differenze. In modalità `shadow`, il risultato del KNN nativo è usato per validazione e analisi: non sostituisce la selezione principale dei prototipi.
|
||||||
|
|
||||||
|
Eventuali errori o discrepanze del confronto vengono registrati nei log; secondo il flusso esaminato, non annullano il salvataggio dei prototipi già completato.
|
||||||
|
|
||||||
|
### 3. `tools/faceKnnRuntime.js` — runtime KNN
|
||||||
|
|
||||||
|
Questo modulo prepara e avvia l'esecuzione del KNN nativo.
|
||||||
|
|
||||||
|
In base al codice esaminato, si occupa di attività come:
|
||||||
|
|
||||||
|
- leggere la configurazione KNN;
|
||||||
|
- recuperare gli embedding delle facce e i prototipi da confrontare;
|
||||||
|
- preparare i file di input temporanei richiesti dal programma nativo;
|
||||||
|
- invocare il launcher configurato;
|
||||||
|
- leggere e interpretare l'output JSON del binario.
|
||||||
|
|
||||||
|
Il launcher è configurato nel file:
|
||||||
|
|
||||||
|
```text
|
||||||
|
native/face-knn/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Il valore atteso per `launcher` è:
|
||||||
|
|
||||||
|
```text
|
||||||
|
native/face-knn/run-face-knn.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
L'effettiva esecuzione dipende dalla configurazione: il KNN deve essere abilitato e la modalità shadow deve essere attiva.
|
||||||
|
|
||||||
|
### 4. `native/face-knn/run-face-knn.sh` — script shell
|
||||||
|
|
||||||
|
È il punto di ingresso shell usato per lanciare il programma nativo.
|
||||||
|
|
||||||
|
Lo script cambia nella propria directory e poi esegue il binario:
|
||||||
|
|
||||||
|
```text
|
||||||
|
./bin/face_knn
|
||||||
|
```
|
||||||
|
|
||||||
|
Questo passaggio permette al programma nativo di trovare correttamente i file relativi alla propria directory, come il kernel OpenCL, senza dipendere dalla directory da cui è stato avviato il server.
|
||||||
|
|
||||||
|
Lo script è quindi un **launcher lato server**. Non viene eseguito dal browser.
|
||||||
|
|
||||||
|
### 5. `native/face-knn/bin/face_knn` — binario nativo
|
||||||
|
|
||||||
|
È il programma compilato che esegue il confronto KNN.
|
||||||
|
|
||||||
|
Riceve dal runtime i percorsi dei file di input e i parametri necessari, come il numero di query, il numero di prototipi, la dimensione degli embedding, il valore di `top-k` e il backend richiesto.
|
||||||
|
|
||||||
|
Il programma restituisce i risultati al processo Node.js, che li interpreta e li usa nel rapporto di confronto shadow.
|
||||||
|
|
||||||
|
## Quando viene eseguito il flusso
|
||||||
|
|
||||||
|
Il flusso non viene eseguito semplicemente perché un utente apre una pagina web.
|
||||||
|
|
||||||
|
Viene avviato dal worker server durante l'elaborazione di un job di aggiornamento dei prototipi, dopo il completamento del salvataggio principale, se la configurazione KNN abilita il confronto shadow.
|
||||||
|
|
||||||
|
L'assegnazione di un cluster a una persona accoda un job di aggiornamento dei prototipi. Il daemon/worker elabora quel job; il confronto KNN shadow è una fase successiva del lavoro server.
|
||||||
|
|
||||||
|
## Cosa fa e cosa non fa la modalità shadow
|
||||||
|
|
||||||
|
| Attività | Componente principale |
|
||||||
|
|---|---|
|
||||||
|
| Gestire il job di aggiornamento | `runPrototypeWorker.js` |
|
||||||
|
| Selezionare e salvare i prototipi principali | Worker e procedura di selezione |
|
||||||
|
| Coordinare il confronto di validazione | `runFaceKnnShadow.js` |
|
||||||
|
| Preparare input e invocare il programma nativo | `faceKnnRuntime.js` |
|
||||||
|
| Avviare il binario | `run-face-knn.sh` |
|
||||||
|
| Eseguire il calcolo KNN nativo | `bin/face_knn` |
|
||||||
|
|
||||||
|
**Importante:** in modalità `shadow`, il KNN nativo è un controllo parallelo di validazione. Non è il motore che determina direttamente quali prototipi vengono salvati. Per cambiare questo comportamento servirebbe una modifica esplicita al flusso applicativo e una verifica separata.
|
||||||
|
|
||||||
|
## Verifiche sul server
|
||||||
|
|
||||||
|
Per controllare la configurazione effettiva e i punti di collegamento, eseguire sul server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/nvme/dockerdata/prove/s190js
|
||||||
|
|
||||||
|
echo "=== Configurazione KNN ==="
|
||||||
|
cat native/face-knn/config.json
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== Collegamenti nel codice ==="
|
||||||
|
grep -n -E \
|
||||||
|
'runFaceKnnShadow|runNativeKnn|launcher|spawnSync' \
|
||||||
|
tools/runPrototypeWorker.js \
|
||||||
|
tools/runFaceKnnShadow.js \
|
||||||
|
tools/faceKnnRuntime.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Per verificare che lo script shell lanci il binario previsto:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/nvme/dockerdata/prove/s190js
|
||||||
|
|
||||||
|
cat native/face-knn/run-face-knn.sh
|
||||||
|
ls -l native/face-knn/run-face-knn.sh \
|
||||||
|
native/face-knn/bin/face_knn
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nota sul fallback
|
||||||
|
|
||||||
|
La configurazione può contenere un backend di fallback, ad esempio CPU. La sola presenza di un'impostazione come `fallbackBackend` non dimostra però che il codice esegua automaticamente un secondo tentativo in caso di errore. Per affermarlo con certezza occorre verificare nel runtime il percorso di gestione degli errori e l'eventuale seconda invocazione.
|
||||||
|
|
||||||
|
## Conclusione
|
||||||
|
|
||||||
|
La catena è interamente lato server:
|
||||||
|
|
||||||
|
```text
|
||||||
|
runPrototypeWorker.js
|
||||||
|
→ runFaceKnnShadow.js
|
||||||
|
→ faceKnnRuntime.js
|
||||||
|
→ run-face-knn.sh
|
||||||
|
→ bin/face_knn
|
||||||
|
```
|
||||||
|
|
||||||
|
Il worker principale salva i prototipi; successivamente, se la configurazione lo consente, viene lanciato il confronto KNN shadow per confrontare e validare i risultati. Il browser non esegue né lo script shell né il binario nativo.
|
||||||
|
|
||||||
|
Questo documento descrive il flusso ricostruito dal codice esaminato. Per confermare che una specifica esecuzione sia avvenuta, occorre controllare la configurazione attiva e i log del worker.
|
||||||
164
KNN-SCAN.md
Normal file
164
KNN-SCAN.md
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
# Gestione dei prototipi facciali: flusso di assegnazione e aggiornamento
|
||||||
|
|
||||||
|
**Progetto:** server fotografico `s190js`
|
||||||
|
**Percorso di riferimento:** `/home/nvme/dockerdata/prove/s190js`
|
||||||
|
**Scopo:** descrivere il comportamento verificato nel codice, dalla nomina di un cluster al salvataggio dei prototipi usati per il riconoscimento facciale.
|
||||||
|
|
||||||
|
> **Nota sul livello di verifica:** questo documento descrive il codice esaminato durante l'analisi. Non dimostra che uno specifico job sia stato completato nel database in produzione: per quello occorre controllare i record reali.
|
||||||
|
|
||||||
|
## 1. Panoramica
|
||||||
|
|
||||||
|
Quando si assegna una persona a un cluster dalla revisione dei volti, la route aggiorna le associazioni dei volti e richiede un aggiornamento dei prototipi per quella persona.
|
||||||
|
|
||||||
|
La richiesta viene registrata nella tabella `face_prototype_jobs`. Un daemon controlla la coda e avvia `tools/runPrototypeWorker.js` in modalità persistente (`--persist`). Il worker esegue la selezione dei prototipi e, se l'elaborazione riesce, salva i risultati in una transazione SQLite.
|
||||||
|
|
||||||
|
Il confronto KNN/OpenCL in modalità `shadow` viene eseguito **dopo** il salvataggio. Serve a confrontare i risultati e non decide quali prototipi vengono salvati.
|
||||||
|
|
||||||
|
## 2. Componenti coinvolti
|
||||||
|
|
||||||
|
| Componente | Responsabilità |
|
||||||
|
|---|---|
|
||||||
|
| `routes/faceReview.js` | Gestisce l'assegnazione della persona al cluster e richiede l'aggiornamento dei prototipi. |
|
||||||
|
| `queuePrototypeRefresh()` in `routes/faceReview.js` | Crea o aggiorna un job `pending` per la persona e l'utente. |
|
||||||
|
| Tabella `face_prototype_jobs` | Registra le richieste, lo stato, i tentativi, gli errori e il risultato. |
|
||||||
|
| `tools/runPrototypeDaemon.js` | Controlla periodicamente la coda, recupera alcuni job bloccati e avvia il worker. |
|
||||||
|
| `tools/runPrototypeWorker.js` | Calcola la selezione, salva i prototipi e le valutazioni e aggiorna lo stato del job. |
|
||||||
|
| `person_face_prototypes` | Contiene i prototipi facciali associati alle persone. |
|
||||||
|
| `person_face_recognition_evaluations` | Contiene le valutazioni di riconoscimento calcolate dal worker. |
|
||||||
|
| `face_recognition_index_state` | Indica che l'indice di riconoscimento deve essere aggiornato (`dirty`). |
|
||||||
|
| `tools/faceKnnRuntime.js` e `tools/runFaceKnnShadow.js` | Eseguono il confronto KNN in modalità shadow, se abilitato e configurato. |
|
||||||
|
|
||||||
|
## 3. Dall'assegnazione del cluster alla coda
|
||||||
|
|
||||||
|
Il frontend invia una richiesta alla route:
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /face-review/clusters/:clusterId/assign-person
|
||||||
|
```
|
||||||
|
|
||||||
|
con i dati della persona e gli ID dei volti inclusi. Nel codice esaminato, la route:
|
||||||
|
|
||||||
|
1. verifica che la persona e il cluster siano validi;
|
||||||
|
2. verifica che i volti indicati appartengano al cluster;
|
||||||
|
3. aggiorna le membership, segnando i volti inclusi come accettati e quelli esclusi come esclusi;
|
||||||
|
4. assegna `person_id` ai volti inclusi e rimuove eventuali esclusioni corrispondenti;
|
||||||
|
5. gestisce i volti esclusi e le relative righe in `person_face_exclusions`;
|
||||||
|
6. aggiorna `face_clusters.person_id`;
|
||||||
|
7. chiama `queuePrototypeRefresh()` con `reason: 'cluster_assigned'`.
|
||||||
|
|
||||||
|
Questi aggiornamenti e l'accodamento sono eseguiti nel contesto della transazione della route.
|
||||||
|
|
||||||
|
### Come viene accorpata la coda
|
||||||
|
|
||||||
|
`queuePrototypeRefresh()` cerca un job con lo stesso `user`, lo stesso `person_id` e `status = 'pending'`.
|
||||||
|
|
||||||
|
- **Se lo trova:** aggiorna il job esistente, compresi `reason`, `requested_by` e `requested_at`.
|
||||||
|
- **Se non lo trova:** crea un nuovo job con `status = 'pending'`.
|
||||||
|
|
||||||
|
Il riutilizzo riguarda solo i job `pending`. Se esiste già un job `processing`, questa funzione non lo aggiorna: può creare un nuovo job `pending`.
|
||||||
|
|
||||||
|
## 4. Come il daemon esegue i job
|
||||||
|
|
||||||
|
Il `package.json` definisce:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"prototype:daemon": "node tools/runPrototypeDaemon.js",
|
||||||
|
"prototype:worker": "node tools/runPrototypeWorker.js --persist",
|
||||||
|
"prototype:once": "node tools/runPrototypeDaemon.js --once"
|
||||||
|
```
|
||||||
|
|
||||||
|
Il daemon:
|
||||||
|
|
||||||
|
1. conta i job con `status = 'pending'`;
|
||||||
|
2. se non ne trova, attende l'intervallo configurato e ricontrolla (salvo la modalità `--once`);
|
||||||
|
3. se ne trova, avvia `tools/runPrototypeWorker.js --persist`;
|
||||||
|
4. dopo un successo, può avviare immediatamente un altro job pending;
|
||||||
|
5. se il worker fallisce, registra l'errore nei log e attende prima di ricontrollare la coda.
|
||||||
|
|
||||||
|
### Recupero dei job bloccati
|
||||||
|
|
||||||
|
`recoverStaleJobs()` può riportare da `processing` a `pending` i job che hanno `started_at` più vecchio della soglia `staleMinutes` configurata. Il job viene contrassegnato con il motivo `stale_processing_recovered`.
|
||||||
|
|
||||||
|
Questa è una protezione per i job rimasti bloccati in elaborazione; non equivale a un nuovo tentativo automatico di tutti i job in stato `error`.
|
||||||
|
|
||||||
|
## 5. Cosa fa il worker
|
||||||
|
|
||||||
|
### 5.1 Selezione e acquisizione
|
||||||
|
|
||||||
|
`loadPendingJob()` cerca un job `pending` unito alla tabella `persons`, ordinando per `requested_at` crescente. Quando inizia il salvataggio persistente, `claimJob()` tenta di cambiare lo stato da `pending` a `processing`, incrementando `attempts` e registrando la firma degli input.
|
||||||
|
|
||||||
|
Se un altro worker ha già acquisito il job, l'aggiornamento condizionale non riesce e il worker segnala un errore.
|
||||||
|
|
||||||
|
### 5.2 Calcolo e controlli
|
||||||
|
|
||||||
|
Il worker carica i prototipi correnti, le esclusioni e una firma dei dati di input. Esegue l'esperimento di selezione e filtra i volti esclusi. Se non resta alcun prototipo selezionato, il job fallisce.
|
||||||
|
|
||||||
|
Prima di salvare, `persistResult()` ricalcola la firma degli input. Se è cambiata durante l'elaborazione:
|
||||||
|
|
||||||
|
- il job corrente diventa `superseded`;
|
||||||
|
- viene creato o riutilizzato un job sostitutivo `pending`;
|
||||||
|
- il risultato registra l'ID del job sostitutivo.
|
||||||
|
|
||||||
|
Questo evita di applicare una selezione calcolata su dati che nel frattempo sono cambiati.
|
||||||
|
|
||||||
|
### 5.3 Salvataggio dei prototipi
|
||||||
|
|
||||||
|
Quando gli input sono ancora validi, `persistResult()`:
|
||||||
|
|
||||||
|
1. carica le esclusioni di riferimento;
|
||||||
|
2. mantiene attivi i prototipi bloccati (`locked`) che non sono esclusi;
|
||||||
|
3. disattiva i prototipi non bloccati precedenti della persona;
|
||||||
|
4. inserisce o aggiorna i prototipi automatici selezionati in `person_face_prototypes`;
|
||||||
|
5. aggiorna l'ordine di selezione e i metadati;
|
||||||
|
6. ricalcola e salva le valutazioni in `person_face_recognition_evaluations`;
|
||||||
|
7. aggiorna `face_recognition_index_state` impostando `status = 'dirty'` e `dirty = 1`;
|
||||||
|
8. porta il job a `done`, registra `completed_at` e salva il riepilogo in `result_json`.
|
||||||
|
|
||||||
|
Le operazioni descritte sono eseguite dentro una singola transazione SQLite. Se la transazione fallisce, le modifiche non vengono confermate.
|
||||||
|
|
||||||
|
## 6. Errori e stato dei job
|
||||||
|
|
||||||
|
| Stato | Significato nel flusso esaminato |
|
||||||
|
|---|---|
|
||||||
|
| `pending` | Richiesta in attesa di essere elaborata. |
|
||||||
|
| `processing` | Worker ha acquisito il job e lo sta elaborando. |
|
||||||
|
| `done` | Salvataggio completato e risultato registrato. |
|
||||||
|
| `error` | Il worker ha registrato un errore in `last_error`. |
|
||||||
|
| `superseded` | Gli input sono cambiati durante il calcolo; è stata richiesta una nuova elaborazione. |
|
||||||
|
|
||||||
|
Se il worker fallisce, `markJobError()` imposta `status = 'error'`, registra `completed_at` e scrive il dettaglio dell'errore in `last_error`. Il daemon seleziona soltanto job `pending`: perciò un job `error` non viene ripreso automaticamente da quel normale ciclo di coda. Il recupero dei job `processing` scaduti è un meccanismo distinto.
|
||||||
|
|
||||||
|
## 7. KNN/OpenCL in modalità shadow
|
||||||
|
|
||||||
|
Dopo che `persistResult()` ha completato la transazione, il worker prova a eseguire `runFaceKnnShadow()`.
|
||||||
|
|
||||||
|
- Il confronto avviene dopo il salvataggio dei prototipi.
|
||||||
|
- Non modifica i prototipi, le valutazioni o lo stato del job.
|
||||||
|
- Un risultato incoerente viene riportato nei log.
|
||||||
|
- Un errore dello shadow viene intercettato e registrato nei log: non annulla il salvataggio già completato.
|
||||||
|
|
||||||
|
Pertanto, la modalità shadow è un controllo comparativo e non è il componente che decide la selezione persistita.
|
||||||
|
|
||||||
|
## 8. Come verificare un caso reale
|
||||||
|
|
||||||
|
Per concludere che l'assegnazione di un determinato cluster abbia prodotto prototipi, bisogna verificare nel database:
|
||||||
|
|
||||||
|
1. il job della persona e dell'utente, con motivo `cluster_assigned` o un motivo successivo se il job è stato accorpato;
|
||||||
|
2. lo stato finale e, in caso di errore, il contenuto di `last_error`;
|
||||||
|
3. `result_json`, in particolare `selected_count` e `selected_face_ids`;
|
||||||
|
4. le righe attive di `person_face_prototypes` per quella persona;
|
||||||
|
5. le valutazioni in `person_face_recognition_evaluations`;
|
||||||
|
6. lo stato dell'indice in `face_recognition_index_state`.
|
||||||
|
|
||||||
|
**Importante:** l'esistenza del codice di accodamento e del worker prova che il flusso è implementato, ma soltanto i dati reali del database confermano l'esito di una specifica assegnazione.
|
||||||
|
|
||||||
|
## 9. File e punti del codice esaminati
|
||||||
|
|
||||||
|
- `routes/faceReview.js`: route di assegnazione e `queuePrototypeRefresh()`.
|
||||||
|
- `tools/runPrototypeDaemon.js`: coda, ciclo del daemon e recupero dei job `processing` scaduti.
|
||||||
|
- `tools/runPrototypeWorker.js`: acquisizione del job, selezione, salvataggio transazionale, gestione degli errori e chiamata allo shadow KNN.
|
||||||
|
- `package.json`: script `prototype:daemon`, `prototype:worker` e `prototype:once`.
|
||||||
|
- `tools/faceKnnRuntime.js` e `tools/runFaceKnnShadow.js`: runtime e confronto KNN shadow.
|
||||||
|
|
||||||
|
---
|
||||||
|
Documento descrittivo basato sul codice ispezionato; verificare il codice e il database della versione in esecuzione prima di usarlo come specifica operativa definitiva.
|
||||||
14
docs/face-knn-source/deploy/config.json
Normal file
14
docs/face-knn-source/deploy/config.json
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"enabled": true,
|
||||||
|
"mode": "shadow",
|
||||||
|
"backend": "opencl",
|
||||||
|
"fallbackBackend": "cpu",
|
||||||
|
"dimension": 128,
|
||||||
|
"topK": 5,
|
||||||
|
"recognitionThreshold": 0.5,
|
||||||
|
"scoreTolerance": 0.00001,
|
||||||
|
"autoBackendMinimumComparisons": 100000,
|
||||||
|
"launcher": "native/face-knn/run-face-knn.sh",
|
||||||
|
"indexDirectory": "api_v1/face-recognition-index",
|
||||||
|
"runtimeDirectory": "var/face-knn"
|
||||||
|
}
|
||||||
13
docs/face-knn-source/deploy/run-face-knn.sh
Executable file
13
docs/face-knn-source/deploy/run-face-knn.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
script_dir="$(
|
||||||
|
CDPATH= cd \
|
||||||
|
-- "$(dirname -- "$0")" \
|
||||||
|
&& pwd
|
||||||
|
)"
|
||||||
|
|
||||||
|
cd "$script_dir"
|
||||||
|
|
||||||
|
exec ./bin/face_knn "$@"
|
||||||
BIN
docs/face-scan-source/bin/face_scan
Executable file
BIN
docs/face-scan-source/bin/face_scan
Executable file
Binary file not shown.
61
sync-face-knn.sh
Executable file
61
sync-face-knn.sh
Executable file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
SRC="docs/face-knn-source"
|
||||||
|
DEPLOY="$SRC/deploy"
|
||||||
|
DST="native/face-knn"
|
||||||
|
|
||||||
|
# Sorgente -> destinazione
|
||||||
|
declare -A FILES=(
|
||||||
|
["bin/face_knn"]="$SRC/bin/face_knn"
|
||||||
|
["kernels/knn_float4_topk.cl"]="$SRC/kernels/knn_float4_topk.cl"
|
||||||
|
["config.json"]="$DEPLOY/config.json"
|
||||||
|
["run-face-knn.sh"]="$DEPLOY/run-face-knn.sh"
|
||||||
|
["SHA256SUMS"]="$SRC/SHA256SUMS"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "=== Verifica dei file sorgente ==="
|
||||||
|
|
||||||
|
for dest in "${!FILES[@]}"; do
|
||||||
|
src="${FILES[$dest]}"
|
||||||
|
|
||||||
|
if [[ ! -f "$src" ]]; then
|
||||||
|
echo "ERRORE: file sorgente mancante: $src" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Tutti i file sorgente sono presenti."
|
||||||
|
echo
|
||||||
|
echo "=== Copia ==="
|
||||||
|
|
||||||
|
for dest in \
|
||||||
|
"bin/face_knn" \
|
||||||
|
"kernels/knn_float4_topk.cl" \
|
||||||
|
"config.json" \
|
||||||
|
"run-face-knn.sh" \
|
||||||
|
"SHA256SUMS"
|
||||||
|
do
|
||||||
|
src="${FILES[$dest]}"
|
||||||
|
mkdir -p "$DST/$(dirname "$dest")"
|
||||||
|
cp -p "$src" "$DST/$dest"
|
||||||
|
echo "Copiato: $src -> $DST/$dest"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== Verifica SHA256SUMS ==="
|
||||||
|
if [[ -f "$DST/SHA256SUMS" ]]; then
|
||||||
|
(
|
||||||
|
cd "$DST"
|
||||||
|
sha256sum -c SHA256SUMS
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=== File presenti nella destinazione ==="
|
||||||
|
find "$DST" -type f -printf '%P\n' | sort
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Copia completata."
|
||||||
48
sync-face-scan-source.sh
Executable file
48
sync-face-scan-source.sh
Executable file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT="$(pwd)"
|
||||||
|
|
||||||
|
echo "Sincronizzazione Face Scan..."
|
||||||
|
|
||||||
|
mkdir -p \
|
||||||
|
docs/face-scan-source/bin \
|
||||||
|
docs/face-scan-source/models \
|
||||||
|
docs/face-scan-source/lib
|
||||||
|
|
||||||
|
cp -f bin/face_scan \
|
||||||
|
docs/face-scan-source/bin/face_scan
|
||||||
|
|
||||||
|
cp -f models/SCRFD_500M_KPS_640.rknn \
|
||||||
|
docs/face-scan-source/models/
|
||||||
|
|
||||||
|
cp -f models/face_recognition_sface_2021dec.rknn \
|
||||||
|
docs/face-scan-source/models/
|
||||||
|
|
||||||
|
cp -f lib/librknnrt.so \
|
||||||
|
docs/face-scan-source/lib/
|
||||||
|
|
||||||
|
chmod 755 docs/face-scan-source/bin/face_scan
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Verifica file copiati:"
|
||||||
|
echo
|
||||||
|
|
||||||
|
ls -lh docs/face-scan-source/bin/face_scan
|
||||||
|
ls -lh docs/face-scan-source/models/SCRFD_500M_KPS_640.rknn
|
||||||
|
ls -lh docs/face-scan-source/models/face_recognition_sface_2021dec.rknn
|
||||||
|
ls -lh docs/face-scan-source/lib/librknnrt.so
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "SHA256:"
|
||||||
|
echo
|
||||||
|
|
||||||
|
sha256sum \
|
||||||
|
docs/face-scan-source/bin/face_scan \
|
||||||
|
docs/face-scan-source/models/SCRFD_500M_KPS_640.rknn \
|
||||||
|
docs/face-scan-source/models/face_recognition_sface_2021dec.rknn \
|
||||||
|
docs/face-scan-source/lib/librknnrt.so
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Sincronizzazione completata."
|
||||||
Loading…
Reference in a new issue