Pickling Fehler

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
taugenichts
User
Beiträge: 4
Registriert: Donnerstag 13. Februar 2014, 17:23

Hallo liebe Community,

als Python-Anfänger stolper ich immer wieder über vermeintlich banale Probleme wie das Folgende.

Ich benutze die library mpi4py um mein script zu parallelisieren. Zum Glück ist die library relativ benutzerfreundlich und auch gut dokumentiert. Leider nutzt sie (wie ich das verstanden habe) 'pickle' für die Kommunikation zwischen den Prozessoren. Nun ist es jedoch so, dass sich nur bestimmte Datentypen 'picklen' lassen. Ein Workaround um z.B. Funktionen zu verschicken habe ich bereits auf stackoverflow gefunden. Leider habe ich das nicht so richtig verstanden und zum Thema module verschicken gibt es gar nichts im Netz. Um mein Problem zu veranschaulichen, hier ein kleines Beispiel:

Code: Alles auswählen

from mpi4py import MPI

from tvtk.api import tvtk
from mayavi import mlab

comm=MPI.COMM_WORLD

size=comm.Get_size()
rank=comm.Get_rank()

if rank==0:
        from tvtk.api import tvtk
        from mayavi import mlab

if __name__=='__main__':        
   
        mlab=comm.bcast(mlab,root=0)   
Resultat:

Code: Alles auswählen

cPickle.PicklingError: Can't pickle <type 'module'>: attribute lookup __builtin__.module failed
Hat jemand eine Idee wie ich das zum laufen kriege oder wenigstens wie ich das Problem umgehen könnte? In C würde ich statt dem Objekt mlab in so einem Fall einfach den Zeiger auf dieses Objekt übergeben. So könnte ich von jedem Prozessor aus auf dasselbe 'mlab' zugreifen. Geht das auch irgendwie mit Python?
BlackJack

@taugenichts: Soweit ich das verstanden habe ist MPI (auch) für Sachen die über mehrere Rechner hinweg laufen, da kannst Du auch in C keinen Pointer auf Speicher in einem Rechner zu einem anderen Rechner übertragen. Selbst auf dem gleichen Rechner in mehreren Prozessen macht das in der Regel keinen Sinn.

Warum willst Du überhaupt ein Modul übertragen? Normalerweise hat man bei solchen Programmen den Code bereits auf den entsprechenden Rechnern installiert beziehungsweise kann der andere Prozess das doch auch importieren.
taugenichts
User
Beiträge: 4
Registriert: Donnerstag 13. Februar 2014, 17:23

Danke für die Antwort, BlackJack.

Ich versuche meine Intention mal etwas genauer darzulegen.
Ich möchte eine Serie von komplexen Rechenvorgängen (Delaunay Tesselation) auf mehrere Prozessoren aufteilen, da es auf einem einzigen einfach zu lange dauert.
Dazu muss jeder Prozessor über das modul "mlab" verfügen, da dieses die entsprechenden Klassen und Algorithmen enthält.

Natürlich könnte ich nun für jeden Kern das "mlab" separat importieren. Das blöde ist nur, dass sobald mlab importiert ist, ein GUI-Fenster erzeugt wird (Darin werden die Ergebnisse später grafisch veranschaulicht), und zwar für jeden Prozessor. Ich brauche allerdings nur ein einziges Fenster, also auch nur 1 mal mlab. Ein 'globales' mlab so zu sagen, auf das ich von jedem Kern aus zugreifen kann.

Das ist aber auch nur einer der Gründe... Jedenfalls brauche ich mlab nur 1 mal.

edit: ist es evtl. möglich ein Objekt vom Typ 'class' zu 'picklen' und an einen anderen Prozessor zu schicken?
BlackJack

@taugenichts: Das wird alles nichts nützen, denn offensichtlich ist das `mlab`-Modul nicht für diese Vorgehensweise geeignet. Ein schönes Beispiel dafür warum es blöd ist wenn das importieren eines Moduls Seiteneffekte hat.
taugenichts
User
Beiträge: 4
Registriert: Donnerstag 13. Februar 2014, 17:23

falls es wen interessieren sollte.es gibt eine simple lösung:

from mpi4py import MPI
MPI._p_pickle.dumps = dill.dumps
MPI._p_pickle.loads = dill.loads
BlackJack

Implementierungsdetails von MPI durch Funktionen aus einer Bibliothek im Alpha-Status ersetzen, wahrscheinlich ohne die Konsequenzen überblicken zu können. Wem's Spass macht… :-)
taugenichts
User
Beiträge: 4
Registriert: Donnerstag 13. Februar 2014, 17:23

hast vermutlich recht, aber was besseres fällt mir momentan nicht ein..

Habe dazu noch eine allgemeine Verständnisfrage:
Wenn ich libraries nutze so wie mpi4py oder mayavi,tvtk, etc., kann ich dann die Module bearbeiten oder sind sie in der Regel kompiliert und nicht mehr zu ändern?
BlackJack

@taugenichts: Das kommt auf die Module an, aber warum möchtest Du die denn ändern? Das bedeutet ja letztendlich dass Du auch deren Code mit pflegen musst.
Antworten