8

Ich bin neu bei IPython und möchte Zwischenergebnisse auf stdout drucken, während IPython parallel Cluster-Funktionen ausgeführt werden. (Ich bin mir bewusst, dass dies bei mehreren Prozessen die Ausgabe beeinträchtigen kann, aber das ist gut - es ist nur zum Testen/Debuggen und die Prozesse, die ich ausführen würde, sind lang genug, dass eine solche Kollision unwahrscheinlich ist.) Dokumentation für IPython, kann jedoch kein Beispiel finden, in dem die parallelisierte Funktion druckt. Grundsätzlich bin ich nach einer Möglichkeit, die Druckausgabe der Teilprozesse auf die Haupt stdout, die IPython ÄquivalentDrucken in IPython parallelen Prozessen stdout

subprocess.Popen(... , stdout=...) 

Druck innerhalb des Prozesses zu umleiten nicht funktioniert:

rc = Client() 
dview = rc() 
def ff(x): 
    print(x) 
    return x**2 
sync = dview.map_sync(ff,[1,2,3,4]) 
print('sync res=%s'%repr(sync)) 
async = dview.map_async(ff,[1,2,3,4]) 
print('async res=%s'%repr(async)) 
print(async.display_outputs()) 

kehrt
sync res=[1, 4, 9, 16] 
async res=[1, 4, 9, 16] 

So ist die Berechnung korrekt ausgeführt wird, aber die print-Anweisung in der Funktion ff wird nie gedruckt, nicht einmal, wenn alle Prozesse returne haben d. Was mache ich falsch? Wie bekomme ich "Drucken" zur Arbeit?

Antwort

9

Es ist tatsächlich ähnlicher zu subprocess.Popen(... , stdout=PIPE) als Sie zu erwarten scheinen. Genau wie das Popen Objekt ein stdout Attribut hat, die man lesen kann, die stdout des subprocess zu sehen, hat Ein AsyncResult ein stdout Attribut, das die stdout von den Motoren erfaßt enthält. Es unterscheidet sich darin, dass AsyncResult.stdout eine Liste der Zeichenfolgen ist, wobei jedes Element in der Liste das Standout einer einzelnen Engine als Zeichenfolge ist.

Also, beginnen:

rc = parallel.Client() 
dview = rc[:] 
def ff(x): 
    print(x) 
    return x**2 
sync = dview.map_sync(ff,[1,2,3,4]) 
print('sync res=%r' % sync) 
async = dview.map_async(ff,[1,2,3,4]) 
print('async res=%r' % async) 
async.get() 

sync res=[1, 4, 9, 16] 
async res=<AsyncMapResult: ff> 

gibt Wir können die AsyncResult.stdout Liste von Strings sehen:

print(async.stdout) 
['1\n2\n', '3\n4\n'] 

Wir haben die stdout des Asynchron-Ergebnis sehen können :

print('async output:') 
async.display_outputs() 

die druckt:

async output: 
[stdout:0] 
1 
2 
[stdout:1] 
3 
4 

Und here is a notebook mit all dies unter Beweis gestellt.

Einige Dinge zu beachten, auf der Grundlage Ihrer Frage:

  1. Sie für die AsyncResult warten zu beenden, bevor Ausgänge bereit sind (async.get())
  2. display_outputs() gibt nichts zurück - es tatsächlich tut das Drucken/Anzeigen selbst, so print(async.display_outputs()) macht keinen Sinn.
+0

Sehr hilfreiche Antwort. Gibt es eine Möglichkeit, die stdout-Ausdrucke während der Berechnung zu sehen? – spencerlyon2

+0

ja - für Druckanweisungen, tun Sie einfach "für out in asyncresult.stdout: ausdrucken", was Sie jederzeit tun können, auch wenn die Ausgabe teilweise ist. – minrk

+1

Gibt es eine Möglichkeit, dies zu erreichen, ohne auf den Quellcode zugreifen zu müssen? Es gibt eine Bibliothek, die ich verwende, die Protokollnachrichten in Threads druckt, und ich möchte, dass es während der Ausführung druckt. Müsste ich eine von IPythons Klassen erweitern, um dies zu tun? – hgcrpd

Verwandte Themen