- Indico style
- Indico style - inline minutes
- Indico style - numbered
- Indico style - numbered + minutes
- Indico Weeks View
NOTE: Je n'ai pas pris de notes des participants, et l'évènement est survenu il y a un moment, donc j'ai pu oublier/rajouter du monde. Comme d'habitude, n'hésitez pas à me signaler toute erreur.
Antoine a eu des nouvelles de Laurent, qui travaille maintenant à l'INRIA sur la plus grande salle virtuelle de France, Immersia en Bretagne. Guy a déjà entendu parler de cette salle via un documentaire sur Arte, apparemment elle est notamment utilisée en archéologie.
Par ailleurs, c'est maintenant officiel: le LAL a bien un poste IR pour remplacer Christian Arnault dans ses activités sur Spark.
Le LAL possède maintenant un compte sonarqube "cloud", que l'on peut connecter à ses projets sur Github ou sur le Gitlab du LAL. Puisque le CCIN2P3 ne veut pas héberger une instance, une question se pose: pourrait-on en héberger une au LAL et ensuite "vendre" ce service au CC?
Cette discussion en a entraîné une autre sur la gestion de version et ses dépôts. Ainsi, Christian héberge un de ses projets professionnels sur Github afin d'avoir une meilleure intégration avec ReadTheDocs. Cette intégration pouvait aussi être mise en place avec Gitlab, mais semblait plus complexe en raison du fait que le dépôt doit être rendu public au moment de la génération de la doc. Ceci dit, il est aussi possible d'avoir un dépôt public sous Gitlab.
De son côté, Jean-Noël a repassé certains de ses projets de Git(hub) à SVN car il en avait assez de la complexité de la gestion de version distribuée (dépôts multiples à synchroniser, etc). Après quelques discussions sur les différences conceptuelles entre une gestion centralisée et une gestion distribuée, Antoine a mentionné qu'un point fort de la gestion distribuée est quand même la facilité de gérer des branches, et le workflow "merge/pull request" que cela permet.
Nous sommes un peu revenus sur les discussions du café LoOPS concernant la part qu'un langage de programmation peut prendre dans la détection et la prévention des erreurs. Si des langages comme Ada peuvent indubitablement aider dans des scénarios comme les systèmes critiques où l'échec n'est pas une option, d'autres pratiques comme le développement dirigé par les tests (TDD) ont aussi été mentionnées. Quelqu'un (Christian?) a rappelé que le TDD est aussi utile comme une forme de documentation et de spécification qui clarifie ce qu'on est en train d'essayer de programmer au moment où on le programme.
La discussion a ensuite dérivé sur les différentes stratégies employées par les langages de programmation et les bibliothèques pour faciliter l'écriture de code parallèle. Globalement, trois grandes familles d'approches semblent émerger pour empêcher les race conditions (écriture et accès concurrent à une zone mémoire) :
La troisième approche est essentiellement une combinaison des deux précédentes, qui prend en compte d'une part l'importance d'un code impératif pour une performance maximale (le fonctionnel pur engendrant un trop grand trafic mémoire du fait puisqu'on doit faire une copie des données à chaque modification), et d'autre part les limites d'une approche où les programmes ne sont autorisés à partager aucune donnée (très adapté aux environnements distribués, mais souvent beaucoup plus complexe et moins intuitif que le code séquentiel équivalent, et inefficace sur les architectures à mémoire partagée).
Cependant, pour bien fonctionner, cette approche nécessite un support du compilateur. Dans des langages relativement simples comme FORTRAN, des annotations à la OpenMP peuvent suffire, mais dès qu'on introduit la notion de pointeur, s'assurer que la mémoire soit accédée "comme il faut" est très difficile. C'est la raison pour laquelle Rust a adopté un modèle de pointeur relativement restrictif qui assure l'exclusion mutuelle entre mutabilité et partage des données par construction.
Que doit faire un programme quand il ne peut pas terminer sa tâche comme prévu ? Historiquement, deux grandes familles d'approches ont été adoptées:
Chacune de ces familles possède un certain nombre de raffinements. Dans le cas de la gestion des erreurs par renvoi d'un résultat spécial, on trouve ainsi trois grandes sous-approches:
La première approche a pour inconvénient que tous les types ne se prêtent pas à la transmission d'erreur, et que même quand ils s'y prêtent, leur expressivité pour ce qui est d'exprimer la nature de l'erreur est très limitée.
La seconde approche est plus expressive, mais requiert de renvoyer des données mal initialisées au client (résultat incomplet), compte fortement sur ce dernier pour vérifier la présence d'erreur, et nécessite soit un mécanisme de valeurs de retour multiples complexe pour les fonctions, soit un mécanisme global qui pose de sérieux problèmes dans les programmes concurrents.
La troisième approche est donc généralement supérieure aux deux précédentes, puisqu'elle force le client à traiter la possibilité d'erreur (lors de l'analyse du type variant), sans pour autant imposer la moindre contrainte sur le type résultant ou l'expressivité du signalement d'erreur. Mais c'est aussi l'approche qui nécessite le support le plus complexe de la part du langage, puisqu'elle nécessite que ce dernier offre un support natif, et si possible efficace, des types variants.
Dans le cas des exceptions, les différences entre solutions concrètes se situent plutôt au niveau des caractéristiques de performance du mécanisme utilisé pour lever les exceptions, de la portée de ces dernières, et de l'effet d'une exception non gérée par l'utilisateur :
Cependant, presque tous les mécanismes de gestion d'exception ont en commun de rendre la gestion d'erreur soit non-locale et peu compréhensible, à la manière du mot-clé GOTO (cas, le plus courant, des exceptions non vérifiées), soit très rébarbative, en obligeant chaque fonction à lister quelles exceptions elle est susceptible de lancer (cas des exceptions vérifiées, notamment présentes en Java).
Pour cette raison, et aussi parce que la gestion d'exceptions est très peu efficace au niveau performances, un certain nombre de langages conçus récemment, comme Go, Rust et Swift, tentent de réserver les exceptions au signalement d'erreurs fatales relevant d'un défaut du programme (ex: accès hors des bornes d'un tableau), et de décourager fortement (Go) voire interdire partiellement (Rust) la gestion de ces dernières par le programmeur. Ces langages recommandent, à la place, un signalement des erreurs courantes (ex: accès à un fichier refusé) par résultat supplémentaire de fonction (Go) ou par type variant erreur/résultat (Rust).
Pour reproduire le caractère "propagatif" d'une exception, parfois utile quand on veut positionner la gestion d'une erreur très en amont du traitement associé, Rust propose aussi toutes sortes de raccourcis syntaxiques permettant de reproduire ce "feeling", au prix toutefois d'une lourdeur supplémentaire dans la définition du type de retour de chaque fonction intermédiaire (moins importante toutefois que celle des exceptions vérifiées).
Spark peut s'interfacer avec pas mal de mécanismes pour la sérialisation et distribution des données. Dans l'écosystème Hadoop sous-jacent, Julius a déjà testé Avro, et travaille régulièrement avec HBase. Mais il existe aussi un support de bases de données non relationnelles telles que MongoDB, auquel Christian s'est intéressé récemment dans le cadre de ses travaux pour LSST.
Antoine comprenait mal comment Spark peut travailler avec les données peu structurées d'une base de données orientée documents comme MongoDB. Mais en fait, il est possible avec MongoDB d'adopter un schéma de données dans lequel pour chaque document, certains champs de données "invariants" seront toujours présents, tout en laissant à l'utilisateur la possibilité d'ajouter ensuite des champs spécifiques à chaque document.
Sur ces champs invariants, on peut ensuite effectuer des requêtes comparables à ce que l'univers SQL autorise. Et c'est avec ces champs que les programmes Spark de Christian travaillent.
Antoine mentionne que les jDev auront lieu à Marseille durant la première semaine de Juillet. Seront présent David, Antoine, Grigory, et peut-être Michel. Attention lors des réservations d'hôtel: la période est très demandée...
Le sujet de la fusion refondation de laboratoires d'Orsay proposé par la direction du LAL a été évoqué par Philippe sans qu'il émerge grand-chose de concret de cette discussion.
David et Hadrien ont présenté Lucas Serrano, stagiaire M2 fraîchement arrivé qui travaille à mi-temps avec Télécom Paris. Il oeuvrera avec nous sur l'optimisation des performances la bibliothèque de tracking ACTS, notamment par vectorisation et portage GPU, avec à plus long terme la perspective d'une thèse sur ce sujet.