Multiprocessing will nicht

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
Pookie
User
Beiträge: 8
Registriert: Freitag 6. März 2015, 10:21

Hallöchen,
irgendwie werde ich nicht grün mit der ganzen multiprocessing Problematik.

Also ich habe folgenden Aufbau:
Die Dateien liegen beide im selben Ordner.

Code: Alles auswählen

from TEM import calc_f_tinf
from numpy import zeros    
from sympy import mpmath as mp
from multiprocessing import Pool

lsg = []

def callback_func(x):
    lsg.append(x)

def main():    
    cores = 3    
    #phys. Params
    mp.mp.dps = 30
    E1c=mp.mpf('0.1')
    E2c=mp.mpf('0.05')
    #usw die anderen variablen werden hier auch noch definiert
    pool = Pool(cores)
    p_par = mp.mp.zero
    p_perp_arr = mp.linspace(mp.mp.zero,mp.mp.one,cores)
    for i in p_perp_arr:
        print('test')
        p_perp = i
        pool.apply_async(calc_f_tinf,args=(zeros,mp.mp,E1c,E2c,X,N,Ton,Tflat,p_perp,p_par,degree,tol,max_radius),callback=callback_func)    
    pool.close()    
    pool.join()
    print(sorted(lsg))

if __name__ == '__main__':
    main()
und die Datei TEM von der ich die Funktion nutzen will.

Code: Alles auswählen

def hilfsfkt():
    return hilfe
def calc_f_tinf(zeros,ctx,E1c,E2c,X,N,Ton,Tflat,p_perp,p_par,degree,tol,max_radius):
    #code code
    hilfsfkt() #soll heißen hier wird nochmal eine funktion aus der datei genutzen ich könnte mir das als mögliches Problem vorstellen
    #code code
    return [p_perp,p_par,ctx.fsub(ctx.one,erg[0,0],exact=True)]
Ich benutze die IDE Spyder auf Windows. Der Witz ist nun das die Ausgabe mit Python einfach nur:
test
test
test
[]
ist und gar kein Fehler kommt, wenn ich jedoch IPython nutze kommt zwar die selbe ausgabe aber im Kernel kommt noch folgender Traceback:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "F:\Anaconda3\lib\multiprocessing\spawn.py", line 106, in spawn_main
exitcode = _main(fd)
File "F:\Anaconda3\lib\multiprocessing\spawn.py", line 115, in _main
prepare(preparation_data)
File "F:\Anaconda3\lib\multiprocessing\spawn.py", line 226, in prepare
_fixup_main_from_path(data['init_main_from_path'])
File "F:\Anaconda3\lib\multiprocessing\spawn.py", line 278, in _fixup_main_from_path
run_name="__mp_main__")
File "F:\Anaconda3\lib\runpy.py", line 240, in run_path
pkg_name=pkg_name, script_name=fname)
File "F:\Anaconda3\lib\runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "F:\Anaconda3\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "F:\geheim_pfad_;)\calc_multi.py", line 3, in <module>
from TEM import calc_f_tinf
ImportError: No module named 'TEM'
Und das dreimal direkt quasi einmal für jeden Kern, nur verstehe ich das gar nicht, da bei der funktion calc_f_tinf welche beim multiprocessing aufgerufen werden soll gar nix mehr importiert werden soll. Und wenn ich das mit dem Pool weglasse und sonst alles wie oben lasse, nur die funktion calc_f_tinf direkt aufrufe mit allen Parametern dann funktioniert es, was mir eigentlich sagt das es ja TEM doch findet.
Pookie
User
Beiträge: 8
Registriert: Freitag 6. März 2015, 10:21

ich hab jetzt nochmal als test einfach mal

Code: Alles auswählen

lsg = []
     
def callback_func(x):
    lsg.append(x)
     
def main():    
    from TEM import calc_f_tinf
    from numpy import zeros    
    from sympy import mpmath as mp
    from multiprocessing import Pool

    cores = 3    
    #phys. Params
    mp.mp.dps = 30
    E1c=mp.mpf('0.1')
    E2c=mp.mpf('0.05')
    #usw die anderen variablen werden hier auch noch definiert
    pool = Pool(cores)
    p_par = mp.mp.zero
    p_perp_arr = mp.linspace(mp.mp.zero,mp.mp.one,cores)
    for i in p_perp_arr:
        print('test')
        p_perp = i
        pool.apply_async(calc_f_tinf,args=(zeros,mp.mp,E1c,E2c,X,N,Ton,Tflat,p_perp,p_par,degree,tol,max_radius),callback=callback_func)    
    pool.close()    
    pool.join()
    print(sorted(lsg))
     
if __name__ == '__main__':
    main()
gemacht - auch wenn mir das irgendwie sehr komisch erscheint, jetzt kommt gar keine Fehlermeldung mehr aber die Output ist immer noch der selbe. Man sieht auch im Task Manager das ganz kurz 3 Python prozesse gestartet werden aber auch schnell wieder weg sind und scheinbar nix machen.
BlackJack

@Pookie: Das Modul das als Programm gestartet wurde wird in jedem Prozess importiert (zumindest unter Windows), darum muss das auch ohne Nebeneffekte importierbar sein, also das Hauptprogramm beispielsweise durch das ``if __name__ == '__main__':``-Idiom abgesichert sein.

Und in jedem der Prozesse wird die `callback_func()` *dort* aufgerufen und das Ergebnis an die Liste *dort* angehängt. Wenn Du Rückgabewerte über Prozessgrenzen hinweg haben möchtest, musst Du die Kommunikationsmittel nutzen die `multiprocessing` zur Verfügung stellt, oder einfach das Ergebnis zurückgeben lassen und dann eine der `Pool.map*()`-Methoden verwenden.
Pookie
User
Beiträge: 8
Registriert: Freitag 6. März 2015, 10:21

Also das Konstrukt müsste eigentlich Funktionieren, denn wenn ich:

Code: Alles auswählen

from multiprocessing import Pool

lsg = []

def callback_func(x):
    lsg.append(x)

def calculation(a):
    y = 0
    for i in range(10000000):
        y+=a
    return y

if __name__ == '__main__':
    b = 6
    pool = Pool()
    for i in range(10):
        pool.apply_async(calculation,args=(b,),callback=callback_func)
    pool.close()
    pool.join()
    print(lsg)
ausführe kommt als Output:
[60000000, 60000000, 60000000, 60000000, 60000000, 60000000, 60000000, 60000000, 60000000, 60000000]
Also genau was man/ich erwarten würde und vom Prinzip her auch in der Version oben haben möchte.
Und wie ich geschrieben habe funktioniert der import von TEM ja wenn ich das ganze mit multiprocessing weg lasse und nur die Funktion direkt aufführe, da wundert mich wieso es auf einmal import Probleme gibt - und vorallem wie ich diese dann beheben sollte.
BlackJack

@Pookie: Ist aus `TEM` denn importierbar ohne das man irgend etwas spezielles machen muss? Also kann das von dem Arbeitsverzeichnis aus wo Du das Programm startest von einem normalen Python-Interpreter importiert werden oder macht Deine IDE da irgendwelche Magie um Projektordner zum Suchpfad hinzuzufügen oder ähnliches?

Auch wenn es mit der globalen Liste funktioniert, warum benutzt Du so einen unübersichtlichen Ansatz und keine der `map()`-Methoden?
Pookie
User
Beiträge: 8
Registriert: Freitag 6. März 2015, 10:21

Ok mit der map das schau ich mir mal an, ich hab ich nicht genutzt weil ich es nicht kannte ;)

Ansonsten hab ich die Sache jetzt mal per Konsole versucht um IDE Sachen auszuschließen und da passiert das selbe, keine Fehlermeldung und der Output wie beschrieben.
Antworten