Skip to content

feat: add optional parallel processing and disk cache for scan_templates#7

Open
MariusYvard wants to merge 3 commits intoSeismicSource:mainfrom
MariusYvard:feature/parallel-processing
Open

feat: add optional parallel processing and disk cache for scan_templates#7
MariusYvard wants to merge 3 commits intoSeismicSource:mainfrom
MariusYvard:feature/parallel-processing

Conversation

@MariusYvard
Copy link
Copy Markdown

Salut Claudio,

Je te soumets une feature sur laquelle j'ai travaillé après le stage, en partant directement des observations faites sur FDF, MPOM et BIM pendant la détection des séismes répétés dans les Petites Antilles.

Contexte

Le scan séquentiel devient le goulot d'étranglement dès qu'on dépasse quelques années de données continues. Sur 20 ans de données FDF, les runs prenaient plusieurs jours même avec le chunking et la décimation optimisés (chunk = 24 h, taux = 2). L'idée ici est de paralléliser le dispatch des chunks temporels en gardant le comportement séquentiel intact par défaut (n_jobs = 1).

Ce que j'ai ajouté

requake/parallel_utils.py (nouveau module) :

  • parallel_map() — wrapper léger autour de ProcessPoolExecutor, utilisable dans scan_catalog.py pour les paires sérialisables
  • Cache disque optionnel (pickle + SHA-256) : si un scan est interrompu, les chunks déjà calculés ne sont pas retraités
  • Convention n_jobs identique à joblib (−1 = tous les CPUs, etc.)
  • Aucune dépendance externe : uniquement concurrent.futures et hashlib de la stdlib

requake/scan/scan_templates.py (ajouts uniquement, original intact) :

  • _split_time_range() — découpe avec chevauchement aux bords (marge = durée du template, 120 s par défaut) pour éviter de couper un pic de CC à cheval sur deux chunks
  • _merge_detections() — déduplique les détections dans les zones de chevauchement en gardant la CC la plus haute
  • _scan_chunk_threaded() — worker thread-safe avec cache local par thread
  • scan_templates() étendue : mode séquentiel (n_jobs=1) inchangé, mode parallèle via ThreadPoolExecutor quand n_jobs > 1

Note : j'ai choisi ThreadPoolExecutor plutôt que ProcessPoolExecutor pour scan_templates car le singleton config n'est pas pickleable. Le gain principal est le chevauchement des téléchargements FDSN entre chunks. Pour le NCC lui-même (CPU-bound), parallel_utils.parallel_map() reste disponible pour une future intégration dans scan_catalog.

requake/config/configspec.conf (ajouts en bas) :

[parallel]
n_jobs = integer(default=1)
cache_dir = string(default=None)

[scan]
chunk_hours = integer(default=24)
template_margin_seconds = integer(default=120)

Comportement par défaut inchangé

Sans toucher à la config, n_jobs = 1 maintient le mode séquentiel exact — le bloc if n_jobs == 1 appelle le code original ligne pour ligne.

Ce que j'ai testé

  • Cohérence séquentiel / parallèle vérifiée sur jeux de données synthétiques (résultats identiques à l'ordre de tri près)
  • Style aligné sur le reste du projet : imports paresseux dans les fonctions, en-têtes SPDX avec ton copyright + le mien, docstrings reStructuredText, pas de type hints

N'hésite pas à me dire si tu préfères une organisation différente (ex. intégrer les helpers directement dans scan_catalog.py plutôt qu'un module séparé, ou renommer n_jobs pour coller à une convention existante dans Requake). Je suis dispo pour adapter.

Marius

@claudiodsf
Copy link
Copy Markdown
Member

Bonjour Marius,
super ! merci pour cette contribution !

Je regarderai plus dans le détails dans quelque semaine (deadline importante en approche).

Deux questions rapides :

  1. est-ce que cette PR inclue les modifications à scan_templates faites pendant le stage ? Sinon, cela te dirait d'en faire une autre PR ?
  2. serait-il plus avantageux de rendre l'objet Config() pickeable, pour utiliser ProcessPoolExecutor ? Si oui, je peux regarder cela

@MariusYvard
Copy link
Copy Markdown
Author

Bonjour Claudio,

Merci ! Bonne chance pour ta deadline, et ne t'inquiète pas, ce n'est pas pressé.

  1. PR stage : Celle-ci se concentre uniquement sur l'infrastructure parallèle. Les améliorations fonctionnelles du stage (NCC sur ondes S, gestion dégénérescence des templates, adaptation format FDSN 1998–2002, seuils combinés NCC/NCCs) n'y sont pas encore. Une PR séparée serait plus propre pour garder ça propre. Je m'en occupe dès que j'ai le temps.

  2. Config pickleable : Très bonne idée. Le workaround dict ↔ ConfigParser actuel fonctionne, mais c'est un peu lourd. Si tu regardes ça de ton côté, ça simplifiera beaucoup l'API.

À bientôt,
Marius

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants