diff --git a/.drone.yml b/.drone.yml index 4f2259ef..43cba1e7 100644 --- a/.drone.yml +++ b/.drone.yml @@ -23,4 +23,5 @@ steps: - pip list - python -c "import torch ; print(' & '.join([torch.cuda.get_device_name(i) for i in range(torch.cuda.device_count())]) if torch.cuda.is_available() else 'only CPU')" - coverage run --source pytorch_lightning -m py.test pytorch_lightning tests pl_examples -v --doctest-modules # --flake8 + - coverage report - codecov --token $CODECOV_TOKEN # --pr $DRONE_PULL_REQUEST --build $DRONE_BUILD_NUMBER --branch $DRONE_BRANCH --commit $DRONE_COMMIT --tag $DRONE_TAG diff --git a/.pep8speaks.yml b/.pep8speaks.yml index e33d46b1..2b92bded 100644 --- a/.pep8speaks.yml +++ b/.pep8speaks.yml @@ -5,7 +5,7 @@ scanner: linter: pycodestyle # Other option is flake8 pycodestyle: # Same as scanner.linter value. Other option is flake8 - max-line-length: 100 # Default is 79 in PEP 8 + max-line-length: 110 # Default is 79 in PEP 8 ignore: # Errors and warnings to ignore - W504 # line break after binary operator - E402 # module level import not at top of file diff --git a/pl_examples/basic_examples/lightning_module_template.py b/pl_examples/basic_examples/lightning_module_template.py index 3069ddb8..1880bffa 100644 --- a/pl_examples/basic_examples/lightning_module_template.py +++ b/pl_examples/basic_examples/lightning_module_template.py @@ -225,7 +225,7 @@ class LightningTemplateModel(LightningModule): return self.__dataloader(train=False) @staticmethod - def add_model_specific_args(parent_parser, root_dir): # pragma: no cover + def add_model_specific_args(parent_parser, root_dir): # pragma: no-cover """ Parameters you define here will be available to your model through self.hparams :param parent_parser: diff --git a/pl_examples/full_examples/imagenet/imagenet_example.py b/pl_examples/full_examples/imagenet/imagenet_example.py index e82a696d..646d092d 100644 --- a/pl_examples/full_examples/imagenet/imagenet_example.py +++ b/pl_examples/full_examples/imagenet/imagenet_example.py @@ -181,7 +181,7 @@ class ImageNetLightningModel(LightningModule): return val_loader @staticmethod - def add_model_specific_args(parent_parser): # pragma: no cover + def add_model_specific_args(parent_parser): # pragma: no-cover parser = argparse.ArgumentParser(parents=[parent_parser]) parser.add_argument('-a', '--arch', metavar='ARCH', default='resnet18', choices=MODEL_NAMES, help='model architecture: ' + diff --git a/pytorch_lightning/__init__.py b/pytorch_lightning/__init__.py index 07668034..d956cb11 100644 --- a/pytorch_lightning/__init__.py +++ b/pytorch_lightning/__init__.py @@ -19,18 +19,17 @@ except NameError: __LIGHTNING_SETUP__ = False if __LIGHTNING_SETUP__: - import sys - sys.stderr.write('Partial import of `torchlightning` during the build process.\n') - # We are not importing the rest of the scikit during the build - # process, as it may not be compiled yet + import sys # pragma: no-cover + sys.stderr.write('Partial import of `torchlightning` during the build process.\n') # pragma: no-cover + # We are not importing the rest of the lightning during the build process, as it may not be compiled yet else: from logging import getLogger _logger = getLogger("lightning") - from .core import LightningModule - from .trainer import Trainer - from .callbacks import Callback - from .core import data_loader + from pytorch_lightning.core import LightningModule + from pytorch_lightning.trainer import Trainer + from pytorch_lightning.callbacks import Callback + from pytorch_lightning.core import data_loader __all__ = [ 'Trainer', diff --git a/pytorch_lightning/callbacks/__init__.py b/pytorch_lightning/callbacks/__init__.py index 3a3d9d52..b1c47767 100644 --- a/pytorch_lightning/callbacks/__init__.py +++ b/pytorch_lightning/callbacks/__init__.py @@ -1,7 +1,7 @@ -from .base import Callback -from .early_stopping import EarlyStopping -from .gradient_accumulation_scheduler import GradientAccumulationScheduler -from .model_checkpoint import ModelCheckpoint +from pytorch_lightning.callbacks.base import Callback +from pytorch_lightning.callbacks.early_stopping import EarlyStopping +from pytorch_lightning.callbacks.gradient_accumulation_scheduler import GradientAccumulationScheduler +from pytorch_lightning.callbacks.model_checkpoint import ModelCheckpoint __all__ = [ 'Callback', diff --git a/pytorch_lightning/callbacks/early_stopping.py b/pytorch_lightning/callbacks/early_stopping.py index de16bcca..53d6b4cf 100644 --- a/pytorch_lightning/callbacks/early_stopping.py +++ b/pytorch_lightning/callbacks/early_stopping.py @@ -9,8 +9,8 @@ import warnings import numpy as np -from .base import Callback from pytorch_lightning import _logger as log +from pytorch_lightning.callbacks.base import Callback class EarlyStopping(Callback): diff --git a/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py b/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py index 00d73392..9d2c82e4 100644 --- a/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py +++ b/pytorch_lightning/callbacks/gradient_accumulation_scheduler.py @@ -6,7 +6,7 @@ Change gradient accumulation factor according to scheduling. import warnings -from .base import Callback +from pytorch_lightning.callbacks.base import Callback class GradientAccumulationScheduler(Callback): diff --git a/pytorch_lightning/core/__init__.py b/pytorch_lightning/core/__init__.py index 707393c6..ff03a2d3 100644 --- a/pytorch_lightning/core/__init__.py +++ b/pytorch_lightning/core/__init__.py @@ -335,8 +335,8 @@ LightningModule Class """ -from .decorators import data_loader -from .lightning import LightningModule +from pytorch_lightning.core.decorators import data_loader +from pytorch_lightning.core.lightning import LightningModule __all__ = ['LightningModule', 'data_loader'] # __call__ = __all__ diff --git a/pytorch_lightning/core/memory.py b/pytorch_lightning/core/memory.py index fe650dc9..403e98a0 100644 --- a/pytorch_lightning/core/memory.py +++ b/pytorch_lightning/core/memory.py @@ -72,12 +72,12 @@ class ModelSummary(object): with torch.no_grad(): for _, m in mods: - if isinstance(input_, (list, tuple)): # pragma: no cover + if isinstance(input_, (list, tuple)): # pragma: no-cover out = m(*input_) else: out = m(input_) - if isinstance(input_, (list, tuple)): # pragma: no cover + if isinstance(input_, (list, tuple)): # pragma: no-cover in_size = [] for x in input_: if isinstance(x, list): @@ -89,7 +89,7 @@ class ModelSummary(object): in_sizes.append(in_size) - if isinstance(out, (list, tuple)): # pragma: no cover + if isinstance(out, (list, tuple)): # pragma: no-cover out_size = np.asarray([x.size() for x in out]) else: out_size = np.array(out.size()) @@ -206,7 +206,7 @@ def _format_summary_table(*cols) -> str: return summary -def print_mem_stack() -> None: # pragma: no cover +def print_mem_stack() -> None: # pragma: no-cover for obj in gc.get_objects(): try: if torch.is_tensor(obj) or (hasattr(obj, 'data') and torch.is_tensor(obj.data)): @@ -215,7 +215,7 @@ def print_mem_stack() -> None: # pragma: no cover pass -def count_mem_items() -> Tuple[int, int]: # pragma: no cover +def count_mem_items() -> Tuple[int, int]: # pragma: no-cover num_params = 0 num_tensors = 0 for obj in gc.get_objects(): diff --git a/pytorch_lightning/loggers/__init__.py b/pytorch_lightning/loggers/__init__.py index 93d1b737..e9e48dda 100644 --- a/pytorch_lightning/loggers/__init__.py +++ b/pytorch_lightning/loggers/__init__.py @@ -82,8 +82,8 @@ Supported Loggers """ from os import environ -from .base import LightningLoggerBase, LoggerCollection, rank_zero_only -from .tensorboard import TensorBoardLogger +from pytorch_lightning.loggers.base import LightningLoggerBase, LoggerCollection, rank_zero_only +from pytorch_lightning.loggers.tensorboard import TensorBoardLogger __all__ = ['TensorBoardLogger'] @@ -91,37 +91,43 @@ try: # needed to prevent ImportError and duplicated logs. environ["COMET_DISABLE_AUTO_LOGGING"] = "1" - from .comet import CometLogger + from pytorch_lightning.loggers.comet import CometLogger +except ImportError: # pragma: no-cover + del environ["COMET_DISABLE_AUTO_LOGGING"] # pragma: no-cover +else: __all__.append('CometLogger') -except ImportError: - del environ["COMET_DISABLE_AUTO_LOGGING"] try: - from .mlflow import MLFlowLogger + from pytorch_lightning.loggers.mlflow import MLFlowLogger +except ImportError: # pragma: no-cover + pass # pragma: no-cover +else: __all__.append('MLFlowLogger') -except ImportError: - pass try: - from .neptune import NeptuneLogger + from pytorch_lightning.loggers.neptune import NeptuneLogger +except ImportError: # pragma: no-cover + pass # pragma: no-cover +else: __all__.append('NeptuneLogger') -except ImportError: - pass try: - from .test_tube import TestTubeLogger + from pytorch_lightning.loggers.test_tube import TestTubeLogger +except ImportError: # pragma: no-cover + pass # pragma: no-cover +else: __all__.append('TestTubeLogger') -except ImportError: - pass try: - from .wandb import WandbLogger + from pytorch_lightning.loggers.wandb import WandbLogger +except ImportError: # pragma: no-cover + pass # pragma: no-cover +else: __all__.append('WandbLogger') -except ImportError: - pass try: - from .trains import TrainsLogger + from pytorch_lightning.loggers.trains import TrainsLogger +except ImportError: # pragma: no-cover + pass # pragma: no-cover +else: __all__.append('TrainsLogger') -except ImportError: - pass diff --git a/pytorch_lightning/loggers/base.py b/pytorch_lightning/loggers/base.py index 8c3daa29..1d0c41cf 100644 --- a/pytorch_lightning/loggers/base.py +++ b/pytorch_lightning/loggers/base.py @@ -32,7 +32,6 @@ class LightningLoggerBase(ABC): @abstractmethod def experiment(self) -> Any: """Return the experiment object associated with this logger""" - pass @abstractmethod def log_metrics(self, metrics: Dict[str, float], step: Optional[int] = None): @@ -42,7 +41,6 @@ class LightningLoggerBase(ABC): metrics: Dictionary with metric names as keys and measured quantities as values step: Step number at which the metrics should be recorded """ - pass @staticmethod def _convert_params(params: Union[Dict[str, Any], Namespace]) -> Dict[str, Any]: @@ -85,7 +83,6 @@ class LightningLoggerBase(ABC): Args: params: argparse.Namespace containing the hyperparameters """ - pass def save(self) -> None: """Save log data.""" @@ -117,13 +114,11 @@ class LightningLoggerBase(ABC): @abstractmethod def name(self) -> str: """Return the experiment name.""" - pass @property @abstractmethod def version(self) -> Union[int, str]: """Return the experiment version.""" - pass class LoggerCollection(LightningLoggerBase): diff --git a/pytorch_lightning/loggers/comet.py b/pytorch_lightning/loggers/comet.py index 883dc3ef..e67b1b97 100644 --- a/pytorch_lightning/loggers/comet.py +++ b/pytorch_lightning/loggers/comet.py @@ -16,11 +16,11 @@ try: from comet_ml import BaseExperiment as CometBaseExperiment try: from comet_ml.api import API - except ImportError: + except ImportError: # pragma: no-cover # For more information, see: https://www.comet.ml/docs/python-sdk/releases/#release-300 - from comet_ml.papi import API -except ImportError: - raise ImportError('You want to use `comet_ml` logger which is not installed yet,' + from comet_ml.papi import API # pragma: no-cover +except ImportError: # pragma: no-cover + raise ImportError('You want to use `comet_ml` logger which is not installed yet,' # pragma: no-cover ' install it with `pip install comet-ml`.') import torch diff --git a/pytorch_lightning/loggers/mlflow.py b/pytorch_lightning/loggers/mlflow.py index 9c11f778..36f50b41 100644 --- a/pytorch_lightning/loggers/mlflow.py +++ b/pytorch_lightning/loggers/mlflow.py @@ -29,8 +29,9 @@ from typing import Optional, Dict, Any, Union try: import mlflow -except ImportError: - raise ImportError('You want to use `mlflow` logger which is not installed yet,' + from mlflow.tracking import MlflowClient +except ImportError: # pragma: no-cover + raise ImportError('You want to use `mlflow` logger which is not installed yet,' # pragma: no-cover ' install it with `pip install mlflow`.') from pytorch_lightning import _logger as log @@ -50,13 +51,13 @@ class MLFlowLogger(LightningLoggerBase): tags (dict): todo this param """ super().__init__() - self._mlflow_client = mlflow.tracking.MlflowClient(tracking_uri) + self._mlflow_client = MlflowClient(tracking_uri) self.experiment_name = experiment_name self._run_id = None self.tags = tags @property - def experiment(self) -> mlflow.tracking.MlflowClient: + def experiment(self) -> MlflowClient: r""" Actual mlflow object. To use mlflow features do the following. diff --git a/pytorch_lightning/loggers/neptune.py b/pytorch_lightning/loggers/neptune.py index 324c7bcd..12062026 100644 --- a/pytorch_lightning/loggers/neptune.py +++ b/pytorch_lightning/loggers/neptune.py @@ -12,8 +12,8 @@ from typing import Optional, List, Dict, Any, Union, Iterable try: import neptune from neptune.experiments import Experiment -except ImportError: - raise ImportError('You want to use `neptune` logger which is not installed yet,' +except ImportError: # pragma: no-cover + raise ImportError('You want to use `neptune` logger which is not installed yet,' # pragma: no-cover ' install it with `pip install neptune-client`.') import torch diff --git a/pytorch_lightning/loggers/tensorboard.py b/pytorch_lightning/loggers/tensorboard.py index 662ecdf4..b0598a9e 100644 --- a/pytorch_lightning/loggers/tensorboard.py +++ b/pytorch_lightning/loggers/tensorboard.py @@ -8,7 +8,7 @@ import torch from pkg_resources import parse_version from torch.utils.tensorboard import SummaryWriter -from .base import LightningLoggerBase, rank_zero_only +from pytorch_lightning.loggers.base import LightningLoggerBase, rank_zero_only class TensorBoardLogger(LightningLoggerBase): @@ -21,14 +21,12 @@ class TensorBoardLogger(LightningLoggerBase): .. _tf-logger: - Example - ------------------ + Example: + .. code-block:: python - .. code-block:: python - - logger = TensorBoardLogger("tb_logs", name="my_model") - trainer = Trainer(logger=logger) - trainer.train(model) + logger = TensorBoardLogger("tb_logs", name="my_model") + trainer = Trainer(logger=logger) + trainer.train(model) Args: save_dir (str): Save directory diff --git a/pytorch_lightning/loggers/test_tube.py b/pytorch_lightning/loggers/test_tube.py index fbb57def..4fc421a3 100644 --- a/pytorch_lightning/loggers/test_tube.py +++ b/pytorch_lightning/loggers/test_tube.py @@ -3,11 +3,11 @@ from typing import Optional, Dict, Any, Union try: from test_tube import Experiment -except ImportError: - raise ImportError('You want to use `test_tube` logger which is not installed yet,' +except ImportError: # pragma: no-cover + raise ImportError('You want to use `test_tube` logger which is not installed yet,' # pragma: no-cover ' install it with `pip install test-tube`.') -from .base import LightningLoggerBase, rank_zero_only +from pytorch_lightning.loggers.base import LightningLoggerBase, rank_zero_only class TestTubeLogger(LightningLoggerBase): diff --git a/pytorch_lightning/loggers/trains.py b/pytorch_lightning/loggers/trains.py index 76f1c48d..2f49928d 100644 --- a/pytorch_lightning/loggers/trains.py +++ b/pytorch_lightning/loggers/trains.py @@ -33,8 +33,9 @@ import torch try: import trains -except ImportError: - raise ImportError('You want to use `TRAINS` logger which is not installed yet,' + from trains import Task +except ImportError: # pragma: no-cover + raise ImportError('You want to use `TRAINS` logger which is not installed yet,' # pragma: no-cover ' install it with `pip install trains`.') from pytorch_lightning import _logger as log @@ -55,24 +56,49 @@ class TrainsLogger(LightningLoggerBase): auto_connect_frameworks: If True, automatically patch to trains backend. Defaults to True. auto_resource_monitoring: If true, machine vitals will be sent along side the task scalars. Defaults to True. + + Examples: + >>> logger = TrainsLogger("lightning_log", "my-test", output_uri=".") # doctest: +ELLIPSIS + TRAINS Task: ... + TRAINS results page: https://demoapp.trains.allegro.ai/.../log + >>> logger.log_metrics({"val_loss": 1.23}, step=0) + >>> logger.log_text("sample test") + sample test + >>> import numpy as np + >>> logger.log_artifact("confusion matrix", np.ones((2, 3))) + >>> logger.log_image("passed", "Image 1", np.random.randint(0, 255, (200, 150, 3), dtype=np.uint8)) """ + _bypass = False + def __init__( - self, project_name: Optional[str] = None, task_name: Optional[str] = None, - task_type: str = 'training', reuse_last_task_id: bool = True, - output_uri: Optional[str] = None, auto_connect_arg_parser: bool = True, - auto_connect_frameworks: bool = True, auto_resource_monitoring: bool = True) -> None: + self, + project_name: Optional[str] = None, + task_name: Optional[str] = None, + task_type: str = 'training', + reuse_last_task_id: bool = True, + output_uri: Optional[str] = None, + auto_connect_arg_parser: bool = True, + auto_connect_frameworks: bool = True, + auto_resource_monitoring: bool = True + ) -> None: super().__init__() - self._trains = trains.Task.init( - project_name=project_name, task_name=task_name, task_type=task_type, - reuse_last_task_id=reuse_last_task_id, output_uri=output_uri, - auto_connect_arg_parser=auto_connect_arg_parser, - auto_connect_frameworks=auto_connect_frameworks, - auto_resource_monitoring=auto_resource_monitoring - ) + if self._bypass: + self._trains = None + else: + self._trains = Task.init( + project_name=project_name, + task_name=task_name, + task_type=task_type, + reuse_last_task_id=reuse_last_task_id, + output_uri=output_uri, + auto_connect_arg_parser=auto_connect_arg_parser, + auto_connect_frameworks=auto_connect_frameworks, + auto_resource_monitoring=auto_resource_monitoring + ) @property - def experiment(self) -> trains.Task: + def experiment(self) -> Task: r"""Actual TRAINS object. To use TRAINS features do the following. Example: @@ -88,7 +114,7 @@ class TrainsLogger(LightningLoggerBase): """ ID is a uuid (string) representing this specific experiment in the entire system. """ - if not self._trains: + if self._bypass or not self._trains: return None return self._trains.id @@ -100,7 +126,7 @@ class TrainsLogger(LightningLoggerBase): params: The hyperparameters that passed through the model. """ - if not self._trains: + if self._bypass or not self._trains: return None if not params: return @@ -121,7 +147,7 @@ class TrainsLogger(LightningLoggerBase): then the elements will be logged as "title" and "series" respectively. step: Step number at which the metrics should be recorded. Defaults to None. """ - if not self._trains: + if self._bypass or not self._trains: return None if not step: @@ -153,7 +179,7 @@ class TrainsLogger(LightningLoggerBase): value: The value to log. step: Step number at which the metrics should be recorded. Defaults to None. """ - if not self._trains: + if self._bypass or not self._trains: return None if not step: @@ -171,7 +197,7 @@ class TrainsLogger(LightningLoggerBase): Args: text: The value of the log (data-point). """ - if not self._trains: + if self._bypass or not self._trains: return None self._trains.get_logger().report_text(text) @@ -196,7 +222,7 @@ class TrainsLogger(LightningLoggerBase): step: Step number at which the metrics should be recorded. Defaults to None. """ - if not self._trains: + if self._bypass or not self._trains: return None if not step: @@ -220,7 +246,7 @@ class TrainsLogger(LightningLoggerBase): metadata: Optional[Dict[str, Any]] = None, delete_after_upload: bool = False) -> None: """Save an artifact (file/object) in TRAINS experiment storage. - Args: + Arguments: name: Artifact name. Notice! it will override previous artifact if name already exists artifact: Artifact object to upload. Currently supports: @@ -237,7 +263,7 @@ class TrainsLogger(LightningLoggerBase): If True local artifact will be deleted (only applies if artifact_object is a local file). Defaults to False. """ - if not self._trains: + if self._bypass or not self._trains: return None self._trains.upload_artifact( @@ -249,8 +275,8 @@ class TrainsLogger(LightningLoggerBase): pass @rank_zero_only - def finalize(self, status: str) -> None: - if not self._trains: + def finalize(self, status: str = None) -> None: + if self._bypass or not self._trains: return None self._trains.close() self._trains = None @@ -260,23 +286,52 @@ class TrainsLogger(LightningLoggerBase): """ Name is a human readable non-unique name (str) of the experiment. """ - if not self._trains: - return None + if self._bypass or not self._trains: + return '' return self._trains.name @property def version(self) -> Union[str, None]: - if not self._trains: + if self._bypass or not self._trains: return None return self._trains.id + @classmethod + def set_credentials(cls, api_host: str = None, web_host: str = None, files_host: str = None, + key: str = None, secret: str = None) -> None: + """ + Set new default TRAINS-server host and credentials + These configurations could be overridden by either OS environment variables + or trains.conf configuration file + + Notice! credentials needs to be set *prior* to Logger initialization + + :param api_host: Trains API server url, example: host='http://localhost:8008' + :param web_host: Trains WEB server url, example: host='http://localhost:8080' + :param files_host: Trains Files server url, example: host='http://localhost:8081' + :param key: user key/secret pair, example: key='thisisakey123' + :param secret: user key/secret pair, example: secret='thisisseceret123' + """ + Task.set_credentials(api_host=api_host, web_host=web_host, files_host=files_host, + key=key, secret=secret) + + @classmethod + def set_bypass_mode(cls, bypass: bool) -> None: + """ + set_bypass_mode will bypass all outside communication, and will drop all logs. + Should only be used in "standalone mode", when there is no access to the *trains-server* + + :param bypass: If True, all outside communication is skipped + """ + cls._bypass = bypass + def __getstate__(self) -> Union[str, None]: - if not self._trains: - return None + if self._bypass or not self._trains: + return '' return self._trains.id def __setstate__(self, state: str) -> None: self._rank = 0 self._trains = None if state: - self._trains = trains.Task.get_task(task_id=state) + self._trains = Task.get_task(task_id=state) diff --git a/pytorch_lightning/loggers/wandb.py b/pytorch_lightning/loggers/wandb.py index 6f22050b..f52cf945 100644 --- a/pytorch_lightning/loggers/wandb.py +++ b/pytorch_lightning/loggers/wandb.py @@ -14,11 +14,11 @@ import torch.nn as nn try: import wandb from wandb.wandb_run import Run -except ImportError: - raise ImportError('You want to use `wandb` logger which is not installed yet,' +except ImportError: # pragma: no-cover + raise ImportError('You want to use `wandb` logger which is not installed yet,' # pragma: no-cover ' install it with `pip install wandb`.') -from .base import LightningLoggerBase, rank_zero_only +from pytorch_lightning.loggers.base import LightningLoggerBase, rank_zero_only class WandbLogger(LightningLoggerBase): diff --git a/pytorch_lightning/overrides/data_parallel.py b/pytorch_lightning/overrides/data_parallel.py index 5eaadac5..6b922f65 100644 --- a/pytorch_lightning/overrides/data_parallel.py +++ b/pytorch_lightning/overrides/data_parallel.py @@ -8,7 +8,7 @@ from torch.nn import DataParallel from torch.nn.parallel import DistributedDataParallel -def _find_tensors(obj): # pragma: no cover +def _find_tensors(obj): # pragma: no-cover r""" Recursively find all tensors contained in the specified object. """ @@ -21,7 +21,7 @@ def _find_tensors(obj): # pragma: no cover return [] -def get_a_var(obj): # pragma: no cover +def get_a_var(obj): # pragma: no-cover if isinstance(obj, torch.Tensor): return obj @@ -77,7 +77,7 @@ class LightningDistributedDataParallel(DistributedDataParallel): def parallel_apply(self, replicas, inputs, kwargs): return parallel_apply(replicas, inputs, kwargs, self.device_ids[:len(replicas)]) - def forward(self, *inputs, **kwargs): # pragma: no cover + def forward(self, *inputs, **kwargs): # pragma: no-cover self._sync_params() if self.device_ids: inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids) @@ -114,7 +114,7 @@ class LightningDistributedDataParallel(DistributedDataParallel): return output -def parallel_apply(modules, inputs, kwargs_tup=None, devices=None): # pragma: no cover +def parallel_apply(modules, inputs, kwargs_tup=None, devices=None): # pragma: no-cover r"""Applies each `module` in :attr:`modules` in parallel on arguments contained in :attr:`inputs` (positional) and :attr:`kwargs_tup` (keyword) on each of :attr:`devices`. diff --git a/pytorch_lightning/profiler/__init__.py b/pytorch_lightning/profiler/__init__.py index 58542099..20eece9a 100644 --- a/pytorch_lightning/profiler/__init__.py +++ b/pytorch_lightning/profiler/__init__.py @@ -113,7 +113,7 @@ to track and the profiler will record performance for code executed within this """ -from .profiler import Profiler, AdvancedProfiler, PassThroughProfiler +from pytorch_lightning.profiler.profiler import Profiler, AdvancedProfiler, PassThroughProfiler __all__ = [ 'Profiler', diff --git a/pytorch_lightning/profiler/profiler.py b/pytorch_lightning/profiler/profiler.py index d565dca3..00f375d5 100644 --- a/pytorch_lightning/profiler/profiler.py +++ b/pytorch_lightning/profiler/profiler.py @@ -18,17 +18,11 @@ class BaseProfiler(ABC): @abstractmethod def start(self, action_name): - """ - Defines how to start recording an action. - """ - pass + """Defines how to start recording an action.""" @abstractmethod def stop(self, action_name): - """ - Defines how to record the duration once an action is complete. - """ - pass + """Defines how to record the duration once an action is complete.""" @contextmanager def profile(self, action_name): @@ -62,9 +56,7 @@ class BaseProfiler(ABC): break def describe(self): - """ - Logs a profile report after the conclusion of the training run. - """ + """Logs a profile report after the conclusion of the training run.""" pass @@ -104,7 +96,7 @@ class Profiler(BaseProfiler): def stop(self, action_name): end_time = time.monotonic() if action_name not in self.current_actions: - raise ValueError( + raise ValueError( # pragma: no-cover f"Attempting to stop recording an action ({action_name}) which was never started." ) start_time = self.current_actions.pop(action_name) @@ -154,7 +146,7 @@ class AdvancedProfiler(BaseProfiler): def stop(self, action_name): pr = self.profiled_actions.get(action_name) if pr is None: - raise ValueError( + raise ValueError( # pragma: no-cover f"Attempting to stop recording an action ({action_name}) which was never started." ) pr.disable() diff --git a/pytorch_lightning/trainer/__init__.py b/pytorch_lightning/trainer/__init__.py index 87ceb22b..92179eb6 100644 --- a/pytorch_lightning/trainer/__init__.py +++ b/pytorch_lightning/trainer/__init__.py @@ -878,6 +878,6 @@ Trainer class """ -from .trainer import Trainer +from pytorch_lightning.trainer.trainer import Trainer __all__ = ['Trainer'] diff --git a/pytorch_lightning/trainer/auto_mix_precision.py b/pytorch_lightning/trainer/auto_mix_precision.py index cbcc3f92..49bed8b8 100644 --- a/pytorch_lightning/trainer/auto_mix_precision.py +++ b/pytorch_lightning/trainer/auto_mix_precision.py @@ -21,7 +21,7 @@ class TrainerAMPMixin(ABC): if self.use_amp: log.info('Using 16bit precision.') - if use_amp and not APEX_AVAILABLE: # pragma: no cover + if use_amp and not APEX_AVAILABLE: # pragma: no-cover msg = """ You set `use_amp=True` but do not have apex installed. Install apex first using this guide and rerun with use_amp=True: diff --git a/pytorch_lightning/trainer/distrib_data_parallel.py b/pytorch_lightning/trainer/distrib_data_parallel.py index 0b9a16d9..b90d089f 100644 --- a/pytorch_lightning/trainer/distrib_data_parallel.py +++ b/pytorch_lightning/trainer/distrib_data_parallel.py @@ -208,7 +208,7 @@ class TrainerDDPMixin(ABC): self.use_ddp2 = False # throw error to force user ddp or ddp2 choice - if num_gpu_nodes > 1 and not (self.use_ddp2 or self.use_ddp): # pragma: no cover + if num_gpu_nodes > 1 and not (self.use_ddp2 or self.use_ddp): w = 'DataParallel does not support num_nodes > 1. ' \ 'Switching to DistributedDataParallel for you. ' \ 'To silence this warning set distributed_backend=ddp' \ diff --git a/pytorch_lightning/trainer/distrib_parts.py b/pytorch_lightning/trainer/distrib_parts.py index 96bed05e..a789346d 100644 --- a/pytorch_lightning/trainer/distrib_parts.py +++ b/pytorch_lightning/trainer/distrib_parts.py @@ -511,7 +511,7 @@ class TrainerDPMixin(ABC): # check for this bug (amp + dp + !01 doesn't work) # https://github.com/NVIDIA/apex/issues/227 if self.use_dp and self.use_amp: - if self.amp_level == 'O2': # pragma: no cover + if self.amp_level == 'O2': m = f""" Amp level {self.amp_level} with DataParallel is not supported. See this note from NVIDIA for more info: https://github.com/NVIDIA/apex/issues/227. diff --git a/pytorch_lightning/trainer/evaluation_loop.py b/pytorch_lightning/trainer/evaluation_loop.py index 0bc46b99..e9e4872e 100644 --- a/pytorch_lightning/trainer/evaluation_loop.py +++ b/pytorch_lightning/trainer/evaluation_loop.py @@ -248,7 +248,7 @@ class TrainerEvaluationLoopMixin(ABC): dataloader = dataloader.per_device_loader(device) for batch_idx, batch in enumerate(dataloader): - if batch is None: # pragma: no cover + if batch is None: continue # stop short when on fast_dev_run (sets max_batch=1) diff --git a/pytorch_lightning/trainer/trainer.py b/pytorch_lightning/trainer/trainer.py index 029f404a..602755f9 100644 --- a/pytorch_lightning/trainer/trainer.py +++ b/pytorch_lightning/trainer/trainer.py @@ -598,7 +598,7 @@ class Trainer( elif self.single_gpu: self.single_gpu_train(model) - elif self.use_tpu: # pragma: no cover + elif self.use_tpu: # pragma: no-cover log.info(f'training on {self.num_tpu_cores} TPU cores') # COLAB_GPU is an env var available by default in Colab environments. @@ -855,7 +855,7 @@ class Trainer( if model is not None: self.model = model self.fit(model) - elif self.use_ddp or self.use_tpu: # pragma: no cover + elif self.use_ddp or self.use_tpu: # pragma: no-cover # attempt to load weights from a spawn path = os.path.join(self.default_save_path, '__temp_weight_ddp_end.ckpt') test_model = self.model diff --git a/pytorch_lightning/trainer/training_io.py b/pytorch_lightning/trainer/training_io.py index 1f91ee5a..7d0f22de 100644 --- a/pytorch_lightning/trainer/training_io.py +++ b/pytorch_lightning/trainer/training_io.py @@ -206,7 +206,7 @@ class TrainerIOMixin(ABC): signal.signal(signal.SIGUSR1, self.sig_handler) signal.signal(signal.SIGTERM, self.term_handler) - def sig_handler(self, signum, frame): # pragma: no cover + def sig_handler(self, signum, frame): # pragma: no-cover if self.proc_rank == 0: # save weights log.info('handling SIGUSR1') diff --git a/requirements-extra.txt b/requirements-extra.txt index 1265bc65..c3d1d6b2 100644 --- a/requirements-extra.txt +++ b/requirements-extra.txt @@ -3,4 +3,4 @@ comet-ml>=1.0.56 mlflow>=1.0.0 test_tube>=0.7.5 wandb>=0.8.21 -trains>=0.13.3 +trains>=0.14.1rc0 diff --git a/setup.cfg b/setup.cfg index c7fa283b..26470605 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,9 +19,9 @@ max-line-length = 120 [coverage:report] exclude_lines = - pragma: no cover - def __repr__ + pragma: no-cover warnings + pass [flake8] # TODO: this should be 88 or 100 according PEP8 diff --git a/tests/loggers/test_tensorboard.py b/tests/loggers/test_tensorboard.py index e8153840..ba7fd5d4 100644 --- a/tests/loggers/test_tensorboard.py +++ b/tests/loggers/test_tensorboard.py @@ -6,9 +6,7 @@ import torch import tests.models.utils as tutils from pytorch_lightning import Trainer -from pytorch_lightning.loggers import ( - TensorBoardLogger -) +from pytorch_lightning.loggers import TensorBoardLogger from tests.models import LightningTestModel diff --git a/tests/loggers/test_trains.py b/tests/loggers/test_trains.py index 1c8ca416..384d6be8 100644 --- a/tests/loggers/test_trains.py +++ b/tests/loggers/test_trains.py @@ -12,7 +12,11 @@ def test_trains_logger(tmpdir): hparams = tutils.get_hparams() model = LightningTestModel(hparams) - logger = TrainsLogger(project_name="examples", task_name="pytorch lightning test") + TrainsLogger.set_bypass_mode(True) + TrainsLogger.set_credentials(api_host='http://integration.trains.allegro.ai:8008', + files_host='http://integration.trains.allegro.ai:8081', + web_host='http://integration.trains.allegro.ai:8080', ) + logger = TrainsLogger(project_name="lightning_log", task_name="pytorch lightning test") trainer_options = dict( default_save_path=tmpdir, @@ -24,6 +28,7 @@ def test_trains_logger(tmpdir): result = trainer.fit(model) print('result finished') + logger.finalize() assert result == 1, "Training failed" @@ -33,8 +38,11 @@ def test_trains_pickle(tmpdir): # hparams = tutils.get_hparams() # model = LightningTestModel(hparams) - - logger = TrainsLogger(project_name="examples", task_name="pytorch lightning test") + TrainsLogger.set_bypass_mode(True) + TrainsLogger.set_credentials(api_host='http://integration.trains.allegro.ai:8008', + files_host='http://integration.trains.allegro.ai:8081', + web_host='http://integration.trains.allegro.ai:8080', ) + logger = TrainsLogger(project_name="lightning_log", task_name="pytorch lightning test") trainer_options = dict( default_save_path=tmpdir, @@ -46,3 +54,5 @@ def test_trains_pickle(tmpdir): pkl_bytes = pickle.dumps(trainer) trainer2 = pickle.loads(pkl_bytes) trainer2.logger.log_metrics({"acc": 1.0}) + trainer2.logger.finalize() + logger.finalize() diff --git a/tests/models/base.py b/tests/models/base.py index 8f7f5492..41c26b31 100644 --- a/tests/models/base.py +++ b/tests/models/base.py @@ -203,7 +203,7 @@ class TestModelBase(LightningModule): return loader @staticmethod - def add_model_specific_args(parent_parser, root_dir): # pragma: no cover + def add_model_specific_args(parent_parser, root_dir): # pragma: no-cover """ Parameters you define here will be available to your model through self.hparams :param parent_parser: