├── .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 | [](https://github.com/TezRomacH/layer-to-layer-pytorch/actions?query=workflow%3Abuild)
6 | [](https://pypi.org/project/layer-to-layer-pytorch/)
7 | [](https://github.com/TezRomacH/layer-to-layer-pytorch/pulls?utf8=%E2%9C%93&q=is%3Apr%20author%3Aapp%2Fdependabot)
8 |
9 | [](https://github.com/psf/black)
10 | [](https://github.com/PyCQA/bandit)
11 | [](https://github.com/TezRomacH/layer-to-layer-pytorch/blob/master/.pre-commit-config.yaml)
12 | [](https://github.com/TezRomacH/layer-to-layer-pytorch/releases)
13 | [](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 | [](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 |
--------------------------------------------------------------------------------