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 :

Mieux parall�liser l'extraction de donn�es depuis un netCDF vers des fichiers texte


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    16
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 16
    Par d�faut Mieux parall�liser l'extraction de donn�es depuis un netCDF vers des fichiers texte
    Bonjour,

    J'ai un code utilisant xarray pour extraire des donn�es depuis une source netCDF (ECMWF ERA5).
    De mani�re simplifi�e, il y a quatre dimensions (x, y, z et t) et trois variables (r, h et g).
    Toujours en simplifiant un peu, je dois extraire toutes les valeurs de r, h et g pour toutes les dimensions z et t pour chaque couple x/y.
    J'ai un code s�rie qui marche, dont une repr�sentation simplifi�e est :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    import xarray as xr
     
    def extract_data(data,z,x,y,t):
      out_str = ''
      for t_val in t:
        for z_val in z:
          out_str += data.sel(x,y,t_val,z_val).data
      return(out_str)
     
    def data_get_write(dir,r,h,g,x,y,z,t):
      r_str = extract_data(r,x,y,z,t)
      with open(dir+'r_file', 'w') as f_r:
        f_r.write(r_str)
      h_str = extract_data(h,x,y,z,t)
      with open(dir+'h_file', 'w') as f_h:
        f_h.write(h_str)
      g_str = extract_data(g,x,y,z,t)
      with open(dir+'g_file', 'w') as f_g:
        f_g.write(g_str)
      return(<operation>)
     
    if __name__ == '__main__':
      ds=xr.open_dataset('data.nc')
      r=ds['r']
      h=ds['h']
      g=ds['g']
      z=ds['z']
      t=ds['t']
      dir_list=[]
      x_list=[]
      y_list=[]
      for val_x in x:
        for val_y in y:
          dir=(<operation>)
          dir_list.append(dir)
          x_list.append(x)
          y_list.append(y)
      list_len=len(dir_list)
      r_list=[r]*list_len
      h_list=[h]*list_len
      g_list=[g]*list_len
      z_list=[z]*list_len
      t_list=[t]*list_len
     
      results = map(data_get_write, r_list, h_list, g_list, x_list, y_list, z_list, t_list)
    Je l'ai �crit de cette mani�re (cr�er des listes pour chaque param�tre puis les passer � la fonction via map) dans l'objectif de parall�liser l'ex�cution en utilisant concurrent.futures.ThreadPoolExecutor ou concurrent.futures.ProcessPoolExecutor en rempla�ant l'appel map de cette mani�re :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
        max_workers = min(32, int(arguments["-n"]) + 4)
        with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
          results = executor.map(data_get_write, r_list, h_list, g_list, x_list, y_list, z_list, t_list)
    Avec ThreadPoolExecutor le probl�me c'est que la version parall�lis�e est moins rapide que la version s�rie...
    Sur mon jeu de donn�es de test (netcdf de 600Mo, dimensions x et y avec une vingtaine de valeurs et t � 6 valeurs) et mon serveur de test, la version s�rie prend environ 2'40", la version parall�le 6'30". J'ai fait varier le nombre de c�urs allou�s de 1 � 20, il n'y a aucun impact sur le temps d'ex�cution (ou du moins juste � la marge, plus ou moins quelques secondes, moins de 10%). Il n'y a pas plus de variabilit� entre les runs en faisant changer le nombre de c�urs allou�s qu'en relan�ant plusieurs fois de suite le m�me run.
    �a s'explique, si je ne m'abuse, par le verrou global qui emp�che les threads concurrents d'acc�der aux donn�es en lecture de mani�re r�ellement concurrente puisqu'elles sont pass�es par r�f�rence et pas par valeur. Et �a semble �tre confirm� en basculant sur ProcessPoolExecutor m�me si la baisse de vitesse d'ex�cution est surprenante.

    Avec ProcessPoolExecutor on constate un gain, �a passe � 1'25" mais � nouveau, quel que soit le nombre de c�urs, il n'y pas de modification significative du temps d'ex�cution. On pourrait penser qu'il s'agit d'un bottleneck sur le filesystem mais il n'y a pas non plus de modification en fonction du syst�me de stockage utilis�, que ce soit le disque local au serveur ou un montage NFS.

    Il doit donc y avoir quelque chose de fondamental, soit dans mon choix de biblioth�que de parall�lisation ou dans mon code m�me, qui l'emp�che de scaler avec la surface d'ex�cution. C'est peut-�tre tr�s simple mais je suis compl�tement novice, autant en lecture / extraction de donn�es depuis du netCDF qu'en parall�lisation de code, donc il ne serait pas surprenant que ce soit un cas de pebkac. Toute aide / suggestion de piste pour am�liorer mon code est la bienvenue, merci !

  2. #2
    Expert confirm�
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 095
    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 : 4 095
    Par d�faut
    Bonsoir,

    Il ne serait pas d�j� possible d'optimiser votre algorithme pour �viter les boucles (en vectorisant) ?

    Avant de faire une version parall�lis�e, il faudra d�j� optimiser la version non parall�liser, v�rifier si les temps d'ex�cution conviennent, d�terminer les goulots d'�tranglement puis seulement � partir de l�, parall�liser les t�ches qui prennent du temps.

  3. #3
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 770
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activit� : Architecte technique retrait�
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 770
    Par d�faut
    Salut,

    La loi de Amdhal s'applique (� vous de faire les calculs pour savoir si vos attentes sont r�alistes).
    Passer de 2mn40 � 1mn25, n'est pas si mal.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    16
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 16
    Par d�faut
    Bonjour,

    Merci pour la suggestion de vectorisation. Effectivement, pour la cr�ation des listes initiales qui seront pass�es � map �a aurait du sens et ce serait plus �l�gant, � l'occasion je le ferai.

    Et aussi pour la suggestion d'am�liorer le code hors de l'aspect parall�lisation. Coupl� � d'autres discussions que j'ai eues, �a m'a motiv� pour ajouter des perf_counter() partout dans mon code et regarder le temps d'ex�cution de chaque �tape. Si il y a un conseil que je peux donner, c'est celui l� : si on veut identifier ce qui prend du temps dans un script de ce type, des perf_counter() partout avec des print de diff�rence � la fin c'est vraiment assez parlant.

    J'ai commenc� par le main et on voit assez bien le coupable (en abscisses les �tapes et en ordonn�es le temps d'ex�cution cumulatif) :

    Nom : perf.png
Affichages : 164
Taille : 27,2 Ko

    Toutes les boucles au d�but sont epsilonesques (d'o� le fait que je ne vais pas me pr�cipiter pour les vectoriser autrement que pour l'�l�gance).
    L'�tape qui contribue la quasi totalit� du temps c'est qui correspond � .

    Je suis donc all� mettre des perf_counter() de plus en plus profond dans les fonctions appel�es et ce qui prend vraiment du temps c'est l'extraction des donn�es depuis le tableau xarray qui est de cette forme :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    dataset.sel(x=var1,y=var2)
    .

    Je me suis demand� si on ne pourrait pas acc�l�rer cette �tape et je suis tomb� sur une page pas tr�s rassurante. L'issue est marqu�e r�solue mais en lisant les commentaires c'est parce qu'il n'y a pas de solution, pas parce que le code a �t� am�lior�...

    J'avais choisi d'utiliser xarray plut�t que netCDF4 pour avoir une d�pendance plus g�n�rique mais je me suis demand� si ce ne serait pas plus rapide avec netCDF4. Il est donc temps de faire un petit test, j'ai import� timeit puis :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    >>> code_seg='''\
    ... import netCDF4 as nc
    ... dn = nc.Dataset('ERA/data.nc')
    ... zn=dn['z'][:]
    ... for i in range(10000):
    ...     res=zn[0,:,0,0]
    ... '''
    >>> timeit.timeit(code_seg, number=10**3)
    53.229370541870594
     
    >>> code_seg='''\
    ... import xarray as xr
    ... dn = xr.open_dataset('ERA/data.nc')
    ... zn=dn['z']
    ... for i in range(10000):
    ...     res=zn.sel(valid_time='2019-08-03T06:00:00.000000000',latitude='36.25',longitude='351')
    ... '''
    >>> timeit.timeit(code_seg, number=10**3)
    � l'heure o� j'�cris ces lignes, j'attends encore le r�sultat avec xarray, �a fait plus d'une heure que �a tourne...

    Je crois que j'ai une piste pour am�liorer mon code et je la dois au moins en partie � vos suggestions, merci beaucoup

  5. #5
    Expert confirm�
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 095
    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 : 4 095
    Par d�faut
    N'ayant aucune donn�e, difficile d'affirmer ni v�rifier ce que vous d�tes, moins encore vous proposer des solutions qui fonctionnent du premier coup, �tant donn� qu'on ne peut pas tester.

    On ne conna�t m�me pas les longueurs de t et z. S�re que si elles sont de petites tailles, l'impact c�t� vectorisation est n�gligeable.

    En plus vous fa�tes de la concat�nation non optimis�e (utiliser les listes, append et join pour am�liorer).

    Mais bon encore une fois, sans donn�e de test, difficile de vous aider plus...

  6. #6
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 770
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activit� : Architecte technique retrait�
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 770
    Par d�faut
    Citation Envoy� par DrWaste Voir le message
    Je crois que j'ai une piste pour am�liorer mon code et je la dois au moins en partie � vos suggestions, merci beaucoup
    A tout hasard, si on cherche avec les mots clefs "parallel netcdf python" on tombe sur des biblioth�ques comme celle ci.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    16
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 16
    Par d�faut
    Hello,

    Citation Envoy� par fred1599 Voir le message
    N'ayant aucune donn�e, difficile d'affirmer ni v�rifier ce que vous d�tes, moins encore vous proposer des solutions qui fonctionnent du premier coup, �tant donn� qu'on ne peut pas tester.

    On ne conna�t m�me pas les longueurs de t et z. S�re que si elles sont de petites tailles, l'impact c�t� vectorisation est n�gligeable.

    En plus vous fa�tes de la concat�nation non optimis�e (utiliser les listes, append et join pour am�liorer).

    Mais bon encore une fois, sans donn�e de test, difficile de vous aider plus...
    Les longueurs de t e z sont effectivement assez r�duites. Environ max 800 pour t actuellement, habituellement plut�t aux alentours de 10. Et z est � environ 30.

    Un jeu de donn�e ressemble � cette pi�ce jointe : data.zip. Le fichier netcdf ici est tout petit par rapport aux jeux tests qu'on utilise habituellement, t = 1, x et y (lat et lon) � moins de 10, un exemple typique est un � deux ordres de grandeur sup�rieurs sur x et y.

    �a permet de voir que ce qui prend vraiment du temps, de tr�s tr�s loin, c'est le select des donn�es, comme sur mon graphique pr�c�dent.

    Citation Envoy� par wiztricks Voir le message
    A tout hasard, si on cherche avec les mots clefs "parallel netcdf python" on tombe sur des biblioth�ques comme celle ci.

    - W
    Oui, merci en effet, et je l'envisagerai sur un autre projet qui utilise ces m�me donn�es mais � un ordre de grandeur sup�rieur o� la parall�lisation de la lecture en input commencera � avoir un int�r�t. Sur le projet en cours c'est n�gligeable, ce qui impacte vraiment c'est le select des donn�es dans la structure en m�moire.

    D'ailleurs, � cet effet, j'ai �crit un petit script tout b�te qui utilise timeit pour comparer le temps de diff�rentes m�thodes. Actuellement je charge les donn�es dans un xarray et je fais un select en utilisant les �tiquettes des dimensions. Ce script compare cette m�thode � l'extraction du tableau de la variable seule, en utilisant netCDF4 et xarray, sur la structure netcdf jointe plus haut demo-timeit.zip, il lui faut les biblioth�ques timeit, xarray et netCDF4. On voit que l'extraction des donn�es en utilisant les �tiquettes est beaucoup beaucoup plus lente que la lecture directe dans le tableau de donn�es, l'�cart est assez saisissant. Avec xarray on a un facteur d'environ 300x ! Le probl�me c'est qu'extraire les donn�es en utilisant le tableau pr�sume qu'on conna�t l'ordre des dimensions dans l'imbrication des tableaux, dans l'exemple donn�e c'est 1) t, 2) p, 3) x et 4) y. Si cet ordre change je dois changer l'ordre des arguments pass�s dans le tableau res=zn[0,:,0,0]. Et comme je boucle sur t et z, je ne peux pas tester et construire cet ordre avant d'�tre sur cette boucle assez interne de mon code, ou alors pr�voir les 16 combinaisons possibles et selon l'ordre des dimensions appeler la fonction correspondante mais �a veut dire autant de fonctions qui font quasiment exactement la m�me chose. J'ai l'impression qu'une m�thode plus �l�gante / efficace doit exister mais je bute encore sur ce point. Pour l'instant je teste si l'ordre est celui que j'ai d�fini par d�faut et je g�n�re une erreur critique mais �a cr�e une fragilit� dans mon code.
    Fichiers attach�s Fichiers attach�s

  8. #8
    Expert �minent
    Homme Profil pro
    Architecte technique retrait�
    Inscrit en
    Juin 2008
    Messages
    21 770
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activit� : Architecte technique retrait�
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 770
    Par d�faut
    Dans vos tests, ce qui prend du temps, c'est le chargement de la base de donn�e (l'instruction dn = machinset('timeit-test.nc'). Comme on est suppos� ne le faire qu'une seule fois et que c'est p�nalis� par la vitesse du disque, je ne suis pas certain qu'on mesure quoi que ce soit de pertinent.

    Ceci dit, des gros tas de donn�es g�ographiques et l'optimisation d'outils tels que netcdf ou xarray ne sont pas des sujets python basiques. L'exp�rience devrait se trouver dans les forums utilisateurs de ces engins.


    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    16
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 16
    Par d�faut
    Citation Envoy� par wiztricks Voir le message
    Dans vos tests, ce qui prend du temps, c'est le chargement de la base de donn�e (l'instruction dn = machinset('timeit-test.nc'). Comme on est suppos� ne le faire qu'une seule fois et que c'est p�nalis� par la vitesse du disque, je ne suis pas certain qu'on mesure quoi que ce soit de pertinent.

    Ceci dit, des gros tas de donn�es g�ographiques et l'optimisation d'outils tels que netcdf ou xarray ne sont pas des sujets python basiques. L'exp�rience devrait se trouver dans les forums utilisateurs de ces engins.


    - W
    Oui, comme instruction unitaire c'est sur elle est lourde. Ceci dit, elle n'est faite qu'une fois alors comme j'ai mis dans les commentaires du code, l'extraction des valeurs est r�ellement r�p�t� en moyenne une dizaine de milliers de fois dans les cas classiques. J'ai �crit les tests comme �a parce qu'ils refl�tent au mieux la situation en production. Mais en effet, optimiser aussi la lecture initiale des donn�es en m�moire est un sujet int�ressant, c'est juste que j'ai peu � gagner l� dessus par rapport au reste en production. Mais la remarque et tout � fait pertinente.

    En tout cas merci pour vos retours, �a m'a grandement aid� �claircir ma r�flexion, trouver des pistes et structurer mon d�veloppement.

Discussions similaires

  1. [XL-2010] Demande d'aide exporter les donn�s depuis un classeur vers d'autre classeur avec macro
    Par l'aprentisse dans le forum Macros et VBA Excel
    R�ponses: 10
    Dernier message: 12/08/2016, 01h07
  2. R�ponses: 3
    Dernier message: 16/12/2015, 15h30
  3. extraction de donnes depuis un phichier physique
    Par mery007 dans le forum DB2
    R�ponses: 11
    Dernier message: 26/03/2012, 21h08
  4. R�ponses: 19
    Dernier message: 25/10/2011, 16h55
  5. R�ponses: 2
    Dernier message: 08/11/2006, 18h13

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