├── .dockerignore ├── .editorconfig ├── .github ├── .stale.yml ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ ├── feature_request.md │ └── question.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── build.yml │ ├── greetings.yml │ ├── release-drafter.yml │ └── upload-release.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── SECURITY.md ├── cookiecutter-config-file.yml ├── docker ├── Dockerfile └── README.md ├── examples ├── train.ipynb └── train_fp16.ipynb ├── layer_to_layer_pytorch ├── __init__.py ├── __main__.py ├── helpers.py ├── l2l.py ├── py.typed └── types.py ├── poetry.lock ├── pyproject.toml ├── requirements.txt ├── setup.cfg └── tests └── test_verison └── test_hello.py /.dockerignore: -------------------------------------------------------------------------------- 1 | # Git 2 | .git 3 | .gitignore 4 | .github 5 | 6 | # Docker 7 | .dockerignore 8 | 9 | # IDE 10 | .idea 11 | .vscode 12 | 13 | # Byte-compiled / optimized / DLL files 14 | __pycache__/ 15 | **/__pycache__/ 16 | *.pyc 17 | *.pyo 18 | *.pyd 19 | .Python 20 | *.py[cod] 21 | *$py.class 22 | .pytest_cache/ 23 | ..mypy_cache/ 24 | 25 | # poetry 26 | .venv 27 | 28 | # C extensions 29 | *.so 30 | 31 | # Virtual environment 32 | .venv 33 | venv 34 | 35 | .DS_Store 36 | .AppleDouble 37 | .LSOverride 38 | ._* 39 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Check http://editorconfig.org for more information 2 | # This is the main config file for this project: 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | indent_style = space 10 | indent_size = 2 11 | trim_trailing_whitespace = true 12 | 13 | [*.{py, pyi}] 14 | indent_style = space 15 | indent_size = 4 16 | 17 | [Makefile] 18 | indent_style = tab 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | 23 | [*.{diff,patch}] 24 | trim_trailing_whitespace = false 25 | -------------------------------------------------------------------------------- /.github/.stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: tezikov # https://www.patreon.com/tezikov 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug report 3 | about: If something isn't working 🔧 4 | title: '' 5 | labels: bug 6 | assignees: 7 | --- 8 | 9 | ## 🐛 Bug Report 10 | 11 | 12 | 13 | ## 🔬 How To Reproduce 14 | 15 | Steps to reproduce the behavior: 16 | 17 | 1. ... 18 | 19 | ### Code sample 20 | 21 | 22 | 23 | ### Environment 24 | 25 | * OS: [e.g. Linux / Windows / macOS] 26 | * Python version, get it with: 27 | 28 | ```bash 29 | python --version 30 | ``` 31 | 32 | ### Screenshots 33 | 34 | 35 | 36 | ## 📈 Expected behavior 37 | 38 | 39 | 40 | ## 📎 Additional context 41 | 42 | 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # Configuration: https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository 2 | 3 | blank_issues_enabled: false 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature request 3 | about: Suggest an idea for this project 🏖 4 | title: '' 5 | labels: enhancement 6 | assignees: 7 | --- 8 | 9 | ## 🚀 Feature Request 10 | 11 | 12 | 13 | ## 🔈 Motivation 14 | 15 | 16 | 17 | ## 🛰 Alternatives 18 | 19 | 20 | 21 | ## 📎 Additional context 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ❓ Question 3 | about: Ask a question about this project 🎓 4 | title: '' 5 | labels: question 6 | assignees: 7 | --- 8 | 9 | ## Checklist 10 | 11 | 12 | 13 | - [ ] I've searched the project's [`issues`](https://github.com/TezRomacH/layer-to-layer-pytorch/issues?q=is%3Aissue). 14 | 15 | ## ❓ Question 16 | 17 | 18 | 19 | How can I [...]? 20 | 21 | Is it possible to [...]? 22 | 23 | ## 📎 Additional context 24 | 25 | 26 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | 4 | 5 | ## Related Issue 6 | 7 | 8 | 9 | ## Type of Change 10 | 11 | 12 | 13 | - [ ] 📚 Examples / docs / tutorials / dependencies update 14 | - [ ] 🔧 Bug fix (non-breaking change which fixes an issue) 15 | - [ ] 🥂 Improvement (non-breaking change which improves an existing feature) 16 | - [ ] 🚀 New feature (non-breaking change which adds functionality) 17 | - [ ] 💥 Breaking change (fix or feature that would cause existing functionality to change) 18 | - [ ] 🔐 Security fix 19 | 20 | ## Checklist 21 | 22 | 23 | 24 | - [ ] I've read the [`CODE_OF_CONDUCT.md`](https://github.com/TezRomacH/layer-to-layer-pytorch/blob/master/CODE_OF_CONDUCT.md) document. 25 | - [ ] I've read the [`CONTRIBUTING.md`](https://github.com/TezRomacH/layer-to-layer-pytorch/blob/master/CONTRIBUTING.md) guide. 26 | - [ ] I've updated the code style using `make codestyle`. 27 | - [ ] I've written tests for all new methods and classes that I created. 28 | - [ ] I've written the docstring in Google format for all the methods and classes that I used. 29 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Configuration: https://dependabot.com/docs/config-file/ 2 | # Docs: https://docs.github.com/en/github/administering-a-repository/keeping-your-dependencies-updated-automatically 3 | 4 | version: 2 5 | 6 | updates: 7 | - package-ecosystem: "pip" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | allow: 12 | - dependency-type: "all" 13 | commit-message: 14 | prefix: ":arrow_up:" 15 | - package-ecosystem: "github-actions" 16 | directory: "/" 17 | schedule: 18 | interval: "daily" 19 | allow: 20 | - dependency-type: "all" 21 | commit-message: 22 | prefix: ":arrow_up:" 23 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | # Release drafter configuration https://github.com/release-drafter/release-drafter#configuration 2 | # Emojis were chosen to match the https://gitmoji.carloscuesta.me/ 3 | 4 | name-template: "v$NEXT_PATCH_VERSION" 5 | tag-template: "v$NEXT_PATCH_VERSION" 6 | 7 | categories: 8 | - title: ":rocket: Features" 9 | labels: [enhancement, feature] 10 | - title: ":wrench: Fixes & Refactoring" 11 | labels: [bug, refactoring, bugfix, fix] 12 | - title: ":package: Build System & CI/CD" 13 | labels: [build, ci, testing] 14 | - title: ":boom: Breaking Changes" 15 | labels: [breaking] 16 | - title: ":pencil: Documentation" 17 | labels: [documentation] 18 | - title: ":arrow_up: Dependencies updates" 19 | labels: [dependencies] 20 | 21 | template: | 22 | ## What’s Changed 23 | 24 | $CHANGES 25 | 26 | ## :busts_in_silhouette: List of contributors 27 | 28 | $CONTRIBUTORS 29 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | python-version: ["3.7", "3.8"] 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Set up Python ${{ matrix.python-version }} 15 | uses: actions/setup-python@v2.1.4 16 | with: 17 | python-version: ${{ matrix.python-version }} 18 | 19 | - name: Install poetry 20 | run: make download-poetry 21 | 22 | - name: Set up cache 23 | uses: actions/cache@v2.1.3 24 | with: 25 | path: .venv 26 | key: venv-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('poetry.lock') }} 27 | 28 | - name: Install dependencies 29 | run: | 30 | source "$HOME/.poetry/env" 31 | poetry config virtualenvs.in-project true 32 | poetry install 33 | 34 | - name: Run safety checks 35 | run: | 36 | source "$HOME/.poetry/env" 37 | STRICT=1 make check-safety 38 | 39 | - name: Run style checks 40 | run: | 41 | source "$HOME/.poetry/env" 42 | STRICT=1 make check-style 43 | 44 | - name: Run tests 45 | run: | 46 | source "$HOME/.poetry/env" 47 | make test 48 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: [pull_request, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/first-interaction@v1 10 | with: 11 | repo-token: ${{ secrets.GITHUB_TOKEN }} 12 | pr-message: 'Hello @${{ github.actor }}, thank you for submitting a PR! We will respond as soon as possible.' 13 | issue-message: | 14 | Hello @${{ github.actor }}, thank you for your interest in our work! 15 | 16 | If this is a bug report, please provide screenshots and **minimum viable code to reproduce your issue**, otherwise we can not help you. 17 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - master 8 | 9 | jobs: 10 | update_release_draft: 11 | runs-on: ubuntu-latest 12 | steps: 13 | # Drafts your next Release notes as Pull Requests are merged into "master" 14 | - uses: release-drafter/release-drafter@v5.14.0 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/upload-release.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Upload a new release to PyPI 3 | 4 | on: 5 | release: 6 | types: [created] 7 | 8 | jobs: 9 | upload: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Set up Python 15 | uses: actions/setup-python@v2.1.4 16 | with: 17 | python-version: "3.7" 18 | 19 | - name: Install poetry 20 | run: make download-poetry 21 | 22 | - name: Install dependencies 23 | run: | 24 | python -m pip install --upgrade pip 25 | source "$HOME/.poetry/env" 26 | poetry config virtualenvs.in-project true 27 | poetry install 28 | 29 | - name: Build and publish 30 | env: 31 | PYPI_USERNAME: ${{ secrets.PYPI_USERNAME }} 32 | PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 33 | run: | 34 | source "$HOME/.poetry/env" 35 | poetry publish --build --username $PYPI_USERNAME --password $PYPI_PASSWORD 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # local 2 | pythonenv*/ 3 | 4 | # Created by https://www.gitignore.io/api/osx,python,pycharm,windows,visualstudio,visualstudiocode 5 | # Edit at https://www.gitignore.io/?templates=osx,python,pycharm,windows,visualstudio,visualstudiocode 6 | 7 | ### OSX ### 8 | # General 9 | .DS_Store 10 | .AppleDouble 11 | .LSOverride 12 | 13 | # Icon must end with two \r 14 | Icon 15 | 16 | # Thumbnails 17 | ._* 18 | 19 | # Files that might appear in the root of a volume 20 | .DocumentRevisions-V100 21 | .fseventsd 22 | .Spotlight-V100 23 | .TemporaryItems 24 | .Trashes 25 | .VolumeIcon.icns 26 | .com.apple.timemachine.donotpresent 27 | 28 | # Directories potentially created on remote AFP share 29 | .AppleDB 30 | .AppleDesktop 31 | Network Trash Folder 32 | Temporary Items 33 | .apdisk 34 | 35 | ### PyCharm ### 36 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 37 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 38 | 39 | # User-specific stuff 40 | .idea/**/workspace.xml 41 | .idea/**/tasks.xml 42 | .idea/**/usage.statistics.xml 43 | .idea/**/dictionaries 44 | .idea/**/shelf 45 | 46 | # Generated files 47 | .idea/**/contentModel.xml 48 | 49 | # Sensitive or high-churn files 50 | .idea/**/dataSources/ 51 | .idea/**/dataSources.ids 52 | .idea/**/dataSources.local.xml 53 | .idea/**/sqlDataSources.xml 54 | .idea/**/dynamic.xml 55 | .idea/**/uiDesigner.xml 56 | .idea/**/dbnavigator.xml 57 | 58 | # Gradle 59 | .idea/**/gradle.xml 60 | .idea/**/libraries 61 | 62 | # Gradle and Maven with auto-import 63 | # When using Gradle or Maven with auto-import, you should exclude module files, 64 | # since they will be recreated, and may cause churn. Uncomment if using 65 | # auto-import. 66 | # .idea/modules.xml 67 | # .idea/*.iml 68 | # .idea/modules 69 | # *.iml 70 | # *.ipr 71 | 72 | # CMake 73 | cmake-build-*/ 74 | 75 | # Mongo Explorer plugin 76 | .idea/**/mongoSettings.xml 77 | 78 | # File-based project format 79 | *.iws 80 | 81 | # IntelliJ 82 | out/ 83 | 84 | # mpeltonen/sbt-idea plugin 85 | .idea_modules/ 86 | 87 | # JIRA plugin 88 | atlassian-ide-plugin.xml 89 | 90 | # Cursive Clojure plugin 91 | .idea/replstate.xml 92 | 93 | # Crashlytics plugin (for Android Studio and IntelliJ) 94 | com_crashlytics_export_strings.xml 95 | crashlytics.properties 96 | crashlytics-build.properties 97 | fabric.properties 98 | 99 | # Editor-based Rest Client 100 | .idea/httpRequests 101 | 102 | # Android studio 3.1+ serialized cache file 103 | .idea/caches/build_file_checksums.ser 104 | 105 | ### PyCharm Patch ### 106 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 107 | 108 | # *.iml 109 | # modules.xml 110 | # .idea/misc.xml 111 | # *.ipr 112 | 113 | # Sonarlint plugin 114 | .idea/**/sonarlint/ 115 | 116 | # SonarQube Plugin 117 | .idea/**/sonarIssues.xml 118 | 119 | # Markdown Navigator plugin 120 | .idea/**/markdown-navigator.xml 121 | .idea/**/markdown-navigator/ 122 | 123 | ### Python ### 124 | # Byte-compiled / optimized / DLL files 125 | __pycache__/ 126 | *.py[cod] 127 | *$py.class 128 | 129 | # C extensions 130 | *.so 131 | 132 | # Distribution / packaging 133 | .Python 134 | build/ 135 | develop-eggs/ 136 | dist/ 137 | downloads/ 138 | eggs/ 139 | .eggs/ 140 | lib/ 141 | lib64/ 142 | parts/ 143 | sdist/ 144 | var/ 145 | wheels/ 146 | pip-wheel-metadata/ 147 | share/python-wheels/ 148 | *.egg-info/ 149 | .installed.cfg 150 | *.egg 151 | MANIFEST 152 | 153 | # PyInstaller 154 | # Usually these files are written by a python script from a template 155 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 156 | *.manifest 157 | *.spec 158 | 159 | # Installer logs 160 | pip-log.txt 161 | pip-delete-this-directory.txt 162 | 163 | # Unit test / coverage reports 164 | htmlcov/ 165 | .tox/ 166 | .nox/ 167 | .coverage 168 | .coverage.* 169 | .cache 170 | nosetests.xml 171 | coverage.xml 172 | *.cover 173 | .hypothesis/ 174 | .pytest_cache/ 175 | 176 | # Translations 177 | *.mo 178 | *.pot 179 | 180 | # Scrapy stuff: 181 | .scrapy 182 | 183 | # Sphinx documentation 184 | docs/_build/ 185 | 186 | # PyBuilder 187 | target/ 188 | 189 | # pyenv 190 | .python-version 191 | 192 | # poetry 193 | .venv 194 | 195 | # pipenv 196 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 197 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 198 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 199 | # install all needed dependencies. 200 | #Pipfile.lock 201 | 202 | # celery beat schedule file 203 | celerybeat-schedule 204 | 205 | # SageMath parsed files 206 | *.sage.py 207 | 208 | # Spyder project settings 209 | .spyderproject 210 | .spyproject 211 | 212 | # Rope project settings 213 | .ropeproject 214 | 215 | # Mr Developer 216 | .mr.developer.cfg 217 | .project 218 | .pydevproject 219 | 220 | # mkdocs documentation 221 | /site 222 | 223 | # mypy 224 | .mypy_cache/ 225 | .dmypy.json 226 | dmypy.json 227 | 228 | # Pyre type checker 229 | .pyre/ 230 | 231 | # Plugins 232 | .secrets.baseline 233 | 234 | ### VisualStudioCode ### 235 | .vscode/* 236 | !.vscode/tasks.json 237 | !.vscode/launch.json 238 | !.vscode/extensions.json 239 | 240 | ### VisualStudioCode Patch ### 241 | # Ignore all local history of files 242 | .history 243 | 244 | ### Windows ### 245 | # Windows thumbnail cache files 246 | Thumbs.db 247 | Thumbs.db:encryptable 248 | ehthumbs.db 249 | ehthumbs_vista.db 250 | 251 | # Dump file 252 | *.stackdump 253 | 254 | # Folder config file 255 | [Dd]esktop.ini 256 | 257 | # Recycle Bin used on file shares 258 | $RECYCLE.BIN/ 259 | 260 | # Windows Installer files 261 | *.cab 262 | *.msi 263 | *.msix 264 | *.msm 265 | *.msp 266 | 267 | # Windows shortcuts 268 | *.lnk 269 | 270 | ### VisualStudio ### 271 | ## Ignore Visual Studio temporary files, build results, and 272 | ## files generated by popular Visual Studio add-ons. 273 | ## 274 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 275 | 276 | # User-specific files 277 | *.rsuser 278 | *.suo 279 | *.user 280 | *.userosscache 281 | *.sln.docstates 282 | 283 | # User-specific files (MonoDevelop/Xamarin Studio) 284 | *.userprefs 285 | 286 | # Mono auto generated files 287 | mono_crash.* 288 | 289 | # Build results 290 | [Dd]ebug/ 291 | [Dd]ebugPublic/ 292 | [Rr]elease/ 293 | [Rr]eleases/ 294 | x64/ 295 | x86/ 296 | [Aa][Rr][Mm]/ 297 | [Aa][Rr][Mm]64/ 298 | bld/ 299 | [Bb]in/ 300 | [Oo]bj/ 301 | [Ll]og/ 302 | 303 | # Visual Studio 2015/2017 cache/options directory 304 | .vs/ 305 | # Uncomment if you have tasks that create the project's static files in wwwroot 306 | #wwwroot/ 307 | 308 | # Visual Studio 2017 auto generated files 309 | Generated\ Files/ 310 | 311 | # MSTest test Results 312 | [Tt]est[Rr]esult*/ 313 | [Bb]uild[Ll]og.* 314 | 315 | # NUnit 316 | *.VisualState.xml 317 | TestResult.xml 318 | nunit-*.xml 319 | 320 | # Build Results of an ATL Project 321 | [Dd]ebugPS/ 322 | [Rr]eleasePS/ 323 | dlldata.c 324 | 325 | # Benchmark Results 326 | BenchmarkDotNet.Artifacts/ 327 | 328 | # .NET Core 329 | project.lock.json 330 | project.fragment.lock.json 331 | artifacts/ 332 | 333 | # StyleCop 334 | StyleCopReport.xml 335 | 336 | # Files built by Visual Studio 337 | *_i.c 338 | *_p.c 339 | *_h.h 340 | *.ilk 341 | *.obj 342 | *.iobj 343 | *.pch 344 | *.pdb 345 | *.ipdb 346 | *.pgc 347 | *.pgd 348 | *.rsp 349 | *.sbr 350 | *.tlb 351 | *.tli 352 | *.tlh 353 | *.tmp 354 | *.tmp_proj 355 | *_wpftmp.csproj 356 | *.log 357 | *.vspscc 358 | *.vssscc 359 | .builds 360 | *.pidb 361 | *.svclog 362 | *.scc 363 | 364 | # Chutzpah Test files 365 | _Chutzpah* 366 | 367 | # Visual C++ cache files 368 | ipch/ 369 | *.aps 370 | *.ncb 371 | *.opendb 372 | *.opensdf 373 | *.sdf 374 | *.cachefile 375 | *.VC.db 376 | *.VC.VC.opendb 377 | 378 | # Visual Studio profiler 379 | *.psess 380 | *.vsp 381 | *.vspx 382 | *.sap 383 | 384 | # Visual Studio Trace Files 385 | *.e2e 386 | 387 | # TFS 2012 Local Workspace 388 | $tf/ 389 | 390 | # Guidance Automation Toolkit 391 | *.gpState 392 | 393 | # ReSharper is a .NET coding add-in 394 | _ReSharper*/ 395 | *.[Rr]e[Ss]harper 396 | *.DotSettings.user 397 | 398 | # JustCode is a .NET coding add-in 399 | .JustCode 400 | 401 | # TeamCity is a build add-in 402 | _TeamCity* 403 | 404 | # DotCover is a Code Coverage Tool 405 | *.dotCover 406 | 407 | # AxoCover is a Code Coverage Tool 408 | .axoCover/* 409 | !.axoCover/settings.json 410 | 411 | # Visual Studio code coverage results 412 | *.coverage 413 | *.coveragexml 414 | 415 | # NCrunch 416 | _NCrunch_* 417 | .*crunch*.local.xml 418 | nCrunchTemp_* 419 | 420 | # MightyMoose 421 | *.mm.* 422 | AutoTest.Net/ 423 | 424 | # Web workbench (sass) 425 | .sass-cache/ 426 | 427 | # Installshield output folder 428 | [Ee]xpress/ 429 | 430 | # DocProject is a documentation generator add-in 431 | DocProject/buildhelp/ 432 | DocProject/Help/*.HxT 433 | DocProject/Help/*.HxC 434 | DocProject/Help/*.hhc 435 | DocProject/Help/*.hhk 436 | DocProject/Help/*.hhp 437 | DocProject/Help/Html2 438 | DocProject/Help/html 439 | 440 | # Click-Once directory 441 | publish/ 442 | 443 | # Publish Web Output 444 | *.[Pp]ublish.xml 445 | *.azurePubxml 446 | # Note: Comment the next line if you want to checkin your web deploy settings, 447 | # but database connection strings (with potential passwords) will be unencrypted 448 | *.pubxml 449 | *.publishproj 450 | 451 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 452 | # checkin your Azure Web App publish settings, but sensitive information contained 453 | # in these scripts will be unencrypted 454 | PublishScripts/ 455 | 456 | # NuGet Packages 457 | *.nupkg 458 | # NuGet Symbol Packages 459 | *.snupkg 460 | # The packages folder can be ignored because of Package Restore 461 | **/[Pp]ackages/* 462 | # except build/, which is used as an MSBuild target. 463 | !**/[Pp]ackages/build/ 464 | # Uncomment if necessary however generally it will be regenerated when needed 465 | #!**/[Pp]ackages/repositories.config 466 | # NuGet v3's project.json files produces more ignorable files 467 | *.nuget.props 468 | *.nuget.targets 469 | 470 | # Microsoft Azure Build Output 471 | csx/ 472 | *.build.csdef 473 | 474 | # Microsoft Azure Emulator 475 | ecf/ 476 | rcf/ 477 | 478 | # Windows Store app package directories and files 479 | AppPackages/ 480 | BundleArtifacts/ 481 | Package.StoreAssociation.xml 482 | _pkginfo.txt 483 | *.appx 484 | *.appxbundle 485 | *.appxupload 486 | 487 | # Visual Studio cache files 488 | # files ending in .cache can be ignored 489 | *.[Cc]ache 490 | # but keep track of directories ending in .cache 491 | !?*.[Cc]ache/ 492 | 493 | # Others 494 | ClientBin/ 495 | ~$* 496 | *~ 497 | *.dbmdl 498 | *.dbproj.schemaview 499 | *.jfm 500 | *.pfx 501 | *.publishsettings 502 | orleans.codegen.cs 503 | 504 | # Including strong name files can present a security risk 505 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 506 | #*.snk 507 | 508 | # Since there are multiple workflows, uncomment next line to ignore bower_components 509 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 510 | #bower_components/ 511 | 512 | # RIA/Silverlight projects 513 | Generated_Code/ 514 | 515 | # Backup & report files from converting an old project file 516 | # to a newer Visual Studio version. Backup files are not needed, 517 | # because we have git ;-) 518 | _UpgradeReport_Files/ 519 | Backup*/ 520 | UpgradeLog*.XML 521 | UpgradeLog*.htm 522 | ServiceFabricBackup/ 523 | *.rptproj.bak 524 | 525 | # SQL Server files 526 | *.mdf 527 | *.ldf 528 | *.ndf 529 | 530 | # Business Intelligence projects 531 | *.rdl.data 532 | *.bim.layout 533 | *.bim_*.settings 534 | *.rptproj.rsuser 535 | *- [Bb]ackup.rdl 536 | *- [Bb]ackup ([0-9]).rdl 537 | *- [Bb]ackup ([0-9][0-9]).rdl 538 | 539 | # Microsoft Fakes 540 | FakesAssemblies/ 541 | 542 | # GhostDoc plugin setting file 543 | *.GhostDoc.xml 544 | 545 | # Node.js Tools for Visual Studio 546 | .ntvs_analysis.dat 547 | node_modules/ 548 | 549 | # Visual Studio 6 build log 550 | *.plg 551 | 552 | # Visual Studio 6 workspace options file 553 | *.opt 554 | 555 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 556 | *.vbw 557 | 558 | # Visual Studio LightSwitch build output 559 | **/*.HTMLClient/GeneratedArtifacts 560 | **/*.DesktopClient/GeneratedArtifacts 561 | **/*.DesktopClient/ModelManifest.xml 562 | **/*.Server/GeneratedArtifacts 563 | **/*.Server/ModelManifest.xml 564 | _Pvt_Extensions 565 | 566 | # Paket dependency manager 567 | .paket/paket.exe 568 | paket-files/ 569 | 570 | # FAKE - F# Make 571 | .fake/ 572 | 573 | # CodeRush personal settings 574 | .cr/personal 575 | 576 | # Python Tools for Visual Studio (PTVS) 577 | *.pyc 578 | 579 | # Cake - Uncomment if you are using it 580 | # tools/** 581 | # !tools/packages.config 582 | 583 | # Tabs Studio 584 | *.tss 585 | 586 | # Telerik's JustMock configuration file 587 | *.jmconfig 588 | 589 | # BizTalk build output 590 | *.btp.cs 591 | *.btm.cs 592 | *.odx.cs 593 | *.xsd.cs 594 | 595 | # OpenCover UI analysis results 596 | OpenCover/ 597 | 598 | # Azure Stream Analytics local run output 599 | ASALocalRun/ 600 | 601 | # MSBuild Binary and Structured Log 602 | *.binlog 603 | 604 | # NVidia Nsight GPU debugger configuration file 605 | *.nvuser 606 | 607 | # MFractors (Xamarin productivity tool) working folder 608 | .mfractor/ 609 | 610 | # Local History for Visual Studio 611 | .localhistory/ 612 | 613 | # BeatPulse healthcheck temp database 614 | healthchecksdb 615 | 616 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 617 | MigrationBackup/ 618 | 619 | # End of https://www.gitignore.io/api/osx,python,pycharm,windows,visualstudio,visualstudiocode 620 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_language_version: 2 | python: python3.7 3 | 4 | default_stages: [commit, push] 5 | 6 | repos: 7 | # - repo: https://github.com/pre-commit/pre-commit-hooks 8 | # rev: v2.5.0 9 | # hooks: 10 | # - id: check-yaml 11 | # - id: end-of-file-fixer 12 | 13 | - repo: local 14 | hooks: 15 | - id: pyupgrade 16 | name: pyupgrade 17 | entry: poetry run pyupgrade --py37-plus 18 | types: [python] 19 | language: system 20 | 21 | - repo: local 22 | hooks: 23 | - id: isort 24 | name: isort 25 | entry: poetry run isort --settings-path pyproject.toml 26 | types: [python] 27 | language: system 28 | 29 | - repo: local 30 | hooks: 31 | - id: black 32 | name: black 33 | entry: poetry run black --config pyproject.toml 34 | types: [python] 35 | language: system 36 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at tez.romach@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | ## Dependencies 4 | 5 | We use `poetry` to manage the [dependencies](https://github.com/python-poetry/poetry). 6 | If you dont have `poetry` installed, you should run the command below. 7 | 8 | ```bash 9 | make download-poetry 10 | ``` 11 | 12 | To install dependencies and prepare [`pre-commit`](https://pre-commit.com/) hooks you would need to run `install` command: 13 | 14 | ```bash 15 | make install 16 | ``` 17 | 18 | To activate your `virtualenv` run `poetry shell`. 19 | 20 | ## Codestyle 21 | 22 | After you run `make install` you can execute the automatic code formatting. 23 | 24 | ```bash 25 | make codestyle 26 | ``` 27 | 28 | ### Checks 29 | 30 | Many checks are configured for this project. Command `make check-style` will run black diffs, darglint docstring style and mypy. 31 | The `make check-safety` command will look at the security of your code. 32 | 33 | You can also use `STRICT=1` flag to make the check be strict. 34 | 35 | ### Before submitting 36 | 37 | Before submitting your code please do the following steps: 38 | 39 | 1. Add any changes you want 40 | 1. Add tests for the new changes 41 | 1. Edit documentation if you have changed something significant 42 | 1. Run `make codestyle` to format your changes. 43 | 1. Run `STRICT=1 make check-style` to ensure that types and docs are correct 44 | 1. Run `STRICT=1 make check-safety` to ensure that security of your code is correct 45 | 46 | ## Other help 47 | 48 | You can contribute by spreading a word about this library. 49 | It would also be a huge contribution to write 50 | a short article on how you are using this project. 51 | You can also share your best practices with us. 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | Copyright (c) 2020 Roman Tezikov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 21 | OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /usr/bin/env bash 2 | 3 | IMAGE := layer_to_layer_pytorch 4 | VERSION := latest 5 | 6 | #! An ugly hack to create individual flags 7 | ifeq ($(STRICT), 1) 8 | POETRY_COMMAND_FLAG = 9 | PIP_COMMAND_FLAG = 10 | SAFETY_COMMAND_FLAG = 11 | BANDIT_COMMAND_FLAG = 12 | SECRETS_COMMAND_FLAG = 13 | BLACK_COMMAND_FLAG = 14 | DARGLINT_COMMAND_FLAG = 15 | ISORT_COMMAND_FLAG = 16 | MYPY_COMMAND_FLAG = 17 | else 18 | POETRY_COMMAND_FLAG = - 19 | PIP_COMMAND_FLAG = - 20 | SAFETY_COMMAND_FLAG = - 21 | BANDIT_COMMAND_FLAG = - 22 | SECRETS_COMMAND_FLAG = - 23 | BLACK_COMMAND_FLAG = - 24 | DARGLINT_COMMAND_FLAG = - 25 | ISORT_COMMAND_FLAG = - 26 | MYPY_COMMAND_FLAG = - 27 | endif 28 | 29 | ##! Please tell me how to use `for loops` to create variables in Makefile :( 30 | ##! If you have better idea, please PR me in https://github.com/TezRomacH/python-package-template 31 | 32 | ifeq ($(POETRY_STRICT), 1) 33 | POETRY_COMMAND_FLAG = 34 | else ifeq ($(POETRY_STRICT), 0) 35 | POETRY_COMMAND_FLAG = - 36 | endif 37 | 38 | ifeq ($(PIP_STRICT), 1) 39 | PIP_COMMAND_FLAG = 40 | else ifeq ($(PIP_STRICT), 0) 41 | PIP_COMMAND_FLAG = - 42 | endif 43 | 44 | ifeq ($(SAFETY_STRICT), 1) 45 | SAFETY_COMMAND_FLAG = 46 | else ifeq ($SAFETY_STRICT), 0) 47 | SAFETY_COMMAND_FLAG = - 48 | endif 49 | 50 | ifeq ($(BANDIT_STRICT), 1) 51 | BANDIT_COMMAND_FLAG = 52 | else ifeq ($(BANDIT_STRICT), 0) 53 | BANDIT_COMMAND_FLAG = - 54 | endif 55 | 56 | ifeq ($(SECRETS_STRICT), 1) 57 | SECRETS_COMMAND_FLAG = 58 | else ifeq ($(SECRETS_STRICT), 0) 59 | SECRETS_COMMAND_FLAG = - 60 | endif 61 | 62 | ifeq ($(BLACK_STRICT), 1) 63 | BLACK_COMMAND_FLAG = 64 | else ifeq ($(BLACK_STRICT), 0) 65 | BLACK_COMMAND_FLAG = - 66 | endif 67 | 68 | ifeq ($(DARGLINT_STRICT), 1) 69 | DARGLINT_COMMAND_FLAG = 70 | else ifeq (DARGLINT_STRICT), 0) 71 | DARGLINT_COMMAND_FLAG = - 72 | endif 73 | 74 | ifeq ($(ISORT_STRICT), 1) 75 | ISORT_COMMAND_FLAG = 76 | else ifeq ($(ISORT_STRICT), 0) 77 | ISORT_COMMAND_FLAG = - 78 | endif 79 | 80 | 81 | ifeq ($(MYPY_STRICT), 1) 82 | MYPY_COMMAND_FLAG = 83 | else ifeq ($(MYPY_STRICT), 0) 84 | MYPY_COMMAND_FLAG = - 85 | endif 86 | 87 | #! The end of the ugly part. I'm really sorry 88 | 89 | .PHONY: download-poetry 90 | download-poetry: 91 | curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python 92 | 93 | .PHONY: install 94 | install: 95 | poetry lock -n 96 | poetry install -n 97 | ifneq ($(NO_PRE_COMMIT), 1) 98 | poetry run pre-commit install 99 | endif 100 | 101 | .PHONY: check-safety 102 | check-safety: 103 | $(POETRY_COMMAND_FLAG)poetry check 104 | $(PIP_COMMAND_FLAG)poetry run pip check 105 | $(SAFETY_COMMAND_FLAG)poetry run safety check --full-report 106 | $(BANDIT_COMMAND_FLAG)poetry run bandit -ll -r layer_to_layer_pytorch/ 107 | 108 | .PHONY: check-style 109 | check-style: 110 | $(BLACK_COMMAND_FLAG)poetry run black --config pyproject.toml --diff --check ./ 111 | $(DARGLINT_COMMAND_FLAG)poetry run darglint -v 2 **/*.py 112 | $(ISORT_COMMAND_FLAG)poetry run isort --settings-path pyproject.toml --check-only **/*.py 113 | # $(MYPY_COMMAND_FLAG)poetry run mypy --config-file setup.cfg layer_to_layer_pytorch 114 | 115 | .PHONY: codestyle 116 | codestyle: 117 | -poetry run pyupgrade --py37-plus **/*.py 118 | poetry run isort --settings-path pyproject.toml **/*.py 119 | poetry run black --config pyproject.toml ./ 120 | 121 | 122 | .PHONY: test 123 | test: 124 | poetry run pytest 125 | 126 | .PHONY: lint 127 | lint: test check-safety check-style 128 | 129 | # Example: make docker VERSION=latest 130 | # Example: make docker IMAGE=some_name VERSION=0.1.0 131 | .PHONY: docker 132 | docker: 133 | @echo Building docker $(IMAGE):$(VERSION) ... 134 | docker build \ 135 | -t $(IMAGE):$(VERSION) . \ 136 | -f ./docker/Dockerfile --no-cache 137 | 138 | # Example: make clean_docker VERSION=latest 139 | # Example: make clean_docker IMAGE=some_name VERSION=0.1.0 140 | .PHONY: clean_docker 141 | clean_docker: 142 | @echo Removing docker $(IMAGE):$(VERSION) ... 143 | docker rmi -f $(IMAGE):$(VERSION) 144 | 145 | .PHONY: clean_build 146 | clean: 147 | rm -rf build/ 148 | 149 | .PHONY: clean 150 | clean: clean_build clean_docker 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # L2L execution algorithm PyTorch 2 | 3 |
4 | 5 | [![Build status](https://github.com/TezRomacH/layer-to-layer-pytorch/workflows/build/badge.svg?branch=master&event=push)](https://github.com/TezRomacH/layer-to-layer-pytorch/actions?query=workflow%3Abuild) 6 | [![Python Version](https://img.shields.io/pypi/pyversions/layer-to-layer-pytorch.svg)](https://pypi.org/project/layer-to-layer-pytorch/) 7 | [![Dependencies Status](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/TezRomacH/layer-to-layer-pytorch/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot) 8 | 9 | [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) 10 | [![Security: bandit](https://img.shields.io/badge/security-bandit-green.svg)](https://github.com/PyCQA/bandit) 11 | [![Pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/TezRomacH/layer-to-layer-pytorch/blob/master/.pre-commit-config.yaml) 12 | [![Semantic Versions](https://img.shields.io/badge/%F0%9F%9A%80-semantic%20versions-informational.svg)](https://github.com/TezRomacH/layer-to-layer-pytorch/releases) 13 | [![License](https://img.shields.io/github/license/TezRomacH/layer-to-layer-pytorch)](https://github.com/TezRomacH/layer-to-layer-pytorch/blob/master/LICENSE) 14 | 15 | PyTorch implementation of L2L execution algorithm from paper [Training Large Neural Networks with Constant Memory using a New Execution Algorithm](https://arxiv.org/abs/2002.05645) 16 |
17 | 18 | ## 🚀 Example 19 | 20 | You need to define a torch model where all layers are specified in ModuleList. 21 | 22 | See [examples folder](examples) 23 | 24 | ### Basic usage 25 | 26 | ```python 27 | import torch 28 | from torch import nn, optim 29 | 30 | class M(nn.Module): 31 | def __init__(self, depth: int, dim: int, hidden_dim: Optional[int] = None): 32 | super().__init__() 33 | hidden_dim = hidden_dim or dim 34 | self.layers = nn.ModuleList( 35 | [ 36 | nn.Sequential( 37 | nn.Linear(dim, hidden_dim), 38 | nn.BatchNorm1d(hidden_dim), 39 | nn.LeakyReLU(), 40 | ) 41 | ] 42 | + [ 43 | nn.Sequential( 44 | nn.Linear(hidden_dim, hidden_dim), 45 | nn.BatchNorm1d(hidden_dim), 46 | nn.LeakyReLU(), 47 | ) 48 | for i in range(depth) 49 | ] 50 | + [nn.Linear(hidden_dim, dim), nn.Sigmoid()] 51 | ) 52 | 53 | def forward(self, batch: torch.Tensor) -> torch.Tensor: 54 | x = batch 55 | for l in self.layers: 56 | x = l(x) 57 | 58 | return x 59 | 60 | 61 | model = M(depth=5, dim=40).train() # on CPU 62 | ``` 63 | 64 | Then, you can use the L2L wrapper over this model. 65 | 66 | ```python 67 | from layer_to_layer_pytorch.l2l import Layer2Layer 68 | 69 | l2l_model = Layer2Layer( 70 | model, 71 | layers_attr="layers", # attribute with ModuleList 72 | microbatch_size=100, # size of a microbatch in a minibatch :) from original paper 73 | verbose=False # enable tqdm 74 | ) 75 | ``` 76 | 77 | And train it, like torch model (almost): 78 | 79 | ```python 80 | from tqdm.auto import tqdm, trange 81 | 82 | x = torch.rand(1_000, 40) # on CPU 83 | y = torch.rand(1_000, 40) # on CPU 84 | 85 | losses = [] 86 | criterion = nn.MSELoss() 87 | 88 | optimizer = optim.AdamW(l2l_model.main_params) # optimizer works with the main model on CPU 89 | 90 | for i in trange(2000): 91 | l2l_model.zero_grad() 92 | _ = l2l_model.forward(x) 93 | 94 | loss_value: float = l2l_model.compute_loss(y, criterion) 95 | 96 | if i % 50 == 0: 97 | tqdm.write(f"[{i}] loss = {loss_value}") 98 | losses.append(loss_value) 99 | 100 | 101 | l2l_model.backward() 102 | optimizer.step() 103 | l2l_model.update_main_model_params() # Sync params with CPU 104 | ``` 105 | 106 | ### FP-16 usage 107 | 108 | Cross-mixes-precision available in init params 109 | 110 | ```python 111 | from layer_to_layer_pytorch.l2l import Layer2Layer 112 | 113 | l2l_model = Layer2Layer( 114 | model, 115 | layers_attr="layers", 116 | microbatch_size=100, 117 | 118 | # fp-16 119 | mixed_precision=True, 120 | loss_scale = 128.0 121 | ) 122 | ``` 123 | 124 | And then train the same way 😉 125 | 126 | ## Installation 127 | 128 | ```bash 129 | pip install layer-to-layer-pytorch 130 | ``` 131 | 132 | or install with `Poetry` 133 | 134 | ```bash 135 | poetry add layer-to-layer-pytorch 136 | ``` 137 | 138 | ## 📈 Releases 139 | 140 | You can see the list of available releases on the [GitHub Releases](https://github.com/TezRomacH/layer-to-layer-pytorch/releases) page. 141 | 142 | We follow [Semantic Versions](https://semver.org/) specification. 143 | 144 | ## 🛡 License 145 | 146 | [![License](https://img.shields.io/github/license/TezRomacH/layer-to-layer-pytorch)](https://github.com/TezRomacH/layer-to-layer-pytorch/blob/master/LICENSE) 147 | 148 | This project is licensed under the terms of the `MIT` license. See [LICENSE](https://github.com/TezRomacH/layer-to-layer-pytorch/blob/master/LICENSE) for more details. 149 | 150 | ## 📃 Citation 151 | 152 | ### This library 153 | 154 | ``` 155 | @misc{layer-to-layer-pytorch, 156 | author = {Roman Tezikov}, 157 | title = {PyTorch implementation of L2L execution algorithm}, 158 | year = {2020}, 159 | publisher = {GitHub}, 160 | journal = {GitHub repository}, 161 | howpublished = {\url{https://github.com/TezRomacH/layer-to-layer-pytorch}} 162 | } 163 | ``` 164 | 165 | ### Original paper 166 | 167 | ``` 168 | @article{Pudipeddi2020TrainingLN, 169 | title={Training Large Neural Networks with Constant Memory using a New Execution Algorithm}, 170 | author={Bharadwaj Pudipeddi and Maral Mesmakhosroshahi and J. Xi and S. Bharadwaj}, 171 | journal={ArXiv}, 172 | year={2020}, 173 | volume={abs/2002.05645} 174 | } 175 | ``` 176 | 177 | ## Credits 178 | 179 | This project was generated with [`python-package-template`](https://github.com/TezRomacH/python-package-template). 180 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | ## 🔐 Reporting Security Issues 4 | 5 | > Do not open issues that might have security implications! 6 | > It is critical that security related issues are reported privately so we have time to address them before they become public knowledge. 7 | 8 | Vulnerabilities can be reported by emailing core members: 9 | 10 | - Roman Tezikov [tez.romach@gmail.com](mailto:tez.romach@gmail.com) 11 | 12 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 13 | 14 | - Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 15 | - Full paths of source file(s) related to the manifestation of the issue 16 | - The location of the affected source code (tag/branch/commit or direct URL) 17 | - Any special configuration required to reproduce the issue 18 | - Environment (e.g. Linux / Windows / macOS) 19 | - Step-by-step instructions to reproduce the issue 20 | - Proof-of-concept or exploit code (if possible) 21 | - Impact of the issue, including how an attacker might exploit the issue 22 | 23 | This information will help us triage your report more quickly. 24 | 25 | ## Preferred Languages 26 | 27 | We prefer all communications to be in English. 28 | -------------------------------------------------------------------------------- /cookiecutter-config-file.yml: -------------------------------------------------------------------------------- 1 | # This file contains values from Cookiecutter 2 | 3 | default_context: 4 | project_name: "layer-to-layer-pytorch" 5 | project_description: "PyTorch implementation of L2L execution algorithm" 6 | organization: "Roman Tezikov" 7 | license: "MIT" 8 | version: "0.1.0" 9 | github_name: "TezRomacH" 10 | email: "tez.romach@gmail.com" 11 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7-slim-buster 2 | 3 | ENV LANG=C.UTF-8 \ 4 | LC_ALL=C.UTF-8 \ 5 | PATH="${PATH}:/root/.poetry/bin" 6 | 7 | RUN apt-get update && \ 8 | apt-get install -y --no-install-recommends \ 9 | curl \ 10 | && rm -rf /var/lib/apt/lists/* 11 | 12 | COPY pyproject.toml ./ 13 | 14 | # Install Poetry 15 | RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_HOME=/opt/poetry python && \ 16 | cd /usr/local/bin && \ 17 | ln -s /opt/poetry/bin/poetry && \ 18 | poetry config virtualenvs.create false 19 | 20 | # Allow installing dev dependencies to run tests 21 | ARG INSTALL_DEV=false 22 | RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then poetry install --no-root ; else poetry install --no-root --no-dev ; fi" 23 | 24 | 25 | CMD mkdir -p /workspace 26 | WORKDIR /workspace 27 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Docker for layer-to-layer-pytorch 2 | 3 | ## Installation 4 | 5 | To create Docker you need to run: 6 | 7 | ```bash 8 | make docker 9 | ``` 10 | 11 | which is equivalent to: 12 | 13 | ```bash 14 | make docker VERSION=latest 15 | ``` 16 | 17 | You could also provide name and version for the image itself. 18 | Default name is `IMAGE := layer_to_layer_pytorch`. 19 | Default version is `VERSION := latest`. 20 | 21 | ```bash 22 | make docker IMAGE=some_name VERSION=0.1.0 23 | ``` 24 | 25 | ## Usage 26 | 27 | ```bash 28 | docker run -it --rm \ 29 | -v $(pwd):/workspace \ 30 | layer_to_layer_pytorch bash 31 | ``` 32 | 33 | ## How to clean up 34 | 35 | To uninstall docker image run `make clean_docker` with `VERSION`: 36 | 37 | ```bash 38 | make clean_docker VERSION=0.1.0 39 | ``` 40 | 41 | like in installation, you can also choose the image name 42 | 43 | ```bash 44 | make clean_docker IMAGE=some_name VERSION=latest 45 | ``` 46 | 47 | If you want to clean all, including `build` run `make clean` 48 | -------------------------------------------------------------------------------- /layer_to_layer_pytorch/__init__.py: -------------------------------------------------------------------------------- 1 | # type: ignore[attr-defined] 2 | """PyTorch implementation of L2L execution algorithm""" 3 | 4 | try: 5 | from importlib.metadata import PackageNotFoundError, version 6 | except ImportError: # pragma: no cover 7 | from importlib_metadata import PackageNotFoundError, version 8 | 9 | 10 | try: 11 | __version__ = version(__name__) 12 | except PackageNotFoundError: # pragma: no cover 13 | __version__ = "unknown" 14 | 15 | from layer_to_layer_pytorch.l2l import Layer2Layer 16 | from layer_to_layer_pytorch.types import Criterion, Device 17 | -------------------------------------------------------------------------------- /layer_to_layer_pytorch/__main__.py: -------------------------------------------------------------------------------- 1 | # type: ignore[attr-defined] 2 | 3 | from typing import Optional 4 | 5 | import random 6 | from enum import Enum 7 | 8 | import typer 9 | 10 | from layer_to_layer_pytorch import __version__ 11 | 12 | app = typer.Typer( 13 | name="layer-to-layer-pytorch", 14 | help="PyTorch implementation of L2L execution algorithm", 15 | add_completion=False, 16 | ) 17 | 18 | 19 | def version_callback(value: bool): 20 | """Prints the version of the package.""" 21 | if value: 22 | print(f"layer-to-layer-pytorch version: {__version__}") 23 | raise typer.Exit() 24 | 25 | 26 | @app.command(name="") 27 | def main( 28 | version: bool = typer.Option( 29 | None, 30 | "-v", 31 | "--version", 32 | callback=version_callback, 33 | is_eager=True, 34 | help="Prints the version of the layer-to-layer-pytorch package.", 35 | ), 36 | ): 37 | pass 38 | -------------------------------------------------------------------------------- /layer_to_layer_pytorch/helpers.py: -------------------------------------------------------------------------------- 1 | from typing import Iterable 2 | 3 | from tqdm.auto import tqdm 4 | from tqdm.contrib import tenumerate, tzip 5 | 6 | 7 | def iterator(iterable: Iterable, verbose: bool, **kwargs): 8 | if not verbose: 9 | return iterable 10 | 11 | return tqdm(iterable, **kwargs) 12 | 13 | 14 | def enumerator(iterable: Iterable, verbose: bool, **kwargs): 15 | if not verbose: 16 | return enumerate(iterable) 17 | 18 | return tenumerate(iterable, **kwargs) 19 | 20 | 21 | def zipper(iterable1: Iterable, iterable2, verbose: bool, **kwargs): 22 | if not verbose: 23 | return zip(iterable1, iterable2) 24 | 25 | return tzip(iterable1, iterable2, **kwargs) 26 | 27 | 28 | __all__ = ["iterator", "enumerator", "zipper"] 29 | -------------------------------------------------------------------------------- /layer_to_layer_pytorch/l2l.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | import torch 4 | from torch import nn 5 | 6 | from layer_to_layer_pytorch.helpers import enumerator 7 | from layer_to_layer_pytorch.types import Criterion, Device 8 | 9 | 10 | class Layer2Layer: 11 | def __init__( 12 | self, 13 | model: nn.Module, 14 | microbatch_size: Optional[int], 15 | layers_attr: str = "layers", 16 | mixed_precision: bool = False, 17 | loss_scale: float = 128.0, # 2**7 18 | gpu_device: Device = "cuda", 19 | verbose: bool = False, 20 | ): 21 | layers = getattr(model, layers_attr, None) 22 | if (layers is None) or (not isinstance(layers, nn.ModuleList)): 23 | raise ValueError( 24 | f"Model must contain `nn.ModuleList` in attribute `{layers_attr}`." 25 | f"Got {type(layers)}" 26 | ) 27 | 28 | if (microbatch_size is not None) and (microbatch_size < 0): 29 | raise ValueError( 30 | f"Size of a microbatch must be greater than zero." 31 | f"Got microbatch_size={microbatch_size}" 32 | ) 33 | 34 | if mixed_precision and loss_scale <= 0.0: 35 | raise ValueError( 36 | f"Loss scale cannot less or equal to zero if mixed_precision is True." 37 | f"Got loss_scale={loss_scale}" 38 | ) 39 | 40 | # model stuff 41 | self.layers_attr: str = layers_attr 42 | self.model: nn.Module = model.cpu() 43 | self._master_params = self._copy_master_params(self.model) 44 | 45 | # hyperparams 46 | self.microbatch_size: Optional[int] = microbatch_size 47 | self.gpu_device: Device = gpu_device 48 | 49 | # fp16 stuff 50 | self.mixed_precision = mixed_precision 51 | self.loss_scale = loss_scale 52 | 53 | if self.mixed_precision: 54 | self.model.half() 55 | 56 | self.verbose: bool = verbose 57 | 58 | # inner stuff 59 | self._num_layers: int = len(layers) 60 | self._activations: List[torch.Tensor] = [] 61 | self._grads: List[torch.Tensor] = [] 62 | 63 | @property 64 | def num_layers(self) -> int: 65 | return self._num_layers 66 | 67 | @property 68 | def main_params(self): 69 | return self._master_params 70 | 71 | def zero_grad(self) -> None: 72 | for model_param, master_param in zip( 73 | self.model.parameters(), self._master_params 74 | ): 75 | model_param.grad = None 76 | master_param.grad = None 77 | 78 | self._reset_activations() 79 | 80 | def update_main_model_params(self): 81 | for model_params, master_params in zip( 82 | self.model.parameters(), self._master_params 83 | ): 84 | model_params.data.copy_(master_params.data) 85 | 86 | @torch.no_grad() 87 | def forward(self, batch: torch.Tensor, **kwargs) -> torch.Tensor: 88 | if self.mixed_precision: 89 | self._activations.append(batch.half()) 90 | else: 91 | self._activations.append(batch) 92 | 93 | for idx, layer in enumerator( 94 | self._get_layers(), 95 | verbose=self.verbose, 96 | desc="Layers", 97 | total=self.num_layers, 98 | leave=False, 99 | ): 100 | layer.to(self.gpu_device) 101 | input: torch.Tensor = self._activations[idx] 102 | microbatch_size = self._get_microbatch_size(input) 103 | 104 | layer_activations: List[torch.Tensor] = [] 105 | for microbatch in input.split(microbatch_size): 106 | activation: torch.Tensor = layer( 107 | microbatch.to(self.gpu_device), **kwargs 108 | ) 109 | 110 | layer_activations.append(activation.cpu()) 111 | 112 | layer.cpu() 113 | self._activations.append(torch.cat(layer_activations, dim=0)) 114 | 115 | return self._activations[-1] 116 | 117 | def compute_loss( 118 | self, targets: torch.Tensor, criterion: Criterion, **criterion_kwargs 119 | ) -> float: 120 | loss_value = 0.0 121 | grads = [] 122 | 123 | inputs: torch.Tensor = self._activations[-1] 124 | microbatch_size = self._get_microbatch_size(inputs) 125 | num_steps: int = inputs.shape[0] // microbatch_size 126 | 127 | for _activation, _target in zip( 128 | inputs.split(microbatch_size), targets.split(microbatch_size) 129 | ): 130 | activation = _activation.to(self.gpu_device).requires_grad_(True) 131 | target = _target.to(self.gpu_device) 132 | 133 | loss = ( 134 | criterion(activation.float(), target, **criterion_kwargs) 135 | / num_steps 136 | ) 137 | loss_value += loss.item() # Append Before Scaling 138 | 139 | if self.mixed_precision and self.loss_scale != 0: 140 | loss *= self.loss_scale 141 | 142 | loss.backward() 143 | grads.append(activation.grad.cpu()) 144 | 145 | self._grads.append(torch.cat(grads, dim=0)) 146 | return loss_value 147 | 148 | def backward(self) -> None: 149 | for idx, (layer, activations) in enumerator( 150 | zip(reversed(self._get_layers()), reversed(self._activations[:-1])), 151 | verbose=self.verbose, 152 | desc="Reverse Layers", 153 | total=self.num_layers, 154 | leave=False, 155 | ): 156 | layer.to(self.gpu_device) 157 | 158 | microbatch_size = self._get_microbatch_size(activations) 159 | grads = [] 160 | 161 | for _activation, gradient in zip( 162 | activations.split(microbatch_size), 163 | self._grads[idx].split(microbatch_size), 164 | ): 165 | activation: torch.Tensor = _activation.to( 166 | self.gpu_device 167 | ).requires_grad_(True) 168 | output: torch.Tensor = layer(activation) 169 | 170 | output.backward(gradient.to(self.gpu_device)) 171 | grads.append(activation.grad.cpu()) 172 | 173 | layer.cpu() 174 | self._grads.append(torch.cat(grads, dim=0)) 175 | self._model_grad_to_master() 176 | 177 | def _get_microbatch_size(self, batch: torch.Tensor) -> int: 178 | batch_size = batch.shape[0] 179 | return ( 180 | batch_size if self.microbatch_size is None else self.microbatch_size 181 | ) 182 | 183 | def _copy_master_params(self, model): 184 | master_params = [ 185 | # PyTorch sets `requires_grad = False` when clone and detach 186 | p.detach().clone().float().requires_grad_(True) 187 | for p in model.parameters() 188 | if p.requires_grad == True 189 | ] 190 | 191 | return master_params 192 | 193 | def __len__(self) -> int: 194 | return self._num_layers 195 | 196 | def _reset_activations(self): 197 | self._activations = [] 198 | self._grads = [] 199 | 200 | def _get_layers(self) -> nn.ModuleList: 201 | return getattr(self.model, self.layers_attr) 202 | 203 | def _model_grad_to_master(self): 204 | for model_param, master_param in zip( 205 | self.model.parameters(), self._master_params 206 | ): 207 | if master_param.grad is None: 208 | master_param.grad = torch.empty_like(master_param.data).float() 209 | 210 | master_param.grad.data.copy_(model_param.grad.data) 211 | 212 | if self.mixed_precision and self.loss_scale != 0: 213 | master_param.grad.data = ( 214 | master_param.grad.data / self.loss_scale 215 | ) 216 | 217 | 218 | __all__ = ["Layer2Layer"] 219 | -------------------------------------------------------------------------------- /layer_to_layer_pytorch/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TezRomacH/layer-to-layer-pytorch/3b72ad7ec5668dcf6bb090f65d65065f4c432498/layer_to_layer_pytorch/py.typed -------------------------------------------------------------------------------- /layer_to_layer_pytorch/types.py: -------------------------------------------------------------------------------- 1 | from typing import Callable, Union 2 | 3 | import torch 4 | 5 | Device = Union[str, torch.device] 6 | Criterion = Callable[[torch.Tensor, torch.Tensor], torch.Tensor] 7 | 8 | __all__ = ["Device", "Criterion"] 9 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "appdirs" 3 | version = "1.4.4" 4 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 5 | category = "dev" 6 | optional = false 7 | python-versions = "*" 8 | 9 | [[package]] 10 | name = "astroid" 11 | version = "2.4.2" 12 | description = "An abstract syntax tree for Python with inference support." 13 | category = "dev" 14 | optional = false 15 | python-versions = ">=3.5" 16 | 17 | [package.dependencies] 18 | lazy-object-proxy = ">=1.4.0,<1.5.0" 19 | six = ">=1.12,<2.0" 20 | typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} 21 | wrapt = ">=1.11,<2.0" 22 | 23 | [[package]] 24 | name = "atomicwrites" 25 | version = "1.4.0" 26 | description = "Atomic file writes." 27 | category = "dev" 28 | optional = false 29 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 30 | 31 | [[package]] 32 | name = "attrs" 33 | version = "20.3.0" 34 | description = "Classes Without Boilerplate" 35 | category = "dev" 36 | optional = false 37 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 38 | 39 | [package.extras] 40 | dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] 41 | docs = ["furo", "sphinx", "zope.interface"] 42 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] 43 | tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] 44 | 45 | [[package]] 46 | name = "bandit" 47 | version = "1.7.0" 48 | description = "Security oriented static analyser for python code." 49 | category = "dev" 50 | optional = false 51 | python-versions = ">=3.5" 52 | 53 | [package.dependencies] 54 | colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} 55 | GitPython = ">=1.0.1" 56 | PyYAML = ">=5.3.1" 57 | six = ">=1.10.0" 58 | stevedore = ">=1.20.0" 59 | 60 | [[package]] 61 | name = "black" 62 | version = "20.8b1" 63 | description = "The uncompromising code formatter." 64 | category = "dev" 65 | optional = false 66 | python-versions = ">=3.6" 67 | 68 | [package.dependencies] 69 | appdirs = "*" 70 | click = ">=7.1.2" 71 | mypy-extensions = ">=0.4.3" 72 | pathspec = ">=0.6,<1" 73 | regex = ">=2020.1.8" 74 | toml = ">=0.10.1" 75 | typed-ast = ">=1.4.0" 76 | typing-extensions = ">=3.7.4" 77 | 78 | [package.extras] 79 | colorama = ["colorama (>=0.4.3)"] 80 | d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] 81 | 82 | [[package]] 83 | name = "certifi" 84 | version = "2020.11.8" 85 | description = "Python package for providing Mozilla's CA Bundle." 86 | category = "dev" 87 | optional = false 88 | python-versions = "*" 89 | 90 | [[package]] 91 | name = "cfgv" 92 | version = "3.2.0" 93 | description = "Validate configuration and produce human readable error messages." 94 | category = "dev" 95 | optional = false 96 | python-versions = ">=3.6.1" 97 | 98 | [[package]] 99 | name = "chardet" 100 | version = "3.0.4" 101 | description = "Universal encoding detector for Python 2 and 3" 102 | category = "dev" 103 | optional = false 104 | python-versions = "*" 105 | 106 | [[package]] 107 | name = "click" 108 | version = "7.1.2" 109 | description = "Composable command line interface toolkit" 110 | category = "main" 111 | optional = false 112 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 113 | 114 | [[package]] 115 | name = "colorama" 116 | version = "0.4.4" 117 | description = "Cross-platform colored terminal text." 118 | category = "main" 119 | optional = false 120 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 121 | 122 | [[package]] 123 | name = "darglint" 124 | version = "1.5.8" 125 | description = "A utility for ensuring Google-style docstrings stay up to date with the source code." 126 | category = "dev" 127 | optional = false 128 | python-versions = ">=3.6,<4.0" 129 | 130 | [[package]] 131 | name = "distlib" 132 | version = "0.3.1" 133 | description = "Distribution utilities" 134 | category = "dev" 135 | optional = false 136 | python-versions = "*" 137 | 138 | [[package]] 139 | name = "dparse" 140 | version = "0.5.1" 141 | description = "A parser for Python dependency files" 142 | category = "dev" 143 | optional = false 144 | python-versions = ">=3.5" 145 | 146 | [package.dependencies] 147 | packaging = "*" 148 | pyyaml = "*" 149 | toml = "*" 150 | 151 | [package.extras] 152 | pipenv = ["pipenv"] 153 | 154 | [[package]] 155 | name = "filelock" 156 | version = "3.0.12" 157 | description = "A platform independent file lock." 158 | category = "dev" 159 | optional = false 160 | python-versions = "*" 161 | 162 | [[package]] 163 | name = "gitdb" 164 | version = "4.0.5" 165 | description = "Git Object Database" 166 | category = "dev" 167 | optional = false 168 | python-versions = ">=3.4" 169 | 170 | [package.dependencies] 171 | smmap = ">=3.0.1,<4" 172 | 173 | [[package]] 174 | name = "gitpython" 175 | version = "3.1.11" 176 | description = "Python Git Library" 177 | category = "dev" 178 | optional = false 179 | python-versions = ">=3.4" 180 | 181 | [package.dependencies] 182 | gitdb = ">=4.0.1,<5" 183 | 184 | [[package]] 185 | name = "identify" 186 | version = "1.5.10" 187 | description = "File identification library for Python" 188 | category = "dev" 189 | optional = false 190 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 191 | 192 | [package.extras] 193 | license = ["editdistance"] 194 | 195 | [[package]] 196 | name = "idna" 197 | version = "2.10" 198 | description = "Internationalized Domain Names in Applications (IDNA)" 199 | category = "dev" 200 | optional = false 201 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 202 | 203 | [[package]] 204 | name = "importlib-metadata" 205 | version = "3.3.0" 206 | description = "Read metadata from Python packages" 207 | category = "main" 208 | optional = false 209 | python-versions = ">=3.6" 210 | 211 | [package.dependencies] 212 | typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} 213 | zipp = ">=0.5" 214 | 215 | [package.extras] 216 | docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] 217 | testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] 218 | 219 | [[package]] 220 | name = "iniconfig" 221 | version = "1.1.1" 222 | description = "iniconfig: brain-dead simple config-ini parsing" 223 | category = "dev" 224 | optional = false 225 | python-versions = "*" 226 | 227 | [[package]] 228 | name = "isort" 229 | version = "5.6.4" 230 | description = "A Python utility / library to sort Python imports." 231 | category = "dev" 232 | optional = false 233 | python-versions = ">=3.6,<4.0" 234 | 235 | [package.extras] 236 | pipfile_deprecated_finder = ["pipreqs", "requirementslib"] 237 | requirements_deprecated_finder = ["pipreqs", "pip-api"] 238 | colors = ["colorama (>=0.4.3,<0.5.0)"] 239 | 240 | [[package]] 241 | name = "lazy-object-proxy" 242 | version = "1.4.3" 243 | description = "A fast and thorough lazy object proxy." 244 | category = "dev" 245 | optional = false 246 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 247 | 248 | [[package]] 249 | name = "mccabe" 250 | version = "0.6.1" 251 | description = "McCabe checker, plugin for flake8" 252 | category = "dev" 253 | optional = false 254 | python-versions = "*" 255 | 256 | [[package]] 257 | name = "mypy" 258 | version = "0.790" 259 | description = "Optional static typing for Python" 260 | category = "dev" 261 | optional = false 262 | python-versions = ">=3.5" 263 | 264 | [package.dependencies] 265 | mypy-extensions = ">=0.4.3,<0.5.0" 266 | typed-ast = ">=1.4.0,<1.5.0" 267 | typing-extensions = ">=3.7.4" 268 | 269 | [package.extras] 270 | dmypy = ["psutil (>=4.0)"] 271 | 272 | [[package]] 273 | name = "mypy-extensions" 274 | version = "0.4.3" 275 | description = "Experimental type system extensions for programs checked with the mypy typechecker." 276 | category = "dev" 277 | optional = false 278 | python-versions = "*" 279 | 280 | [[package]] 281 | name = "nodeenv" 282 | version = "1.5.0" 283 | description = "Node.js virtual environment builder" 284 | category = "dev" 285 | optional = false 286 | python-versions = "*" 287 | 288 | [[package]] 289 | name = "numpy" 290 | version = "1.19.4" 291 | description = "NumPy is the fundamental package for array computing with Python." 292 | category = "main" 293 | optional = false 294 | python-versions = ">=3.6" 295 | 296 | [[package]] 297 | name = "packaging" 298 | version = "20.8" 299 | description = "Core utilities for Python packages" 300 | category = "dev" 301 | optional = false 302 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 303 | 304 | [package.dependencies] 305 | pyparsing = ">=2.0.2" 306 | 307 | [[package]] 308 | name = "pathspec" 309 | version = "0.8.1" 310 | description = "Utility library for gitignore style pattern matching of file paths." 311 | category = "dev" 312 | optional = false 313 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 314 | 315 | [[package]] 316 | name = "pbr" 317 | version = "5.5.1" 318 | description = "Python Build Reasonableness" 319 | category = "dev" 320 | optional = false 321 | python-versions = ">=2.6" 322 | 323 | [[package]] 324 | name = "pluggy" 325 | version = "0.13.1" 326 | description = "plugin and hook calling mechanisms for python" 327 | category = "dev" 328 | optional = false 329 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 330 | 331 | [package.dependencies] 332 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 333 | 334 | [package.extras] 335 | dev = ["pre-commit", "tox"] 336 | 337 | [[package]] 338 | name = "pre-commit" 339 | version = "2.9.2" 340 | description = "A framework for managing and maintaining multi-language pre-commit hooks." 341 | category = "dev" 342 | optional = false 343 | python-versions = ">=3.6.1" 344 | 345 | [package.dependencies] 346 | cfgv = ">=2.0.0" 347 | identify = ">=1.0.0" 348 | importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} 349 | nodeenv = ">=0.11.1" 350 | pyyaml = ">=5.1" 351 | toml = "*" 352 | virtualenv = ">=20.0.8" 353 | 354 | [[package]] 355 | name = "py" 356 | version = "1.9.0" 357 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 358 | category = "dev" 359 | optional = false 360 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 361 | 362 | [[package]] 363 | name = "pydocstyle" 364 | version = "5.1.1" 365 | description = "Python docstring style checker" 366 | category = "dev" 367 | optional = false 368 | python-versions = ">=3.5" 369 | 370 | [package.dependencies] 371 | snowballstemmer = "*" 372 | 373 | [[package]] 374 | name = "pylint" 375 | version = "2.6.0" 376 | description = "python code static checker" 377 | category = "dev" 378 | optional = false 379 | python-versions = ">=3.5.*" 380 | 381 | [package.dependencies] 382 | astroid = ">=2.4.0,<=2.5" 383 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 384 | isort = ">=4.2.5,<6" 385 | mccabe = ">=0.6,<0.7" 386 | toml = ">=0.7.1" 387 | 388 | [[package]] 389 | name = "pyparsing" 390 | version = "2.4.7" 391 | description = "Python parsing module" 392 | category = "dev" 393 | optional = false 394 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 395 | 396 | [[package]] 397 | name = "pytest" 398 | version = "6.1.2" 399 | description = "pytest: simple powerful testing with Python" 400 | category = "dev" 401 | optional = false 402 | python-versions = ">=3.5" 403 | 404 | [package.dependencies] 405 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} 406 | attrs = ">=17.4.0" 407 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 408 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 409 | iniconfig = "*" 410 | packaging = "*" 411 | pluggy = ">=0.12,<1.0" 412 | py = ">=1.8.2" 413 | toml = "*" 414 | 415 | [package.extras] 416 | checkqa_mypy = ["mypy (==0.780)"] 417 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] 418 | 419 | [[package]] 420 | name = "pyupgrade" 421 | version = "2.7.4" 422 | description = "A tool to automatically upgrade syntax for newer versions." 423 | category = "dev" 424 | optional = false 425 | python-versions = ">=3.6.1" 426 | 427 | [package.dependencies] 428 | tokenize-rt = ">=3.2.0" 429 | 430 | [[package]] 431 | name = "pyyaml" 432 | version = "5.3.1" 433 | description = "YAML parser and emitter for Python" 434 | category = "dev" 435 | optional = false 436 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 437 | 438 | [[package]] 439 | name = "regex" 440 | version = "2020.11.13" 441 | description = "Alternative regular expression module, to replace re." 442 | category = "dev" 443 | optional = false 444 | python-versions = "*" 445 | 446 | [[package]] 447 | name = "requests" 448 | version = "2.25.0" 449 | description = "Python HTTP for Humans." 450 | category = "dev" 451 | optional = false 452 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 453 | 454 | [package.dependencies] 455 | certifi = ">=2017.4.17" 456 | chardet = ">=3.0.2,<4" 457 | idna = ">=2.5,<3" 458 | urllib3 = ">=1.21.1,<1.27" 459 | 460 | [package.extras] 461 | security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] 462 | socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] 463 | 464 | [[package]] 465 | name = "safety" 466 | version = "1.9.0" 467 | description = "Checks installed dependencies for known vulnerabilities." 468 | category = "dev" 469 | optional = false 470 | python-versions = ">=3.5" 471 | 472 | [package.dependencies] 473 | Click = ">=6.0" 474 | dparse = ">=0.5.1" 475 | packaging = "*" 476 | requests = "*" 477 | 478 | [[package]] 479 | name = "shellingham" 480 | version = "1.3.2" 481 | description = "Tool to Detect Surrounding Shell" 482 | category = "main" 483 | optional = false 484 | python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,>=2.6" 485 | 486 | [[package]] 487 | name = "six" 488 | version = "1.15.0" 489 | description = "Python 2 and 3 compatibility utilities" 490 | category = "dev" 491 | optional = false 492 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 493 | 494 | [[package]] 495 | name = "smmap" 496 | version = "3.0.4" 497 | description = "A pure Python implementation of a sliding window memory map manager" 498 | category = "dev" 499 | optional = false 500 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 501 | 502 | [[package]] 503 | name = "snowballstemmer" 504 | version = "2.0.0" 505 | description = "This package provides 26 stemmers for 25 languages generated from Snowball algorithms." 506 | category = "dev" 507 | optional = false 508 | python-versions = "*" 509 | 510 | [[package]] 511 | name = "stevedore" 512 | version = "3.3.0" 513 | description = "Manage dynamic plugins for Python applications" 514 | category = "dev" 515 | optional = false 516 | python-versions = ">=3.6" 517 | 518 | [package.dependencies] 519 | importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} 520 | pbr = ">=2.0.0,<2.1.0 || >2.1.0" 521 | 522 | [[package]] 523 | name = "tokenize-rt" 524 | version = "4.0.0" 525 | description = "A wrapper around the stdlib `tokenize` which roundtrips." 526 | category = "dev" 527 | optional = false 528 | python-versions = ">=3.6.1" 529 | 530 | [[package]] 531 | name = "toml" 532 | version = "0.10.2" 533 | description = "Python Library for Tom's Obvious, Minimal Language" 534 | category = "dev" 535 | optional = false 536 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 537 | 538 | [[package]] 539 | name = "torch" 540 | version = "1.7.1" 541 | description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" 542 | category = "main" 543 | optional = false 544 | python-versions = ">=3.6.2" 545 | 546 | [package.dependencies] 547 | numpy = "*" 548 | typing-extensions = "*" 549 | 550 | [[package]] 551 | name = "tqdm" 552 | version = "4.54.1" 553 | description = "Fast, Extensible Progress Meter" 554 | category = "main" 555 | optional = false 556 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 557 | 558 | [package.extras] 559 | dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown", "wheel"] 560 | 561 | [[package]] 562 | name = "typed-ast" 563 | version = "1.4.1" 564 | description = "a fork of Python 2 and 3 ast modules with type comment support" 565 | category = "dev" 566 | optional = false 567 | python-versions = "*" 568 | 569 | [[package]] 570 | name = "typer" 571 | version = "0.3.2" 572 | description = "Typer, build great CLIs. Easy to code. Based on Python type hints." 573 | category = "main" 574 | optional = false 575 | python-versions = ">=3.6" 576 | 577 | [package.dependencies] 578 | click = ">=7.1.1,<7.2.0" 579 | colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""} 580 | shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""} 581 | 582 | [package.extras] 583 | test = ["pytest-xdist (>=1.32.0,<2.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "mypy (==0.782)", "black (>=19.10b0,<20.0b0)", "isort (>=5.0.6,<6.0.0)", "shellingham (>=1.3.0,<2.0.0)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "coverage (>=5.2,<6.0)"] 584 | all = ["colorama (>=0.4.3,<0.5.0)", "shellingham (>=1.3.0,<2.0.0)"] 585 | dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)"] 586 | doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=5.4.0,<6.0.0)", "markdown-include (>=0.5.1,<0.6.0)"] 587 | 588 | [[package]] 589 | name = "typing-extensions" 590 | version = "3.7.4.3" 591 | description = "Backported and Experimental Type Hints for Python 3.5+" 592 | category = "main" 593 | optional = false 594 | python-versions = "*" 595 | 596 | [[package]] 597 | name = "urllib3" 598 | version = "1.26.2" 599 | description = "HTTP library with thread-safe connection pooling, file post, and more." 600 | category = "dev" 601 | optional = false 602 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" 603 | 604 | [package.extras] 605 | brotli = ["brotlipy (>=0.6.0)"] 606 | secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] 607 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] 608 | 609 | [[package]] 610 | name = "virtualenv" 611 | version = "20.2.1" 612 | description = "Virtual Python Environment builder" 613 | category = "dev" 614 | optional = false 615 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 616 | 617 | [package.dependencies] 618 | appdirs = ">=1.4.3,<2" 619 | distlib = ">=0.3.1,<1" 620 | filelock = ">=3.0.0,<4" 621 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 622 | six = ">=1.9.0,<2" 623 | 624 | [package.extras] 625 | docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] 626 | testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] 627 | 628 | [[package]] 629 | name = "wrapt" 630 | version = "1.12.1" 631 | description = "Module for decorators, wrappers and monkey patching." 632 | category = "dev" 633 | optional = false 634 | python-versions = "*" 635 | 636 | [[package]] 637 | name = "zipp" 638 | version = "3.4.0" 639 | description = "Backport of pathlib-compatible object wrapper for zip files" 640 | category = "main" 641 | optional = false 642 | python-versions = ">=3.6" 643 | 644 | [package.extras] 645 | docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] 646 | testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] 647 | 648 | [metadata] 649 | lock-version = "1.1" 650 | python-versions = "^3.7" 651 | content-hash = "34347cf32ab842777f2ac5d1a082bc65b6be66ccddd16725574990048c809ed2" 652 | 653 | [metadata.files] 654 | appdirs = [ 655 | {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, 656 | {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, 657 | ] 658 | astroid = [ 659 | {file = "astroid-2.4.2-py3-none-any.whl", hash = "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386"}, 660 | {file = "astroid-2.4.2.tar.gz", hash = "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703"}, 661 | ] 662 | atomicwrites = [ 663 | {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, 664 | {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, 665 | ] 666 | attrs = [ 667 | {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, 668 | {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, 669 | ] 670 | bandit = [ 671 | {file = "bandit-1.7.0-py3-none-any.whl", hash = "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07"}, 672 | {file = "bandit-1.7.0.tar.gz", hash = "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608"}, 673 | ] 674 | black = [ 675 | {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, 676 | ] 677 | certifi = [ 678 | {file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"}, 679 | {file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"}, 680 | ] 681 | cfgv = [ 682 | {file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"}, 683 | {file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"}, 684 | ] 685 | chardet = [ 686 | {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, 687 | {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, 688 | ] 689 | click = [ 690 | {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, 691 | {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, 692 | ] 693 | colorama = [ 694 | {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, 695 | {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, 696 | ] 697 | darglint = [ 698 | {file = "darglint-1.5.8-py3-none-any.whl", hash = "sha256:2e1012945a09d19a15cc87f9d15e7b14c18473ec9cf7769c641951b348de1353"}, 699 | {file = "darglint-1.5.8.tar.gz", hash = "sha256:529f4969029d5ff5f74bfec48adc14b6f003409141f722b6cc4b787dddc8a4dd"}, 700 | ] 701 | distlib = [ 702 | {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, 703 | {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, 704 | ] 705 | dparse = [ 706 | {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, 707 | {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, 708 | ] 709 | filelock = [ 710 | {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, 711 | {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, 712 | ] 713 | gitdb = [ 714 | {file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"}, 715 | {file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"}, 716 | ] 717 | gitpython = [ 718 | {file = "GitPython-3.1.11-py3-none-any.whl", hash = "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b"}, 719 | {file = "GitPython-3.1.11.tar.gz", hash = "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8"}, 720 | ] 721 | identify = [ 722 | {file = "identify-1.5.10-py2.py3-none-any.whl", hash = "sha256:cc86e6a9a390879dcc2976cef169dd9cc48843ed70b7380f321d1b118163c60e"}, 723 | {file = "identify-1.5.10.tar.gz", hash = "sha256:943cd299ac7f5715fcb3f684e2fc1594c1e0f22a90d15398e5888143bd4144b5"}, 724 | ] 725 | idna = [ 726 | {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, 727 | {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, 728 | ] 729 | importlib-metadata = [ 730 | {file = "importlib_metadata-3.3.0-py3-none-any.whl", hash = "sha256:bf792d480abbd5eda85794e4afb09dd538393f7d6e6ffef6e9f03d2014cf9450"}, 731 | {file = "importlib_metadata-3.3.0.tar.gz", hash = "sha256:5c5a2720817414a6c41f0a49993908068243ae02c1635a228126519b509c8aed"}, 732 | ] 733 | iniconfig = [ 734 | {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, 735 | {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, 736 | ] 737 | isort = [ 738 | {file = "isort-5.6.4-py3-none-any.whl", hash = "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7"}, 739 | {file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"}, 740 | ] 741 | lazy-object-proxy = [ 742 | {file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"}, 743 | {file = "lazy_object_proxy-1.4.3-cp27-cp27m-macosx_10_13_x86_64.whl", hash = "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442"}, 744 | {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win32.whl", hash = "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4"}, 745 | {file = "lazy_object_proxy-1.4.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a"}, 746 | {file = "lazy_object_proxy-1.4.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d"}, 747 | {file = "lazy_object_proxy-1.4.3-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a"}, 748 | {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win32.whl", hash = "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e"}, 749 | {file = "lazy_object_proxy-1.4.3-cp34-cp34m-win_amd64.whl", hash = "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357"}, 750 | {file = "lazy_object_proxy-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50"}, 751 | {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db"}, 752 | {file = "lazy_object_proxy-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449"}, 753 | {file = "lazy_object_proxy-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156"}, 754 | {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531"}, 755 | {file = "lazy_object_proxy-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb"}, 756 | {file = "lazy_object_proxy-1.4.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08"}, 757 | {file = "lazy_object_proxy-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383"}, 758 | {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142"}, 759 | {file = "lazy_object_proxy-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea"}, 760 | {file = "lazy_object_proxy-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62"}, 761 | {file = "lazy_object_proxy-1.4.3-cp38-cp38-win32.whl", hash = "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd"}, 762 | {file = "lazy_object_proxy-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239"}, 763 | ] 764 | mccabe = [ 765 | {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, 766 | {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, 767 | ] 768 | mypy = [ 769 | {file = "mypy-0.790-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:bd03b3cf666bff8d710d633d1c56ab7facbdc204d567715cb3b9f85c6e94f669"}, 770 | {file = "mypy-0.790-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:2170492030f6faa537647d29945786d297e4862765f0b4ac5930ff62e300d802"}, 771 | {file = "mypy-0.790-cp35-cp35m-win_amd64.whl", hash = "sha256:e86bdace26c5fe9cf8cb735e7cedfe7850ad92b327ac5d797c656717d2ca66de"}, 772 | {file = "mypy-0.790-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e97e9c13d67fbe524be17e4d8025d51a7dca38f90de2e462243ab8ed8a9178d1"}, 773 | {file = "mypy-0.790-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0d34d6b122597d48a36d6c59e35341f410d4abfa771d96d04ae2c468dd201abc"}, 774 | {file = "mypy-0.790-cp36-cp36m-win_amd64.whl", hash = "sha256:72060bf64f290fb629bd4a67c707a66fd88ca26e413a91384b18db3876e57ed7"}, 775 | {file = "mypy-0.790-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eea260feb1830a627fb526d22fbb426b750d9f5a47b624e8d5e7e004359b219c"}, 776 | {file = "mypy-0.790-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c614194e01c85bb2e551c421397e49afb2872c88b5830e3554f0519f9fb1c178"}, 777 | {file = "mypy-0.790-cp37-cp37m-win_amd64.whl", hash = "sha256:0a0d102247c16ce93c97066443d11e2d36e6cc2a32d8ccc1f705268970479324"}, 778 | {file = "mypy-0.790-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4e7bf7f1214826cf7333627cb2547c0db7e3078723227820d0a2490f117a01"}, 779 | {file = "mypy-0.790-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:af4e9ff1834e565f1baa74ccf7ae2564ae38c8df2a85b057af1dbbc958eb6666"}, 780 | {file = "mypy-0.790-cp38-cp38-win_amd64.whl", hash = "sha256:da56dedcd7cd502ccd3c5dddc656cb36113dd793ad466e894574125945653cea"}, 781 | {file = "mypy-0.790-py3-none-any.whl", hash = "sha256:2842d4fbd1b12ab422346376aad03ff5d0805b706102e475e962370f874a5122"}, 782 | {file = "mypy-0.790.tar.gz", hash = "sha256:2b21ba45ad9ef2e2eb88ce4aeadd0112d0f5026418324176fd494a6824b74975"}, 783 | ] 784 | mypy-extensions = [ 785 | {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, 786 | {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, 787 | ] 788 | nodeenv = [ 789 | {file = "nodeenv-1.5.0-py2.py3-none-any.whl", hash = "sha256:5304d424c529c997bc888453aeaa6362d242b6b4631e90f3d4bf1b290f1c84a9"}, 790 | {file = "nodeenv-1.5.0.tar.gz", hash = "sha256:ab45090ae383b716c4ef89e690c41ff8c2b257b85b309f01f3654df3d084bd7c"}, 791 | ] 792 | numpy = [ 793 | {file = "numpy-1.19.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9b30d4bd69498fc0c3fe9db5f62fffbb06b8eb9321f92cc970f2969be5e3949"}, 794 | {file = "numpy-1.19.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:fedbd128668ead37f33917820b704784aff695e0019309ad446a6d0b065b57e4"}, 795 | {file = "numpy-1.19.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8ece138c3a16db8c1ad38f52eb32be6086cc72f403150a79336eb2045723a1ad"}, 796 | {file = "numpy-1.19.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:64324f64f90a9e4ef732be0928be853eee378fd6a01be21a0a8469c4f2682c83"}, 797 | {file = "numpy-1.19.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ad6f2ff5b1989a4899bf89800a671d71b1612e5ff40866d1f4d8bcf48d4e5764"}, 798 | {file = "numpy-1.19.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d6c7bb82883680e168b55b49c70af29b84b84abb161cbac2800e8fcb6f2109b6"}, 799 | {file = "numpy-1.19.4-cp36-cp36m-win32.whl", hash = "sha256:13d166f77d6dc02c0a73c1101dd87fdf01339febec1030bd810dcd53fff3b0f1"}, 800 | {file = "numpy-1.19.4-cp36-cp36m-win_amd64.whl", hash = "sha256:448ebb1b3bf64c0267d6b09a7cba26b5ae61b6d2dbabff7c91b660c7eccf2bdb"}, 801 | {file = "numpy-1.19.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:27d3f3b9e3406579a8af3a9f262f5339005dd25e0ecf3cf1559ff8a49ed5cbf2"}, 802 | {file = "numpy-1.19.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:16c1b388cc31a9baa06d91a19366fb99ddbe1c7b205293ed072211ee5bac1ed2"}, 803 | {file = "numpy-1.19.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e5b6ed0f0b42317050c88022349d994fe72bfe35f5908617512cd8c8ef9da2a9"}, 804 | {file = "numpy-1.19.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:18bed2bcb39e3f758296584337966e68d2d5ba6aab7e038688ad53c8f889f757"}, 805 | {file = "numpy-1.19.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:fe45becb4c2f72a0907c1d0246ea6449fe7a9e2293bb0e11c4e9a32bb0930a15"}, 806 | {file = "numpy-1.19.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:6d7593a705d662be5bfe24111af14763016765f43cb6923ed86223f965f52387"}, 807 | {file = "numpy-1.19.4-cp37-cp37m-win32.whl", hash = "sha256:6ae6c680f3ebf1cf7ad1d7748868b39d9f900836df774c453c11c5440bc15b36"}, 808 | {file = "numpy-1.19.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9eeb7d1d04b117ac0d38719915ae169aa6b61fca227b0b7d198d43728f0c879c"}, 809 | {file = "numpy-1.19.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cb1017eec5257e9ac6209ac172058c430e834d5d2bc21961dceeb79d111e5909"}, 810 | {file = "numpy-1.19.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:edb01671b3caae1ca00881686003d16c2209e07b7ef8b7639f1867852b948f7c"}, 811 | {file = "numpy-1.19.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:f29454410db6ef8126c83bd3c968d143304633d45dc57b51252afbd79d700893"}, 812 | {file = "numpy-1.19.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:ec149b90019852266fec2341ce1db513b843e496d5a8e8cdb5ced1923a92faab"}, 813 | {file = "numpy-1.19.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:1aeef46a13e51931c0b1cf8ae1168b4a55ecd282e6688fdb0a948cc5a1d5afb9"}, 814 | {file = "numpy-1.19.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:08308c38e44cc926bdfce99498b21eec1f848d24c302519e64203a8da99a97db"}, 815 | {file = "numpy-1.19.4-cp38-cp38-win32.whl", hash = "sha256:5734bdc0342aba9dfc6f04920988140fb41234db42381cf7ccba64169f9fe7ac"}, 816 | {file = "numpy-1.19.4-cp38-cp38-win_amd64.whl", hash = "sha256:09c12096d843b90eafd01ea1b3307e78ddd47a55855ad402b157b6c4862197ce"}, 817 | {file = "numpy-1.19.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e452dc66e08a4ce642a961f134814258a082832c78c90351b75c41ad16f79f63"}, 818 | {file = "numpy-1.19.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a5d897c14513590a85774180be713f692df6fa8ecf6483e561a6d47309566f37"}, 819 | {file = "numpy-1.19.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:a09f98011236a419ee3f49cedc9ef27d7a1651df07810ae430a6b06576e0b414"}, 820 | {file = "numpy-1.19.4-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:50e86c076611212ca62e5a59f518edafe0c0730f7d9195fec718da1a5c2bb1fc"}, 821 | {file = "numpy-1.19.4-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f0d3929fe88ee1c155129ecd82f981b8856c5d97bcb0d5f23e9b4242e79d1de3"}, 822 | {file = "numpy-1.19.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c42c4b73121caf0ed6cd795512c9c09c52a7287b04d105d112068c1736d7c753"}, 823 | {file = "numpy-1.19.4-cp39-cp39-win32.whl", hash = "sha256:8cac8790a6b1ddf88640a9267ee67b1aee7a57dfa2d2dd33999d080bc8ee3a0f"}, 824 | {file = "numpy-1.19.4-cp39-cp39-win_amd64.whl", hash = "sha256:4377e10b874e653fe96985c05feed2225c912e328c8a26541f7fc600fb9c637b"}, 825 | {file = "numpy-1.19.4-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:2a2740aa9733d2e5b2dfb33639d98a64c3b0f24765fed86b0fd2aec07f6a0a08"}, 826 | {file = "numpy-1.19.4.zip", hash = "sha256:141ec3a3300ab89c7f2b0775289954d193cc8edb621ea05f99db9cb181530512"}, 827 | ] 828 | packaging = [ 829 | {file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"}, 830 | {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, 831 | ] 832 | pathspec = [ 833 | {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, 834 | {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, 835 | ] 836 | pbr = [ 837 | {file = "pbr-5.5.1-py2.py3-none-any.whl", hash = "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00"}, 838 | {file = "pbr-5.5.1.tar.gz", hash = "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9"}, 839 | ] 840 | pluggy = [ 841 | {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, 842 | {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, 843 | ] 844 | pre-commit = [ 845 | {file = "pre_commit-2.9.2-py2.py3-none-any.whl", hash = "sha256:949b13efb7467ae27e2c8f9e83434dacf2682595124d8902554a4e18351e5781"}, 846 | {file = "pre_commit-2.9.2.tar.gz", hash = "sha256:e31c04bc23741194a7c0b983fe512801e151a0638c6001c49f2bd034f8a664a1"}, 847 | ] 848 | py = [ 849 | {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, 850 | {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, 851 | ] 852 | pydocstyle = [ 853 | {file = "pydocstyle-5.1.1-py3-none-any.whl", hash = "sha256:aca749e190a01726a4fb472dd4ef23b5c9da7b9205c0a7857c06533de13fd678"}, 854 | {file = "pydocstyle-5.1.1.tar.gz", hash = "sha256:19b86fa8617ed916776a11cd8bc0197e5b9856d5433b777f51a3defe13075325"}, 855 | ] 856 | pylint = [ 857 | {file = "pylint-2.6.0-py3-none-any.whl", hash = "sha256:bfe68f020f8a0fece830a22dd4d5dddb4ecc6137db04face4c3420a46a52239f"}, 858 | {file = "pylint-2.6.0.tar.gz", hash = "sha256:bb4a908c9dadbc3aac18860550e870f58e1a02c9f2c204fdf5693d73be061210"}, 859 | ] 860 | pyparsing = [ 861 | {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, 862 | {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, 863 | ] 864 | pytest = [ 865 | {file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"}, 866 | {file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"}, 867 | ] 868 | pyupgrade = [ 869 | {file = "pyupgrade-2.7.4-py2.py3-none-any.whl", hash = "sha256:ab2f47377e977bec8dd41db634fde35bce78fedd2be0e8b189fe687f23fb1d85"}, 870 | {file = "pyupgrade-2.7.4.tar.gz", hash = "sha256:e57057ccef3fd8e8fad5ba9f365c1288a076271a222ccb502d865c0d8fe16c3a"}, 871 | ] 872 | pyyaml = [ 873 | {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, 874 | {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, 875 | {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, 876 | {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, 877 | {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, 878 | {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, 879 | {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, 880 | {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, 881 | {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, 882 | {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, 883 | {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, 884 | {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, 885 | {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, 886 | ] 887 | regex = [ 888 | {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, 889 | {file = "regex-2020.11.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70"}, 890 | {file = "regex-2020.11.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee"}, 891 | {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5"}, 892 | {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7"}, 893 | {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31"}, 894 | {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa"}, 895 | {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6"}, 896 | {file = "regex-2020.11.13-cp36-cp36m-win32.whl", hash = "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e"}, 897 | {file = "regex-2020.11.13-cp36-cp36m-win_amd64.whl", hash = "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884"}, 898 | {file = "regex-2020.11.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b"}, 899 | {file = "regex-2020.11.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88"}, 900 | {file = "regex-2020.11.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0"}, 901 | {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1"}, 902 | {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0"}, 903 | {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512"}, 904 | {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba"}, 905 | {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538"}, 906 | {file = "regex-2020.11.13-cp37-cp37m-win32.whl", hash = "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4"}, 907 | {file = "regex-2020.11.13-cp37-cp37m-win_amd64.whl", hash = "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444"}, 908 | {file = "regex-2020.11.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f"}, 909 | {file = "regex-2020.11.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d"}, 910 | {file = "regex-2020.11.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af"}, 911 | {file = "regex-2020.11.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f"}, 912 | {file = "regex-2020.11.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b"}, 913 | {file = "regex-2020.11.13-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8"}, 914 | {file = "regex-2020.11.13-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5"}, 915 | {file = "regex-2020.11.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b"}, 916 | {file = "regex-2020.11.13-cp38-cp38-win32.whl", hash = "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c"}, 917 | {file = "regex-2020.11.13-cp38-cp38-win_amd64.whl", hash = "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683"}, 918 | {file = "regex-2020.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc"}, 919 | {file = "regex-2020.11.13-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364"}, 920 | {file = "regex-2020.11.13-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e"}, 921 | {file = "regex-2020.11.13-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e"}, 922 | {file = "regex-2020.11.13-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917"}, 923 | {file = "regex-2020.11.13-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b"}, 924 | {file = "regex-2020.11.13-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9"}, 925 | {file = "regex-2020.11.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c"}, 926 | {file = "regex-2020.11.13-cp39-cp39-win32.whl", hash = "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f"}, 927 | {file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"}, 928 | {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"}, 929 | ] 930 | requests = [ 931 | {file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"}, 932 | {file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"}, 933 | ] 934 | safety = [ 935 | {file = "safety-1.9.0-py2.py3-none-any.whl", hash = "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087"}, 936 | {file = "safety-1.9.0.tar.gz", hash = "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9"}, 937 | ] 938 | shellingham = [ 939 | {file = "shellingham-1.3.2-py2.py3-none-any.whl", hash = "sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044"}, 940 | {file = "shellingham-1.3.2.tar.gz", hash = "sha256:576c1982bea0ba82fb46c36feb951319d7f42214a82634233f58b40d858a751e"}, 941 | ] 942 | six = [ 943 | {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, 944 | {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, 945 | ] 946 | smmap = [ 947 | {file = "smmap-3.0.4-py2.py3-none-any.whl", hash = "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4"}, 948 | {file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"}, 949 | ] 950 | snowballstemmer = [ 951 | {file = "snowballstemmer-2.0.0-py2.py3-none-any.whl", hash = "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0"}, 952 | {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, 953 | ] 954 | stevedore = [ 955 | {file = "stevedore-3.3.0-py3-none-any.whl", hash = "sha256:50d7b78fbaf0d04cd62411188fa7eedcb03eb7f4c4b37005615ceebe582aa82a"}, 956 | {file = "stevedore-3.3.0.tar.gz", hash = "sha256:3a5bbd0652bf552748871eaa73a4a8dc2899786bc497a2aa1fcb4dcdb0debeee"}, 957 | ] 958 | tokenize-rt = [ 959 | {file = "tokenize_rt-4.0.0-py2.py3-none-any.whl", hash = "sha256:c47d3bd00857c24edefccdd6dc99c19d4ceed77c5971a3e2fac007fb0c02e39d"}, 960 | {file = "tokenize_rt-4.0.0.tar.gz", hash = "sha256:07d5f88b6a953612159b160129bcf9425677c8d062b0cb83250968ba803e1c64"}, 961 | ] 962 | toml = [ 963 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 964 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 965 | ] 966 | torch = [ 967 | {file = "torch-1.7.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:422e64e98d0e100c360993819d0307e5d56e9517b26135808ad68984d577d75a"}, 968 | {file = "torch-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f0aaf657145533824b15f2fd8fde8f8c67fe6c6281088ef588091f03fad90243"}, 969 | {file = "torch-1.7.1-cp36-none-macosx_10_9_x86_64.whl", hash = "sha256:af464a6f4314a875035e0c4c2b07517599704b214634f4ed3ad2e748c5ef291f"}, 970 | {file = "torch-1.7.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5d76c255a41484c1d41a9ff570b9c9f36cb85df9428aa15a58ae16ac7cfc2ea6"}, 971 | {file = "torch-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:d241c3f1c4d563e4ba86f84769c23e12606db167ee6f674eedff6d02901462e3"}, 972 | {file = "torch-1.7.1-cp37-none-macosx_10_9_x86_64.whl", hash = "sha256:de84b4166e3f7335eb868b51d3bbd909ec33828af27290b4171bce832a55be3c"}, 973 | {file = "torch-1.7.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:dd2fc6880c95e836960d86efbbc7f63d3287f2e1893c51d31f96dbfe02f0d73e"}, 974 | {file = "torch-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:e000b94be3aa58ad7f61e7d07cf379ea9366cf6c6874e68bd58ad0bdc537b3a7"}, 975 | {file = "torch-1.7.1-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:2e49cac969976be63117004ee00d0a3e3dd4ea662ad77383f671b8992825de1a"}, 976 | {file = "torch-1.7.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:a3793dcceb12b1e2281290cca1277c5ce86ddfd5bf044f654285a4d69057aea7"}, 977 | {file = "torch-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:6652a767a0572ae0feb74ad128758e507afd3b8396b6e7f147e438ba8d4c6f63"}, 978 | {file = "torch-1.7.1-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:38d67f4fb189a92a977b2c0a38e4f6dd413e0bf55aa6d40004696df7e40a71ff"}, 979 | ] 980 | tqdm = [ 981 | {file = "tqdm-4.54.1-py2.py3-none-any.whl", hash = "sha256:d4f413aecb61c9779888c64ddf0c62910ad56dcbe857d8922bb505d4dbff0df1"}, 982 | {file = "tqdm-4.54.1.tar.gz", hash = "sha256:38b658a3e4ecf9b4f6f8ff75ca16221ae3378b2e175d846b6b33ea3a20852cf5"}, 983 | ] 984 | typed-ast = [ 985 | {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, 986 | {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, 987 | {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, 988 | {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, 989 | {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, 990 | {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, 991 | {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, 992 | {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, 993 | {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, 994 | {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, 995 | {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, 996 | {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, 997 | {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, 998 | {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, 999 | {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, 1000 | {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, 1001 | {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, 1002 | {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, 1003 | {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, 1004 | {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, 1005 | {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, 1006 | {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, 1007 | {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, 1008 | {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, 1009 | {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, 1010 | {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, 1011 | {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, 1012 | {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, 1013 | {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, 1014 | {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, 1015 | ] 1016 | typer = [ 1017 | {file = "typer-0.3.2-py3-none-any.whl", hash = "sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b"}, 1018 | {file = "typer-0.3.2.tar.gz", hash = "sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303"}, 1019 | ] 1020 | typing-extensions = [ 1021 | {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, 1022 | {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, 1023 | {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, 1024 | ] 1025 | urllib3 = [ 1026 | {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, 1027 | {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, 1028 | ] 1029 | virtualenv = [ 1030 | {file = "virtualenv-20.2.1-py2.py3-none-any.whl", hash = "sha256:07cff122e9d343140366055f31be4dcd61fd598c69d11cd33a9d9c8df4546dd7"}, 1031 | {file = "virtualenv-20.2.1.tar.gz", hash = "sha256:e0aac7525e880a429764cefd3aaaff54afb5d9f25c82627563603f5d7de5a6e5"}, 1032 | ] 1033 | wrapt = [ 1034 | {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, 1035 | ] 1036 | zipp = [ 1037 | {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"}, 1038 | {file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"}, 1039 | ] 1040 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | # Poetry pyproject.toml: https://python-poetry.org/docs/pyproject/ 2 | 3 | [build-system] 4 | requires = ["poetry>=1.0"] 5 | build-backend = "poetry.masonry.api" 6 | 7 | [tool.poetry] 8 | name = "layer-to-layer-pytorch" 9 | version = "0.3.0" 10 | description = "PyTorch implementation of L2L execution algorithm" 11 | readme = "README.md" 12 | authors = [ 13 | "Roman Tezikov " 14 | ] 15 | license = "MIT" 16 | repository = "https://github.com/TezRomacH/layer-to-layer-pytorch" 17 | homepage = "https://github.com/TezRomacH/layer-to-layer-pytorch" 18 | 19 | # Keywords description https://python-poetry.org/docs/pyproject/#keywords 20 | keywords = [] # Update me 21 | 22 | # Pypi classifiers: https://pypi.org/classifiers/ 23 | classifiers = [ # Update me 24 | "Development Status :: 3 - Alpha", 25 | "Intended Audience :: Developers", 26 | "Operating System :: OS Independent", 27 | "Topic :: Software Development :: Libraries :: Python Modules", 28 | ] 29 | 30 | [tool.poetry.scripts] 31 | # Entry points for the package https://python-poetry.org/docs/pyproject/#scripts 32 | "layer-to-layer-pytorch" = "layer_to_layer_pytorch.__main__:app" 33 | 34 | [tool.poetry.dependencies] 35 | python = "^3.7" 36 | importlib_metadata = {version = ">=1.6,<4.0", python = "<3.8"} 37 | typer = {extras = ["all"], version = "^0.3.2"} 38 | torch = "^1.6.0" 39 | tqdm = "^4.50.0" 40 | numpy = "^1.19.1" 41 | 42 | [tool.poetry.dev-dependencies] 43 | darglint = "^1.5.8" 44 | isort = "^5.6.4" 45 | pyupgrade = "^2.7.4" 46 | black = "^20.8b1" 47 | mypy = "^0.790" 48 | bandit = "^1.7.0" 49 | safety = "^1.9.0" 50 | pytest = "^6.1.2" 51 | pylint = "^2.5.3" 52 | pydocstyle = "^5.0.2" 53 | pre-commit = "^2.9.2" 54 | 55 | [tool.black] 56 | # https://github.com/psf/black 57 | line-length = 80 58 | target-version = ["py37"] 59 | 60 | [tool.isort] 61 | # https://github.com/timothycrosley/isort/ 62 | known_typing = "typing,types,typing_extensions,mypy,mypy_extensions" 63 | sections = "FUTURE,TYPING,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER" 64 | include_trailing_comma = true 65 | multi_line_output = 3 66 | indent = 4 67 | force_grid_wrap = 0 68 | use_parentheses = true 69 | line_length = 80 70 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | click==7.1.2 \ 2 | --hash=sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc \ 3 | --hash=sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a 4 | colorama==0.4.3 \ 5 | --hash=sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff \ 6 | --hash=sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1 7 | future==0.18.2 \ 8 | --hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d 9 | importlib-metadata==2.0.0; python_version < "3.8" \ 10 | --hash=sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3 \ 11 | --hash=sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da 12 | numpy==1.19.2 \ 13 | --hash=sha256:b594f76771bc7fc8a044c5ba303427ee67c17a09b36e1fa32bde82f5c419d17a \ 14 | --hash=sha256:e6ddbdc5113628f15de7e4911c02aed74a4ccff531842c583e5032f6e5a179bd \ 15 | --hash=sha256:3733640466733441295b0d6d3dcbf8e1ffa7e897d4d82903169529fd3386919a \ 16 | --hash=sha256:4339741994c775396e1a274dba3609c69ab0f16056c1077f18979bec2a2c2e6e \ 17 | --hash=sha256:7c6646314291d8f5ea900a7ea9c4261f834b5b62159ba2abe3836f4fa6705526 \ 18 | --hash=sha256:7118f0a9f2f617f921ec7d278d981244ba83c85eea197be7c5a4f84af80a9c3c \ 19 | --hash=sha256:9a3001248b9231ed73894c773142658bab914645261275f675d86c290c37f66d \ 20 | --hash=sha256:967c92435f0b3ba37a4257c48b8715b76741410467e2bdb1097e8391fccfae15 \ 21 | --hash=sha256:d526fa58ae4aead839161535d59ea9565863bb0b0bdb3cc63214613fb16aced4 \ 22 | --hash=sha256:eb25c381d168daf351147713f49c626030dcff7a393d5caa62515d415a6071d8 \ 23 | --hash=sha256:62139af94728d22350a571b7c82795b9d59be77fc162414ada6c8b6a10ef5d02 \ 24 | --hash=sha256:0c66da1d202c52051625e55a249da35b31f65a81cb56e4c69af0dfb8fb0125bf \ 25 | --hash=sha256:2117536e968abb7357d34d754e3733b0d7113d4c9f1d921f21a3d96dec5ff716 \ 26 | --hash=sha256:54045b198aebf41bf6bf4088012777c1d11703bf74461d70cd350c0af2182e45 \ 27 | --hash=sha256:aba1d5daf1144b956bc87ffb87966791f5e9f3e1f6fab3d7f581db1f5b598f7a \ 28 | --hash=sha256:addaa551b298052c16885fc70408d3848d4e2e7352de4e7a1e13e691abc734c1 \ 29 | --hash=sha256:58d66a6b3b55178a1f8a5fe98df26ace76260a70de694d99577ddeab7eaa9a9d \ 30 | --hash=sha256:59f3d687faea7a4f7f93bd9665e5b102f32f3fa28514f15b126f099b7997203d \ 31 | --hash=sha256:cebd4f4e64cfe87f2039e4725781f6326a61f095bc77b3716502bed812b385a9 \ 32 | --hash=sha256:c35a01777f81e7333bcf276b605f39c872e28295441c265cd0c860f4b40148c1 \ 33 | --hash=sha256:d7ac33585e1f09e7345aa902c281bd777fdb792432d27fca857f39b70e5dd31c \ 34 | --hash=sha256:04c7d4ebc5ff93d9822075ddb1751ff392a4375e5885299445fcebf877f179d5 \ 35 | --hash=sha256:51ee93e1fac3fe08ef54ff1c7f329db64d8a9c5557e6c8e908be9497ac76374b \ 36 | --hash=sha256:1669ec8e42f169ff715a904c9b2105b6640f3f2a4c4c2cb4920ae8b2785dac65 \ 37 | --hash=sha256:0bfd85053d1e9f60234f28f63d4a5147ada7f432943c113a11afcf3e65d9d4c8 \ 38 | --hash=sha256:0d310730e1e793527065ad7dde736197b705d0e4c9999775f212b03c44a8484c 39 | shellingham==1.3.2 \ 40 | --hash=sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044 \ 41 | --hash=sha256:576c1982bea0ba82fb46c36feb951319d7f42214a82634233f58b40d858a751e 42 | torch==1.6.0 \ 43 | --hash=sha256:7669f4d923b5758e28b521ea749c795ed67ff24b45ba20296bc8cff706d08df8 \ 44 | --hash=sha256:728facb972a5952323c6d790c2c5922b2b35c44b0bc7bdfa02f8639727671a0c \ 45 | --hash=sha256:87d65c01d1b70bb46070824f28bfd93c86d3c5c56b90cbbe836a3f2491d91c76 \ 46 | --hash=sha256:3838bd01af7dfb1f78573973f6842ce75b17e8e4f22be99c891dcb7c94bc13f5 \ 47 | --hash=sha256:5357873e243bcfa804c32dc341f564e9a4c12addfc9baae4ee857fcc09a0a216 \ 48 | --hash=sha256:4f9a4ad7947cef566afb0a323d99009fe8524f0b0f2ca1fb7ad5de0400381a5b 49 | tqdm==4.50.0 \ 50 | --hash=sha256:2dd75fdb764f673b8187643496fcfbeac38348015b665878e582b152f3391cdb \ 51 | --hash=sha256:93b7a6a9129fce904f6df4cf3ae7ff431d779be681a95c3344c26f3e6c09abfa 52 | typer==0.3.2 \ 53 | --hash=sha256:ba58b920ce851b12a2d790143009fa00ac1d05b3ff3257061ff69dbdfc3d161b \ 54 | --hash=sha256:5455d750122cff96745b0dec87368f56d023725a7ebc9d2e54dd23dc86816303 55 | zipp==3.3.0; python_version < "3.8" \ 56 | --hash=sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066 \ 57 | --hash=sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b 58 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | # All configuration for plugins and other utils is defined here. 2 | # Read more about `setup.cfg`: 3 | # https://docs.python.org/3/distutils/configfile.html 4 | 5 | [darglint] 6 | # darglint configuration: 7 | # https://github.com/terrencepreilly/darglint 8 | strictness = long 9 | docstring_style = google 10 | 11 | [mypy] 12 | # mypy configurations: http://bit.ly/2zEl9WI 13 | python_version = 3.7 14 | pretty = True 15 | allow_redefinition = False 16 | check_untyped_defs = True 17 | disallow_any_generics = True 18 | disallow_incomplete_defs = True 19 | ignore_missing_imports = True 20 | implicit_reexport = False 21 | strict_optional = True 22 | strict_equality = True 23 | no_implicit_optional = True 24 | warn_no_return = True 25 | warn_unused_ignores = True 26 | warn_redundant_casts = True 27 | warn_unused_configs = True 28 | warn_return_any = True 29 | warn_unreachable = True 30 | show_error_codes = True 31 | show_column_numbers = True 32 | show_error_context = True 33 | 34 | # plugins = pydantic.mypy, sqlmypy 35 | 36 | # [pydantic-mypy] 37 | # init_typed = True 38 | # warn_untyped_fields = True 39 | 40 | [tool:pytest] 41 | # Directories that are not visited by pytest collector: 42 | norecursedirs = *.egg .eggs dist build docs .tox .git __pycache__ 43 | doctest_optionflags = NUMBER NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL 44 | 45 | # Extra options: 46 | addopts = 47 | --strict 48 | --tb=short 49 | --doctest-modules 50 | --doctest-continue-on-failure 51 | -------------------------------------------------------------------------------- /tests/test_verison/test_hello.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from layer_to_layer_pytorch import __version__ 4 | 5 | 6 | def test_hello(): 7 | """Example test""" 8 | assert __version__ is not None 9 | --------------------------------------------------------------------------------