Skip to content

Commit

Permalink
[App] Add automatic conversion to structures (#15961)
Browse files Browse the repository at this point in the history
  • Loading branch information
tchaton authored Dec 8, 2022
1 parent 772d121 commit 67a47d4
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/lightning_app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

- Added a `configure_layout` method to the `LightningWork` which can be used to control how the work is handled in the layout of a parent flow ([#15926](https://github.com/Lightning-AI/lightning/pull/15926))

- Added automatic conversion of list and dict of works and flows to structures ([#15961](https://github.com/Lightning-AI/lightning/pull/15961))


### Changed

Expand Down
12 changes: 10 additions & 2 deletions src/lightning_app/core/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ def __setattr__(self, name: str, value: Any) -> None:
if name in self._works and value != getattr(self, name):
raise AttributeError(f"Cannot set attributes as the work can't be changed once defined: {name}")

if isinstance(value, (list, dict)) and value:
_type = (LightningFlow, LightningWork, List, Dict)
if isinstance(value, list) and all(isinstance(va, _type) for va in value):
value = List(*value)

if isinstance(value, dict) and all(isinstance(va, _type) for va in value.values()):
value = Dict(**value)

if isinstance(value, LightningFlow):
self._flows.add(name)
_set_child_name(self, value, name)
Expand All @@ -163,10 +171,10 @@ def __setattr__(self, name: str, value: Any) -> None:
value._register_cloud_compute()

elif isinstance(value, (Dict, List)):
value._backend = self._backend
self._structures.add(name)
_set_child_name(self, value, name)
if self._backend:
if getattr(self, "_backend", None) is not None:
value._backend = self._backend
for flow in value.flows:
LightningFlow._attach_backend(flow, self._backend)
for work in value.works:
Expand Down
26 changes: 26 additions & 0 deletions tests/tests_app/structures/test_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,29 @@ def __init__(self):
LightningApp(flow) # wrap in app to init all component names
assert flow.list_structure[0].name == "root.list_structure.0"
assert flow.dict_structure["dict_child"].name == "root.dict_structure.dict_child"


class FlowWiStructures(LightningFlow):
def __init__(self):
super().__init__()

self.ws = [EmptyFlow(), EmptyFlow()]

self.ws1 = {"a": EmptyFlow(), "b": EmptyFlow()}

self.ws2 = {
"a": EmptyFlow(),
"b": EmptyFlow(),
"c": List(EmptyFlow(), EmptyFlow()),
"d": Dict(**{"a": EmptyFlow()}),
}

def run(self):
pass


def test_flow_without_structures():

flow = FlowWiStructures()
assert isinstance(flow.ws, List)
assert isinstance(flow.ws1, Dict)

0 comments on commit 67a47d4

Please sign in to comment.