IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

multiprocessing : obtenir des valeurs de fonctions


Sujet :

Python

  1. #1
    Candidat au Club
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    5
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut multiprocessing : obtenir des valeurs de fonctions
    Bonjour,
    J'ai une fonction que je veux exécuter simultanément avec plusieurs arguments et récupérer le tout dans (si possible) une unique variable.

    En regardant la doc de python, j'ai essayé les codes suivants :

    p=Pool(4)
    result=p.map(ffind_all_axis_method2_parall, sphere_pts )
    result=result.get()
    avec :
    ffind_all_axis_method2_parall une fonction qui a en argument sphere_pts et qui renvoie une liste
    sphere_pts : une liste contenant les coordonnées de points sous forme de listes

    et

    def f(y, result):
    result.put(ffind_all_axis_method2_parall (y))

    result=Queue()
    i=0
    while i <4:
    p=Process(target=f, args=(y, result,))
    p.start()
    i+=1
    p.join()
    result=result.get()

    J'ai essayé pas mal d'autres versions, mais les seules qui fonctionnaient (donnaient un résultat cohérent avec celui trouvé par la version non parallélisée) n'utilisaient pas les 4 coeurs de mon pc (pas 100% en utilisant htop, sachant que le programme non parallélisé met environ 15 secondes à s'exécuter).

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    La question plus importante est : Que justifie l'utilisation du multiprocessing?

    L'autre question, en rapport avec ce que tu écris, c'est qu'on a pas les résultats de tes essais, peux-tu nous les donner?

    As-tu vérifier que l'OS ne gérait pas cela automatiquement?

    Ton code est-il optimisé? Si oui peut-on le voir? ou au moins la fonction prenant du temps?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Candidat au Club
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    5
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Ce qui justifie l'utilisation du multiprocessing est que plusieurs fonctions qui prennent du temps peuvent être accélérées de la même façon.


    Qvar :
    [[-1.4794819743158694, 15.431016222977084, -55.49544789532253],
    [-1.219318858733191, 12.585954720927015, -44.872927469225765],
    [-0.2496199733795712, 1.9816345769222128, -5.279896790137833],
    81.0,
    114.7,
    0,
    0,
    -0.17739858471018485],
    [[-1.4794819743158694, 15.431016222977084, -55.49544789532253],
    [-1.195667666407493, 12.32731276619519, -43.90724379412606],
    [-0.22596878105387308, 1.7229926221903895, -4.314213115038129],
    81.0,
    114.7,
    0,
    0,
    -0.17739858471018485],
    [[-1.4794819743158694, 15.431016222977084, -55.49544789532253],
    [-1.1720164740817949, 12.068670811463367, -42.941560119026356],
    [-0.20231758872817518, 1.4643506674585645, -3.3485294399384316],
    85.5,
    114.7,
    0,
    0,
    -0.16861638330503265],
    [[-1.4794819743158694, 15.431016222977084, -55.49544789532253],
    [-1.1483652817560968, 11.810028856731542, -41.97587644392665],
    [-0.17866639640247706, 1.2057087127267394, -2.38284576483872],
    91.1,
    114.7,
    0,
    0,
    -0.15768742155639878],
    (elle fait plusieurs dizaines de milliers de lignes, je n'en ai mis qu'un extrait.)

    Pour les erreurs, le premier code me renvoie :
    Exception in thread Thread-2:
    Traceback (most recent call last):
    File "/usr/lib/python3.2/threading.py", line 740, in _bootstrap_inner
    self.run()
    File "/usr/lib/python3.2/threading.py", line 693, in run
    self._target(*self._args, **self._kwargs)
    File "/usr/lib/python3.2/multiprocessing/pool.py", line 346, in _handle_tasks
    put(task)
    _pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed
    Et le second donne plus d'erreurs, celle sur le processus 1 :
    Process Process-1:
    Traceback (most recent call last):
    File "/usr/lib/python3.2/multiprocessing/process.py", line 267, in _bootstrap
    Process Process-2:
    self.run()
    File "/usr/lib/python3.2/multiprocessing/process.py", line 116, in run
    self._target(*self._args, **self._kwargs)
    File "./find_membranes/testparall.py", line 96, in f
    Traceback (most recent call last):
    File "/usr/lib/python3.2/multiprocessing/process.py", line 267, in _bootstrap
    File "./find_membranes/testparall.py", line 76, in <lambda>
    File "/home/cacao/guiraud/find_membranes/functions.py", line 652, in ffind_all_axis_method2
    Ensuite, je ne suis pas sûr de comprendre la question sur l'OS

    Et le code est moyennement optimisé, la fonction prend plusieurs axes et calcule une Qvalue pour chaque tranche de chaque axe. L'idée pour accélérer le programme était de donner une partie des axes à la fonction (en donnant une partie de la variable sphere_pts) par processus et regrouper les résultats à la fin.


    Sphere_points ressemble à ça (extrait) :
    [[-0.9633258011405611, -71.39091101647321, -8.727625808298926],
    [12.264360679139417, -70.01880032074531, -11.814972725936206],
    [0.22271086690316289, -68.64668962501743, -27.80207842745018],
    [-20.40442187336518, -67.27457892928955, -21.543938022575837],
    [-26.25613373248748, -65.90246823356166, -0.027326028766863075],
    [-13.025339716462094, -64.53035753783378, 18.463752754254664],
    [9.749799218353143, -63.15824684210588, 21.862711279404518],
    [29.049424890526844, -61.786136146377984, 8.926997218458123],
    [35.75193021940098, -60.414025450650094, -13.480168874381004],
    [27.480160649108644, -59.04191475492221, -35.48477747346122],
    [7.91415338009759, -57.66980405919432, -48.68738645536939]]
    Voilà le code de la fonction, même si seule je doute que cela semble très clair

    def ffind_all_axis_method2(center, sphere_pts, data, kyteD, widthmin, widthmax, step):

    """Get the Q value for all axis and all points """
    Qvar=[] #Will be the var that countains all Q valuzes for all points
    for point in sphere_pts:

    diam_vect=fvect(point, center)
    for i,plop in enumerate(diam_vect): #We take the vector that is 2*RR
    diam_vect[i]=2*plop

    #We build every interval for a diam_vect
    i=0 # i will be ||sphere-point C1 ||
    diam_norm=fnorm(diam_vect)
    Qvartemp=[]
    structure=0
    while (i+1) < diam_norm:

    #We get the 2 plans
    d_pointC1=i
    d_pointC2=i+1

    C1=fthales(diam_vect, d_pointC1, point )
    C2=fthales(diam_vect, d_pointC2, point )

    hydrophile=0
    hydrophobe=0
    tot=0
    for elt in data: # elt : ligne de data

    ok=fis_in_space(diam_vect, C1, C2, elt[:3])
    if ok:
    if elt[4] >= 50:
    tot+=1
    #Find hydrophilic and hydrophobic values
    hydrophile, hydrophobe = fcalc_hydroph(hydrophile,
    hydrophobe, elt, kyteD)
    Qvartemp.append([point, C1, C2, hydrophobe, hydrophile, tot, structure, 0, i])



    i += step

    width2=widthmin
    while width2 <= widthmax:
    imax=len(Qvartemp)-width2 -1
    i=0
    while i < imax:
    C1=Qvartemp[i][1]
    C2=Qvartemp[(i+width2)][2]
    j=0
    hydrophobe=0
    hydrophile=0
    tot=0
    while j < width2:
    hydrophile+=Qvartemp[i+j][4]
    hydrophobe+=Qvartemp[i+j][3]
    tot+=Qvartemp[i+j][5]
    j+=1
    if hydrophobe !=0:
    Qvar.append([point,C1, C2, hydrophobe, hydrophile, structure, 0, width2])
    i+=1
    width2+=1

    return Qvar

    Après la fonction en appelle pas mal d'autres, et l'ensemble est plutôt assez moche...

  4. #4
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Ce qui justifie l'utilisation du multiprocessing est que plusieurs fonctions qui prennent du temps peuvent être accélérées de la même façon.
    Mouais, je suis pas un spécialiste du multiprocessing, je ne l'utilise jamais, car normalement l'OS doit gérer cela automatiquement. En tout cas sous Unix, c'est le cas.

    Je dirais que son intérêt est une meilleure gestion du partage des tâches sur chaque coeur.

    Citation Envoyé par arty0
    _pickle.PicklingError: Can't pickle <class 'function'>: attribute lookup builtins.function failed
    Ce n'est pas une erreur en rapport avec le multiprocessing, mais une erreur avec le module pickle qui ne sérialise pas les classes.

    Voir ici pour une solution...

    Citation Envoyé par arty0
    Process Process-1:
    Traceback (most recent call last):
    File "/usr/lib/python3.2/multiprocessing/process.py", line 267, in _bootstrap
    Process Process-2:
    self.run()
    File "/usr/lib/python3.2/multiprocessing/process.py", line 116, in run
    self._target(*self._args, **self._kwargs)
    File "./find_membranes/testparall.py", line 96, in f
    Traceback (most recent call last):
    File "/usr/lib/python3.2/multiprocessing/process.py", line 267, in _bootstrap
    File "./find_membranes/testparall.py", line 76, in <lambda>
    File "/home/cacao/guiraud/find_membranes/functions.py", line 652, in ffind_all_axis_method2
    L'erreur est incomplète, non?

    Comment as-tu récupéré les données de Sphere_points?

    Il aurait été préférable de travailler sous forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    -0.9633258011405611, -71.39091101647321, -8.727625808298926
    12.264360679139417, -70.01880032074531, -11.814972725936206
    0.22271086690316289, -68.64668962501743, -27.80207842745018
    et récupérer avec le module numpy sous forme d'arrays.

    Citation Envoyé par arty0
    Après la fonction en appelle pas mal d'autres, et l'ensemble est plutôt assez moche...
    exact, difficile d'en dire plus...

    Si tu vois qu'avec numpy, c'est encore lent, tu peux faire de l'interfaçage C/python, mais généralement numpy suffit.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    C'est difficile à dire vu que tu n'as pas posté le code de ffind_all_axis_method2_parall, mais d'après ce que je lis dans le premier post:
    ffind_all_axis_method2_parall une fonction qui a en argument sphere_pts et qui renvoie une liste
    sphere_pts : une liste contenant les coordonnées de points sous forme de listes
    Je me demande s'il y a pas une confusion.

    La fonction ffind_all_axis_method2_parall ne devrait pas prendre en argument sphere_pts, mais un seul point de la liste, vu que c'est Pool.map qui fait le dispatching...

Discussions similaires

  1. Réponses: 2
    Dernier message: 12/10/2009, 22h55
  2. [XL-2003] récupérer des valeurs en fonction de caractères
    Par doudou8mc dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 15/09/2009, 09h31
  3. [XSLT] Affichage des valeurs en fonction d'autres
    Par devlo2006 dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 08/04/2008, 18h28
  4. Afficher des valeurs en fonction des données d'un champ
    Par Tchouk01 dans le forum VBA Access
    Réponses: 0
    Dernier message: 02/04/2008, 14h24
  5. Obtenir des dates en fonction du n° de la semaine
    Par coeur74 dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 10/02/2005, 13h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo