-
Notifications
You must be signed in to change notification settings - Fork 531
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Core] Reduce import time with lazy imports and exec time by avoiding…
… script rsync (#3394) * lazy imports for pandas and lazy data frame * fix fetch_aws * fix fetchers * avoid sync script for task * format * format * Fix tests with autoscaler * fix serve test * refactor all cloud adaptors * comments * address comments * format * refactor * format * separate storage installation * typo from Fail to Failed * fix lazy imports * revert gcp adaptor * use base64 instead of shlex * Add comments * add comments * change to LazyDataFrame for typing * add annotation for self._df * add some early load back * fix exceptions * Add examples * format * format * fix typing * Update sky/adaptors/common.py Co-authored-by: Zongheng Yang <[email protected]> * Update sky/adaptors/common.py Co-authored-by: Zongheng Yang <[email protected]> --------- Co-authored-by: Zongheng Yang <[email protected]>
- Loading branch information
1 parent
ffc8618
commit bca709b
Showing
47 changed files
with
536 additions
and
697 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
"""Lazy import for modules to avoid import error when not used.""" | ||
import functools | ||
import importlib | ||
from typing import Any, Optional, Tuple | ||
|
||
|
||
class LazyImport: | ||
"""Lazy importer for heavy modules or cloud modules only when enabled. | ||
We use this for pandas and networkx, as they can be time-consuming to import | ||
(0.1-0.2 seconds). With this class, we can avoid the unnecessary import time | ||
when the module is not used (e.g., `networkx` should not be imported for | ||
`sky status and `pandas` should not be imported for `sky exec`). | ||
We also use this for cloud adaptors, because we do not want to import the | ||
cloud dependencies when it is not enabled. | ||
""" | ||
|
||
def __init__(self, | ||
module_name: str, | ||
import_error_message: Optional[str] = None): | ||
self._module_name = module_name | ||
self._module = None | ||
self._import_error_message = import_error_message | ||
|
||
def load_module(self): | ||
if self._module is None: | ||
try: | ||
self._module = importlib.import_module(self._module_name) | ||
except ImportError as e: | ||
if self._import_error_message is not None: | ||
raise ImportError(self._import_error_message) from e | ||
raise | ||
return self._module | ||
|
||
def __getattr__(self, name: str) -> Any: | ||
# Attempt to access the attribute, if it fails, assume it's a submodule | ||
# and lazily import it | ||
try: | ||
if name in self.__dict__: | ||
return self.__dict__[name] | ||
return getattr(self.load_module(), name) | ||
except AttributeError: | ||
# Dynamically create a new LazyImport instance for the submodule | ||
submodule_name = f'{self._module_name}.{name}' | ||
lazy_submodule = LazyImport(submodule_name, | ||
self._import_error_message) | ||
setattr(self, name, lazy_submodule) | ||
return lazy_submodule | ||
|
||
|
||
def load_lazy_modules(modules: Tuple[LazyImport, ...]): | ||
"""Load lazy modules before entering a function to error out quickly.""" | ||
|
||
def decorator(func): | ||
|
||
@functools.wraps(func) | ||
def wrapper(*args, **kwargs): | ||
for m in modules: | ||
m.load_module() | ||
return func(*args, **kwargs) | ||
|
||
return wrapper | ||
|
||
return decorator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,8 @@ | ||
"""Cudo Compute cloud adaptor.""" | ||
|
||
import functools | ||
from sky.adaptors import common | ||
|
||
_cudo_sdk = None | ||
|
||
|
||
def import_package(func): | ||
|
||
@functools.wraps(func) | ||
def wrapper(*args, **kwargs): | ||
global _cudo_sdk | ||
if _cudo_sdk is None: | ||
try: | ||
import cudo_compute as _cudo # pylint: disable=import-outside-toplevel | ||
_cudo_sdk = _cudo | ||
except ImportError: | ||
raise ImportError( | ||
'Fail to import dependencies for Cudo Compute.' | ||
'Try pip install "skypilot[cudo]"') from None | ||
return func(*args, **kwargs) | ||
|
||
return wrapper | ||
|
||
|
||
@import_package | ||
def cudo(): | ||
"""Return the Cudo Compute package.""" | ||
return _cudo_sdk | ||
cudo = common.LazyImport( | ||
'cudo_compute', | ||
import_error_message='Failed to import dependencies for Cudo Compute. ' | ||
'Try running: pip install "skypilot[cudo]"') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.