2018-01-28 Calcul distribué en Python (CPU)

Le langage Python est très lent. C’est pourquoi la plupart les calculs scientifiques sont implémentés en C++ ou tout autre alternative à mi-chemin comme Cython qui est presque un langage à part entière. La connaissance du C++ n’est pas indispensable mais elle facilite énormément la période d’apprentissage.

Il est toujours possible de parallèle les calculs en utilisant des threads mais le langage Python, pour éviter les erreurs d’exécution et garder le langage simple, protège tous les objects qu’il manipule contre les accès concurrentiels via une unique porte qu’on appelle le GIL. Il faut concevoir ce GIL comme une fil d’attente par laquelle le programme passe lors de son exécution pour lire ou modifier tout objet, toute classe, liste ou dictionnaire. Comme on y accède fréquemment, les programmes multithreads sont fortement ralentis au point de ne pas aller plus vite qu’un programme à un seul thread. Le GIL peut être désactivé mais il faut recourir à des outils comme Cython ou au C++. Sans C++, des technologies comme OpenMP sont difficilement accessibles.

Une autre façon de paralléliser consiste à utiliser plusieurs processus, autrement dit, plusieurs interpréteurs Python tournent en même temps. L’inconvénient de cette méthode est que la mémoire n’est pas partagée : les processus peuvent travailler sur les mêmes données mais il faut qu’elles soient recopiées dans la mémoire de chacun. De même, les processus doivent communiquer entre eux pour partager le résultat de leurs calculs. Ce n’est pas compliqué en soi mais cela complique un peu l’écriture des programmes et cela les ralentit. Il faut communiquer le minimum d’information.

Des librairies ont été implémentées pour simplifier l’écriture de telles programmes comme joblib qui est la solution adoptée par scikit-learn. La première librairie sur le sujet fut MPI portée sous Python avec mpi4p. D’autres options existent comme dispy. Il vaut mieux vérifier la fréquence des mises à jour et le nombre de contributeurs avant d’utiliser une librairie.

pymp est une librairie à part car elle permet d’utiliser OpenMP en utilisant une particularité du système d’exploitation linux.

Une dernière option consiste à utiliser des modules qui convertissent des programmes Python en C++ comme numba. A l’exécution, numba détecte les types des variables manipulées et en déduit un code C++ équivalent, le compile et remplace la fonction Python par une version plus rapide. Ce faisant, il est possible de désactiver le GIL : nogil. La connaissance du C++ aide à comprendre comment écrire des bouts de code qui peuvent se passer du GIL. Néanmoins, la fonction ne crée aucun containeur, aucun tableau mais reçoit en paramètre tous ceux qu’elles doit modifier - ils sont donc créés au préalable -, le programme devrait tourner sans erreur d’exécution.