Show More
@@ -34,7 +34,7 b' Use activate() on a DirectView object to activate it for magics.' | |||||
34 | class ParalleMagic(Plugin): |
|
34 | class ParalleMagic(Plugin): | |
35 | """A component to manage the %result, %px and %autopx magics.""" |
|
35 | """A component to manage the %result, %px and %autopx magics.""" | |
36 |
|
36 | |||
37 | active_view = Any() |
|
37 | active_view = Instance('IPython.parallel.client.view.DirectView') | |
38 | verbose = Bool(False, config=True) |
|
38 | verbose = Bool(False, config=True) | |
39 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') |
|
39 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') | |
40 |
|
40 | |||
@@ -103,8 +103,10 b' class ParalleMagic(Plugin):' | |||||
103 | print NO_ACTIVE_VIEW |
|
103 | print NO_ACTIVE_VIEW | |
104 | return |
|
104 | return | |
105 | print "Parallel execution on engines: %s" % self.active_view.targets |
|
105 | print "Parallel execution on engines: %s" % self.active_view.targets | |
106 | result = self.active_view.execute(parameter_s) |
|
106 | result = self.active_view.execute(parameter_s, block=False) | |
107 | return result |
|
107 | if self.active_view.block: | |
|
108 | result.get() | |||
|
109 | self._maybe_display_output(result) | |||
108 |
|
110 | |||
109 | @testdec.skip_doctest |
|
111 | @testdec.skip_doctest | |
110 | def magic_autopx(self, ipself, parameter_s=''): |
|
112 | def magic_autopx(self, ipself, parameter_s=''): | |
@@ -123,9 +125,13 b' class ParalleMagic(Plugin):' | |||||
123 | %autopx to enabled |
|
125 | %autopx to enabled | |
124 |
|
126 | |||
125 | In [26]: a = 10 |
|
127 | In [26]: a = 10 | |
126 | <Results List> |
|
128 | Parallel execution on engines: [0,1,2,3] | |
127 |
|
|
129 | In [27]: print a | |
128 | [1] In [8]: a = 10 |
|
130 | Parallel execution on engines: [0,1,2,3] | |
|
131 | [stdout:0] 10 | |||
|
132 | [stdout:1] 10 | |||
|
133 | [stdout:2] 10 | |||
|
134 | [stdout:3] 10 | |||
129 |
|
135 | |||
130 |
|
136 | |||
131 | In [27]: %autopx |
|
137 | In [27]: %autopx | |
@@ -168,23 +174,15 b' class ParalleMagic(Plugin):' | |||||
168 | If self.active_view.block is True, wait for the result |
|
174 | If self.active_view.block is True, wait for the result | |
169 | and display the result. Otherwise, this is a noop. |
|
175 | and display the result. Otherwise, this is a noop. | |
170 | """ |
|
176 | """ | |
171 |
|
|
177 | targets = self.active_view.targets | |
172 | try: |
|
178 | if isinstance(targets, int): | |
173 | result.get() |
|
179 | targets = [targets] | |
174 | except: |
|
180 | if targets == 'all': | |
175 | self.shell.showtraceback() |
|
181 | targets = self.active_view.client.ids | |
176 | return True |
|
182 | stdout = [s.rstrip() for s in result.stdout] | |
177 | else: |
|
183 | if any(stdout): | |
178 | targets = self.active_view.targets |
|
184 | for i,eid in enumerate(targets): | |
179 | if isinstance(targets, int): |
|
185 | print '[stdout:%i]'%eid, stdout[i] | |
180 | targets = [targets] |
|
|||
181 | if targets == 'all': |
|
|||
182 | targets = self.active_view.client.ids |
|
|||
183 | stdout = [s.rstrip() for s in result.stdout] |
|
|||
184 | if any(stdout): |
|
|||
185 | for i,eid in enumerate(targets): |
|
|||
186 | print '[stdout:%i]'%eid, stdout[i] |
|
|||
187 | return False |
|
|||
188 |
|
186 | |||
189 |
|
187 | |||
190 | def pxrun_cell(self, cell, store_history=True): |
|
188 | def pxrun_cell(self, cell, store_history=True): | |
@@ -234,9 +232,17 b' class ParalleMagic(Plugin):' | |||||
234 | result = self.active_view.execute(cell, block=False) |
|
232 | result = self.active_view.execute(cell, block=False) | |
235 | except: |
|
233 | except: | |
236 | ipself.showtraceback() |
|
234 | ipself.showtraceback() | |
237 |
return |
|
235 | return True | |
238 | else: |
|
236 | else: | |
239 | return self._maybe_display_output(result) |
|
237 | if self.active_view.block: | |
|
238 | try: | |||
|
239 | result.get() | |||
|
240 | except: | |||
|
241 | self.shell.showtraceback() | |||
|
242 | return True | |||
|
243 | else: | |||
|
244 | self._maybe_display_output(result) | |||
|
245 | return False | |||
240 |
|
246 | |||
241 | def pxrun_code(self, code_obj, post_execute=True): |
|
247 | def pxrun_code(self, code_obj, post_execute=True): | |
242 | """drop-in replacement for InteractiveShell.run_code. |
|
248 | """drop-in replacement for InteractiveShell.run_code. | |
@@ -256,9 +262,17 b' class ParalleMagic(Plugin):' | |||||
256 | result = self.active_view.execute(code_obj, block=False) |
|
262 | result = self.active_view.execute(code_obj, block=False) | |
257 | except: |
|
263 | except: | |
258 | ipself.showtraceback() |
|
264 | ipself.showtraceback() | |
259 |
return |
|
265 | return True | |
260 | else: |
|
266 | else: | |
261 | return self._maybe_display_output(result) |
|
267 | if self.active_view.block: | |
|
268 | try: | |||
|
269 | result.get() | |||
|
270 | except: | |||
|
271 | self.shell.showtraceback() | |||
|
272 | return True | |||
|
273 | else: | |||
|
274 | self._maybe_display_output(result) | |||
|
275 | return False | |||
262 |
|
276 | |||
263 |
|
277 | |||
264 |
|
278 |
@@ -10,8 +10,10 b'' | |||||
10 | # Imports |
|
10 | # Imports | |
11 | #------------------------------------------------------------------------------- |
|
11 | #------------------------------------------------------------------------------- | |
12 |
|
12 | |||
|
13 | import sys | |||
13 | import time |
|
14 | import time | |
14 | from tempfile import mktemp |
|
15 | from tempfile import mktemp | |
|
16 | from StringIO import StringIO | |||
15 |
|
17 | |||
16 | import zmq |
|
18 | import zmq | |
17 |
|
19 | |||
@@ -300,3 +302,112 b' class TestView(ClusterTestCase):' | |||||
300 |
|
302 | |||
301 | self.assertEquals(view.apply_sync(findall, '\w+', 'hello world'), 'hello world'.split()) |
|
303 | self.assertEquals(view.apply_sync(findall, '\w+', 'hello world'), 'hello world'.split()) | |
302 |
|
304 | |||
|
305 | # parallel magic tests | |||
|
306 | ||||
|
307 | def test_magic_px_blocking(self): | |||
|
308 | ip = get_ipython() | |||
|
309 | v = self.client[-1] | |||
|
310 | v.activate() | |||
|
311 | v.block=True | |||
|
312 | ||||
|
313 | ip.magic_px('a=5') | |||
|
314 | self.assertEquals(v['a'], 5) | |||
|
315 | ip.magic_px('a=10') | |||
|
316 | self.assertEquals(v['a'], 10) | |||
|
317 | sio = StringIO() | |||
|
318 | savestdout = sys.stdout | |||
|
319 | sys.stdout = sio | |||
|
320 | ip.magic_px('print a') | |||
|
321 | sys.stdout = savestdout | |||
|
322 | sio.read() | |||
|
323 | self.assertTrue('[stdout:%i]'%v.targets in sio.buf) | |||
|
324 | self.assertRaisesRemote(ZeroDivisionError, ip.magic_px, '1/0') | |||
|
325 | ||||
|
326 | def test_magic_px_nonblocking(self): | |||
|
327 | ip = get_ipython() | |||
|
328 | v = self.client[-1] | |||
|
329 | v.activate() | |||
|
330 | v.block=False | |||
|
331 | ||||
|
332 | ip.magic_px('a=5') | |||
|
333 | self.assertEquals(v['a'], 5) | |||
|
334 | ip.magic_px('a=10') | |||
|
335 | self.assertEquals(v['a'], 10) | |||
|
336 | sio = StringIO() | |||
|
337 | savestdout = sys.stdout | |||
|
338 | sys.stdout = sio | |||
|
339 | ip.magic_px('print a') | |||
|
340 | sys.stdout = savestdout | |||
|
341 | sio.read() | |||
|
342 | self.assertFalse('[stdout:%i]'%v.targets in sio.buf) | |||
|
343 | ip.magic_px('1/0') | |||
|
344 | ar = v.get_result(-1) | |||
|
345 | self.assertRaisesRemote(ZeroDivisionError, ar.get) | |||
|
346 | ||||
|
347 | def test_magic_autopx_blocking(self): | |||
|
348 | ip = get_ipython() | |||
|
349 | v = self.client[-1] | |||
|
350 | v.activate() | |||
|
351 | v.block=True | |||
|
352 | ||||
|
353 | sio = StringIO() | |||
|
354 | savestdout = sys.stdout | |||
|
355 | sys.stdout = sio | |||
|
356 | ip.magic_autopx() | |||
|
357 | ip.run_cell('\n'.join(('a=5','b=10','c=0'))) | |||
|
358 | ip.run_cell('print b') | |||
|
359 | ip.run_cell("b/c") | |||
|
360 | ip.run_code(compile('b*=2', '', 'single')) | |||
|
361 | ip.magic_autopx() | |||
|
362 | sys.stdout = savestdout | |||
|
363 | sio.read() | |||
|
364 | output = sio.buf.strip() | |||
|
365 | self.assertTrue(output.startswith('%autopx enabled')) | |||
|
366 | self.assertTrue(output.endswith('%autopx disabled')) | |||
|
367 | self.assertTrue('RemoteError: ZeroDivisionError' in output) | |||
|
368 | ar = v.get_result(-2) | |||
|
369 | self.assertEquals(v['a'], 5) | |||
|
370 | self.assertEquals(v['b'], 20) | |||
|
371 | self.assertRaisesRemote(ZeroDivisionError, ar.get) | |||
|
372 | ||||
|
373 | def test_magic_autopx_nonblocking(self): | |||
|
374 | ip = get_ipython() | |||
|
375 | v = self.client[-1] | |||
|
376 | v.activate() | |||
|
377 | v.block=False | |||
|
378 | ||||
|
379 | sio = StringIO() | |||
|
380 | savestdout = sys.stdout | |||
|
381 | sys.stdout = sio | |||
|
382 | ip.magic_autopx() | |||
|
383 | ip.run_cell('\n'.join(('a=5','b=10','c=0'))) | |||
|
384 | ip.run_cell('print b') | |||
|
385 | ip.run_cell("b/c") | |||
|
386 | ip.run_code(compile('b*=2', '', 'single')) | |||
|
387 | ip.magic_autopx() | |||
|
388 | sys.stdout = savestdout | |||
|
389 | sio.read() | |||
|
390 | output = sio.buf.strip() | |||
|
391 | self.assertTrue(output.startswith('%autopx enabled')) | |||
|
392 | self.assertTrue(output.endswith('%autopx disabled')) | |||
|
393 | self.assertFalse('ZeroDivisionError' in output) | |||
|
394 | ar = v.get_result(-2) | |||
|
395 | self.assertEquals(v['a'], 5) | |||
|
396 | self.assertEquals(v['b'], 20) | |||
|
397 | self.assertRaisesRemote(ZeroDivisionError, ar.get) | |||
|
398 | ||||
|
399 | def test_magic_result(self): | |||
|
400 | ip = get_ipython() | |||
|
401 | v = self.client[-1] | |||
|
402 | v.activate() | |||
|
403 | v['a'] = 111 | |||
|
404 | ra = v['a'] | |||
|
405 | ||||
|
406 | ar = ip.magic_result() | |||
|
407 | self.assertEquals(ar.msg_ids, [v.history[-1]]) | |||
|
408 | self.assertEquals(ar.get(), 111) | |||
|
409 | ar = ip.magic_result('-2') | |||
|
410 | self.assertEquals(ar.msg_ids, [v.history[-2]]) | |||
|
411 | ||||
|
412 | ||||
|
413 |
General Comments 0
You need to be logged in to leave comments.
Login now