10
10
11
11
# Import packages
12
12
from multiprocessing import Process , Pool , cpu_count , pool
13
- import threading
14
13
from traceback import format_exception
15
14
import sys
16
15
@@ -83,7 +82,8 @@ class NonDaemonPool(pool.Pool):
83
82
84
83
85
84
class MultiProcPlugin (DistributedPluginBase ):
86
- """Execute workflow with multiprocessing, not sending more jobs at once
85
+ """
86
+ Execute workflow with multiprocessing, not sending more jobs at once
87
87
than the system can support.
88
88
89
89
The plugin_args input to run can be used to control the multiprocessing
@@ -102,6 +102,8 @@ class MultiProcPlugin(DistributedPluginBase):
102
102
- non_daemon : boolean flag to execute as non-daemon processes
103
103
- n_procs: maximum number of threads to be executed in parallel
104
104
- memory_gb: maximum memory (in GB) that can be used at once.
105
+ - raise_insufficient: raise error if the requested resources for
106
+ a node over the maximum `n_procs` and/or `memory_gb`.
105
107
106
108
"""
107
109
@@ -112,7 +114,6 @@ def __init__(self, plugin_args=None):
112
114
self ._task_obj = {}
113
115
self ._taskid = 0
114
116
self ._timeout = 2.0
115
- # self._event = threading.Event()
116
117
117
118
# Read in options or set defaults.
118
119
non_daemon = self .plugin_args .get ('non_daemon' , True )
@@ -126,18 +127,8 @@ def __init__(self, plugin_args=None):
126
127
'non' if non_daemon else '' , self .processors , self .memory_gb )
127
128
self .pool = (NonDaemonPool if non_daemon else Pool )(processes = self .processors )
128
129
129
- # def _wait(self):
130
- # if len(self.pending_tasks) > 0:
131
- # if self._config['execution']['poll_sleep_duration']:
132
- # self._timeout = float(self._config['execution']['poll_sleep_duration'])
133
- # sig_received = self._event.wait(self._timeout)
134
- # if not sig_received:
135
- # logger.debug('MultiProcPlugin timeout before signal received. Deadlock averted??')
136
- # self._event.clear()
137
-
138
130
def _async_callback (self , args ):
139
131
self ._taskresult [args ['taskid' ]] = args
140
- # self._event.set()
141
132
142
133
def _get_result (self , taskid ):
143
134
return self ._taskresult .get (taskid )
@@ -178,7 +169,8 @@ def _send_procs_to_workers(self, updatehash=False, graph=None):
178
169
179
170
# Check to see if a job is available
180
171
currently_running_jobids = np .flatnonzero (
181
- self .proc_pending & (self .depidx .sum (axis = 0 ) == 0 ).__array__ ())
172
+ np .array (self .proc_pending , dtype = bool ) & ~ self .depidx .sum (axis = 0 ).astype (bool )
173
+ )
182
174
183
175
# Check available system resources by summing all threads and memory used
184
176
busy_memory_gb = 0
@@ -210,6 +202,8 @@ def _send_procs_to_workers(self, updatehash=False, graph=None):
210
202
# Check all jobs without dependency not run
211
203
jobids = np .flatnonzero ((self .proc_done == False ) &
212
204
(self .depidx .sum (axis = 0 ) == 0 ).__array__ ())
205
+ # jobids = np.flatnonzero(~np.array(self.proc_done, dtype=bool) &
206
+ # (self.depidx.sum(axis=0) == 0))
213
207
214
208
# Sort jobs ready to run first by memory and then by number of threads
215
209
# The most resource consuming jobs run first
@@ -226,10 +220,9 @@ def _send_procs_to_workers(self, updatehash=False, graph=None):
226
220
# Submit first job on the list
227
221
for jobid in jobids :
228
222
if resource_monitor :
229
- logger .debug ('Next Job: %d, memory (GB): %d, threads: %d' \
230
- % (jobid ,
231
- self .procs [jobid ]._interface .estimated_memory_gb ,
232
- self .procs [jobid ]._interface .num_threads ))
223
+ logger .debug ('Next Job: %d, memory (GB): %d, threads: %d' ,
224
+ jobid , self .procs [jobid ]._interface .estimated_memory_gb ,
225
+ self .procs [jobid ]._interface .num_threads )
233
226
234
227
if self .procs [jobid ]._interface .estimated_memory_gb <= free_memory_gb and \
235
228
self .procs [jobid ]._interface .num_threads <= free_processors :
0 commit comments