Metafor

ULiege - Aerospace & Mechanical Engineering

User Tools

Site Tools


commit:2008:08_18

Commit 2008-08-18

Modifs

Threads / Interpréteur python

Pour mon nouveau TFiste j'ai besoin de manipuler des PythonCurves. Petit problème, elle cohabitent assez mal avec l'interface graphique. Par exemple, Metafor explose quand on appuie sur “update” de VizWin en fin de calcul quand celui-ci utilise une PythonCurve. Impossible donc de voir les résultats!

J'ai donc corrigé la gestion des threads dans notre interpréteur python graphique. C'est pas la première fois que j'essaye mais cette fois-ci c'est la bonne.

Le problème vient du fait que l'interpréteur python n'est pas thread-safe quand on le mixe avec des module compilés en C++. Autrement dit, on ne peut pas appeler simultanément des fonctions de l'API python dans 2 threads différents. Pour pouvoir quand même y arriver, python fournit une sorte de mutex global appelé GIL (Global Interpreter Lock) dont il faut prendre le contrôle quand on veut appeler python à partir du C++.

Comment cela pouvait-il marcher avant alors? (on a toujours pu voir les courbes interprétées dans VizWin avant ou pendant le calcul). Hé ben un peu par hasard: par erreur, j'initialisais python dans le thread graphique, ce qui lui donnait une existence dans python (un PyThreadState) qui était conservé. Lorsque python appelait win.update(), j'avais programmé un blocage à l'aide des outils Qt pour attendre la fin de la mise à jour. Il faut croire que ce système de blocage rendait la main au thread principal au niveau python… Par contre, si on appuyait sur le bouton, le thread python n'attend pas et PAF!

En résumé,

  • j'ai initialisé python dans le thread python (du coup, les PythonCurve faisaient logiquement planter Metafor).
  • j'ai activé la gestion des threads dans SWIG par le mot clef threads=“1” dans chaque .i. Cette commande permet de relacher la GIL à chaque appel du C++. Inévitablement, puisque python n'a plus la main quand on est en C++, cette modif fait planter tous les appels à l'API python.
  • j'ai ajouté du code manipulant la GIL partout où on utilise l'API python en C++. Grâce à cela, tout a fonctionné sauf Gen4 qui utilise l'interfaçage SWIG des itérateurs standards qui semble bugué. Pour contourner le problème: deux solutions, soit compiler Gen4 sans support des threads (c'est un peu dommage puisqu'il faudrait alors se rappeler que ce module ne supporte pas les threads), soit désactiver le support des threads dans LA routine qui merdouille (le destructeur des iterateurs SWIG). C'est cette deuxième solution que j'ai choisie.

Dans mes essais, j'ai migré le code vers swig-1.3.36 que j'ai installé sur toutes les machines. Il est indispensable d'utiliser cette nouvelle version pour compiler Metafor (j'ai dû modifier le source).

Petite ref vers le site qui m'a mis sur la voie: Matt's blog

Le système ci-dessus fonctionne correctement avec les directors utilisés par Luc pour dériver des fonctions objectives sous python. Cependant, j'ai eu un problème avec la fonction membre write de PythonObjectiveFunction qui, si elle est déclarée dans le director est appelée infiniment de manière récursive. Ce problème n'a rien à voir avec les threads.

Convection de défauts sur maillages ALE

J'aimerais ajouter une interface python à fournir a mon TFiste pour coder des ReZoners. J'ai donc créé une nouvelle classe CurveReZoner qui sera prochainement interfacée avec python.

J'ai ajouté un test de convection de défaut dans la batterie (une gaussienne qui se ballade sur un maillage fixe): apps.ale.defaut.

Projet

Windows: Téléchargez SWIG-1.3.36 (je l'ai mis sur calimero) ou mettez à jour vos libdeluques.

Unix: Ajoutez /opt/swig-1.3.36/bin a votre PATH sur toutes les machines.

Fichiers ajoutés/supprimés

mtALE/CurveReZoner.cpp	added
mtALE/IterativeReZoner2D.cpp	added (+)
mtALE/CurveReZoner.h	added
mtALE/IterativeReZoner2D.h	added (+)
mtALE/ReZoner2D.cpp	deleted
mtALE/ReZoner2D.h	deleted

Romain BOMAN 2008/08/18 11:45

commit/2008/08_18.txt · Last modified: 2016/03/30 15:23 (external edit)