From 7d019bde679c78fa8c3ebd1cecec7e7ef1eaade9 Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 11 Dec 2020 12:06:04 +0100 Subject: [PATCH 1/6] draft --- .../lightning.py => __init__.py} | 6 +- .../pytorch_geometric/__init__.py | 1 + .../pytorch_geometric/cora_dna.py | 66 +++++++++---------- 3 files changed, 38 insertions(+), 35 deletions(-) rename pl_examples/pytorch_ecosystem/{pytorch_geometric/lightning.py => __init__.py} (87%) diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/lightning.py b/pl_examples/pytorch_ecosystem/__init__.py similarity index 87% rename from pl_examples/pytorch_ecosystem/pytorch_geometric/lightning.py rename to pl_examples/pytorch_ecosystem/__init__.py index 2c765d1449c57..8840b376e0f4a 100644 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/lightning.py +++ b/pl_examples/pytorch_ecosystem/__init__.py @@ -1,3 +1,7 @@ +from pytorch_lightning.utilities import _module_available + +_TORCH_GEOMETRIC_AVAILABLE = _module_available("torch_geometric") + def nice_print(msg, last=False): print() print("\033[0;35m" + msg + "\033[0m") @@ -5,7 +9,7 @@ def nice_print(msg, last=False): print() -lightning_logo = """ +LIGHTNING_LOGO = """ #### ########### #################### diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py b/pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py index e69de29bb2d1d..8b137891791fe 100644 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py +++ b/pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py @@ -0,0 +1 @@ + diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py b/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py index e4e040ff7072e..c88618e0aef3a 100644 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py +++ b/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py @@ -5,22 +5,19 @@ model can be easily torch-scripted, thanks to Pytorch Geometric. """ # python imports -import os import os.path as osp -import sys -from functools import partial -from collections import namedtuple from argparse import ArgumentParser +from collections import namedtuple from typing import List, Optional, NamedTuple -# thrid parties libraries -import numpy as np -from torch import nn import torch +import torch.nn.functional as F from torch import Tensor +# thrid parties libraries +from torch import nn from torch.optim import Adam -import torch.nn.functional as F +from pl_examples.pytorch_ecosystem import _TORCH_GEOMETRIC_AVAILABLE, nice_print, LIGHTNING_LOGO # Lightning imports from pytorch_lightning import ( Trainer, @@ -29,18 +26,12 @@ ) from pytorch_lightning.metrics import Accuracy -try: +if _TORCH_GEOMETRIC_AVAILABLE: # Pytorch Geometric imports from torch_geometric.nn import DNAConv, MessagePassing - from torch_geometric.data import DataLoader from torch_geometric.datasets import Planetoid - import torch_geometric.transforms as T + from torch_geometric import transforms as T from torch_geometric.data import NeighborSampler - from lightning import lightning_logo, nice_print -except Exception: - HAS_PYTORCH_GEOMETRIC = False -else: - HAS_PYTORCH_GEOMETRIC = True # use to make model jittable @@ -67,16 +58,20 @@ class CoraDataset(LightningDataModule): Nodes represent documents and edges represent citation links. Training, validation and test splits are given by binary masks. c.f https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/datasets/planetoid.py + + >>> CoraDataset() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE """ NAME = "cora" - def __init__(self, - num_workers: int = 1, - batch_size: int = 8, - drop_last: bool = True, - pin_memory: bool = True, - num_layers: int = None): + def __init__( + self, + num_workers: int = 1, + batch_size: int = 8, + drop_last: bool = True, + pin_memory: bool = True, + num_layers: int = None, + ): super().__init__() assert num_layers is not None @@ -169,18 +164,21 @@ class DNAConvNet(LightningModule): Towards Dynamic Neighborhood Aggregation in Graph Neural Networks" `_ paper c.f https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/nn/conv/dna_conv.py#L172 + + >>> DNAConvNet() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE """ - def __init__(self, - num_layers: int = 2, - hidden_channels: int = 128, - heads: int = 8, - groups: int = 16, - dropout: float = 0.8, - cached: bool = False, - num_features: int = None, - num_classes: int = None, - ): + def __init__( + self, + num_layers: int = 2, + hidden_channels: int = 128, + heads: int = 8, + groups: int = 16, + dropout: float = 0.8, + cached: bool = False, + num_features: int = None, + num_classes: int = None, + ): super().__init__() assert num_features is not None @@ -343,7 +341,7 @@ def get_single_batch(datamodule): def run(args): nice_print("You are about to train a TorchScripted Pytorch Geometric Lightning model !") - nice_print(lightning_logo) + nice_print(LIGHTNING_LOGO) datamodule: LightningDataModule = instantiate_datamodule(args) model: LightningModule = instantiate_model(args, datamodule) @@ -361,7 +359,7 @@ def run(args): if __name__ == "__main__": - if not HAS_PYTORCH_GEOMETRIC: + if not _TORCH_GEOMETRIC_AVAILABLE: print("Skip training. Pytorch Geometric isn't installed. Please, check README.md !") else: From 68b7f91365e03df15a50994470067d7b09b93e87 Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 11 Dec 2020 12:36:37 +0100 Subject: [PATCH 2/6] wip --- .../pytorch_geometric/cora_dna.py | 20 +++++++++++-------- .../pytorch_geometric/pyproject.toml | 2 +- requirements/examples.txt | 4 ++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py b/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py index c88618e0aef3a..94bee241f7c6d 100644 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py +++ b/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py @@ -4,7 +4,6 @@ on Cora Dataset using pytorch-lightning. This example will also demonstrate how this model can be easily torch-scripted, thanks to Pytorch Geometric. """ -# python imports import os.path as osp from argparse import ArgumentParser from collections import namedtuple @@ -13,12 +12,10 @@ import torch import torch.nn.functional as F from torch import Tensor -# thrid parties libraries from torch import nn from torch.optim import Adam from pl_examples.pytorch_ecosystem import _TORCH_GEOMETRIC_AVAILABLE, nice_print, LIGHTNING_LOGO -# Lightning imports from pytorch_lightning import ( Trainer, LightningDataModule, @@ -59,19 +56,23 @@ class CoraDataset(LightningDataModule): Training, validation and test splits are given by binary masks. c.f https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/datasets/planetoid.py - >>> CoraDataset() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE + >>> CoraDataset(1) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE """ NAME = "cora" def __init__( self, + num_layers: int, num_workers: int = 1, batch_size: int = 8, drop_last: bool = True, pin_memory: bool = True, - num_layers: int = None, ): + + if not _TORCH_GEOMETRIC_AVAILABLE: + raise RuntimeError("Skip training. Pytorch Geometric isn't installed. Please, check README.md :]") + super().__init__() assert num_layers is not None @@ -165,20 +166,23 @@ class DNAConvNet(LightningModule): `_ paper c.f https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/nn/conv/dna_conv.py#L172 - >>> DNAConvNet() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE + >>> DNAConvNet(5, 2) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE """ def __init__( self, + num_features: int, + num_classes: int, num_layers: int = 2, hidden_channels: int = 128, heads: int = 8, groups: int = 16, dropout: float = 0.8, cached: bool = False, - num_features: int = None, - num_classes: int = None, ): + if not _TORCH_GEOMETRIC_AVAILABLE: + raise RuntimeError("Skip training. Pytorch Geometric isn't installed. Please, check README.md :]") + super().__init__() assert num_features is not None diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml b/pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml index 99f516323e976..1e388ac590b34 100644 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml +++ b/pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml @@ -2,7 +2,7 @@ name = "lightning-geometric" version = "0.1.0" description = "TorchScripted Pytorch Geometric Examples with Pytorch Lightning" -authors = ["Thomas Chaton "] +authors = ["Thomas Chaton "] [tool.poetry.dependencies] python = "3.7.8" diff --git a/requirements/examples.txt b/requirements/examples.txt index 6e48778cb222a..0d9742c68c43a 100644 --- a/requirements/examples.txt +++ b/requirements/examples.txt @@ -1,2 +1,6 @@ torchvision>=0.4.1 gym>=0.17.0 + +# Ecosystem +torch-geometric>=1.6.1 +torch-sparse>=0.6.7 \ No newline at end of file From 66997323d4ff51e98d03d40005ba147814e73dcf Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 11 Dec 2020 12:47:01 +0100 Subject: [PATCH 3/6] CI --- .github/workflows/ci_test-eco.yml | 97 +++++++++++++++++++++++++++++++ requirements/ecosystem.txt | 3 + requirements/examples.txt | 6 +- 3 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci_test-eco.yml create mode 100644 requirements/ecosystem.txt diff --git a/.github/workflows/ci_test-eco.yml b/.github/workflows/ci_test-eco.yml new file mode 100644 index 0000000000000..b10d94df11a85 --- /dev/null +++ b/.github/workflows/ci_test-eco.yml @@ -0,0 +1,97 @@ +name: CI ecosystem examples + +# see: https://help.github.com/en/actions/reference/events-that-trigger-workflows +on: # Trigger the workflow on push or pull request, but only for the master branch + push: + branches: [master, "release/*"] # include release branches like release/1.0.x + pull_request: + branches: [master, "release/*"] + +jobs: + pytest: + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-18.04] #, windows-2019, macOS-10.15 + python-version: [3.7] + requires: ['minimal', 'latest'] + + # Timeout: https://stackoverflow.com/a/59076067/4521646 + timeout-minutes: 35 # TODO: the macOS is taking too long, probably caching did not work... + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Update Pip + run: | + # todo: unfreeze PIP after resolving minimal dependencies + pip install --quiet "pip==20.1" --upgrade --user # needed for get pip cacher folder + + - name: Set min. dependencies + if: matrix.requires == 'minimal' + run: | + python -c "fname = 'requirements.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" + python -c "fname = 'requirements/extra.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" + python -c "fname = 'requirements/loggers.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" + python -c "fname = 'requirements/test.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" + python -c "fname = 'requirements/examples.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" + python -c "fname = 'requirements/ecosystem.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" + # remove Fairscale from requirements + python -c "fname = 'requirements/extra.txt' ; lines = [line for line in open(fname).readlines() if 'fairscale' not in line] ; open(fname, 'w').writelines(lines)" + + # Note: This uses an internal pip API and may not always work + # https://github.com/actions/cache/blob/master/examples.md#multiple-oss-in-a-workflow + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-py${{ matrix.python-version }}-${{ matrix.requires }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements/extra.txt') }} + restore-keys: | + ${{ runner.os }}-pip-py${{ matrix.python-version }}-${{ matrix.requires }}- + + - name: Install dependencies + run: | + # python -m pip install --upgrade --user pip + # todo: skip horovod + pip install --requirement requirements.txt --find-links https://download.pytorch.org/whl/cpu/torch_stable.html --quiet --upgrade + pip install --requirement ./requirements/ecosystem.txt --find-links https://download.pytorch.org/whl/cpu/torch_stable.html --quiet --upgrade + python --version + pip --version + pip list + shell: bash + + - name: Cache datasets + uses: actions/cache@v2 + with: + path: Datasets # This path is specific to Ubuntu + # Look to see if there is a cache hit for the corresponding requirements file + key: pl-dataset + + - name: Tests + run: | + # NOTE: do not include coverage report here, see: https://github.com/nedbat/coveragepy/issues/1003 + coverage run --source pytorch_lightning -m pytest pl_examples/ecosystem -v --durations=50 --junitxml=junit/test-results-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.requires }}.xml + + - name: Upload pytest test results + uses: actions/upload-artifact@v2 + with: + name: pytest-results-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.requires }} + path: junit/test-results-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.requires }}.xml + # Use always() to always run this step to publish test results when there are test failures + if: failure() + + - name: Statistics + if: success() + run: | + coverage report + coverage xml diff --git a/requirements/ecosystem.txt b/requirements/ecosystem.txt new file mode 100644 index 0000000000000..5a225d799ddbb --- /dev/null +++ b/requirements/ecosystem.txt @@ -0,0 +1,3 @@ +# Geometry +torch-geometric>=1.6.1 +torch-sparse>=0.6.7 \ No newline at end of file diff --git a/requirements/examples.txt b/requirements/examples.txt index 0d9742c68c43a..c87d10a39346f 100644 --- a/requirements/examples.txt +++ b/requirements/examples.txt @@ -1,6 +1,2 @@ torchvision>=0.4.1 -gym>=0.17.0 - -# Ecosystem -torch-geometric>=1.6.1 -torch-sparse>=0.6.7 \ No newline at end of file +gym>=0.17.0 \ No newline at end of file From ec3094287e9a540d9914de583e06a6492227d3f7 Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 11 Dec 2020 13:51:42 +0100 Subject: [PATCH 4/6] drop pl geometry --- .github/workflows/ci_test-eco.yml | 97 ----- .../pytorch_geometric/README.md | 38 -- .../pytorch_geometric/__init__.py | 1 - .../pytorch_geometric/cora_dna.py | 377 ------------------ .../pytorch_geometric/pyproject.toml | 25 -- requirements/ecosystem.txt | 3 - 6 files changed, 541 deletions(-) delete mode 100644 .github/workflows/ci_test-eco.yml delete mode 100644 pl_examples/pytorch_ecosystem/pytorch_geometric/README.md delete mode 100644 pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py delete mode 100644 pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py delete mode 100644 pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml delete mode 100644 requirements/ecosystem.txt diff --git a/.github/workflows/ci_test-eco.yml b/.github/workflows/ci_test-eco.yml deleted file mode 100644 index b10d94df11a85..0000000000000 --- a/.github/workflows/ci_test-eco.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: CI ecosystem examples - -# see: https://help.github.com/en/actions/reference/events-that-trigger-workflows -on: # Trigger the workflow on push or pull request, but only for the master branch - push: - branches: [master, "release/*"] # include release branches like release/1.0.x - pull_request: - branches: [master, "release/*"] - -jobs: - pytest: - - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-18.04] #, windows-2019, macOS-10.15 - python-version: [3.7] - requires: ['minimal', 'latest'] - - # Timeout: https://stackoverflow.com/a/59076067/4521646 - timeout-minutes: 35 # TODO: the macOS is taking too long, probably caching did not work... - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - name: Update Pip - run: | - # todo: unfreeze PIP after resolving minimal dependencies - pip install --quiet "pip==20.1" --upgrade --user # needed for get pip cacher folder - - - name: Set min. dependencies - if: matrix.requires == 'minimal' - run: | - python -c "fname = 'requirements.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" - python -c "fname = 'requirements/extra.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" - python -c "fname = 'requirements/loggers.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" - python -c "fname = 'requirements/test.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" - python -c "fname = 'requirements/examples.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" - python -c "fname = 'requirements/ecosystem.txt' ; req = open(fname).read().replace('>=', '==') ; open(fname, 'w').write(req)" - # remove Fairscale from requirements - python -c "fname = 'requirements/extra.txt' ; lines = [line for line in open(fname).readlines() if 'fairscale' not in line] ; open(fname, 'w').writelines(lines)" - - # Note: This uses an internal pip API and may not always work - # https://github.com/actions/cache/blob/master/examples.md#multiple-oss-in-a-workflow - - name: Get pip cache dir - id: pip-cache - run: | - echo "::set-output name=dir::$(pip cache dir)" - - - name: pip cache - uses: actions/cache@v2 - with: - path: ${{ steps.pip-cache.outputs.dir }} - key: ${{ runner.os }}-pip-py${{ matrix.python-version }}-${{ matrix.requires }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements/extra.txt') }} - restore-keys: | - ${{ runner.os }}-pip-py${{ matrix.python-version }}-${{ matrix.requires }}- - - - name: Install dependencies - run: | - # python -m pip install --upgrade --user pip - # todo: skip horovod - pip install --requirement requirements.txt --find-links https://download.pytorch.org/whl/cpu/torch_stable.html --quiet --upgrade - pip install --requirement ./requirements/ecosystem.txt --find-links https://download.pytorch.org/whl/cpu/torch_stable.html --quiet --upgrade - python --version - pip --version - pip list - shell: bash - - - name: Cache datasets - uses: actions/cache@v2 - with: - path: Datasets # This path is specific to Ubuntu - # Look to see if there is a cache hit for the corresponding requirements file - key: pl-dataset - - - name: Tests - run: | - # NOTE: do not include coverage report here, see: https://github.com/nedbat/coveragepy/issues/1003 - coverage run --source pytorch_lightning -m pytest pl_examples/ecosystem -v --durations=50 --junitxml=junit/test-results-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.requires }}.xml - - - name: Upload pytest test results - uses: actions/upload-artifact@v2 - with: - name: pytest-results-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.requires }} - path: junit/test-results-${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.requires }}.xml - # Use always() to always run this step to publish test results when there are test failures - if: failure() - - - name: Statistics - if: success() - run: | - coverage report - coverage xml diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/README.md b/pl_examples/pytorch_ecosystem/pytorch_geometric/README.md deleted file mode 100644 index 5c9a42d5a8942..0000000000000 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# [Pytorch Geometric](https://github.com/rusty1s/pytorch_geometric) examples with Lighting - -### Introduction - -PyTorch Geometric (PyG) is a geometric deep learning extension library for PyTorch. It relies on lower level libraries such as - -* PyTorch Cluster: A package consists of a small extension library of highly optimized graph cluster algorithms in Pytorch -* PyTorch Sparse: A package consists of a small extension library of optimized sparse matrix operations with autograd support in Pytorch -* PyTorch Scatter: A package consists of a small extension library of highly optimized sparse update (scatter and segment) operations for the use in PyTorch - -## Setup - -``` -pyenv install 3.7.8 -pyenv local 3.7.8 -python -m venv -source .venv/bin/activate -poetry install -``` - -Run example - -``` -python cora_dna.py -``` - -## Current example lists - -| `DATASET` | `MODEL` | `TASK` | DATASET DESCRIPTION | MODEL DESCRIPTION | | -| :---: | :---: | :---: | :---: | :---: | :---: | -| Cora | DNA | Node Classification | The citation network datasets "Cora", "CiteSeer" and "PubMed" from the "Revisiting Semi-Supervised Learning with Graph Embeddings" | The dynamic neighborhood aggregation operator from the "Just Jump: Towards Dynamic Neighborhood Aggregation in Graph Neural Networks" - - -## DATASET SIZES - -``` - 16M ./cora -``` diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py b/pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py deleted file mode 100644 index 8b137891791fe..0000000000000 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py b/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py deleted file mode 100644 index 94bee241f7c6d..0000000000000 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/cora_dna.py +++ /dev/null @@ -1,377 +0,0 @@ -"""Graph Convolution Example using Pytorch Geometric - -This example illustrates how one could train a graph convolution model with DNA Conv -on Cora Dataset using pytorch-lightning. This example will also demonstrate how this -model can be easily torch-scripted, thanks to Pytorch Geometric. -""" -import os.path as osp -from argparse import ArgumentParser -from collections import namedtuple -from typing import List, Optional, NamedTuple - -import torch -import torch.nn.functional as F -from torch import Tensor -from torch import nn -from torch.optim import Adam - -from pl_examples.pytorch_ecosystem import _TORCH_GEOMETRIC_AVAILABLE, nice_print, LIGHTNING_LOGO -from pytorch_lightning import ( - Trainer, - LightningDataModule, - LightningModule -) -from pytorch_lightning.metrics import Accuracy - -if _TORCH_GEOMETRIC_AVAILABLE: - # Pytorch Geometric imports - from torch_geometric.nn import DNAConv, MessagePassing - from torch_geometric.datasets import Planetoid - from torch_geometric import transforms as T - from torch_geometric.data import NeighborSampler - - -# use to make model jittable -OptTensor = Optional[Tensor] -ListTensor = List[Tensor] - - -class TensorBatch(NamedTuple): - x: Tensor - edge_index: ListTensor - edge_attr: OptTensor - batch: OptTensor - -################################### -# LightningDataModule # -################################### - - -class CoraDataset(LightningDataModule): - - r"""The citation network datasets "Cora", "CiteSeer" and "PubMed" from the - `"Revisiting Semi-Supervised Learning with Graph Embeddings" - `_ paper. - Nodes represent documents and edges represent citation links. - Training, validation and test splits are given by binary masks. - c.f https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/datasets/planetoid.py - - >>> CoraDataset(1) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE - """ - - NAME = "cora" - - def __init__( - self, - num_layers: int, - num_workers: int = 1, - batch_size: int = 8, - drop_last: bool = True, - pin_memory: bool = True, - ): - - if not _TORCH_GEOMETRIC_AVAILABLE: - raise RuntimeError("Skip training. Pytorch Geometric isn't installed. Please, check README.md :]") - - super().__init__() - - assert num_layers is not None - - self._num_workers = num_workers - self._batch_size = batch_size - self._drop_last = drop_last - self._pin_memory = pin_memory - self._num_layers = num_layers - - self._transform = T.NormalizeFeatures() - - @property - def num_features(self): - return 1433 - - @property - def num_classes(self): - return 7 - - @property - def hyper_parameters(self): - # used to inform the model the dataset specifications - return {"num_features": self.num_features, "num_classes": self.num_classes} - - def prepare_data(self): - path = osp.join( - osp.dirname(osp.realpath(__file__)), "..", "..", "data", self.NAME - ) - self.dataset = Planetoid(path, self.NAME, transform=self._transform) - self.data = self.dataset[0] - - def create_neighbor_sampler(self, batch_size=2, stage=None): - # https://github.com/rusty1s/pytorch_geometric/tree/master/torch_geometric/data/sampler.py#L18 - return NeighborSampler( - self.data.edge_index, - # the nodes that should be considered for sampling. - node_idx=getattr(self.data, f"{stage}_mask"), - # -1 indicates all neighbors will be selected - sizes=[self._num_layers, -1], - num_workers=self._num_workers, - drop_last=self._drop_last, - pin_memory=self._pin_memory, - ) - - def train_dataloader(self): - return self.create_neighbor_sampler(stage="train") - - def validation_dataloader(self): - return self.create_neighbor_sampler(stage="val") - - def test_dataloader(self): - return self.create_neighbor_sampler(stage="test") - - def gather_data_and_convert_to_namedtuple(self, batch, batch_nb): - """ - This function will select features using node_idx - and create a NamedTuple Object. - """ - - usual_keys = ["x", "edge_index", "edge_attr", "batch"] - Batch: TensorBatch = namedtuple("Batch", usual_keys) - return ( - Batch( - self.data.x[batch[1]], - [e.edge_index for e in batch[2]], - None, - None, - ), - self.data.y[batch[1]], - ) - - @staticmethod - def add_argparse_args(parser): - parser.add_argument("--num_workers", type=int, default=1) - parser.add_argument("--batch_size", type=int, default=2) - parser.add_argument("--drop_last", default=True) - parser.add_argument("--pin_memory", default=True) - return parser - - -############################### -# LightningModule # -############################### - - -class DNAConvNet(LightningModule): - - r"""The dynamic neighborhood aggregation operator from the `"Just Jump: - Towards Dynamic Neighborhood Aggregation in Graph Neural Networks" - `_ paper - c.f https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/nn/conv/dna_conv.py#L172 - - >>> DNAConvNet(5, 2) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE - """ - - def __init__( - self, - num_features: int, - num_classes: int, - num_layers: int = 2, - hidden_channels: int = 128, - heads: int = 8, - groups: int = 16, - dropout: float = 0.8, - cached: bool = False, - ): - if not _TORCH_GEOMETRIC_AVAILABLE: - raise RuntimeError("Skip training. Pytorch Geometric isn't installed. Please, check README.md :]") - - super().__init__() - - assert num_features is not None - assert num_classes is not None - - # utils from Lightning to save __init__ arguments - self.save_hyperparameters() - hparams = self.hparams - - # Instantiate metrics - self.val_acc = Accuracy(hparams["num_classes"]) - self.test_acc = Accuracy(hparams["num_classes"]) - - # Define DNA graph convolution model - self.hidden_channels = hparams["hidden_channels"] - self.lin1 = nn.Linear(hparams["num_features"], hparams["hidden_channels"]) - - # Create ModuleList to hold all convolutions - self.convs = nn.ModuleList() - - # Iterate through the number of layers - for _ in range(hparams["num_layers"]): - - # Create a DNA Convolution - This graph convolution relies on MultiHead Attention mechanism - # to route information similar to Transformers. - # https://github.com/rusty1s/pytorch_geometric/blob/master/torch_geometric/nn/conv/dna_conv.py#L172 - self.convs.append( - DNAConv( - hparams["hidden_channels"], - hparams["heads"], - hparams["groups"], - dropout=hparams["dropout"], - cached=False, - ) - ) - # classification MLP - self.lin2 = nn.Linear(hparams["hidden_channels"], hparams["num_classes"], bias=False) - - def forward(self, batch: TensorBatch): - # batch needs to be typed for making this model jittable. - x = batch.x - x = F.relu(self.lin1(x)) - x = F.dropout(x, p=0.5, training=self.training) - x_all = x.view(-1, 1, self.hidden_channels) - - # iterate over all convolutions - for idx, conv in enumerate(self.convs): - # perform convolution using previously concatenated embedding - # through edge_index - x = F.relu(conv(x_all, batch.edge_index[idx])) - x = x.view(-1, 1, self.hidden_channels) - - # concatenate with previously computed embedding - x_all = torch.cat([x_all, x], dim=1) - - # extra latest layer embedding - x = x_all[:, -1] - - x = F.dropout(x, p=0.5, training=self.training) - - # return logits per nodes - return F.log_softmax(self.lin2(x), -1) - - def step(self, batch, batch_nb): - typed_batch, targets = self.gather_data_and_convert_to_namedtuple(batch, batch_nb) - logits = self(typed_batch) - return logits, targets - - def training_step(self, batch, batch_nb): - logits, targets = self.step(batch, batch_nb) - train_loss = F.nll_loss(logits, targets) - self.log("train_loss", train_loss, on_step=True, on_epoch=True, prog_bar=True) - return train_loss - - def validation_step(self, batch, batch_nb): - logits, targets = self.step(batch, batch_nb) - val_loss = F.nll_loss(logits, targets) - self.log("val_loss", val_loss, on_step=False, on_epoch=True, prog_bar=True) - self.log("val_acc", self.val_acc(logits, targets), on_step=False, on_epoch=True, prog_bar=True) - - def test_step(self, batch, batch_nb): - logits, targets = self.step(batch, batch_nb) - test_loss = F.nll_loss(logits, targets) - self.log("test_loss", test_loss, on_step=False, on_epoch=True, prog_bar=True) - self.log("test_acc", self.test_acc(logits, targets), on_step=False, on_epoch=True, prog_bar=True) - - # Use for jittable demonstration. - - def _convert_to_jittable(self, module): - for key, m in module._modules.items(): - if isinstance(m, MessagePassing) and m.jittable is not None: - # Pytorch Geometric MessagePassing implements a `.jittable` function - # which converts the current module into its jittable version. - module._modules[key] = m.jittable() - else: - self._convert_to_jittable(m) - return module - - def jittable(self): - for key, m in self._modules.items(): - self._modules[key] = self._convert_to_jittable(m) - - def configure_optimizers(self): - return Adam(self.parameters(), lr=1e-3) - - @staticmethod - def add_argparse_args(parser): - parser.add_argument("--num_layers", type=int, default=2) - parser.add_argument("--hidden_channels", type=int, default=128) - parser.add_argument("--heads", type=int, default=8) - parser.add_argument("--groups", type=int, default=16) - parser.add_argument("--dropout", type=float, default=0.8) - parser.add_argument("--cached", type=int, default=0) - parser.add_argument("--jit", default=True) - return parser - -################################# -# Instantiate Functions # -################################# - - -def instantiate_datamodule(args): - datamodule = CoraDataset( - num_workers=args.num_workers, - batch_size=args.batch_size, - drop_last=args.drop_last, - pin_memory=args.pin_memory, - num_layers=args.num_layers, - ) - return datamodule - - -def instantiate_model(args, datamodule): - model = DNAConvNet( - num_layers=args.num_layers, - hidden_channels=args.hidden_channels, - heads=args.heads, - groups=args.groups, - dropout=args.dropout, - # provide dataset specific arguments - **datamodule.hyper_parameters, - ) - if args.jit: - model.jittable() - - # Attached datamodule function to model - model.gather_data_and_convert_to_namedtuple = datamodule.gather_data_and_convert_to_namedtuple - return model - - -def get_single_batch(datamodule): - for batch in datamodule.test_dataloader(): - return datamodule.gather_data_and_convert_to_namedtuple(batch, 0) - -####################### -# Trainer Run # -####################### - - -def run(args): - - nice_print("You are about to train a TorchScripted Pytorch Geometric Lightning model !") - nice_print(LIGHTNING_LOGO) - - datamodule: LightningDataModule = instantiate_datamodule(args) - model: LightningModule = instantiate_model(args, datamodule) - trainer = Trainer.from_argparse_args(args) - trainer.fit(model, datamodule) - trainer.test() - - batch = get_single_batch(datamodule) - model.to_torchscript(file_path="model_trace.pt", - method='script', - example_inputs=batch) - - nice_print("Congratulations !") - nice_print("You trained your first TorchScripted Pytorch Geometric Lightning model !", last=True) - - -if __name__ == "__main__": - if not _TORCH_GEOMETRIC_AVAILABLE: - print("Skip training. Pytorch Geometric isn't installed. Please, check README.md !") - - else: - parser = ArgumentParser(description="Pytorch Geometric Example") - parser = Trainer.add_argparse_args(parser) - parser = CoraDataset.add_argparse_args(parser) - parser = DNAConvNet.add_argparse_args(parser) - - cmd_line = '--max_epochs 1'.split(' ') - - run(parser.parse_args(cmd_line)) diff --git a/pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml b/pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml deleted file mode 100644 index 1e388ac590b34..0000000000000 --- a/pl_examples/pytorch_ecosystem/pytorch_geometric/pyproject.toml +++ /dev/null @@ -1,25 +0,0 @@ -[tool.poetry] -name = "lightning-geometric" -version = "0.1.0" -description = "TorchScripted Pytorch Geometric Examples with Pytorch Lightning" -authors = ["Thomas Chaton "] - -[tool.poetry.dependencies] -python = "3.7.8" -torch = "^1.6.0" -torch-cluster = "^1.5.7" -torch-sparse = "^0.6.7" -torch-scatter = "^2.0.5" -torch-geometric = "^1.6.1" -pytorch-lightning = "^ 1.0.5" -openmesh = "^1.1.4" -torch-spline-conv = "^1.2.0" -tqdm = "^4.50.0" -pytest = "^6.1.0" - -[tool.poetry.dev-dependencies] -black = {version = "^20.8b1", allow-prereleases = true} - -[build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" diff --git a/requirements/ecosystem.txt b/requirements/ecosystem.txt deleted file mode 100644 index 5a225d799ddbb..0000000000000 --- a/requirements/ecosystem.txt +++ /dev/null @@ -1,3 +0,0 @@ -# Geometry -torch-geometric>=1.6.1 -torch-sparse>=0.6.7 \ No newline at end of file From d11498a3af7b5d8f979baf2459a2257af4d6bef2 Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 11 Dec 2020 13:55:10 +0100 Subject: [PATCH 5/6] copy --- .../computer_vision_fine_tuning.py | 13 +++++++++++++ .../generative_adversarial_net.py | 13 +++++++++++++ pl_examples/domain_templates/imagenet.py | 13 +++++++++++++ .../domain_templates/reinforce_learn_Qnet.py | 13 +++++++++++++ .../domain_templates/semantic_segmentation.py | 14 ++++++++++++++ pl_examples/domain_templates/unet.py | 14 ++++++++++++++ pl_examples/pytorch_ecosystem/__init__.py | 16 +++++++++++++--- pl_examples/test_examples.py | 14 ++++++++++++++ 8 files changed, 107 insertions(+), 3 deletions(-) diff --git a/pl_examples/domain_templates/computer_vision_fine_tuning.py b/pl_examples/domain_templates/computer_vision_fine_tuning.py index 21f6644b09a5b..90bf3167ccb02 100644 --- a/pl_examples/domain_templates/computer_vision_fine_tuning.py +++ b/pl_examples/domain_templates/computer_vision_fine_tuning.py @@ -1,3 +1,16 @@ +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """Computer vision example on Transfer Learning. This computer vision example illustrates how one could fine-tune a pre-trained diff --git a/pl_examples/domain_templates/generative_adversarial_net.py b/pl_examples/domain_templates/generative_adversarial_net.py index 088b625e31d01..f6bbb45433ab1 100644 --- a/pl_examples/domain_templates/generative_adversarial_net.py +++ b/pl_examples/domain_templates/generative_adversarial_net.py @@ -1,3 +1,16 @@ +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ To run this template just do: python generative_adversarial_net.py diff --git a/pl_examples/domain_templates/imagenet.py b/pl_examples/domain_templates/imagenet.py index b7116547d389b..96369c7ca45fb 100644 --- a/pl_examples/domain_templates/imagenet.py +++ b/pl_examples/domain_templates/imagenet.py @@ -1,3 +1,16 @@ +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ This example is largely adapted from https://github.com/pytorch/examples/blob/master/imagenet/main.py diff --git a/pl_examples/domain_templates/reinforce_learn_Qnet.py b/pl_examples/domain_templates/reinforce_learn_Qnet.py index 4b01f83e36639..8587265e13af8 100644 --- a/pl_examples/domain_templates/reinforce_learn_Qnet.py +++ b/pl_examples/domain_templates/reinforce_learn_Qnet.py @@ -1,3 +1,16 @@ +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Deep Reinforcement Learning: Deep Q-network (DQN) diff --git a/pl_examples/domain_templates/semantic_segmentation.py b/pl_examples/domain_templates/semantic_segmentation.py index 4ca1ebc2aec76..7106df284a52c 100644 --- a/pl_examples/domain_templates/semantic_segmentation.py +++ b/pl_examples/domain_templates/semantic_segmentation.py @@ -1,3 +1,17 @@ +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import os import random from argparse import ArgumentParser, Namespace diff --git a/pl_examples/domain_templates/unet.py b/pl_examples/domain_templates/unet.py index 6117447e5ed33..20b4bdb2a4bf9 100644 --- a/pl_examples/domain_templates/unet.py +++ b/pl_examples/domain_templates/unet.py @@ -1,3 +1,17 @@ +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import torch import torch.nn as nn import torch.nn.functional as F diff --git a/pl_examples/pytorch_ecosystem/__init__.py b/pl_examples/pytorch_ecosystem/__init__.py index 8840b376e0f4a..878f71cd8d624 100644 --- a/pl_examples/pytorch_ecosystem/__init__.py +++ b/pl_examples/pytorch_ecosystem/__init__.py @@ -1,6 +1,16 @@ -from pytorch_lightning.utilities import _module_available - -_TORCH_GEOMETRIC_AVAILABLE = _module_available("torch_geometric") +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. def nice_print(msg, last=False): print() diff --git a/pl_examples/test_examples.py b/pl_examples/test_examples.py index da21384190163..91145c5bd0d0b 100644 --- a/pl_examples/test_examples.py +++ b/pl_examples/test_examples.py @@ -1,3 +1,17 @@ +# Copyright The PyTorch Lightning team. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import importlib import platform from unittest import mock From d77d102af1da7e532f7355f7f696394a5a5ff2d7 Mon Sep 17 00:00:00 2001 From: Jirka Borovec Date: Fri, 11 Dec 2020 14:00:58 +0100 Subject: [PATCH 6/6] logo --- pl_examples/__init__.py | 37 +++++++++++++++++++ pl_examples/basic_examples/autoencoder.py | 3 +- .../backbone_image_classifier.py | 3 +- .../basic_examples/conv_sequential_example.py | 2 + .../basic_examples/dali_image_classifier.py | 3 +- .../basic_examples/simple_image_classifier.py | 2 + pl_examples/bug_report_model.py | 3 ++ .../computer_vision_fine_tuning.py | 2 + .../generative_adversarial_net.py | 2 + pl_examples/domain_templates/imagenet.py | 2 + .../domain_templates/reinforce_learn_Qnet.py | 2 + .../domain_templates/semantic_segmentation.py | 2 + pl_examples/pytorch_ecosystem/__init__.py | 32 ---------------- 13 files changed, 60 insertions(+), 35 deletions(-) diff --git a/pl_examples/__init__.py b/pl_examples/__init__.py index d7cec9fc1bc3a..147fc330ecd59 100644 --- a/pl_examples/__init__.py +++ b/pl_examples/__init__.py @@ -8,3 +8,40 @@ TORCHVISION_AVAILABLE = _module_available("torchvision") DALI_AVAILABLE = _module_available("nvidia.dali") + + +LIGHTNING_LOGO = """ + #### + ########### + #################### + ############################ + ##################################### +############################################## +######################### ################### +####################### ################### +#################### #################### +################## ##################### +################ ###################### +##################### ################# +###################### ################### +##################### ##################### +#################### ####################### +################### ######################### +############################################## + ##################################### + ############################ + #################### + ########## + #### +""" + + +def nice_print(msg, last=False): + print() + print("\033[0;35m" + msg + "\033[0m") + if last: + print() + + +def cli_lightning_logo(): + nice_print(LIGHTNING_LOGO) diff --git a/pl_examples/basic_examples/autoencoder.py b/pl_examples/basic_examples/autoencoder.py index 58a117a648458..72bfcb17c0872 100644 --- a/pl_examples/basic_examples/autoencoder.py +++ b/pl_examples/basic_examples/autoencoder.py @@ -21,7 +21,7 @@ from torch.utils.data import random_split import pytorch_lightning as pl -from pl_examples import TORCHVISION_AVAILABLE +from pl_examples import TORCHVISION_AVAILABLE, cli_lightning_logo if TORCHVISION_AVAILABLE: from torchvision.datasets.mnist import MNIST @@ -105,4 +105,5 @@ def cli_main(): if __name__ == '__main__': + cli_lightning_logo() cli_main() diff --git a/pl_examples/basic_examples/backbone_image_classifier.py b/pl_examples/basic_examples/backbone_image_classifier.py index 91a8481de7fd9..b0ca2efd5d76b 100644 --- a/pl_examples/basic_examples/backbone_image_classifier.py +++ b/pl_examples/basic_examples/backbone_image_classifier.py @@ -19,7 +19,7 @@ from torch.utils.data import DataLoader, random_split import pytorch_lightning as pl -from pl_examples import DATASETS_PATH, TORCHVISION_AVAILABLE +from pl_examples import DATASETS_PATH, TORCHVISION_AVAILABLE, cli_lightning_logo if TORCHVISION_AVAILABLE: from torchvision.datasets.mnist import MNIST @@ -125,4 +125,5 @@ def cli_main(): if __name__ == '__main__': + cli_lightning_logo() cli_main() diff --git a/pl_examples/basic_examples/conv_sequential_example.py b/pl_examples/basic_examples/conv_sequential_example.py index 36c8c2c1f69b3..06fddd689260f 100644 --- a/pl_examples/basic_examples/conv_sequential_example.py +++ b/pl_examples/basic_examples/conv_sequential_example.py @@ -29,6 +29,7 @@ import torchvision import pytorch_lightning as pl +from pl_examples import cli_lightning_logo from pytorch_lightning import Trainer from pytorch_lightning.metrics.functional import accuracy from pytorch_lightning.plugins.ddp_sequential_plugin import DDPSequentialPlugin @@ -190,6 +191,7 @@ def instantiate_datamodule(args): if __name__ == "__main__": + cli_lightning_logo() parser = ArgumentParser(description="Pipe Example") parser.add_argument("--use_ddp_sequential", action="store_true") parser = Trainer.add_argparse_args(parser) diff --git a/pl_examples/basic_examples/dali_image_classifier.py b/pl_examples/basic_examples/dali_image_classifier.py index 0a39f1cb9a9ae..9f3ba5e08b37e 100644 --- a/pl_examples/basic_examples/dali_image_classifier.py +++ b/pl_examples/basic_examples/dali_image_classifier.py @@ -22,7 +22,7 @@ from torch.utils.data import random_split import pytorch_lightning as pl -from pl_examples import TORCHVISION_AVAILABLE, DALI_AVAILABLE +from pl_examples import TORCHVISION_AVAILABLE, DALI_AVAILABLE, cli_lightning_logo if TORCHVISION_AVAILABLE: from torchvision.datasets.mnist import MNIST @@ -204,4 +204,5 @@ def cli_main(): if __name__ == "__main__": + cli_lightning_logo() cli_main() diff --git a/pl_examples/basic_examples/simple_image_classifier.py b/pl_examples/basic_examples/simple_image_classifier.py index a341728554d31..6b8457e0e4897 100644 --- a/pl_examples/basic_examples/simple_image_classifier.py +++ b/pl_examples/basic_examples/simple_image_classifier.py @@ -19,6 +19,7 @@ from torch.nn import functional as F import pytorch_lightning as pl +from pl_examples import cli_lightning_logo from pl_examples.basic_examples.mnist_datamodule import MNISTDataModule @@ -103,4 +104,5 @@ def cli_main(): if __name__ == '__main__': + cli_lightning_logo() cli_main() diff --git a/pl_examples/bug_report_model.py b/pl_examples/bug_report_model.py index dbea2013d1110..e2201db12f894 100644 --- a/pl_examples/bug_report_model.py +++ b/pl_examples/bug_report_model.py @@ -22,6 +22,8 @@ import os import torch from torch.utils.data import Dataset + +from pl_examples import cli_lightning_logo from pytorch_lightning import Trainer, LightningModule @@ -137,4 +139,5 @@ def on_train_epoch_start(self) -> None: if __name__ == '__main__': + cli_lightning_logo() run_test() diff --git a/pl_examples/domain_templates/computer_vision_fine_tuning.py b/pl_examples/domain_templates/computer_vision_fine_tuning.py index 90bf3167ccb02..1c60e3aa6d23f 100644 --- a/pl_examples/domain_templates/computer_vision_fine_tuning.py +++ b/pl_examples/domain_templates/computer_vision_fine_tuning.py @@ -53,6 +53,7 @@ from torchvision.datasets.utils import download_and_extract_archive import pytorch_lightning as pl +from pl_examples import cli_lightning_logo from pytorch_lightning import _logger as log BN_TYPES = (torch.nn.BatchNorm1d, torch.nn.BatchNorm2d, torch.nn.BatchNorm3d) @@ -464,4 +465,5 @@ def get_args() -> argparse.Namespace: if __name__ == '__main__': + cli_lightning_logo() main(get_args()) diff --git a/pl_examples/domain_templates/generative_adversarial_net.py b/pl_examples/domain_templates/generative_adversarial_net.py index f6bbb45433ab1..210a80721d9a9 100644 --- a/pl_examples/domain_templates/generative_adversarial_net.py +++ b/pl_examples/domain_templates/generative_adversarial_net.py @@ -31,6 +31,7 @@ from torch.utils.data import DataLoader from torchvision.datasets import MNIST +from pl_examples import cli_lightning_logo from pytorch_lightning.core import LightningModule, LightningDataModule from pytorch_lightning.trainer import Trainer @@ -224,6 +225,7 @@ def main(args: Namespace) -> None: if __name__ == '__main__': + cli_lightning_logo() parser = ArgumentParser() # Add program level args, if any. diff --git a/pl_examples/domain_templates/imagenet.py b/pl_examples/domain_templates/imagenet.py index 96369c7ca45fb..b1eea307478f9 100644 --- a/pl_examples/domain_templates/imagenet.py +++ b/pl_examples/domain_templates/imagenet.py @@ -45,6 +45,7 @@ import torchvision.transforms as transforms import pytorch_lightning as pl +from pl_examples import cli_lightning_logo from pytorch_lightning.core import LightningModule @@ -259,4 +260,5 @@ def run_cli(): if __name__ == '__main__': + cli_lightning_logo() run_cli() diff --git a/pl_examples/domain_templates/reinforce_learn_Qnet.py b/pl_examples/domain_templates/reinforce_learn_Qnet.py index 8587265e13af8..a8b9db095f377 100644 --- a/pl_examples/domain_templates/reinforce_learn_Qnet.py +++ b/pl_examples/domain_templates/reinforce_learn_Qnet.py @@ -46,6 +46,7 @@ from torch.utils.data.dataset import IterableDataset import pytorch_lightning as pl +from pl_examples import cli_lightning_logo class DQN(nn.Module): @@ -362,6 +363,7 @@ def main(args) -> None: if __name__ == '__main__': + cli_lightning_logo() torch.manual_seed(0) np.random.seed(0) diff --git a/pl_examples/domain_templates/semantic_segmentation.py b/pl_examples/domain_templates/semantic_segmentation.py index 7106df284a52c..08bdc1140916a 100644 --- a/pl_examples/domain_templates/semantic_segmentation.py +++ b/pl_examples/domain_templates/semantic_segmentation.py @@ -24,6 +24,7 @@ from torch.utils.data import DataLoader, Dataset import pytorch_lightning as pl +from pl_examples import cli_lightning_logo from pl_examples.domain_templates.unet import UNet from pytorch_lightning.loggers import WandbLogger @@ -239,6 +240,7 @@ def main(hparams: Namespace): if __name__ == '__main__': + cli_lightning_logo() parser = ArgumentParser() parser.add_argument("--data_path", type=str, help="path where dataset is stored") parser.add_argument("--gpus", type=int, default=-1, help="number of available GPUs") diff --git a/pl_examples/pytorch_ecosystem/__init__.py b/pl_examples/pytorch_ecosystem/__init__.py index 878f71cd8d624..d7aa17d7f8468 100644 --- a/pl_examples/pytorch_ecosystem/__init__.py +++ b/pl_examples/pytorch_ecosystem/__init__.py @@ -11,35 +11,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - -def nice_print(msg, last=False): - print() - print("\033[0;35m" + msg + "\033[0m") - if last: - print() - - -LIGHTNING_LOGO = """ - #### - ########### - #################### - ############################ - ##################################### -############################################## -######################### ################### -####################### ################### -#################### #################### -################## ##################### -################ ###################### -##################### ################# -###################### ################### -##################### ##################### -#################### ####################### -################### ######################### -############################################## - ##################################### - ############################ - #################### - ########## - #### -"""