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

Releasing/1.8.4 extra #15952

Merged
merged 3 commits into from Dec 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/source-app/api_reference/runners.rst
Expand Up @@ -18,5 +18,4 @@ ______________
:template: classtemplate.rst

~cloud.CloudRuntime
~singleprocess.SingleProcessRuntime
~multiprocess.MultiProcessRuntime
1 change: 0 additions & 1 deletion docs/source-app/api_references.rst
Expand Up @@ -89,7 +89,6 @@ _______
:template: classtemplate_no_index.rst

~cloud.CloudRuntime
~singleprocess.SingleProcessRuntime
~multiprocess.MultiProcessRuntime

----
Expand Down
3 changes: 0 additions & 3 deletions docs/source-app/testing.rst
Expand Up @@ -120,7 +120,6 @@ We provide ``application_testing`` as a helper funtion to get your application u
os.path.join(_PROJECT_ROOT, "examples/app_v0/app.py"),
"--blocking",
"False",
"--multiprocess",
"--open-ui",
"False",
]
Expand All @@ -129,9 +128,7 @@ First in the list for ``command_line`` is the location of your script. It is an

Next there are a couple of options you can leverage:


* ``blocking`` - Blocking is an app status that says "Do not run until I click run in the UI". For our integration test, since we are not using the UI, we are setting this to "False".
* ``multiprocess/singleprocess`` - This is the runtime your app is expected to run under.
* ``open-ui`` - We set this to false since this is the routine that opens a browser for your local execution.

Once you have your commandline ready, you will then be able to kick off the test and gather results:
Expand Down
8 changes: 4 additions & 4 deletions examples/app_template_streamlit_ui/app.py
@@ -1,8 +1,8 @@
import logging

from lightning_app import LightningApp, LightningFlow
from lightning_app.frontend import StreamlitFrontend
from lightning_app.utilities.state import AppState
from lightning.app import LightningApp, LightningFlow
from lightning.app.frontend import StreamlitFrontend
from lightning.app.utilities.state import AppState

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -45,4 +45,4 @@ def configure_layout(self):
return [{"name": "StreamLitUI", "content": self.streamlit_ui}]


app = LightningApp(HelloWorld(), log_level="debug")
app = LightningApp(HelloWorld())
1 change: 0 additions & 1 deletion pyproject.toml
Expand Up @@ -102,7 +102,6 @@ module = [
"lightning_app.runners.cloud",
"lightning_app.runners.multiprocess",
"lightning_app.runners.runtime",
"lightning_app.runners.singleprocess",
"lightning_app.source_code.copytree",
"lightning_app.source_code.hashing",
"lightning_app.source_code.local",
Expand Down
2 changes: 1 addition & 1 deletion requirements/app/base.txt
Expand Up @@ -7,7 +7,7 @@ fsspec>=2022.5.0, <=2022.7.1
croniter>=1.3.0, <1.4.0 # strict; TODO: for now until we find something more robust.
traitlets>=5.3.0, <=5.4.0
arrow>=1.2.0, <1.2.4
lightning-utilities>=0.3.*, !=0.4.0, <0.5.0
lightning-utilities>=0.3.0, !=0.4.0, <0.5.0
beautifulsoup4>=4.8.0, <4.11.2
inquirer>=2.10.0
psutil<5.9.4
Expand Down
2 changes: 1 addition & 1 deletion requirements/lite/base.txt
Expand Up @@ -2,7 +2,7 @@
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

numpy>=1.17.2, <1.23.1
torch>=1.9.*, <=1.13.0
torch>=1.9.0, <=1.13.0
fsspec[http]>2021.06.0, <2022.6.0
packaging>=17.0, <=21.3
typing-extensions>=4.0.0, <=4.4.0
Expand Down
4 changes: 4 additions & 0 deletions requirements/lite/examples.txt
@@ -0,0 +1,4 @@
# NOTE: the upper bound for the package version is only set for CI stability, and it is dropped while installing this package
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

torchvision>=0.10.0, <=0.13.0
2 changes: 1 addition & 1 deletion requirements/pytorch/base.txt
Expand Up @@ -2,7 +2,7 @@
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

numpy>=1.17.2, <1.23.1
torch>=1.9.*, <=1.13.0
torch>=1.9.0, <=1.13.0
tqdm>=4.57.0, <4.65.0
PyYAML>=5.4, <=6.0
fsspec[http]>2021.06.0, <2022.8.0
Expand Down
2 changes: 1 addition & 1 deletion requirements/pytorch/examples.txt
@@ -1,6 +1,6 @@
# NOTE: the upper bound for the package version is only set for CI stability, and it is dropped while installing this package
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

torchvision>=0.10.*, <=0.13.0
torchvision>=0.10.0, <=0.14.0
gym[classic_control]>=0.17.0, <0.26.3
ipython[all] <8.6.1
9 changes: 8 additions & 1 deletion src/lightning_app/CHANGELOG.md
Expand Up @@ -12,7 +12,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Added the CLI command `lightning run model` to launch a `LightningLite` accelerated script ([#15506](https://github.com/Lightning-AI/lightning/pull/15506))
- Added the CLI command `lightning delete app` to delete a lightning app on the cloud ([#15783](https://github.com/Lightning-AI/lightning/pull/15783))
- Added a CloudMultiProcessBackend which enables running a child App from within the Flow in the cloud ([#15800](https://github.com/Lightning-AI/lightning/pull/15800))
- Apps without UIs no longer activate the "Open App" button when running in the cloud ([#15875](https://github.com/Lightning-AI/lightning/pull/15875))
- Added `AutoScaler` component ([#15769](https://github.com/Lightning-AI/lightning/pull/15769))
- Added the property `ready` of the LightningFlow to inform when the `Open App` should be visible ([#15921](https://github.com/Lightning-AI/lightning/pull/15921))
- Added private work attributed `_start_method` to customize how to start the works ([#15923](https://github.com/Lightning-AI/lightning/pull/15923))
Expand All @@ -26,6 +25,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Show a message when `BuildConfig(requirements=[...])` is passed but a `requirements.txt` file is already present in the Work ([#15799](https://github.com/Lightning-AI/lightning/pull/15799))
- Show a message when `BuildConfig(dockerfile="...")` is passed but a `Dockerfile` file is already present in the Work ([#15799](https://github.com/Lightning-AI/lightning/pull/15799))
- Dropped name column from cluster list ([#15721](https://github.com/Lightning-AI/lightning/pull/15721))
- Apps without UIs no longer activate the "Open App" button when running in the cloud ([#15875](https://github.com/Lightning-AI/lightning/pull/15875))
- Wait for full file to be transferred in Path / Payload ([#15934](https://github.com/Lightning-AI/lightning/pull/15934))

### Removed

- Removed the `SingleProcessRuntime` ([#15933](https://github.com/Lightning-AI/lightning/pull/15933))

### Fixed

Expand All @@ -37,6 +42,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Fixed the `enable_spawn` method of the `WorkRunExecutor` ([#15812](https://github.com/Lightning-AI/lightning/pull/15812))
- Fixed require/import decorator ([#15849](https://github.com/Lightning-AI/lightning/pull/15849))

- Fixed a bug where using `L.app.structures` would cause multiple apps to be opened and fail with an error in the cloud ([#15911](https://github.com/Lightning-AI/lightning/pull/15911))


## [1.8.3] - 2022-11-22

Expand Down
2 changes: 1 addition & 1 deletion src/lightning_app/components/auto_scaler.py
Expand Up @@ -25,7 +25,6 @@
from lightning_app.utilities.packaging.cloud_compute import CloudCompute

logger = Logger(__name__)
lock = asyncio.Lock()


def _raise_granular_exception(exception: Exception) -> None:
Expand Down Expand Up @@ -209,6 +208,7 @@ async def process_request(self, data: BaseModel):
def run(self):

logger.info(f"servers: {self.servers}")
lock = asyncio.Lock()

self._iter = cycle(self.servers)
self._last_batch_sent = time.time()
Expand Down
4 changes: 1 addition & 3 deletions src/lightning_app/core/app.py
Expand Up @@ -21,7 +21,7 @@
FRONTEND_DIR,
STATE_ACCUMULATE_WAIT,
)
from lightning_app.core.queues import BaseQueue, SingleProcessQueue
from lightning_app.core.queues import BaseQueue
from lightning_app.core.work import LightningWork
from lightning_app.frontend import Frontend
from lightning_app.storage import Drive, Path, Payload
Expand Down Expand Up @@ -549,8 +549,6 @@ def _collect_work_finish_status(self) -> dict:
def _should_snapshot(self) -> bool:
if len(self.works) == 0:
return True
elif isinstance(self.delta_queue, SingleProcessQueue):
return True
elif self._has_updated:
work_finished_status = self._collect_work_finish_status()
if work_finished_status:
Expand Down
4 changes: 4 additions & 0 deletions src/lightning_app/core/constants.py
Expand Up @@ -75,3 +75,7 @@ def get_lightning_cloud_url() -> str:

def enable_multiple_works_in_default_container() -> bool:
return bool(int(os.getenv("ENABLE_MULTIPLE_WORKS_IN_DEFAULT_CONTAINER", "0")))


# Number of seconds to wait between filesystem checks when waiting for files in remote storage
REMOTE_STORAGE_WAIT = 0.5
20 changes: 1 addition & 19 deletions src/lightning_app/core/queues.py
Expand Up @@ -49,7 +49,6 @@


class QueuingSystem(Enum):
SINGLEPROCESS = "singleprocess"
MULTIPROCESS = "multiprocess"
REDIS = "redis"
HTTP = "http"
Expand All @@ -59,10 +58,8 @@ def get_queue(self, queue_name: str) -> "BaseQueue":
return MultiProcessQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)
elif self == QueuingSystem.REDIS:
return RedisQueue(queue_name, default_timeout=REDIS_QUEUES_READ_DEFAULT_TIMEOUT)
elif self == QueuingSystem.HTTP:
return HTTPQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)
else:
return SingleProcessQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)
return HTTPQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)

def get_api_response_queue(self, queue_id: Optional[str] = None) -> "BaseQueue":
queue_name = f"{queue_id}_{API_RESPONSE_QUEUE_CONSTANT}" if queue_id else API_RESPONSE_QUEUE_CONSTANT
Expand Down Expand Up @@ -179,21 +176,6 @@ def is_running(self) -> bool:
return True


class SingleProcessQueue(BaseQueue):
def __init__(self, name: str, default_timeout: float):
self.name = name
self.default_timeout = default_timeout
self.queue = queue.Queue()

def put(self, item):
self.queue.put(item)

def get(self, timeout: int = None):
if timeout == 0:
timeout = self.default_timeout
return self.queue.get(timeout=timeout, block=(timeout is None))


class MultiProcessQueue(BaseQueue):
def __init__(self, name: str, default_timeout: float):
self.name = name
Expand Down
2 changes: 0 additions & 2 deletions src/lightning_app/runners/__init__.py
@@ -1,7 +1,6 @@
from lightning_app.runners.cloud import CloudRuntime
from lightning_app.runners.multiprocess import MultiProcessRuntime
from lightning_app.runners.runtime import dispatch, Runtime
from lightning_app.runners.singleprocess import SingleProcessRuntime
from lightning_app.utilities.app_commands import run_app_commands
from lightning_app.utilities.load_app import load_app_from_file

Expand All @@ -11,6 +10,5 @@
"run_app_commands",
"Runtime",
"MultiProcessRuntime",
"SingleProcessRuntime",
"CloudRuntime",
]
7 changes: 2 additions & 5 deletions src/lightning_app/runners/runtime_type.py
@@ -1,21 +1,18 @@
from enum import Enum
from typing import Type, TYPE_CHECKING

from lightning_app.runners import CloudRuntime, MultiProcessRuntime, SingleProcessRuntime
from lightning_app.runners import CloudRuntime, MultiProcessRuntime

if TYPE_CHECKING:
from lightning_app.runners.runtime import Runtime


class RuntimeType(Enum):
SINGLEPROCESS = "singleprocess"
MULTIPROCESS = "multiprocess"
CLOUD = "cloud"

def get_runtime(self) -> Type["Runtime"]:
if self == RuntimeType.SINGLEPROCESS:
return SingleProcessRuntime
elif self == RuntimeType.MULTIPROCESS:
if self == RuntimeType.MULTIPROCESS:
return MultiProcessRuntime
elif self == RuntimeType.CLOUD:
return CloudRuntime
Expand Down
62 changes: 0 additions & 62 deletions src/lightning_app/runners/singleprocess.py

This file was deleted.

2 changes: 2 additions & 0 deletions src/lightning_app/storage/orchestrator.py
Expand Up @@ -105,6 +105,7 @@ def run_once(self, work_name: str) -> None:
name=request.name,
path=maybe_artifact_path,
hash=request.hash,
size=self.fs.info(maybe_artifact_path)["size"],
destination=request.destination,
)
if isinstance(request, _ExistsRequest):
Expand Down Expand Up @@ -139,6 +140,7 @@ def run_once(self, work_name: str) -> None:
path=request.path,
name=request.name,
hash=request.hash,
size=0,
destination=request.destination,
)
if isinstance(request, _ExistsRequest):
Expand Down
9 changes: 5 additions & 4 deletions src/lightning_app/storage/path.py
Expand Up @@ -10,6 +10,7 @@
from fsspec import AbstractFileSystem
from fsspec.implementations.local import LocalFileSystem

from lightning_app.core.constants import REMOTE_STORAGE_WAIT
from lightning_app.core.queues import BaseQueue
from lightning_app.storage.requests import _ExistsRequest, _ExistsResponse, _GetRequest, _GetResponse
from lightning_app.utilities.app_helpers import Logger
Expand Down Expand Up @@ -199,9 +200,8 @@ def get(self, overwrite: bool = False) -> None:
fs = _filesystem()

# 3. Wait until the file appears in shared storage
while not fs.exists(response.path):
# TODO: Existence check on folder is not enough, files may not be completely transferred yet
sleep(0.5)
while not fs.exists(response.path) or fs.info(response.path)["size"] != response.size:
sleep(REMOTE_STORAGE_WAIT)

if self.exists_local() and self.is_dir():
# Delete the directory, otherwise we can't overwrite it
Expand Down Expand Up @@ -340,10 +340,11 @@ def _handle_get_request(work: "LightningWork", request: _GetRequest) -> _GetResp
destination_path = _shared_storage_path() / request.hash
response = _GetResponse(
source=request.source,
name=request.name,
path=str(destination_path),
hash=request.hash,
size=source_path.stat().st_size,
destination=request.destination,
name=request.name,
)

try:
Expand Down
7 changes: 4 additions & 3 deletions src/lightning_app/storage/payload.py
Expand Up @@ -5,6 +5,7 @@
from time import sleep
from typing import Any, Optional, TYPE_CHECKING, Union

from lightning_app.core.constants import REMOTE_STORAGE_WAIT
from lightning_app.core.queues import BaseQueue
from lightning_app.storage.path import _filesystem, _shared_storage_path, Path
from lightning_app.storage.requests import _ExistsRequest, _ExistsResponse, _GetRequest, _GetResponse
Expand Down Expand Up @@ -159,9 +160,8 @@ def get(self) -> Any:
fs = _filesystem()

# 3. Wait until the file appears in shared storage
while not fs.exists(response.path):
# TODO: Existence check on folder is not enough, files may not be completely transferred yet
sleep(0.5)
while not fs.exists(response.path) or fs.info(response.path)["size"] != response.size:
sleep(REMOTE_STORAGE_WAIT)

# 4. Copy the file from the shared storage to the destination on the local filesystem
local_path = self._path
Expand Down Expand Up @@ -234,6 +234,7 @@ def _handle_get_request(work: "LightningWork", request: _GetRequest) -> _GetResp
try:
payload = getattr(work, request.name)
payload.save(payload.value, source_path)
response.size = source_path.stat().st_size
_copy_files(source_path, destination_path)
_logger.debug(f"All files copied from {request.path} to {response.path}.")
except Exception as e:
Expand Down
1 change: 1 addition & 0 deletions src/lightning_app/storage/requests.py
Expand Up @@ -17,6 +17,7 @@ class _GetResponse:
name: str
path: str
hash: str
size: int = 0
destination: str = ""
exception: Optional[Exception] = None
timedelta: Optional[float] = None
Expand Down