Show More
@@ -36,9 +36,7 b' Usage' | |||||
36 |
|
36 | |||
37 | import ast |
|
37 | import ast | |
38 | import re |
|
38 | import re | |
39 | import sys |
|
|||
40 |
|
39 | |||
41 | from IPython.core.display import display |
|
|||
42 | from IPython.core.error import UsageError |
|
40 | from IPython.core.error import UsageError | |
43 | from IPython.core.magic import Magics, magics_class, line_magic |
|
41 | from IPython.core.magic import Magics, magics_class, line_magic | |
44 | from IPython.testing.skipdoctest import skip_doctest |
|
42 | from IPython.testing.skipdoctest import skip_doctest | |
@@ -64,7 +62,7 b' class ParallelMagics(Magics):' | |||||
64 | @skip_doctest |
|
62 | @skip_doctest | |
65 | @line_magic |
|
63 | @line_magic | |
66 | def result(self, parameter_s=''): |
|
64 | def result(self, parameter_s=''): | |
67 |
"""Print the result of command i on all engines. |
|
65 | """Print the result of command i on all engines. | |
68 |
|
66 | |||
69 | To use this a :class:`DirectView` instance must be created |
|
67 | To use this a :class:`DirectView` instance must be created | |
70 | and then activated by calling its :meth:`activate` method. |
|
68 | and then activated by calling its :meth:`activate` method. | |
@@ -97,7 +95,7 b' class ParallelMagics(Magics):' | |||||
97 | result = self.active_view.get_result(msg_ids) |
|
95 | result = self.active_view.get_result(msg_ids) | |
98 |
|
96 | |||
99 | result.get() |
|
97 | result.get() | |
100 |
|
|
98 | result.display_outputs() | |
101 |
|
99 | |||
102 | @skip_doctest |
|
100 | @skip_doctest | |
103 | @line_magic |
|
101 | @line_magic | |
@@ -128,7 +126,7 b' class ParallelMagics(Magics):' | |||||
128 | result = self.active_view.execute(parameter_s, silent=False, block=False) |
|
126 | result = self.active_view.execute(parameter_s, silent=False, block=False) | |
129 | if self.active_view.block: |
|
127 | if self.active_view.block: | |
130 | result.get() |
|
128 | result.get() | |
131 |
|
|
129 | result.display_outputs() | |
132 |
|
130 | |||
133 | @skip_doctest |
|
131 | @skip_doctest | |
134 | @line_magic |
|
132 | @line_magic | |
@@ -187,54 +185,6 b' class ParallelMagics(Magics):' | |||||
187 | self._autopx = False |
|
185 | self._autopx = False | |
188 | print "%autopx disabled" |
|
186 | print "%autopx disabled" | |
189 |
|
187 | |||
190 | def _display_result(self, result): |
|
|||
191 | """Display the output of a parallel result. |
|
|||
192 | """ |
|
|||
193 | # flush iopub, just in case |
|
|||
194 | rc = self.active_view.client |
|
|||
195 | rc._flush_iopub(rc._iopub_socket) |
|
|||
196 |
|
||||
197 | if result._single_result: |
|
|||
198 | # single result |
|
|||
199 | stdouts = [result.stdout.rstrip()] |
|
|||
200 | stderrs = [result.stderr.rstrip()] |
|
|||
201 | outputs = [result.outputs] |
|
|||
202 | results = [result.get()] |
|
|||
203 | else: |
|
|||
204 | stdouts = [s.rstrip() for s in result.stdout] |
|
|||
205 | stderrs = [s.rstrip() for s in result.stderr] |
|
|||
206 | outputs = result.outputs |
|
|||
207 | results = result.get() |
|
|||
208 |
|
||||
209 | targets = self.active_view.targets |
|
|||
210 | if isinstance(targets, int): |
|
|||
211 | targets = [targets] |
|
|||
212 | elif targets == 'all': |
|
|||
213 | targets = self.active_view.client.ids |
|
|||
214 |
|
||||
215 | # republish stdout: |
|
|||
216 | if any(stdouts): |
|
|||
217 | for eid,stdout in zip(targets, stdouts): |
|
|||
218 | print '[stdout:%2i]' % eid, stdout |
|
|||
219 |
|
||||
220 | # republish stderr: |
|
|||
221 | if any(stderrs): |
|
|||
222 | for eid,stderr in zip(targets, stderrs): |
|
|||
223 | print >> sys.stderr, '[stderr:%2i]' % eid, stderr |
|
|||
224 |
|
||||
225 | # republish displaypub output |
|
|||
226 | for eid,e_outputs in zip(targets, outputs): |
|
|||
227 | for output in e_outputs: |
|
|||
228 | md = output['metadata'] or {} |
|
|||
229 | md['engine'] = eid |
|
|||
230 | self.shell.display_pub.publish(output['source'], output['data'], md) |
|
|||
231 |
|
||||
232 | # finally, add pyout: |
|
|||
233 | for eid,r in zip(targets, results): |
|
|||
234 | if r.pyout: |
|
|||
235 | display(r) |
|
|||
236 |
|
||||
237 |
|
||||
238 | def pxrun_cell(self, raw_cell, store_history=False, silent=False): |
|
188 | def pxrun_cell(self, raw_cell, store_history=False, silent=False): | |
239 | """drop-in replacement for InteractiveShell.run_cell. |
|
189 | """drop-in replacement for InteractiveShell.run_cell. | |
240 |
|
190 | |||
@@ -295,7 +245,7 b' class ParallelMagics(Magics):' | |||||
295 | self.shell.showtraceback() |
|
245 | self.shell.showtraceback() | |
296 | return True |
|
246 | return True | |
297 | else: |
|
247 | else: | |
298 |
|
|
248 | result.display_outputs() | |
299 | return False |
|
249 | return False | |
300 |
|
250 | |||
301 |
|
251 |
@@ -21,7 +21,7 b' from datetime import datetime' | |||||
21 |
|
21 | |||
22 | from zmq import MessageTracker |
|
22 | from zmq import MessageTracker | |
23 |
|
23 | |||
24 | from IPython.core.display import clear_output |
|
24 | from IPython.core.display import clear_output, display | |
25 | from IPython.external.decorator import decorator |
|
25 | from IPython.external.decorator import decorator | |
26 | from IPython.parallel import error |
|
26 | from IPython.parallel import error | |
27 |
|
27 | |||
@@ -377,6 +377,140 b' class AsyncResult(object):' | |||||
377 | sys.stdout.flush() |
|
377 | sys.stdout.flush() | |
378 |
|
378 | |||
379 | print "done" |
|
379 | print "done" | |
|
380 | ||||
|
381 | def _republish_displaypub(self, content, eid): | |||
|
382 | """republish individual displaypub content dicts""" | |||
|
383 | try: | |||
|
384 | ip = get_ipython() | |||
|
385 | except NameError: | |||
|
386 | # displaypub is meaningless outside IPython | |||
|
387 | return | |||
|
388 | md = content['metadata'] or {} | |||
|
389 | md['engine'] = eid | |||
|
390 | ip.display_pub.publish(content['source'], content['data'], md) | |||
|
391 | ||||
|
392 | ||||
|
393 | def _display_single_result(self): | |||
|
394 | ||||
|
395 | print self.stdout | |||
|
396 | print >> sys.stderr, self.stderr | |||
|
397 | ||||
|
398 | try: | |||
|
399 | get_ipython() | |||
|
400 | except NameError: | |||
|
401 | # displaypub is meaningless outside IPython | |||
|
402 | return | |||
|
403 | ||||
|
404 | for output in self.outputs: | |||
|
405 | self._republish_displaypub(output, self.engine_id) | |||
|
406 | ||||
|
407 | if self.pyout is not None: | |||
|
408 | display(self.get()) | |||
|
409 | ||||
|
410 | @check_ready | |||
|
411 | def display_outputs(self, groupby="type"): | |||
|
412 | """republish the outputs of the computation | |||
|
413 | ||||
|
414 | Parameters | |||
|
415 | ---------- | |||
|
416 | ||||
|
417 | groupby : str [default: type] | |||
|
418 | if 'type': | |||
|
419 | Group outputs by type (show all stdout, then all stderr, etc.): | |||
|
420 | ||||
|
421 | [stdout:1] foo | |||
|
422 | [stdout:2] foo | |||
|
423 | [stderr:1] bar | |||
|
424 | [stderr:2] bar | |||
|
425 | if 'engine': | |||
|
426 | Display outputs for each engine before moving on to the next: | |||
|
427 | ||||
|
428 | [stdout:1] foo | |||
|
429 | [stderr:1] bar | |||
|
430 | [stdout:2] foo | |||
|
431 | [stderr:2] bar | |||
|
432 | ||||
|
433 | if 'order': | |||
|
434 | Like 'type', but further collate individual displaypub | |||
|
435 | outputs. This is meant for cases of each command producing | |||
|
436 | several plots, and you would like to see all of the first | |||
|
437 | plots together, then all of the second plots, and so on. | |||
|
438 | """ | |||
|
439 | # flush iopub, just in case | |||
|
440 | self._client._flush_iopub(self._client._iopub_socket) | |||
|
441 | if self._single_result: | |||
|
442 | self._display_single_result() | |||
|
443 | return | |||
|
444 | ||||
|
445 | stdouts = [s.rstrip() for s in self.stdout] | |||
|
446 | stderrs = [s.rstrip() for s in self.stderr] | |||
|
447 | pyouts = [p for p in self.pyout] | |||
|
448 | output_lists = self.outputs | |||
|
449 | results = self.get() | |||
|
450 | ||||
|
451 | targets = self.engine_id | |||
|
452 | ||||
|
453 | if groupby == "engine": | |||
|
454 | for eid,stdout,stderr,outputs,r,pyout in zip( | |||
|
455 | targets, stdouts, stderrs, output_lists, results, pyouts | |||
|
456 | ): | |||
|
457 | if stdout: | |||
|
458 | print '[stdout:%2i]' % eid, stdout | |||
|
459 | if stderr: | |||
|
460 | print '[stderr:%2i]' % eid, stderr | |||
|
461 | ||||
|
462 | try: | |||
|
463 | get_ipython() | |||
|
464 | except NameError: | |||
|
465 | # displaypub is meaningless outside IPython | |||
|
466 | return | |||
|
467 | ||||
|
468 | for output in outputs: | |||
|
469 | self._republish_displaypub(output, eid) | |||
|
470 | ||||
|
471 | if pyout is not None: | |||
|
472 | display(r) | |||
|
473 | ||||
|
474 | elif groupby in ('type', 'order'): | |||
|
475 | # republish stdout: | |||
|
476 | if any(stdouts): | |||
|
477 | for eid,stdout in zip(targets, stdouts): | |||
|
478 | print '[stdout:%2i]' % eid, stdout | |||
|
479 | ||||
|
480 | # republish stderr: | |||
|
481 | if any(stderrs): | |||
|
482 | for eid,stderr in zip(targets, stderrs): | |||
|
483 | print >> sys.stderr, '[stderr:%2i]' % eid, stderr | |||
|
484 | ||||
|
485 | try: | |||
|
486 | get_ipython() | |||
|
487 | except NameError: | |||
|
488 | # displaypub is meaningless outside IPython | |||
|
489 | return | |||
|
490 | ||||
|
491 | if groupby == 'order': | |||
|
492 | output_dict = dict((eid, outputs) for eid,outputs in zip(targets, output_lists)) | |||
|
493 | N = max(len(outputs) for outputs in output_lists) | |||
|
494 | for i in range(N): | |||
|
495 | for eid in targets: | |||
|
496 | outputs = output_dict[eid] | |||
|
497 | if len(outputs) >= N: | |||
|
498 | self._republish_displaypub(outputs[i], eid) | |||
|
499 | else: | |||
|
500 | # republish displaypub output | |||
|
501 | for eid,outputs in zip(targets, output_lists): | |||
|
502 | for output in outputs: | |||
|
503 | self._republish_displaypub(output, eid) | |||
|
504 | ||||
|
505 | # finally, add pyout: | |||
|
506 | for eid,r,pyout in zip(targets, results, pyouts): | |||
|
507 | if pyout is not None: | |||
|
508 | display(r) | |||
|
509 | ||||
|
510 | else: | |||
|
511 | raise ValueError("groupby must be one of 'type', 'engine', 'collate', not %r" % groupby) | |||
|
512 | ||||
|
513 | ||||
380 |
|
514 | |||
381 |
|
515 | |||
382 | class AsyncMapResult(AsyncResult): |
|
516 | class AsyncMapResult(AsyncResult): |
General Comments 0
You need to be logged in to leave comments.
Login now