8

Jestem nowym użytkownikiem IPython i chciałbym drukować wyniki pośrednie na standardowe wyjście podczas pracy z równoległymi funkcjami klastra IPython. (Mam świadomość, że w przypadku wielu procesów może to zniekształcać dane wyjściowe, ale jest to w porządku - służy tylko do testowania/debugowania, a procesy, które będę wykonywał, są wystarczająco długie, aby takie kolizje były mało prawdopodobne.) Sprawdziłem dokumentacja dla IPython, ale nie może znaleźć przykładu, w którym drukowana jest funkcja zrównoleglona. Zasadniczo szukam sposób przekierowanie wydruków z podprocesów głównej stdout, odpowiednik ipython zDrukowanie na stdout w procesach równoległych IPython

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

drukowania wewnątrz procesu nie działa:

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()) 

zwraca

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

więc obliczenia wykonuje się poprawnie, ale instrukcja print w ff funkcja nie jest drukowany, nawet gdy wszystkie procesy returne re. Co robię źle? Jak mogę "wydrukować" do pracy?

Odpowiedz

9

W rzeczywistości jest bardziej podobny do subprocess.Popen(... , stdout=PIPE), niż można się spodziewać. Podobnie jak obiekt Popen ma atrybut stdout, który można odczytać, aby wyświetlić stout subprocess, AsyncResult ma atrybut stdout zawierający stdout przechwycony z silników. Różni się tym, że AsyncResult.stdout jest listą list ciągów, gdzie każda pozycja na liście jest stdout pojedynczego silnika jako ciąg znaków.

Tak, aby rozpocząć się:

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() 

daje

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

Widzimy listę AsyncResult.stdout ciągów:

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

Widzimy stdout rezultatu asynchronicznym :

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

która drukuje:

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

I here is a notebook z tym wszystkim wykazać.

Niektóre rzeczy, aby pamiętać, oparty na zapytanie:

  1. trzeba czekać na AsyncResult do końca, zanim wyjścia są gotowe (async.get())
  2. display_outputs() niczego nie powrócić - to faktycznie robi drukowanie/wyświetlanie się, więc print(async.display_outputs()) nie ma sensu.
+0

Bardzo pomocna odpowiedź. Czy jest jakiś sposób, aby zobaczyć wydruki standardowe podczas wykonywania obliczeń? – spencerlyon2

+0

yes - dla instrukcji print, po prostu wykonaj 'for out in asyncresult.stdout: print out', które możesz wykonać w dowolnym momencie, nawet jeśli dane wyjściowe są częściowe. – minrk

+1

Czy można to osiągnąć bez dostępu do kodu źródłowego? Istnieje biblioteka, z której korzystam, która drukuje wiadomości dziennika w wątkach i chcę ją wydrukować w trakcie działania. Czy musiałbym rozszerzyć jedną z klas IPython, aby to zrobić? – hgcrpd

Powiązane problemy