2013-08-06 20 views
2

我正在使用IPython的parallelization功能运行一堆长时间运行的任务。IPython并行引擎的实时输出?

如何在IPython客户端中从ipengines的stdout获得实时输出?

例如,我正在运行dview.map_async(fun, lots_of_args)fun打印到标准输出。我希望看到他们正在发生的产出。

我知道AsyncResult.display_output(),但是只有之后所有的任务都完成了。

回答

7

您可以通过访问AsyncResult.stdout来查看标准输出,它将返回一个字符串列表,这是来自每个引擎的标准输出。

最简单的情况存在:

print ar.stdout 

您可以在您等待的AsyncResult完成该标准输出打印一个简单的函数把这个包:

import sys 
import time 
from IPython.display import clear_output 

def wait_watching_stdout(ar, dt=1, truncate=1000): 
    while not ar.ready(): 
     stdouts = ar.stdout 
     if not any(stdouts): 
      continue 
     # clear_output doesn't do much in terminal environments 
     clear_output() 
     print '-' * 30 
     print "%.3fs elapsed" % ar.elapsed 
     print "" 
     for eid, stdout in zip(ar._targets, ar.stdout): 
      if stdout: 
       print "[ stdout %2i ]\n%s" % (eid, stdout[-truncate:]) 
     sys.stdout.flush() 
     time.sleep(dt) 

一个example notebook说明此功能。

现在,如果您使用的是较旧的IPython,您可能会看到stdout属性访问受限制('Result not ready'错误)。 的信息是在元数据可用,所以你仍然可以得到它,而任务没有完成:

rc.spin() 
stdout = [ rc.metadata[msg_id]['stdout'] for msg_id in ar.msg_ids ] 

基本上就是ar.stdout属性的访问做同样的事情。

+0

真棒,非常感谢!我非常感谢你在IPython平行工作以及你在这个答案中付出的努力。做得好! – rodion

+1

笔记本应该可能会更新,因为'任何(stdouts)'引发一个异常。 : - / –

0

以防万一有人仍与各个籽粒的 让普通打印输出挣扎:

我适应minrk的答案这样,我得到的每一个 内核的输出,如果它本来是一个地方一个通过不断检查每个内核的stdout是否在程序运行时发生改变。然后

asdf = dview.map_async(function, arguments) 

# initialize a stdout0 array for comparison 
stdout0 = asdf.stdout 

while not asdf.ready(): 
    # check if stdout changed for any kernel 
    if asdf.stdout != stdout0: 
     for i in range(0,len(asdf.stdout)): 
      if asdf.stdout[i] != stdout0[i]: 
       # print only new stdout's without previous message and remove '\n' at the end 
       print('kernel ' + str(i) + ': ' + asdf.stdout[i][len(stdout0[i]):-1]) 

       # set stdout0 to last output for new comparison 
       stdout0 = asdf.stdout 
    else: 
     continue 


asdf.get() 

输出将是这样的:

kernel0: message 1 from kernel 0 
kernel1: message 1 from kernel 1 
kernel0: message 2 from kernel 0 
kernel0: message 3 from kernel 0 
kernel1: message 2 from kernel 0 
...