|
13 | 13 | from traceback import format_exception
|
14 | 14 | import sys
|
15 | 15 | from logging import INFO
|
| 16 | +import gc |
16 | 17 |
|
17 | 18 | from copy import deepcopy
|
18 | 19 | import numpy as np
|
@@ -131,13 +132,16 @@ def __init__(self, plugin_args=None):
|
131 | 132 | non_daemon = self.plugin_args.get('non_daemon', True)
|
132 | 133 | maxtasks = self.plugin_args.get('maxtasksperchild', 10)
|
133 | 134 | self.processors = self.plugin_args.get('n_procs', cpu_count())
|
134 |
| - self.memory_gb = self.plugin_args.get('memory_gb', # Allocate 90% of system memory |
135 |
| - get_system_total_memory_gb() * 0.9) |
136 |
| - self.raise_insufficient = self.plugin_args.get('raise_insufficient', True) |
| 135 | + self.memory_gb = self.plugin_args.get( |
| 136 | + 'memory_gb', # Allocate 90% of system memory |
| 137 | + get_system_total_memory_gb() * 0.9) |
| 138 | + self.raise_insufficient = self.plugin_args.get('raise_insufficient', |
| 139 | + True) |
137 | 140 |
|
138 | 141 | # Instantiate different thread pools for non-daemon processes
|
139 |
| - logger.debug('[MultiProc] Starting in "%sdaemon" mode (n_procs=%d, mem_gb=%0.2f)', |
140 |
| - 'non' * int(non_daemon), self.processors, self.memory_gb) |
| 142 | + logger.debug('[MultiProc] Starting in "%sdaemon" mode (n_procs=%d, ' |
| 143 | + 'mem_gb=%0.2f)', 'non' * int(non_daemon), self.processors, |
| 144 | + self.memory_gb) |
141 | 145 |
|
142 | 146 | NipypePool = NonDaemonPool if non_daemon else Pool
|
143 | 147 | try:
|
@@ -214,12 +218,13 @@ def _send_procs_to_workers(self, updatehash=False, graph=None):
|
214 | 218 | Sends jobs to workers when system resources are available.
|
215 | 219 | """
|
216 | 220 |
|
217 |
| - # Check to see if a job is available (jobs without dependencies not run) |
| 221 | + # Check to see if a job is available (jobs with all dependencies run) |
218 | 222 | # See https://github.com/nipy/nipype/pull/2200#discussion_r141605722
|
219 | 223 | jobids = np.nonzero(~self.proc_done & (self.depidx.sum(0) == 0))[1]
|
220 | 224 |
|
221 |
| - # Check available system resources by summing all threads and memory used |
222 |
| - free_memory_gb, free_processors = self._check_resources(self.pending_tasks) |
| 225 | + # Check available resources by summing all threads and memory used |
| 226 | + free_memory_gb, free_processors = self._check_resources( |
| 227 | + self.pending_tasks) |
223 | 228 |
|
224 | 229 | stats = (len(self.pending_tasks), len(jobids), free_memory_gb,
|
225 | 230 | self.memory_gb, free_processors, self.processors)
|
@@ -248,7 +253,11 @@ def _send_procs_to_workers(self, updatehash=False, graph=None):
|
248 | 253 | 'be submitted to the queue. Potential deadlock')
|
249 | 254 | return
|
250 | 255 |
|
251 |
| - jobids = self._sort_jobs(jobids, scheduler=self.plugin_args.get('scheduler')) |
| 256 | + jobids = self._sort_jobs(jobids, |
| 257 | + scheduler=self.plugin_args.get('scheduler')) |
| 258 | + |
| 259 | + # Run garbage collector before potentially submitting jobs |
| 260 | + gc.collect() |
252 | 261 |
|
253 | 262 | # Submit jobs
|
254 | 263 | for jobid in jobids:
|
@@ -281,9 +290,10 @@ def _send_procs_to_workers(self, updatehash=False, graph=None):
|
281 | 290 |
|
282 | 291 | free_memory_gb -= next_job_gb
|
283 | 292 | free_processors -= next_job_th
|
284 |
| - logger.debug('Allocating %s ID=%d (%0.2fGB, %d threads). Free: %0.2fGB, %d threads.', |
285 |
| - self.procs[jobid].fullname, jobid, next_job_gb, next_job_th, |
286 |
| - free_memory_gb, free_processors) |
| 293 | + logger.debug('Allocating %s ID=%d (%0.2fGB, %d threads). Free: ' |
| 294 | + '%0.2fGB, %d threads.', self.procs[jobid].fullname, |
| 295 | + jobid, next_job_gb, next_job_th, free_memory_gb, |
| 296 | + free_processors) |
287 | 297 |
|
288 | 298 | # change job status in appropriate queues
|
289 | 299 | self.proc_done[jobid] = True
|
@@ -312,6 +322,9 @@ def _send_procs_to_workers(self, updatehash=False, graph=None):
|
312 | 322 | free_processors += next_job_th
|
313 | 323 | # Display stats next loop
|
314 | 324 | self._stats = None
|
| 325 | + |
| 326 | + # Clean up any debris from running node in main process |
| 327 | + gc.collect() |
315 | 328 | continue
|
316 | 329 |
|
317 | 330 | # Task should be submitted to workers
|
|
0 commit comments