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

Shell et commandes GNU Discussion :

Utilisation de GNU parallel pour executer un programme python


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Doctorant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut Utilisation de GNU parallel pour executer un programme python
    Bonjour à tous,

    J'ai un programme python qui me fait du traitement d'image et je souhaite automatiser un peu tout ça puisqu'un traitement dure à l'heure actuelle une vingtaine de minutes.
    J'ai utilisé GNU Parallel pour me permettre d'avoir quelque chose du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    parallel "monprogramme --option1 --option2 --option3=2" ::: *.tif
    Ce qui me permet de lancer mon programme sur tous les fichiers tif du folder.
    Maintenant le problème c'est que pour un seul fichier je souhaite modifier la valeur d'option3 et enregistrer tout ça dans des dossiers séparés.

    J'ai déjà essayé pas mal de choses:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    parallel -- results outputdir "monprogramme --option1 --option2 --option3={.}" ::: {1.10}
    Ceci ne fonctionne pas il n'enregistre pas les outputs dans le bon dossier du coup chaque output écrase l'ancien dans le répertoire courant.

    J'ai pensé mettre tout ceci dans une grosse boucle en faisant un parallel d'un for mais j'ai peur que ce soit compliqué et inutile. J'ai aussi envisagé quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    parallel --results outputdir "mkdir output{} | cd output{}/ | monprogramme --option1 --option2 --option3={} | cd .."
    mais ça me parait complètement stupide même si ça permet peut-être de bien voir ce que je souhaite faire.

    J'ai tenté également avec un mv après le code dans parallel mais je ne sais pas si c'est utile, j'ai peur qu'il y ait une différence entre l'itération réelle et celle du calcul parallèle.

    Si quelqu'un connait un petit GNU parallel ou même les script shell je suis preneur.

    Merci !

  2. #2
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Bonjour

    • D'abord, pour lancer une tâche en arrière plan, donc en parallèle, nul besoin de parallel. Une simple esperluette suffit.
      Je ne vois pas, dans ton explication, de raison spécifique d'utiliser parallel.
    • Peux-tu être plus précis sur les entrées/sorties ?
      Par exemple, en quoi l'option 3 est-elle spécifique ? Sur quoi est-elle indexée ?
    • Un simple script bash devrait te suffire.

  3. #3
    Membre averti
    Homme Profil pro
    Doctorant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut
    Merci de la réponse rapide,

    J'ai 24 coeurs sur mon processeur donc cela me permet de lancer les tâches en simultané le code n'étant pas programmé pour le multithreading.
    Les entrées sont le fichiers .tif et différentes valeurs à rentrer par l'utilisateur qui sont des paramètres de l'image acquise. En particulier ce que je souhaite changer est une sorte de seuil pour un filtrage. Et je cherche à trouver la valeur optimale. La valeur pouvant aller de 1 à 100 je n'ai pas envie de lancer des dizaines de programmes de 20 minutes à la main.

    Maintenant parallel me semble la meilleure chose à faire pour gagner un facteur 24 sur le temps total même si la durée reste à 20 minutes, je fais cela sur des ensembles de centaines d'images donc j'ai un gros intérêt à utiliser cette commande.

  4. #4
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Honnêtement, ce n'est pas beaucoup plus clair.

    Et je cherche à trouver la valeur optimale. La valeur pouvant aller de 1 à 100
    Soit "script.bin" qui prend un dossier en entrée et qui renvoie une valeur en sortie.
    Pourquoi le code suivant ne répond pas à ton problème ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for ((tour=1;tour<=100;tour++))                                                                                                                                                                                                                                                   
    do                                                                                                                                                                                                                                                                                
           script.bin --option3=$tour $dossier/*.tiff >> /tmp/resultats.txt  &                                                                                                                                                                                                                                                            
    done
    Et voici le test. On lance 100 processus simultanément. Et on récupère la valeur. Puis on calcule le max.
    (Le "programme" ne fait que attendre 5 secondes)

    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
    #!/bin/bash                                                                                                                                                                                                                                                                       
     
    fic=/tmp/resultats.txt                                                                                                                                                                                                                                                            
    > "$fic"                                                                                                                                                                                                                                                                          
    for ((tour=1;tour<=100;tour++))                                                                                                                                                                                                                                                   
    do                                                                                                                                                                                                                                                                                
            {                                                                                                                                                                                                                                                                         
                    sleep 5                                                                                                                                                                                                                                                           
                    echo $tour $tour                                                                                                                                                                                                                                                  
                    #script.bin --option3=$tour $dossier/*.tiff                                                                                                                                                                                                                       
            } >> "$fic"  &                                                                                                                                                                                                                                                            
    done                                                                                                                                                                                                                                                                              
    wait                                                                                                                                                                                                                                                                              
     
    head "$fic"                                                                                                                                                                                                                                                                       
    echo                                                                                                                                                                                                                                                                              
    tail "$fic"                                                                                                                                                                                                                                                                       
    echo                                                                                                                                                                                                                                                                              
     
    awk 'BEGIN{max=0;} {if ($2>max){max=$2;gagnant=$1;}} END{print "GAGNANT",gagnant,"MAX",max;}' "$fic"  
    rm -f "$fic"
    Et voici la console:
    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
    2 2
    1 1
    3 3
    4 4
    5 5
    6 6
    7 7
    8 8
    9 9
    10 10
     
    98 98
    42 42
    94 94
    95 95
    99 99
    77 77
    96 96
    97 97
    100 100
    86 86
     
    GAGNANT 100 MAX 100
    Comprends-tu la démarche ?

  5. #5
    Membre averti
    Homme Profil pro
    Doctorant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut
    J'avoue que je ne suis pas certain de comprendre ce dont tu parles.

    Pour faire au plus simple si ce que j'ai dit n'était pas clair: J'ai une image en entrée, mon programme fait beaucoup de choses sur cette image puis me ressort plusieurs nouvelles images dans le même dossier sans supprimer la première. Le calcul total pour faire cela prend entre 20 minutes et 1 heure.
    Pour le lancer j'utilise tout le temps un script qui est de la forme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #!/bin/...
    #blabla
    date "..."
    monprogramme --option1=2 --options(etc.) monimage.tif
    En sortie j'aurais dans mon dossier: monimage.tif, monimagefiltreact.tif, monimagefiltredesact.tif par exemple.
    Mon désir, c'est de faire cela pour différentes valeurs de option1 allant de 1 à 100 et en enregistrant à chaque fois les nouvelles images dans un dossier spécifique.

    Si j'utilise parallel c'est parce que j'ai habituellement des centaines d'images. Quand on a parfois 1 heure par image et bien je préfère que ce soit lancé sur plusieurs coeurs en simultané car le PC a cette capacité. Après si tu me dis quand dans une boucle for,en utilisant &, le terminal lance de lui-même les itérations dans des processus différents, tu me l'apprends et je n'avais pas besoin de parallel effectivement.

    Soit "script.bin" qui prend un dossier en entrée et qui renvoie une valeur en sortie.
    Pourquoi le code suivant ne répond pas à ton problème ?
    Dans ce cas je dois envisager quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for ((tour=1;tour<=100;tour++))                                                                                                                                                                                                                                                   
    do       
           mkdir $tour                                                                                                                                                                                                                                                               
           monprogramme monimage.tif --option1=$tour | mv *filt .tif $tour/ & #en considerant que mes images finissant par filt                                                                                                                                                                                                                                                            
    done
    Compte tenu de la densité du programme il ne va pas y avoir de plantage général ?

    Merci encore une fois de ta réponse complète et désolé si ce n'est pas clair parfois

  6. #6
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 347
    Par défaut
    Bonjour,

    Je confirme que tu n'as pas besoin de parallel, puisque l'esperluette lance un process fils à part entière.

    Par contre, il reste une inconnue de taille: la commande mv ne prend pas un flux en entrée mais des paramètres, tu ne peux donc pas rediriger une sortie vers mv via un pipe.

    Mais, bon ça c'est un détail, ce que je vois de bloquant c'est que ton script python semble créer le même nom de fichier pour un même fichier en entrée ?

    Si c'est le cas et que l'on ne peut pas paramétrer le nommage, comment peux-tu lancer des commandes en concurrence alors qu'elles vont de toutes façon écrire dans les mêmes fichiers de façon concurrentielle ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/07/2008, 07h52
  2. Utilisation d'un GUI pour paramétrer un programme
    Par Gilleo dans le forum Interfaces Graphiques
    Réponses: 7
    Dernier message: 12/04/2007, 16h27
  3. Aide pour executer un programme
    Par parano dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 26/03/2007, 14h19
  4. [syntaxe] pour executer un programme
    Par Mireyu_c dans le forum Général Python
    Réponses: 2
    Dernier message: 15/03/2006, 15h09
  5. Utiliser le port parallele pour simuler un digicode
    Par nonoRedDevils dans le forum Assembleur
    Réponses: 8
    Dernier message: 30/12/2003, 13h23

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