10
10
absolute_import )
11
11
12
12
# Import packages
13
+ import os
13
14
from multiprocessing import Process , Pool , cpu_count , pool
14
15
from traceback import format_exception
15
16
import sys
@@ -50,6 +51,8 @@ def run_node(node, updatehash, taskid):
50
51
the node to run
51
52
updatehash : boolean
52
53
flag for updating hash
54
+ taskid : int
55
+ an identifier for this task
53
56
54
57
Returns
55
58
-------
@@ -63,7 +66,7 @@ def run_node(node, updatehash, taskid):
63
66
# Try and execute the node via node.run()
64
67
try :
65
68
result ['result' ] = node .run (updatehash = updatehash )
66
- except :
69
+ except : # noqa: E722, intendedly catch all here
67
70
result ['traceback' ] = format_exception (* sys .exc_info ())
68
71
result ['result' ] = node .result
69
72
@@ -131,6 +134,10 @@ def __init__(self, plugin_args=None):
131
134
self ._task_obj = {}
132
135
self ._taskid = 0
133
136
137
+ # Cache current working directory and make sure we
138
+ # change to it when workers are set up
139
+ self ._cwd = os .getcwd ()
140
+
134
141
# Read in options or set defaults.
135
142
non_daemon = self .plugin_args .get ('non_daemon' , True )
136
143
maxtasks = self .plugin_args .get ('maxtasksperchild' , 10 )
@@ -143,19 +150,28 @@ def __init__(self, plugin_args=None):
143
150
144
151
# Instantiate different thread pools for non-daemon processes
145
152
logger .debug ('[MultiProc] Starting in "%sdaemon" mode (n_procs=%d, '
146
- 'mem_gb=%0.2f)' , 'non' * int (non_daemon ), self . processors ,
147
- self .memory_gb )
153
+ 'mem_gb=%0.2f, cwd=%s )' , 'non' * int (non_daemon ),
154
+ self .processors , self . memory_gb , self . _cwd )
148
155
149
156
NipypePool = NonDaemonPool if non_daemon else Pool
150
157
try :
151
158
self .pool = NipypePool (
152
- processes = self .processors , maxtasksperchild = maxtasks )
159
+ processes = self .processors ,
160
+ maxtasksperchild = maxtasks ,
161
+ initializer = os .chdir ,
162
+ initargs = (self ._cwd ,)
163
+ )
153
164
except TypeError :
165
+ # Python < 3.2 does not have maxtasksperchild
166
+ # When maxtasksperchild is not set, initializer is not to be
167
+ # called
154
168
self .pool = NipypePool (processes = self .processors )
155
169
156
170
self ._stats = None
157
171
158
172
def _async_callback (self , args ):
173
+ # Make sure runtime is not left at a dubious working directory
174
+ os .chdir (self ._cwd )
159
175
self ._taskresult [args ['taskid' ]] = args
160
176
161
177
def _get_result (self , taskid ):
@@ -360,7 +376,6 @@ def _sort_jobs(self, jobids, scheduler='tsort'):
360
376
if scheduler == 'mem_thread' :
361
377
return sorted (
362
378
jobids ,
363
- key =
364
- lambda item : (self .procs [item ].mem_gb , self .procs [item ].n_procs )
379
+ key = lambda item : (self .procs [item ].mem_gb , self .procs [item ].n_procs )
365
380
)
366
381
return jobids
0 commit comments