Skip to content

Commit 72afbef

Browse files
committed
more fixes - still need to remove executors from intital submission and handle dependencies
1 parent 3656373 commit 72afbef

5 files changed

Lines changed: 42 additions & 4 deletions

File tree

src/executorlib/backend/executor_nested.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ def submit( # type: ignore
100100
self._future_dict[f] = id(f)
101101
self._tasks_dict[id(f)] = {
102102
"fn": fn,
103-
"args": args,
104-
"kwargs": kwargs,
103+
"args": args, # at the momemt the future objects are not removed from the args
104+
"kwargs": kwargs, # at the momemt the future objects are not removed from the kwargs
105105
"resource_dict": resource_dict,
106106
"dependencies": [
107107
self._future_dict[future_dependency]

src/executorlib/task_scheduler/base.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def __init__(
5050
self._process_kwargs: dict = {}
5151
self._max_cores = max_cores
5252
self._future_queue: Optional[queue.Queue] = queue.Queue()
53+
self._return_queue: Optional[queue.Queue] = queue.Queue()
5354
self._process: Optional[Union[Thread, list[Thread]]] = None
5455
self._validator = validator
5556

@@ -102,6 +103,16 @@ def future_queue(self) -> Optional[queue.Queue]:
102103
"""
103104
return self._future_queue
104105

106+
@property
107+
def return_queue(self) -> Optional[queue.Queue]:
108+
"""
109+
Get the return queue.
110+
111+
Returns:
112+
queue.Queue: The return queue.
113+
"""
114+
return self._return_queue
115+
105116
def batched(
106117
self,
107118
iterable: list[Future],
@@ -238,8 +249,10 @@ def shutdown(self, wait: bool = True, *, cancel_futures: bool = False):
238249
if isinstance(self._process, Thread):
239250
self._process.join()
240251
self._future_queue.join()
252+
self._return_queue.join()
241253
self._process = None
242254
self._future_queue = None
255+
self._return_queue = None
243256

244257
def _set_process(self, process: Thread):
245258
"""

src/executorlib/task_scheduler/interactive/blockallocation.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def __init__(
7575
max_cores=executor_kwargs.get("max_cores"), validator=validator
7676
)
7777
executor_kwargs["future_queue"] = self._future_queue
78+
executor_kwargs["return_queue"] = self._return_queue
7879
executor_kwargs["spawner"] = spawner
7980
executor_kwargs["queue_join_on_shutdown"] = False
8081
executor_kwargs["restart_limit"] = restart_limit
@@ -217,6 +218,7 @@ def _set_process(self, process: list[Thread]): # type: ignore
217218

218219
def _execute_multiple_tasks(
219220
future_queue: queue.Queue,
221+
return_queue: queue.Queue,
220222
cores: int = 1,
221223
spawner: type[BaseSpawner] = MpiExecSpawner,
222224
hostname_localhost: Optional[bool] = None,
@@ -240,6 +242,7 @@ def _execute_multiple_tasks(
240242
241243
Args:
242244
future_queue (queue.Queue): task queue of dictionary objects which are submitted to the parallel process
245+
return_queue (queue.Queue): task queue of dictionary objects which are submitted to the parallel process
243246
cores (int): defines the total number of MPI ranks to use
244247
spawner (BaseSpawner): Spawner to start process on selected compute resources
245248
hostname_localhost (boolean): use localhost instead of the hostname to establish the zmq connection. In the
@@ -317,7 +320,7 @@ def _execute_multiple_tasks(
317320
f.set_exception(exception=interface_initialization_exception)
318321
else:
319322
# The interface failed during the execution
320-
interface.status, _ = execute_task_dict(
323+
interface.status, nested_task_dict = execute_task_dict(
321324
task_dict=task_dict,
322325
future_obj=f,
323326
interface=interface,
@@ -329,6 +332,8 @@ def _execute_multiple_tasks(
329332
reset_task_dict(
330333
future_obj=f, future_queue=future_queue, task_dict=task_dict
331334
)
335+
elif len(nested_task_dict) > 0:
336+
return_queue.put(nested_task_dict)
332337
task_done(future_queue=future_queue)
333338

334339

src/executorlib/task_scheduler/interactive/dependency.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ def _execute_tasks_with_dependencies(
257257
task_dict = future_queue.get_nowait()
258258
except queue.Empty:
259259
task_dict = None
260+
try:
261+
task_return_dict = executor.return_queue.get_nowait()
262+
except queue.Empty:
263+
task_return_dict = None
260264
if ( # shutdown the executor
261265
task_dict is not None and "shutdown" in task_dict and task_dict["shutdown"]
262266
):
@@ -324,6 +328,12 @@ def _execute_tasks_with_dependencies(
324328
executor_queue=executor_queue,
325329
refresh_rate=refresh_rate,
326330
)
331+
elif task_return_dict is not None:
332+
future_lookup_dict = {} # we need this future dict later on to resolve the dependencies
333+
for k, v in task_return_dict.items():
334+
future_lookup_dict[k] = executor.submit(
335+
fn=v["fn"], *v["args"], **v["kwargs"], resource_dict=v["resource_dict"]
336+
)
327337
else:
328338
# If there is nothing else to do, sleep for a moment
329339
sleep(refresh_rate)

src/executorlib/task_scheduler/interactive/onetoone.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import queue
22
from concurrent.futures import Future
33
from threading import Thread
4+
from time import sleep
45
from typing import Callable, Optional
56

67
from executorlib.standalone.command import get_interactive_execute_command
@@ -61,6 +62,7 @@ def __init__(
6162
executor_kwargs.update(
6263
{
6364
"future_queue": self._future_queue,
65+
"return_queue": self._return_queue,
6466
"spawner": spawner,
6567
"max_cores": max_cores,
6668
"max_workers": max_workers,
@@ -77,6 +79,7 @@ def __init__(
7779

7880
def _execute_single_task(
7981
future_queue: queue.Queue,
82+
return_queue: queue.Queue,
8083
spawner: type[BaseSpawner] = MpiExecSpawner,
8184
max_cores: Optional[int] = None,
8285
max_workers: Optional[int] = None,
@@ -88,6 +91,7 @@ def _execute_single_task(
8891
8992
Args:
9093
future_queue (queue.Queue): task queue of dictionary objects which are submitted to the parallel process
94+
return_queue (queue.Queue): task queue of dictionary objects which are submitted to the parallel process
9195
spawner (BaseSpawner): Interface to start process on selected compute resources
9296
max_cores (int): defines the number cores which can be used in parallel
9397
max_workers (int): for backwards compatibility with the standard library, max_workers also defines the number of
@@ -116,6 +120,7 @@ def _execute_single_task(
116120
elif "fn" in task_dict and "future" in task_dict:
117121
process, active_task_dict = _wrap_execute_task_in_separate_process(
118122
task_dict=task_dict,
123+
return_queue=return_queue,
119124
active_task_dict=active_task_dict,
120125
spawner=spawner,
121126
executor_kwargs=kwargs,
@@ -162,6 +167,7 @@ def _wait_for_free_slots(
162167

163168
def _wrap_execute_task_in_separate_process(
164169
task_dict: dict,
170+
return_queue: queue.Queue,
165171
active_task_dict: dict,
166172
spawner: type[BaseSpawner],
167173
executor_kwargs: dict,
@@ -211,6 +217,7 @@ def _wrap_execute_task_in_separate_process(
211217
task_kwargs.update(
212218
{
213219
"task_dict": task_dict,
220+
"return_queue": return_queue,
214221
"spawner": spawner,
215222
"hostname_localhost": hostname_localhost,
216223
"future_obj": f,
@@ -226,6 +233,7 @@ def _wrap_execute_task_in_separate_process(
226233

227234
def _execute_task_in_thread(
228235
task_dict: dict,
236+
return_queue: queue.Queue,
229237
future_obj: Future,
230238
cores: int = 1,
231239
spawner: type[BaseSpawner] = MpiExecSpawner,
@@ -262,7 +270,7 @@ def _execute_task_in_thread(
262270
worker_id (int): Communicate the worker which ID was assigned to it for future reference and resource
263271
distribution.
264272
"""
265-
status, _ = execute_task_dict(
273+
status, nested_task_dict = execute_task_dict(
266274
task_dict=task_dict,
267275
future_obj=future_obj,
268276
interface=interface_bootup(
@@ -282,3 +290,5 @@ def _execute_task_in_thread(
282290
future_obj.set_exception(
283291
ExecutorlibSocketError("SocketInterface crashed during execution.")
284292
)
293+
elif len(nested_task_dict) > 0:
294+
return_queue.put(nested_task_dict)

0 commit comments

Comments
 (0)