Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set the default work start method to spawn on MacOS #16089

Merged
merged 10 commits into from Dec 19, 2022
4 changes: 4 additions & 0 deletions src/lightning_app/CHANGELOG.md
Expand Up @@ -26,9 +26,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Changed


- The default `start_method` for creating Work processes locally on MacOS is now 'spawn' (previously 'fork') ([#16089](https://github.com/Lightning-AI/lightning/pull/16089))


- The utility `lightning.app.utilities.cloud.is_running_in_cloud` now returns `True` during loading of the app locally when running with `--cloud` ([#16045](https://github.com/Lightning-AI/lightning/pull/16045))



### Deprecated

-
Expand Down
2 changes: 1 addition & 1 deletion src/lightning_app/core/work.py
Expand Up @@ -51,7 +51,7 @@ class LightningWork:

_run_executor_cls: Type[WorkRunExecutor] = WorkRunExecutor
# TODO: Move to spawn for all Operating System.
_start_method = "spawn" if sys.platform == "win32" else "fork"
_start_method = "spawn" if sys.platform in ("darwin", "win32") else "fork"

def __init__(
self,
Expand Down
Empty file.
27 changes: 27 additions & 0 deletions tests/tests_app/runners/backends/test_mp_process.py
@@ -0,0 +1,27 @@
from unittest import mock
from unittest.mock import MagicMock, Mock

from lightning_app import LightningApp, LightningWork
from lightning_app.runners.backends import MultiProcessingBackend


@mock.patch("lightning_app.runners.backends.mp_process.multiprocessing")
def test_backend_create_work_with_set_start_method(multiprocessing_mock):
backend = MultiProcessingBackend(entrypoint_file="fake.py")
work = Mock(spec=LightningWork)
work._start_method = "test_start_method"

app = LightningApp(work)
app.caller_queues = MagicMock()
app.delta_queue = MagicMock()
app.readiness_queue = MagicMock()
app.error_queue = MagicMock()
app.request_queues = MagicMock()
app.response_queues = MagicMock()
app.copy_request_queues = MagicMock()
app.copy_response_queues = MagicMock()
app.flow_to_work_delta_queues = MagicMock()

backend.create_work(app=app, work=work)
multiprocessing_mock.get_context.assert_called_with("test_start_method")
multiprocessing_mock.get_context().Process().start.assert_called_once()
4 changes: 2 additions & 2 deletions tests/tests_app/runners/test_multiprocess.py
Expand Up @@ -68,7 +68,7 @@ def run(self):
assert _get_context().value == "work"


class ContxtFlow(LightningFlow):
class ContextFlow(LightningFlow):
def __init__(self):
super().__init__()
self.work = ContextWork()
Expand All @@ -83,7 +83,7 @@ def run(self):

def test_multiprocess_runtime_sets_context():
"""Test that the runtime sets the global variable COMPONENT_CONTEXT in Flow and Work."""
MultiProcessRuntime(LightningApp(ContxtFlow())).dispatch()
MultiProcessRuntime(LightningApp(ContextFlow())).dispatch()


@pytest.mark.parametrize(
Expand Down