Skip to content

Commit d11a2d3

Browse files
authored
Support threads on local backend (#504)
* Support threads on local backend * fixes * more fixes * Fix spawner
1 parent 1565d4c commit d11a2d3

File tree

7 files changed

+7
-38
lines changed

7 files changed

+7
-38
lines changed

executorlib/interactive/executor.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
check_nested_flux_executor,
1616
check_oversubscribe,
1717
check_pmi,
18-
check_threads_per_core,
1918
validate_number_of_cores,
2019
)
2120
from executorlib.standalone.interactive.spawner import (
@@ -258,7 +257,6 @@ def create_executor(
258257
elif backend == "local":
259258
check_executor(executor=flux_executor)
260259
check_nested_flux_executor(nested_flux_executor=flux_executor_nesting)
261-
check_threads_per_core(threads_per_core=resource_dict["threads_per_core"])
262260
check_gpus_per_worker(gpus_per_worker=resource_dict["gpus_per_core"])
263261
check_command_line_argument_lst(
264262
command_line_argument_lst=resource_dict["slurm_cmd_args"]

executorlib/interactive/shared.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,13 +546,14 @@ def _submit_function_to_separate_process(
546546
resource_dict["cores"] == 1 and executor_kwargs["cores"] >= 1
547547
):
548548
resource_dict["cores"] = executor_kwargs["cores"]
549+
slots_required = resource_dict["cores"] * resource_dict.get("threads_per_core", 1)
549550
active_task_dict = _wait_for_free_slots(
550551
active_task_dict=active_task_dict,
551-
cores_requested=resource_dict["cores"],
552+
cores_requested=slots_required,
552553
max_cores=max_cores,
553554
max_workers=max_workers,
554555
)
555-
active_task_dict[task_dict["future"]] = resource_dict["cores"]
556+
active_task_dict[task_dict["future"]] = slots_required
556557
task_kwargs = executor_kwargs.copy()
557558
task_kwargs.update(resource_dict)
558559
task_kwargs.update(

executorlib/standalone/inputcheck.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,6 @@ def check_gpus_per_worker(gpus_per_worker: int) -> None:
3939
)
4040

4141

42-
def check_threads_per_core(threads_per_core: int) -> None:
43-
"""
44-
Check if threads_per_core is not 1 and raise a TypeError if it is.
45-
"""
46-
if threads_per_core != 1:
47-
raise TypeError(
48-
"Thread based parallelism is not supported for the executorlib.mpi.PyMPIExecutor backend."
49-
"Please use threads_per_core=1 instead of threads_per_core="
50-
+ str(threads_per_core)
51-
+ "."
52-
)
53-
54-
5542
def check_executor(executor: Executor) -> None:
5643
"""
5744
Check if executor is not None and raise a ValueError if it is.

executorlib/standalone/interactive/spawner.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ def __init__(
5757
cwd: Optional[str] = None,
5858
cores: int = 1,
5959
openmpi_oversubscribe: bool = False,
60+
threads_per_core: int = 1,
6061
):
6162
"""
6263
Subprocess interface implementation.
6364
6465
Args:
6566
cwd (str, optional): The current working directory. Defaults to None.
6667
cores (int, optional): The number of cores to use. Defaults to 1.
68+
threads_per_core (int, optional): The number of threads per core. Defaults to 1.
6769
oversubscribe (bool, optional): Whether to oversubscribe the cores. Defaults to False.
6870
"""
6971
super().__init__(
@@ -72,6 +74,7 @@ def __init__(
7274
openmpi_oversubscribe=openmpi_oversubscribe,
7375
)
7476
self._process = None
77+
self._threads_per_core = threads_per_core
7578

7679
def bootup(
7780
self,
@@ -169,8 +172,8 @@ def __init__(
169172
cwd=cwd,
170173
cores=cores,
171174
openmpi_oversubscribe=openmpi_oversubscribe,
175+
threads_per_core=threads_per_core,
172176
)
173-
self._threads_per_core = threads_per_core
174177
self._gpus_per_core = gpus_per_core
175178
self._slurm_cmd_args = slurm_cmd_args
176179

tests/test_executor_backend_mpi.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,6 @@ def test_meta_executor_parallel(self):
7474
self.assertTrue(fs_1.done())
7575

7676
def test_errors(self):
77-
with self.assertRaises(TypeError):
78-
Executor(
79-
max_cores=1,
80-
resource_dict={"cores": 1, "threads_per_core": 2},
81-
backend="local",
82-
)
8377
with self.assertRaises(TypeError):
8478
Executor(
8579
max_cores=1,

tests/test_executor_backend_mpi_noblock.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,6 @@ def test_meta_executor_single(self):
5858
self.assertTrue(fs_2.done())
5959

6060
def test_errors(self):
61-
with self.assertRaises(TypeError):
62-
Executor(
63-
max_cores=1,
64-
resource_dict={
65-
"cores": 1,
66-
"threads_per_core": 2,
67-
},
68-
backend="local",
69-
)
7061
with self.assertRaises(TypeError):
7162
Executor(
7263
max_cores=1,

tests/test_shared_input_check.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from executorlib.standalone.inputcheck import (
44
check_command_line_argument_lst,
55
check_gpus_per_worker,
6-
check_threads_per_core,
76
check_oversubscribe,
87
check_executor,
98
check_init_function,
@@ -31,10 +30,6 @@ def test_check_gpus_per_worker(self):
3130
with self.assertRaises(TypeError):
3231
check_gpus_per_worker(gpus_per_worker=1)
3332

34-
def test_check_threads_per_core(self):
35-
with self.assertRaises(TypeError):
36-
check_threads_per_core(threads_per_core=2)
37-
3833
def test_check_oversubscribe(self):
3934
with self.assertRaises(ValueError):
4035
check_oversubscribe(oversubscribe=True)

0 commit comments

Comments
 (0)