##// END OF EJS Templates
update parallel_magic for Views...
MinRK -
Show More
@@ -14,7 +14,9 b''
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import ast
17 import new
18 import new
19 import re
18
20
19 from IPython.core.plugin import Plugin
21 from IPython.core.plugin import Plugin
20 from IPython.utils.traitlets import Bool, Any, Instance
22 from IPython.utils.traitlets import Bool, Any, Instance
@@ -26,15 +28,15 b' from IPython.testing import decorators as testdec'
26 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
27
29
28
30
29 NO_ACTIVE_MULTIENGINE_CLIENT = """
31 NO_ACTIVE_VIEW = """
30 Use activate() on a MultiEngineClient object to activate it for magics.
32 Use activate() on a DirectView object to activate it for magics.
31 """
33 """
32
34
33
35
34 class ParalleMagic(Plugin):
36 class ParalleMagic(Plugin):
35 """A component to manage the %result, %px and %autopx magics."""
37 """A component to manage the %result, %px and %autopx magics."""
36
38
37 active_multiengine_client = Any()
39 active_view = Any()
38 verbose = Bool(False, config=True)
40 verbose = Bool(False, config=True)
39 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
41 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
40
42
@@ -54,7 +56,7 b' class ParalleMagic(Plugin):'
54 def magic_result(self, ipself, parameter_s=''):
56 def magic_result(self, ipself, parameter_s=''):
55 """Print the result of command i on all engines..
57 """Print the result of command i on all engines..
56
58
57 To use this a :class:`MultiEngineClient` instance must be created
59 To use this a :class:`DirectView` instance must be created
58 and then activated by calling its :meth:`activate` method.
60 and then activated by calling its :meth:`activate` method.
59
61
60 Then you can do the following::
62 Then you can do the following::
@@ -71,22 +73,22 b' class ParalleMagic(Plugin):'
71 [0] In [6]: a = 10
73 [0] In [6]: a = 10
72 [1] In [6]: a = 10
74 [1] In [6]: a = 10
73 """
75 """
74 if self.active_multiengine_client is None:
76 if self.active_view is None:
75 print NO_ACTIVE_MULTIENGINE_CLIENT
77 print NO_ACTIVE_VIEW
76 return
78 return
77
79
78 try:
80 try:
79 index = int(parameter_s)
81 index = int(parameter_s)
80 except:
82 except:
81 index = None
83 index = None
82 result = self.active_multiengine_client.get_result(index)
84 result = self.active_view.get_result(index)
83 return result
85 return result
84
86
85 @testdec.skip_doctest
87 @testdec.skip_doctest
86 def magic_px(self, ipself, parameter_s=''):
88 def magic_px(self, ipself, parameter_s=''):
87 """Executes the given python command in parallel.
89 """Executes the given python command in parallel.
88
90
89 To use this a :class:`MultiEngineClient` instance must be created
91 To use this a :class:`DirectView` instance must be created
90 and then activated by calling its :meth:`activate` method.
92 and then activated by calling its :meth:`activate` method.
91
93
92 Then you can do the following::
94 Then you can do the following::
@@ -99,18 +101,18 b' class ParalleMagic(Plugin):'
99 [1] In [7]: a = 5
101 [1] In [7]: a = 5
100 """
102 """
101
103
102 if self.active_multiengine_client is None:
104 if self.active_view is None:
103 print NO_ACTIVE_MULTIENGINE_CLIENT
105 print NO_ACTIVE_VIEW
104 return
106 return
105 print "Parallel execution on engines: %s" % self.active_multiengine_client.targets
107 print "Parallel execution on engines: %s" % self.active_view.targets
106 result = self.active_multiengine_client.execute(parameter_s)
108 result = self.active_view.execute(parameter_s)
107 return result
109 return 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=''):
111 """Toggles auto parallel mode.
113 """Toggles auto parallel mode.
112
114
113 To use this a :class:`MultiEngineClient` instance must be created
115 To use this a :class:`DirectView` instance must be created
114 and then activated by calling its :meth:`activate` method. Once this
116 and then activated by calling its :meth:`activate` method. Once this
115 is called, all commands typed at the command line are send to
117 is called, all commands typed at the command line are send to
116 the engines to be executed in parallel. To control which engine
118 the engines to be executed in parallel. To control which engine
@@ -137,67 +139,89 b' class ParalleMagic(Plugin):'
137 self._enable_autopx()
139 self._enable_autopx()
138
140
139 def _enable_autopx(self):
141 def _enable_autopx(self):
140 """Enable %autopx mode by saving the original run_source and installing
142 """Enable %autopx mode by saving the original run_cell and installing
141 pxrun_source.
143 pxrun_cell.
142 """
144 """
143 if self.active_multiengine_client is None:
145 if self.active_view is None:
144 print NO_ACTIVE_MULTIENGINE_CLIENT
146 print NO_ACTIVE_VIEW
145 return
147 return
146
148
147 self._original_run_source = self.shell.run_source
149 self._original_run_cell = self.shell.run_cell
148 self.shell.run_source = new.instancemethod(
150 self.shell.run_cell = new.instancemethod(
149 self.pxrun_source, self.shell, self.shell.__class__
151 self.pxrun_cell, self.shell, self.shell.__class__
150 )
152 )
151 self.autopx = True
153 self.autopx = True
152 print "%autopx enabled"
154 print "%autopx enabled"
153
155
154 def _disable_autopx(self):
156 def _disable_autopx(self):
155 """Disable %autopx by restoring the original InteractiveShell.run_source.
157 """Disable %autopx by restoring the original InteractiveShell.run_cell.
156 """
158 """
157 if self.autopx:
159 if self.autopx:
158 self.shell.run_source = self._original_run_source
160 self.shell.run_cell = self._original_run_cell
159 self.autopx = False
161 self.autopx = False
160 print "%autopx disabled"
162 print "%autopx disabled"
161
163
162 def pxrun_source(self, ipself, source, filename=None,
164 def pxrun_cell(self, ipself, cell, store_history=True):
163 symbol='single', post_execute=True):
165 """drop-in replacement for InteractiveShell.run_cell.
164
166
165 # We need to ensure that the source is unicode from here on.
167 This executes code remotely, instead of in the local namespace.
166 if type(source)==str:
168 """
167 usource = source.decode(ipself.stdin_encoding)
169 raw_cell = cell
168 else:
170 with ipself.builtin_trap:
169 usource = source
171 cell = ipself.prefilter_manager.prefilter_lines(cell)
172
173 # Store raw and processed history
174 if store_history:
175 ipself.history_manager.store_inputs(ipself.execution_count,
176 cell, raw_cell)
170
177
171 if 0: # dbg
178 # ipself.logger.log(cell, raw_cell)
172 print 'Source:', repr(source) # dbg
173 print 'USource:', repr(usource) # dbg
174 print 'type:', type(source) # dbg
175 print 'encoding', ipself.stdin_encoding # dbg
176
179
177 try:
180 cell_name = ipself.compile.cache(cell, ipself.execution_count)
178 code = ipself.compile(usource, symbol, ipself.execution_count)
181
179 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
182 try:
180 # Case 1
183 code_ast = ast.parse(cell, filename=cell_name)
181 ipself.showsyntaxerror(filename)
184 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
182 return None
185 # Case 1
183
186 ipself.showsyntaxerror()
184 if code is None:
187 ipself.execution_count += 1
185 # Case 2
188 return None
186 return True
189 except NameError:
187
190 pass
188 # Case 3
191
189 # Because autopx is enabled, we now call executeAll or disable autopx if
192 if store_history:
190 # %autopx or autopx has been called
193 # Write output to the database. Does nothing unless
191 if 'get_ipython().magic("%autopx' in source or 'get_ipython().magic("autopx' in source:
194 # history output logging is enabled.
195 ipself.history_manager.store_output(ipself.execution_count)
196 # Each cell is a *single* input, regardless of how many lines it has
197 ipself.execution_count += 1
198 print cell
199
200 if re.search(r'get_ipython\(\)\.magic\(u?"%?autopx', cell):
192 self._disable_autopx()
201 self._disable_autopx()
193 return False
202 return False
194 else:
203 else:
195 try:
204 try:
196 result = self.active_multiengine_client.execute(source)
205 result = self.active_view.execute(cell, block=False)
197 except:
206 except:
198 ipself.showtraceback()
207 ipself.showtraceback()
199 else:
208 return False
200 print result.__repr__()
209
210 if self.active_view.block:
211 try:
212 result.get()
213 except:
214 ipself.showtraceback()
215 else:
216 targets = self.active_view.targets
217 if isinstance(targets, int):
218 targets = [targets]
219 if targets == 'all':
220 targets = self.active_view.client.ids
221 stdout = [s.rstrip() for s in result.stdout]
222 if any(stdout):
223 for i,eid in enumerate(targets):
224 print '[stdout:%i]'%eid, stdout[i]
201 return False
225 return False
202
226
203
227
@@ -648,7 +648,7 b' class DirectView(View):'
648 # block = block if block is not None else self.block
648 # block = block if block is not None else self.block
649 return self.pull(key_s, block=True)
649 return self.pull(key_s, block=True)
650
650
651 def pull(self, names, targets=None, block=True):
651 def pull(self, names, targets=None, block=None):
652 """get object(s) by `name` from remote namespace
652 """get object(s) by `name` from remote namespace
653
653
654 will return one object if it is a key.
654 will return one object if it is a key.
@@ -766,7 +766,7 b' class DirectView(View):'
766 else:
766 else:
767 pmagic = ip.plugin_manager.get_plugin('parallelmagic')
767 pmagic = ip.plugin_manager.get_plugin('parallelmagic')
768 if pmagic is not None:
768 if pmagic is not None:
769 pmagic.active_multiengine_client = self
769 pmagic.active_view = self
770 else:
770 else:
771 print "You must first load the parallelmagic extension " \
771 print "You must first load the parallelmagic extension " \
772 "by doing '%load_ext parallelmagic'"
772 "by doing '%load_ext parallelmagic'"
General Comments 0
You need to be logged in to leave comments. Login now