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 dans une def!


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut multiprocessing dans une def!
    Bonjours, le script suivant fonctionne presque normalement lorsqu'il est dans un objet mais alors à partir du moment que je l'ai mis dans une définition, les choses se sont compliquées!
    Au début, les deux premiers passages se passaient à merveille mais dès la création du troisième objet, le calcul s’arrêtait en plein milieu, il se mettait en pause et les processeurs n'avait plus rien à se mettre sous la dent! (Je ne comprend pas pourquoi d’ailleurs!). Pour tenter d'y remédier, j'ai tout mis dans une définitions de façon à vraiment repartir à 0 à chaque fois que je la rappelle. Seulement, au lieu de faire une pause au troisième passage, Python exprime directement son mécontentement à travers le message suivant:

    File "fractale_objet.py", line 2707, in calculage_rapide
    matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    File "fractale_objet.py", line 2707, in <listcomp>
    matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    File "/usr/lib/python3.4/multiprocessing/pool.py", line 599, in get
    raise self._value
    File "/usr/lib/python3.4/multiprocessing/pool.py", line 383, in _handle_tasks
    put(task)
    File "/usr/lib/python3.4/multiprocessing/connection.py", line 206, in send
    self._send_bytes(ForkingPickler.dumps(obj))
    File "/usr/lib/python3.4/multiprocessing/reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
    _pickle.PicklingError: Can't pickle <function fractale.<locals>.calculage_rapide.<locals>.calcul at 0x7ff331942a60>: attribute lookup calcul on __main__ failed

    Bon, voila, je ne comprend pas vraiment le message mais il se trouve que là, il semble vraiment furax!

    Voici le code qui le met dans cet état:
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    def calculage_rapide(identifiant, lecture):
    	"""
            Rempli peu a peu la variable 'matrice'
            iters_max = nbr maximum d'itérations
            mod_carre = module maximum du nbr complex
            largeur = largeur de la matrice
            hauteur = hauteur de la marice
            z0 = premier terme de la suite
            suite = formule de récurence de la suite
            couleur = information que l'on enregistre dans la matrice
            xmin, xmax, ymin et ymax = dimension du plan complex
            iteration = True quand les itérations comptent et pas seulement le module
            nbr_couleur = Nombre totale de couleur différentes que peut avoir la fractale
            """
    	def calcul(ligne, hauteur):
    		"""
                    Remplissage d'une partie de la matrice
                    Retourne la ligne dans une liste
                    """
    		print("	Ligne n°"+str(ligne+1)+"----"+str(int(100*ligne/hauteur))+"%")
    		liste = []								#On initialise la liste que l'on va remplir
    		I = complex(0,1)							#Ainsi, I est considéré comme une variable
    		y = (ymax-ymin)*ligne/(hauteur-1)+ymin					#La partie imaginaire du plan complex
    		for colone in range(0,largeur):						#Pour chaque case de chaque ligne
    			x = (xmax-xmin)*colone/(largeur-1)+xmin				#La partie réel du plan complex
    			z = eval(z0)							#Création du premier rang de la suite
    			c = 0								#Initialisation du compteur
    			while (c<iters_max) and (((z.real**2)+(z.imag**2))<mod_carre):	#Tant qu'il n'y a aucune raison d'arrêter le calcul de la suite
    				c+=1							#Incrémentation du compteur
    				z = eval(suite)						#Calcul du rang suivant
    			if iteration:							#Si la divergence de la suite compte
    				c = c/iters_max						#On prend en compte le nombre d'itérations
    			else:								#Si le module de la suite compte
    				c = abs(z)/math.sqrt(mod_carre)				#Sinon, c'est le module de z qui est pris en compte
    			liste.append(int(c*nbr_couleurs)/nbr_couleurs)			#Ce pxl est ajouté à la ligne
    		return liste								#La ligne est la valeur de retour
     
    	global matrice,fin								#On fait en sorte que la matrice soit accessible dans tous le programme
     
    	if __name__ == "__main__":							#Si le programme en cours d’exécution est le programme principal
    		tuple1, tuple2 = lecture.lire_tout(identifiant)				#On récupère les données qui permettent de créer l'image
    		iters_max = tuple1[5]
    		mod_carre = tuple1[6]
    		largeur = tuple2[6]
    		hauteur = tuple2[7]
    		z0 = str(tuple1[7])
    		suite = str(tuple1[8])
    		xmin = tuple1[9]
    		xmax = tuple1[10]
    		ymin = tuple1[11]
    		ymax = tuple1[12]
    		iteration = tuple1[13]
    		nbr_couleurs = tuple1[4]
     
    		import multiprocessing							#On importe le module
    		pool = multiprocessing.Pool()						#Il est possible de mettre en argument: processes=nbr_de_coeurs
     
    		liste_res = []								#Tous les résultats seront enregistrés ici
    		compteur = 0								#On met le compteur à 0
    		for ligne in range(0,hauteur):						#Pour chacune des lignes à traiter
    			if fin: return None						#Si il faut en finir, on s'arrète de suite
    			compteur += 1							#On incrémente le compteur
    			liste_res.append(pool.apply_async(calcul, args=(ligne, hauteur)))#On s'en charge
    			compteur = compteur%(hauteur//10)				#C'est le nombre de boucles pandant lesquelles la matrice n'est pas actualisée
    			if compteur == 0:						#Si on en est à la 16ème boucle
    				pool.close()						#On arrète momentanément de charger la liste d'attente
    				pool.join()						#On lance les calculs en liste d'attente
    				matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    				pool = multiprocessing.Pool()				#On réinitialise le pooleur
    				liste_res = []						#On vide la liste des lignes qui ont déjà étés calculées
    		pool.close()								#Validation des dernières lignes
    		pool.join()								#Lancement des derniers calculs
    		matrice.extend([resultat.get() for resultat in liste_res])		#Récupération des derniers résultats
    		fin = True
    		print("		Fin du calcul")
    		return None
    En plus, ce qui complique le programme, c'est qu'il est impératif que la 'matrice' ait une portée global car un thread qui tourne en parallèle, se charge d'enregistrer chaque ligne sur le disque et de supprimer chaque ligne calculée affin de faire de la place en mémoire et de ne pas perdre de temps a la fin du calcul pour enregistrer l'image sur le disque.

    Encore une fois, je suis preneur de toutes les pistes qui permettraient de corriger ce plantage, ou bien d'une autre idée de conception qui aurait le même effet final.

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Il y a trop d'indentations incohérentes dans ton code. On y comprend que dalle.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    Les indentations sont bien voulus. La def dans la def est la exprès. C'était au départ une méthode de l'objet. Je peux encore simplifier le code en enlevant le if 1 et le Else; qui sont en réalités des Try except au cas ou il ait un problème.

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Ben j'ai copié tel quel ton code dans un fichier texte et il est illisible.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Le message d'erreur _pickle.PicklingError: Can't pickle <function fractale.<locals>.calculage_rapide.<locals>.calcul at 0x7ff331942a60>: attribute lookup calcul on __main__ failed dit en gros qu'il ne trouve pas de variable globale "calcul" dans le module '__main__'.
    Erreur que l'on peut reproduire avec bien moins de lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from multiprocessing import Pool
     
    def foo():
        def bar(x, y):
            pass
     
        pool = Pool()
        f = pool.apply_async(bar, args=(1, 2))
        f.wait()
        print (f.get())
     
    if __name__ == '__main__':
        foo()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    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
     
    def calculage_rapide(identifiant, lecture):
     
    	def calcul(ligne, hauteur):
    		liste = range(hauteur)
    		return liste
     
    	global matrice,fin								#On fait en sorte que la matrice soit accessible dans tous le programme
     
    	if __name__ == "__main__":							#Si le programme en cours d’exécution est le programme principal
    		import multiprocessing							#On importe le module
    		pool = multiprocessing.Pool()						#Il est possible de mettre en argument: processes=nbr_de_coeurs
    		liste_res = []								#Tous les résultats seront enregistrés ici
    		compteur = 0								#On met le compteur à 0
    		for ligne in range(0,hauteur):						#Pour chacune des lignes à traiter
    			if fin: return None						#Si il faut en finir, on s'arrète de suite
    			compteur += 1							#On incrémente le compteur
    			liste_res.append(pool.apply_async(calcul, args=(ligne, hauteur)))#On s'en charge
    			compteur = compteur%(hauteur//10)				#C'est le nombre de boucles pandant lesquelles la matrice n'est pas actualisée
    			if compteur == 0:						#Si on en est à la 16ème boucle
    				pool.close()						#On arrète momentanément de charger la liste d'attente
    				pool.join()						#On lance les calculs en liste d'attente
    				matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    				pool = multiprocessing.Pool()				#On réinitialise le pooleur
    				liste_res = []						#On vide la liste des lignes qui ont déjà étés calculées
    		pool.close()								#Validation des dernières lignes
    		pool.join()								#Lancement des derniers calculs
    		matrice.extend([resultat.get() for resultat in liste_res])		#Récupération des derniers résultats
    		return None
    Voici mon code encore plus épuré.

    Je croyait que '__main__' était juste une valeur que prenait la variable name si le programme est lancé depuis l’extérieur. Pourquoi il cherche une variable 'calcul' dans un module??? Cela fait que 1 an que je code et encore beaucoup de choses m'échappent! Du coup, il faut faire quoi pour lui faire comprendre que la variable calcul se trouve dans le programme et pas dans un module (si c'est bien comme ça qu'il faut réparer le bug!) ou bien, comment créer un lien dans le module '__main__' qui mène vers la véritable fonction calcul?

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Du coup, il faut faire quoi pour lui faire comprendre que la variable calcul se trouve dans le programme et pas dans un module (si c'est bien comme ça qu'il faut réparer le bug!) ou bien, comment créer un lien dans le module '__main__' qui mène vers la véritable fonction calcul?
    "calcul" est variable locale de la fonction "calculage_rapide" parce que fonction définie à l'intérieur d'une autre fonction. Faites en une fonction "normale" et çà ira mieux.
    note: multiprocessing vous impose de travailler sur des objets "pickable" (ou de les rendre pickable). Une fonction incluse dans une autre fonction ne l'est pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> import pickle
    >>> def f():
    ...     def g(): pass
    ...     pickle.dumps(g)
    ...
    >>> f()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in f
    _pickle.PicklingError: Can't pickle <function f.<locals>.g at 0x0000000002D8A9D8
    >: attribute lookup g on __main__ failed
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    Cela ne change absolument rien, j'ai exactement le même message d'erreur! Comment peut-on faire pour déclarer une définition en globale?

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Cela ne change absolument rien, j'ai exactement le même message d'erreur! Comment peut-on faire pour déclarer une définition en globale?
    Vous avez changé quoi?

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

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    J'ai sorti la def 'calcul' pour la mètre au même niveau que la définition principale.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    "au même niveau", c'est plutôt vague...
    Si je modifie mon exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from multiprocessing import Pool
     
    def bar(x, y):
          pass
     
    def foo():
        pool = Pool()
        f = pool.apply_async(bar, args=(1, 2))
        f.wait()
        print (f.get())
     
    if __name__ == '__main__':
        foo()
    çà fonctionne... mais cela ne reflète pas ce que vous avez fait vous.

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

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    Ce que j'ai fait suit votre exemple mais cette partie là du programme est elle même aussi dans une autre définition du programme principal. Je ne peux pas tous mettre sur le même plan car ce serait incompréhensible (il y a environ 3500 lignes de code). Du coup, comment faire pour rendre Global, la portée d'une variable de type 'définition'?

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Du coup, comment faire pour rendre Global, la portée d'une variable de type 'définition'?
    "pickable" et "global" ne sont pas les mêmes choses.

    Citation Envoyé par Robin Richard Voir le message
    Ce que j'ai fait suit votre exemple mais cette partie là du programme est elle même aussi dans une autre définition du programme principal. Je ne peux pas tous mettre sur le même plan car ce serait incompréhensible (il y a environ 3500 lignes de code).
    Certes mais rien ne vous empêche de traduire cette structure en un exemple plus petit qui permette de savoir de quoi on parle et quel est le problème à résoudre. A défaut, pas facile de vous aider.

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

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    bon, alors voici la structure:

    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
     
    def fractale():
    	def calcul(lecture,ligne):
    		liste = []
    		return liste													#La ligne est la valeur de retour
     
    	def calculage_rapide(lecture):
    		if __name__ == "__main__":											#Si le programme en cours d'execution est le programme principal
    			import multiprocessing										#On importe le module
    			pool = multiprocessing.Pool()								#Il est possible de mettre en argument: processes=nbr_de_coeurs
    			liste_res = []												#Tous les résultats seront enregistrés ici
    			compteur = 0												#On met le compteur à 0
    			for ligne in range(0,lecture.hauteur):						#Pour chacune des lignes à traiter
    				if lecture.fin_calcul: return None						#Si il faut en finir, on s'arrète de suite
    				compteur += 1											#On incrémente le compteur
    				liste_res.append(pool.apply_async(calcul, args=(lecture,ligne)))#On s'en charge
    				compteur = compteur%(lecture.hauteur//10)				#C'est le nombre de boucles pandant lesquelles la matrice n'est pas actualisée
    				if compteur == 0:										#Si on en est à un multiple du dixième de l'image
    					pool.close()										#On arrète momentanément de charger la liste d'attente
    					pool.join()											#On lance les calculs en liste d'attente
    					lecture.matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    					pool = multiprocessing.Pool()						#On réinitialise le pooleur
    					liste_res = []										#On vide la liste des lignes qui ont déjà étés calculées
    			pool.close()												#Validation des dernières lignes
    			pool.join()													#Lancement des derniers calculs
    			lecture.matrice.extend([resultat.get() for resultat in liste_res])	#Récupération des derniers résultats
    			lecture.fin_calcul = True
    			return None
     
    	if __name__ == "__main__":
    		calculage_rapide(lecture)
    Je pense que cela devrai suffire.

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Je pense que cela devrai suffire.
    Votre code n'est pas assez complet pour reproduire quoi que ce soit.
    On ne peut que le lire et je ne vois pas trop ce que çà a de différent que l'exemple que je vous ai proposé: pour rendre "calcul" pickable, il suffit de le définir "au même niveau" - une fonction globale et non emboîtée dans... - que "fractale".

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

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    J'ai retiré la def 'fractale' pour pouvoir enlever une tabulation à toutes les lignes.
    Désormais, le message d'erreur est le suivant:

    Traceback (most recent call last):
    File "fractale_objet.py", line 3485, in <module>
    calculage_rapide(lecture) #Lancement du calcul de la fractale
    File "fractale_objet.py", line 2784, in calculage_rapide
    lecture.matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    File "fractale_objet.py", line 2784, in <listcomp>
    lecture.matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    File "/usr/lib/python3.4/multiprocessing/pool.py", line 599, in get
    raise self._value
    File "/usr/lib/python3.4/multiprocessing/pool.py", line 383, in _handle_tasks
    put(task)
    File "/usr/lib/python3.4/multiprocessing/connection.py", line 206, in send
    self._send_bytes(ForkingPickler.dumps(obj))
    File "/usr/lib/python3.4/multiprocessing/reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
    TypeError: cannot serialize '_io.TextIOWrapper' object

  17. #17
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    quand on tente d'assainir le code d'origine on obtient - code minimal - ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def calculage_rapide(identifiant, lecture):
       def calcul(ligne, hauteur):
          (...)
     
       global matrice,fin
     
       if __name__ == "__main__":
          import multiprocessing
          (...)
    je rejoins ce que disait VinsS, y'a au minimum un problème d'indentation, probablement du fait de ces affreuses tabulations de 8 char.
    définir une fonction dans une fonction pourquoi pas, encore faut-il qu'il y ait un intérêt, ici il n'est toujours pas évident on ne comprend pas ce que tu cherches à faire.

  18. #18
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    Bonjour, j'édite mes programmes avec Sublime Text et l’intérêt que j'ai de mettre des def dans des def me permet simplement de réussir à comprendre mon propre programme car ce logiciel est capable de cacher tout le contenu d'une tabulation. Je fait des définitions principales dans lesquelles je met des définitions secondaires dans lesquelles je met[...] (bref, c'est ma méthode de rangement).

    Le but de ce bout de programme est de calculer le plus rapidement possible la valeur des pxls d'une image (dans une liste de liste) pendant qu'un thread se charge d'enregistrer l'image.
    En fait, le bout de code que je tente de mettre au pont grâce à vous ajoute des lignes à la fin de la matrice pendant que le thread supprime petit à petit les première ligne de la matrice jusqu'a ce que l'image est été complètement enregistrer. Je fait ça pour 2 raisons: Ne pas perdre de temps à enregistrer l'image pendant que le processeur se tourne les pouces. Ne pas surcharger la rame (avant de mettre au point cette technique la rame était plaine (8GO), et le swap à 50%) car on vide la rame en enregistrant l'image sur le disque en même temps qu'elle se crée.

    Dans l'absolu, je n'ai aucune contrainte de defs dans des defs mais il faut juste que toutes les performances du PC soient utilisées et que l'on puisse recharger la matrice au fur et à mesure des calculs.

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Citation Envoyé par Robin Richard Voir le message
    TypeError: cannot serialize '_io.TextIOWrapper' object
    C'est aussi un problème qu'on peut facilement reproduire:
    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
    from multiprocessing import Pool
     
    def bar(f):
        return y
     
    def func():
     
        def foo():
            f = open('test.dat', 'r')
            pool = Pool()
            f = pool.apply_async(bar, args=(f,))
            f.wait()
            print (f.get())
     
        foo()
    if __name__ == '__main__':
        func()
    mais est-ce que cela correspond à ce que fait votre code?
    Après côté solutions, il faut revoir un peu la conception (ok, on passe un fichier ouvert mais pour en faire quoi?) car le "calcul" donné en exemple ne fait rien de ce paramètre là...

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

  20. #20
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Points : 6
    Points
    6
    Par défaut
    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
     
    class calculage_rapide(object):
     
    	def __init__(self, lecture):
    		self.lecture = lecture
     
    	def calcul(ligne):
     
    		liste = []
    		I = complex(0,1)												#Ainsi, I est considéré comme une variable
    		y = (self.lecture.ymax-self.lecture.ymin)*ligne/(self.lecture.hauteur-1)+self.lecture.ymin#La partie imaginaire du plan complex
    		for colone in range(0,self.lecture.largeur):					#Pour chaque case de chaque ligne
    			x = (self.lecture.xmax-self.lecture.xmin)*colone/(self.lecture.largeur-1)+self.lecture.xmin#La partie réel du plan complex
    			z = eval(self.lecture.z0)									#Création du premier rang de la suite
    			c = 0														#Initialisation du compteur
    			while (c<self.lecture.iters_max) and (((z.real**2)+(z.imag**2))<self.lecture.mod_carre):#Tant qu'il n'y a aucune raison d'arrêter le calcul de la suite
    				c+=1													#Incrémentation du compteur
    				z = eval(self.lecture.suite)							#Calcul du rang suivant
    			if self.lecture.iteration:									#Si la divergence de la suite compte
    				c = c/self.lecture.iters_max							#On prend en compte le nombre d'itérations
    			else:														#Si le module de la suite compte
    				c = abs(z)/math.sqrt(self.lecture.mod_carre)			#Sinon, c'est le module de z qui est pris en compte
    			liste.append(int(c*self.lecture.nbr_couleurs)/self.lecture.nbr_couleurs)#Ce pxl est ajouté à la ligne
    		return liste													#La ligne est la valeur de retour
     
    	def run(self):
    		if __name__ == "__main__":											#Si le programme en cours d'execution est le programme principal
    			import multiprocessing										#On importe le module
    			pool = multiprocessing.Pool()								#Il est possible de mettre en argument: processes=nbr_de_coeurs
    			liste_res = []												#Tous les résultats seront enregistrés ici
    			compteur = 0												#On met le compteur à 0
    			for ligne in range(0,lecture.hauteur):						#Pour chacune des lignes à traiter
    				if lecture.fin_calcul: return None						#Si il faut en finir, on s'arrète de suite
    				liste_res.append(pool.apply_async(self.calcul, args=(ligne)))#On s'en charge
    			pool.close()												#Validation des dernières lignes
    			pool.join()													#Lancement des derniers calculs
    			lecture.matrice.extend([resultat.get() for resultat in liste_res])#Récupération des derniers résultats
    			lecture.fin_calcul = True
    			return None
    Le but est très simple: faire fonctionner cela! (du moins, dans un premier temps!)
    L'idéal serait que quand j'appelle la méthode run() depuis l’extérieur, la variable lecture.matrice se remplisse au fur et à mesure dans l'ordre croissant (sans mélanger les lignes car cela fera bizarre dans l'image finale).

    En fait, je ne comprend pas bien ce que fait ce module. Il se ré-exécute lui-même plusieurs fois en même temps?

Discussions similaires

  1. [Python 3.X] Ajouter des Labels/Buttons sur une fenetre dans une def
    Par RetardedGenji dans le forum Tkinter
    Réponses: 3
    Dernier message: 10/06/2017, 12h55
  2. Réponses: 11
    Dernier message: 29/04/2016, 12h15
  3. [Python 2.X] Déclaration d'un tableau dans une Class MaClass \ def
    Par macErmite dans le forum Général Python
    Réponses: 3
    Dernier message: 26/07/2015, 08h53
  4. Inclure un .def dans une dll
    Par wanchy dans le forum Eclipse C & C++
    Réponses: 0
    Dernier message: 23/07/2009, 09h45
  5. gérer les jpg dans une fenetre directdraw???
    Par Anonymous dans le forum DirectX
    Réponses: 1
    Dernier message: 14/06/2002, 13h39

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