From e0bb3cdbb3538c503e73a19ae6f6f994163f23de Mon Sep 17 00:00:00 2001 From: Xuehai Pan Date: Tue, 26 Jul 2022 15:44:35 +0800 Subject: [PATCH] ver: bump version to 0.4.2 (#31) * ver: bump version to 0.4.2 * docs(CHANGELOG): add CHANGELOG.md * docs: update dictionary * docs: update authors * feat(workflows): test wheels before release * fix(workflows): remove single-quotes in env files * chore(workflows): update triggers * chore: install torchopt in conda environment * chore(.gitignore): ignore wheelhouse * style: update pylint magic comments * chore(conda-recipe): add patchelf * chore(workflows): update triggers * feat: manylinux wheels * docs: update install instruction * chore(workflows): list wheels with size * chore(workflows): use pypa/gh-action-pypi-publish to upload packages * docs: add badges * fix(workflows): show wheels one-by-one * docs: update contribution guide line * chore(pyproject): use pyproject.toml * chore: support str for accelerated_op_available * chore(workflows): test wheels with CPU build of torch * docs: update CHANGELOG * fix(accelerated_op): skip checking op on cuda devices when CUDA is not available * chore: update conda-recipe.yaml * docs: update CHANGELOG * docs: update badges * chore: remove pip edit install in conda recipe --- .github/workflows/build.yml | 202 ++++++++++++++++++ .github/workflows/lint.yml | 13 +- .github/workflows/release.yml | 98 --------- .github/workflows/tests.yml | 24 ++- .gitignore | 3 +- .pre-commit-config.yaml | 1 - CHANGELOG.md | 57 +++++ CITATION.cff | 8 +- Makefile | 4 +- README.md | 20 +- conda-recipe.yaml | 7 +- docs/source/developer/contributing.rst | 28 +++ docs/source/developer/contributor.rst | 1 - docs/source/index.rst | 15 +- docs/source/spelling_wordlist.txt | 2 + pyproject.toml | 101 +++++++++ setup.cfg | 42 ---- setup.py | 42 ---- torchopt/_src/accelerated_op/__init__.py | 11 +- .../_src/accelerated_op/adam_op/adam_op.py | 14 +- torchopt/version.py | 2 +- 21 files changed, 475 insertions(+), 220 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/release.yml create mode 100644 CHANGELOG.md create mode 100644 pyproject.toml delete mode 100644 setup.cfg diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..8b26e861 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,202 @@ +name: Build + +on: + push: + branches: + - main # allow to trigger the workflow with tag push event + pull_request: + paths: + - setup.py + - setup.cfg + - pyproject.toml + - MANIFEST.in + - CMakeLists.txt + - include/** + - src/** + - torchopt/version.py + - .github/workflow/build.yml + release: + types: + - published + # Allow to trigger the workflow manually + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + build: + runs-on: ubuntu-18.04 + if: github.repository == 'metaopt/TorchOpt' && (github.event_name != 'push' || startsWith(github.ref, 'refs/tags/')) + timeout-minutes: 45 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "recursive" + fetch-depth: 1 + + - name: Set up Python 3.7 + id: py37 + uses: actions/setup-python@v4 + with: + python-version: "3.7" + update-environment: false + + - name: Set up Python 3.8 + id: py38 + uses: actions/setup-python@v4 + with: + python-version: "3.8" + update-environment: false + + - name: Set up Python 3.9 + id: py39 + uses: actions/setup-python@v4 + with: + python-version: "3.9" + update-environment: false + + - name: Set up Python 3.10 + id: py310 + uses: actions/setup-python@v4 + with: + python-version: "3.10" + update-environment: false + + - name: Set up Python executable paths + run: | + echo "${{ steps.py37.outputs.python-path }}" > .python-paths + echo "${{ steps.py38.outputs.python-path }}" >> .python-paths + echo "${{ steps.py39.outputs.python-path }}" >> .python-paths + echo "${{ steps.py310.outputs.python-path }}" >> .python-paths + + - name: Setup CUDA Toolkit + uses: Jimver/cuda-toolkit@v0.2.7 + id: cuda-toolkit + with: + cuda: "11.6.2" + method: network + sub-packages: '["nvcc"]' + - run: | + CUDA_VERSION="${{steps.cuda-toolkit.outputs.cuda}}" + echo "CUDA_VERSION=${CUDA_VERSION}" >> "${GITHUB_ENV}" + TORCH_INDEX_URL="https://download.pytorch.org/whl/cu$(echo "${CUDA_VERSION}" | cut -d'.' -f-2 | tr -d '.')" + echo "TORCH_INDEX_URL=${TORCH_INDEX_URL}" >> "${GITHUB_ENV}" + + echo "Installed CUDA version is: ${CUDA_VERSION}" + echo "CUDA install location: ${{steps.cuda-toolkit.outputs.CUDA_PATH}}" + nvcc -V + echo "Torch index URL: ${TORCH_INDEX_URL}" + + - name: Build sdist and wheels + run: | + DEFAULT_PYTHON="$(head -n 1 .python-paths)" + + while read -r PYTHON; do + echo "Building wheel with Python: ${PYTHON} ($("${PYTHON}" --version))" + "${PYTHON}" -m pip install --upgrade pip setuptools wheel build + "${PYTHON}" -m pip install --extra-index-url "${TORCH_INDEX_URL}" \ + -r requirements.txt + if [[ "${PYTHON}" == "${DEFAULT_PYTHON}" ]]; then + "${PYTHON}" -m build + else + "${PYTHON}" -m build --wheel + fi + done < .python-paths + + - name: List built sdist and wheels + run: | + if [[ -n "$(find dist -maxdepth 0 -not -empty -print 2>/dev/null)" ]]; then + echo "Built sdist and wheels:" + ls -lh dist/ + else + echo "No sdist and wheels are built." + exit 1 + fi + + - name: Audit and repair wheels + run: | + while read -r PYTHON; do + PYVER="cp$("${PYTHON}" --version | cut -d ' ' -f2 | cut -d '.' -f-2 | tr -d '.')" + echo "Audit and repair wheel for Python: ${PYTHON} (${PYVER})" + LIBTORCH_PATH="$("${PYTHON}" -c 'import os, site; print(os.path.join(site.getsitepackages()[0], "torch", "lib"))')" + "${PYTHON}" -m pip install --upgrade git+https://github.com/XuehaiPan/auditwheel.git@torchopt + ( + export LD_LIBRARY_PATH="${LIBTORCH_PATH}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" + echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" + "${PYTHON}" -m auditwheel show dist/torchopt-*-${PYVER}-*.whl && + "${PYTHON}" -m auditwheel repair --plat manylinux2014_x86_64 --wheel-dir wheelhouse dist/torchopt-*-${PYVER}-*.whl + ) + done < .python-paths + + rm dist/torchopt-*.whl + mv wheelhouse/torchopt-*manylinux*.whl dist/ + + - name: List built sdist and wheels + run: | + if [[ -n "$(find dist -maxdepth 0 -not -empty -print 2>/dev/null)" ]]; then + echo "Built sdist and wheels:" + ls -lh dist/ + else + echo "No sdist and wheels are built." + exit 1 + fi + + - name: Test sdist and wheels + run: | + DEFAULT_PYTHON="$(head -n 1 .python-paths)" + while read -r PYTHON; do + PYVER="cp$("${PYTHON}" --version | cut -d ' ' -f2 | cut -d '.' -f-2 | tr -d '.')" + mkdir -p "temp-${PYVER}" + pushd "temp-${PYVER}" + if [[ "${PYTHON}" == "${DEFAULT_PYTHON}" ]]; then + echo "Testing sdist with Python: ${PYTHON} (${PYVER})" + "${PYTHON}" -m pip uninstall torch torchopt -y + "${PYTHON}" -m pip install --extra-index-url https://download.pytorch.org/whl/cpu \ + ../dist/torchopt-*.tar.gz + "${PYTHON}" -c 'import torchopt' + fi + echo "Testing wheel with Python: ${PYTHON} (${PYVER})" + "${PYTHON}" -m pip uninstall torch torchopt -y + "${PYTHON}" -m pip install --extra-index-url https://download.pytorch.org/whl/cpu \ + ../dist/torchopt-*-${PYVER}-*.whl + "${PYTHON}" -c 'import torchopt' + "${PYTHON}" -m pip uninstall torch torchopt -y + popd + done < .python-paths + + - name: Check consistency between the package version and release tag + if: startsWith(github.ref, 'refs/tags/') + run: | + RELEASE_TAG="${GITHUB_REF#refs/*/}" + PACKAGE_VER="v$(python setup.py --version)" + if [[ "${PACKAGE_VER}" != "${RELEASE_TAG}" ]]; then + echo "package ver. (${PACKAGE_VER}) != release tag. (${RELEASE_TAG})" + exit 1 + fi + + - name: Publish to TestPyPI + if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' + uses: pypa/gh-action-pypi-publish@v1.5.0 + with: + user: __token__ + password: ${{ secrets.TESTPYPI_UPLOAD_TOKEN }} + repository_url: https://test.pypi.org/legacy/ + verbose: true + print_hash: true + skip_existing: true + + - name: Publish to PyPI + if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' + uses: pypa/gh-action-pypi-publish@v1.5.0 + with: + user: __token__ + password: ${{ secrets.PYPI_UPLOAD_TOKEN }} + verbose: true + print_hash: true + skip_existing: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 35b9d2a1..f2393c77 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,16 +9,15 @@ on: permissions: contents: read +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: lint: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - name: Cancel previous run - uses: styfle/cancel-workflow-action@0.10.0 - with: - access_token: ${{ github.token }} - - name: Checkout uses: actions/checkout@v3 with: @@ -40,9 +39,9 @@ jobs: sub-packages: '["nvcc"]' - run: | CUDA_VERSION="${{steps.cuda-toolkit.outputs.cuda}}" - echo "CUDA_VERSION='${CUDA_VERSION}'" >> "${GITHUB_ENV}" + echo "CUDA_VERSION=${CUDA_VERSION}" >> "${GITHUB_ENV}" TORCH_INDEX_URL="https://download.pytorch.org/whl/cu$(echo "${CUDA_VERSION}" | cut -d'.' -f-2 | tr -d '.')" - echo "TORCH_INDEX_URL='${TORCH_INDEX_URL}'" >> "${GITHUB_ENV}" + echo "TORCH_INDEX_URL=${TORCH_INDEX_URL}" >> "${GITHUB_ENV}" echo "Installed CUDA version is: ${CUDA_VERSION}" echo "CUDA install location: ${{steps.cuda-toolkit.outputs.CUDA_PATH}}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index ceb45f06..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: PyPI - -on: - release: - types: [created] - -jobs: - deploy: - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: "recursive" - fetch-depth: 1 - - - name: Set up Python 3.7 - id: py37 - uses: actions/setup-python@v4 - with: - python-version: "3.7" - update-environment: false - - - name: Set up Python 3.8 - id: py38 - uses: actions/setup-python@v4 - with: - python-version: "3.8" - update-environment: false - - - name: Set up Python 3.9 - id: py39 - uses: actions/setup-python@v4 - with: - python-version: "3.9" - update-environment: false - - - name: Set up Python 3.10 - id: py310 - uses: actions/setup-python@v4 - with: - python-version: "3.10" - update-environment: false - - - name: Set up Python executable paths - run: | - DEFAULT_PYTHON="${{ steps.py37.outputs.python-path }}" - echo "DEFAULT_PYTHON='${DEFAULT_PYTHON}'" >> "${GITHUB_ENV}" - - PYTHON_EXECUTABLES="${{ steps.py37.outputs.python-path }}" - PYTHON_EXECUTABLES="${PYTHON_EXECUTABLES}:${{ steps.py38.outputs.python-path }}" - PYTHON_EXECUTABLES="${PYTHON_EXECUTABLES}:${{ steps.py39.outputs.python-path }}" - PYTHON_EXECUTABLES="${PYTHON_EXECUTABLES}:${{ steps.py310.outputs.python-path }}" - echo "PYTHON_EXECUTABLES='${PYTHON_EXECUTABLES}'" >> "${GITHUB_ENV}" - - - name: Check consistency between the package version and release tag - run: | - RELEASE_VER="${GITHUB_REF#refs/*/}" - PACKAGE_VER="v$(python setup.py --version)" - if [[ "${RELEASE_VER}" != "${PACKAGE_VER}" ]]; then - echo "package ver. (${PACKAGE_VER}) != release ver. (${RELEASE_VER})" - exit 1 - fi - - - name: Setup CUDA Toolkit - uses: Jimver/cuda-toolkit@v0.2.7 - id: cuda-toolkit - with: - cuda: "11.6.2" - method: network - sub-packages: '["nvcc"]' - - run: | - echo "Installed CUDA version is: ${{steps.cuda-toolkit.outputs.cuda}}" - echo "CUDA install location: ${{steps.cuda-toolkit.outputs.CUDA_PATH}}" - nvcc -V - - - name: Build sdist and wheels - run: | - while IFS='' read -rd':' PYTHON || [[ -n "${PYTHON}" ]]; do - [[ -z "${PYTHON}" ]] && continue - echo "Building wheel with Python: ${PYTHON} ($("${PYTHON}" --version))" - "${PYTHON}" -m pip install --upgrade pip setuptools wheel build - if [[ "${PYTHON}" == "${DEFAULT_PYTHON}" ]]; then - "${PYTHON}" -m build - else - "${PYTHON}" -m build --wheel - fi - done <<< "${PYTHON_EXECUTABLES}" - - - name: Publish to PyPI - env: - TWINE_USERNAME: "__token__" - TWINE_PASSWORD: ${{ secrets.PYPI_UPLOAD_TOKEN }} - run: | - "${DEFAULT_PYTHON}" -m pip install --upgrade twine - "${DEFAULT_PYTHON}" -m twine upload --repository testpypi dist/* - "${DEFAULT_PYTHON}" -m twine upload --repository pypi dist/* diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f67d9b46..5c62ff1b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,20 +5,30 @@ on: branches: - main pull_request: + paths: + - setup.py + - setup.cfg + - pyproject.toml + - MANIFEST.in + - CMakeLists.txt + - include/** + - src/** + - tests/** + - torchopt/** + - .github/workflows/tests.yml permissions: contents: read +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: test: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - name: Cancel previous run - uses: styfle/cancel-workflow-action@0.10.0 - with: - access_token: ${{ github.token }} - - name: Checkout uses: actions/checkout@v3 with: @@ -40,9 +50,9 @@ jobs: sub-packages: '["nvcc"]' - run: | CUDA_VERSION="${{steps.cuda-toolkit.outputs.cuda}}" - echo "CUDA_VERSION='${CUDA_VERSION}'" >> "${GITHUB_ENV}" + echo "CUDA_VERSION=${CUDA_VERSION}" >> "${GITHUB_ENV}" TORCH_INDEX_URL="https://download.pytorch.org/whl/cu$(echo "${CUDA_VERSION}" | cut -d'.' -f-2 | tr -d '.')" - echo "TORCH_INDEX_URL='${TORCH_INDEX_URL}'" >> "${GITHUB_ENV}" + echo "TORCH_INDEX_URL=${TORCH_INDEX_URL}" >> "${GITHUB_ENV}" echo "Installed CUDA version is: ${CUDA_VERSION}" echo "CUDA install location: ${{steps.cuda-toolkit.outputs.CUDA_PATH}}" diff --git a/.gitignore b/.gitignore index 5deaf2bb..e195bfa9 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ parts/ sdist/ var/ wheels/ +wheelhouse/ share/python-wheels/ *.egg-info/ .installed.cfg @@ -169,7 +170,7 @@ cython_debug/ .LSOverride # Icon must end with two \r -Icon +Icon # Thumbnails ._* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e1fda090..9849236f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,6 @@ repos: rev: 22.6.0 hooks: - id: black - args: [--safe, -S, -t, py37, -l, '100'] stages: [commit, push, manual] - repo: local hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..70cbe2e8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,57 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +------ + +## [Unreleased] + +------ + +## [0.4.2] - 2022-07-26 + +### Added + +- Read the Docs integration by [@Benjamin-eecs](https://github.com/Benjamin-eecs) and [@XuehaiPan](https://github.com/XuehaiPan) in [#34](https://github.com/metaopt/TorchOpt/pull/34). +- Update documentation and code styles by [@Benjamin-eecs](https://github.com/Benjamin-eecs) and [@XuehaiPan](https://github.com/XuehaiPan) in [#22](https://github.com/metaopt/TorchOpt/pull/22). +- Update tutorial notebooks by [@XuehaiPan](https://github.com/XuehaiPan) in [#27](https://github.com/metaopt/TorchOpt/pull/27). +- Bump PyTorch version to 1.12 by [@XuehaiPan](https://github.com/XuehaiPan) in [#25](https://github.com/metaopt/TorchOpt/pull/25). +- Support custom Python executable path in `CMakeLists.txt` by [@XuehaiPan](https://github.com/XuehaiPan) in [#18](https://github.com/metaopt/TorchOpt/pull/18). +- Add citation information by [@waterhorse1](https://github.com/waterhorse1) in [#14](https://github.com/metaopt/TorchOpt/pull/14) and [@Benjamin-eecs](https://github.com/Benjamin-eecs) in [#15](https://github.com/metaopt/TorchOpt/pull/15). +- Implement RMSProp optimizer by [@future-xy](https://github.com/future-xy) in [#8](https://github.com/metaopt/TorchOpt/pull/8). + +### Changed + +- Use `pyproject.toml` for packaging and update GitHub Action workflows by [@XuehaiPan](https://github.com/XuehaiPan) in [#31](https://github.com/metaopt/TorchOpt/pull/31). +- Rename the package from `TorchOpt` to `torchopt` by [@XuehaiPan](https://github.com/XuehaiPan) in [#20](https://github.com/metaopt/TorchOpt/pull/20). + +### Fixed + +- Fixed errors while building from the source and add `conda` environment recipe by [@XuehaiPan](https://github.com/XuehaiPan) in [#24](https://github.com/metaopt/TorchOpt/pull/24). + +------ + +## [0.4.1] - 2022-04-15 + +### Fixed + +- Fix set devices bug for multi-GPUs. + +------ + +## [0.4.0] - 2022-04-09 + +### Added + +- The first beta release of TorchOpt. +- TorchOpt with L2R, LOLA, MAML-RL, MGRL, and few-shot examples. + +------ + +[Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.4.2...HEAD +[0.4.2]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.4.1...v0.4.2 +[0.4.1]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.4.0...v0.4.1 +[0.4.0]: https://github.com/olivierlacan/keep-a-changelog/releases/tag/v0.4.0 diff --git a/CITATION.cff b/CITATION.cff index 5c239556..60c65cb3 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -16,6 +16,10 @@ authors: email: benjaminliu.eecs@gmail.com affiliation: Peking University orcid: 'https://orcid.org/0000-0001-5426-515X' + - given-names: Xuehai + family-names: Pan + email: xuehaipan@pku.edu.cn + affiliation: Peking University - given-names: Luo family-names: Mai email: luo.mai@ed.ac.uk @@ -24,7 +28,7 @@ authors: family-names: Yang affiliation: Peking University email: yaodong.yang@pku.edu.cn -version: 0.4.1 -date-released: "2022-04-09" +version: 0.4.2 +date-released: "2022-07-26" license: Apache-2.0 repository-code: "https://github.com/metaopt/TorchOpt" diff --git a/Makefile b/Makefile index f6de2a06..f050cf1f 100644 --- a/Makefile +++ b/Makefile @@ -96,7 +96,7 @@ flake8: flake8-install py-format: py-format-install $(PYTHON) -m isort --project torchopt --check $(PYTHON_FILES) && \ - $(PYTHON) -m black --safe -l 100 -t py37 -S --check $(PYTHON_FILES) + $(PYTHON) -m black --check $(PYTHON_FILES) mypy: mypy-install $(PYTHON) -m mypy $(PROJECT_PATH) @@ -135,7 +135,7 @@ lint: flake8 py-format mypy clang-format cpplint docstyle spelling format: py-format-install clang-format-install addlicense-install $(PYTHON) -m isort --project torchopt $(PYTHON_FILES) - $(PYTHON) -m black --safe -l 100 -t py37 -S $(PYTHON_FILES) + $(PYTHON) -m black $(PYTHON_FILES) clang-format -style=file -i $(CXX_FILES) addlicense -c $(COPYRIGHT) -l apache -y 2022 $(SOURCE_FOLDERS) diff --git a/README.md b/README.md index 37477bf9..c73ae163 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,15 @@ +![Python 3.7+](https://img.shields.io/badge/Python-3.7%2B-brightgreen.svg) +[![PyPI](https://img.shields.io/pypi/v/torchopt?label=PyPI)](https://pypi.org/project/torchopt) +![Status](https://img.shields.io/pypi/status/torchopt?label=Status) +![GitHub Workflow Status](https://img.shields.io/github/workflow/status/metaopt/TorchOpt/Tests?label=tests&logo=github) +[![Documentation Status](https://readthedocs.org/projects/torchopt/badge/?version=latest)](https://torchopt.readthedocs.io/en/latest/?badge=latest) +[![Downloads](https://static.pepy.tech/personalized-badge/torchopt?period=month&left_color=grey&right_color=blue&left_text=Downloads/month)](https://pepy.tech/project/torchopt) +[![GitHub Repo Stars](https://img.shields.io/github/stars/metaopt/torchopt?label=Stars&logo=github&color=brightgreen)](https://github.com/metaopt/torchopt/stargazers) +[![License](https://img.shields.io/github/license/metaopt/TorchOpt?label=License)](#license) + **TorchOpt** is a high-performance optimizer library built upon [PyTorch](https://pytorch.org/) for easy implementation of functional optimization and gradient-based meta-learning. It consists of two main features: - TorchOpt provides functional optimizer which enables [JAX-like](https://github.com/google/jax) composable functional optimizer for PyTorch. With TorchOpt, one can easily conduct neural network optimization in PyTorch with functional style optimizer, similar to [Optax](https://github.com/deepmind/optax) in JAX. @@ -25,6 +34,7 @@ The README is organized as follows: - [Visualization](#visualization) - [Installation](#installation) - [Future Plan](#future-plan) +- [Changelog](#changelog) - [The Team](#the-team) - [Citing TorchOpt](#citing-torchopt) @@ -209,6 +219,8 @@ Requirements - (Optional) For visualizing computation graphs - [Graphviz](https://graphviz.org/download/) (for Linux users use `apt/yum install graphviz` or `conda install -c anaconda python-graphviz`) +Please follow the instructions at to install PyTorch in your Python environment first. Then run the following command to install TorchOpt from PyPI ([![PyPI](https://img.shields.io/pypi/v/torchopt?label=PyPI)](https://pypi.org/project/torchopt) / ![Status](https://img.shields.io/pypi/status/torchopt?label=Status)): + ```bash pip3 install torchopt ``` @@ -242,11 +254,15 @@ pip3 install -e . - [ ] Support more optimizers such as AdamW, RMSProp - [ ] CPU-accelerated optimizer +## Changelog + +See [CHANGELOG.md](CHANGELOG.md). + -------------------------------------------------------------------------------- ## The Team -TorchOpt is a work by Jie Ren, Xidong Feng, [Bo Liu](https://github.com/Benjamin-eecs/), [Luo Mai](https://luomai.github.io/) and [Yaodong Yang](https://www.yangyaodong.com/). +TorchOpt is a work by Jie Ren, Xidong Feng, [Bo Liu](https://github.com/Benjamin-eecs), [Xuehai Pan](https://github.com/XuehaiPan), [Luo Mai](https://luomai.github.io/) and [Yaodong Yang](https://www.yangyaodong.com/). ## Citing TorchOpt @@ -254,7 +270,7 @@ If you find TorchOpt useful, please cite it in your publications. ```bibtex @software{TorchOpt, - author = {Jie Ren and Xidong Feng and Bo Liu and Luo Mai and Yaodong Yang}, + author = {Jie Ren and Xidong Feng and Bo Liu and Xuehai Pan and Luo Mai and Yaodong Yang}, title = {TorchOpt}, year = {2022}, publisher = {GitHub}, diff --git a/conda-recipe.yaml b/conda-recipe.yaml index 625a236c..3c10a3ed 100644 --- a/conda-recipe.yaml +++ b/conda-recipe.yaml @@ -26,21 +26,22 @@ dependencies: - sphinxcontrib-katex # for documentation - jax - jaxlib >= 0.3=*cuda* - - optax - - tensorboard + - optax # for tutorials + - tensorboard # for examples - wandb # Device select - nvidia::cudatoolkit = 11.6 - cudnn - # Build toolkit + # Build toolchain - cmake >= 3.4 - make - cxx-compiler - gxx = 10 - nvidia/label/cuda-11.6.2::cuda-nvcc - nvidia/label/cuda-11.6.2::cuda-cudart-dev + - patchelf >= 0.9 - pybind11 # Misc diff --git a/docs/source/developer/contributing.rst b/docs/source/developer/contributing.rst index 656736a3..278e2900 100644 --- a/docs/source/developer/contributing.rst +++ b/docs/source/developer/contributing.rst @@ -1,6 +1,34 @@ Contributing to TorchOpt ======================== +Before contributing to TorchOpt, please follow the instructions below to setup. + +1. Fork TorchOpt (`fork `_) on GitHub and clone the repository. + +.. code-block:: bash + + git clone git@github.com:/TorchOpt.git # use the SSH protocol + cd TorchOpt + + git remote add upstream git@github.com:metaopt/TorchOpt.git + +2. Setup a development environment via `conda `_: + +.. code-block:: bash + + # You may need `CONDA_OVERRIDE_CUDA` if conda fails to detect the NVIDIA driver (e.g. in docker or WSL2) + CONDA_OVERRIDE_CUDA=11.7 conda env create --file conda-recipe.yaml + + conda activate torchopt + +3. Setup the `pre-commit `_ hooks: + +.. code-block:: bash + + pre-commit install --install-hooks + +Then you are ready to rock. Thanks for contributing to TorchOpt! + Install Develop Version ----------------------- diff --git a/docs/source/developer/contributor.rst b/docs/source/developer/contributor.rst index e47a7c12..0f08d38a 100644 --- a/docs/source/developer/contributor.rst +++ b/docs/source/developer/contributor.rst @@ -3,5 +3,4 @@ Contributor We always welcome contributions to help make TorchOpt better. Below is an incomplete list of our contributors (find more on `this page `_). -* Xuehai Pan (`XuehaiPan `_) * Yao Fu (`future-xy `_) diff --git a/docs/source/index.rst b/docs/source/index.rst index 50ccb0fb..892a1090 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,8 +13,12 @@ Installation Requirements -(Optional) For visualizing computation graphs -`Graphviz `_ (for Linux users use ``apt/yum install graphviz`` or ``conda install -c anaconda python-graphviz``) +- PyTorch +- JAX +- (Optional) For visualizing computation graphs + - `Graphviz `_ (for Linux users use ``apt/yum install graphviz`` or ``conda install -c anaconda python-graphviz``) + +Please follow the instructions at https://pytorch.org to install PyTorch in your Python environment first. Then run the following command to install TorchOpt from PyPI: .. code-block:: bash @@ -39,7 +43,6 @@ We provide a `conda `_ environment recipe to ins CONDA_OVERRIDE_CUDA=11.7 conda env create --file conda-recipe.yaml conda activate torchopt - pip3 install -e . .. toctree:: @@ -77,6 +80,7 @@ TorchOpt is a work by * Jie Ren (`JieRen98 `_) * Xidong Feng (`waterhorse1 `_) * Bo Liu (`Benjamin-eecs `_) +* Xuehai Pan (`XuehaiPan `_) * Luo Mai (`luomai `_) * Yaodong Yang (`PKU-YYang `_). @@ -86,6 +90,11 @@ Support If you are having issues, please let us know by filing an issue on our `issue tracker `_. +Changelog +--------- + +See :gitcode:`CHANGELOG.md`. + License ------- diff --git a/docs/source/spelling_wordlist.txt b/docs/source/spelling_wordlist.txt index 24ee9124..db1e67a1 100644 --- a/docs/source/spelling_wordlist.txt +++ b/docs/source/spelling_wordlist.txt @@ -67,3 +67,5 @@ rmsprop RMSProp sgd SGD +CHANGELOG +Changelog diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..d76dd3dc --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,101 @@ +[build-system] +requires = ["setuptools", "torch == 1.12", "numpy", "pybind11"] +build-backend = "setuptools.build_meta" + +[project] +name = "torchopt" +description = "A Jax-style optimizer for PyTorch." +readme = "README.md" +requires-python = ">= 3.7" +authors = [ + {name = "TorchOpt Contributors"}, + {name = "Xuehai Pan", email = "XuehaiPan@pku.edu.cn"}, + {name = "Jie Ren", email = "jieren9806@gmail.com"}, + {name = "Xidong Feng", email = "xidong.feng.20@ucl.ac.uk"}, + {name = "Bo Liu", email = "benjaminliu.eecs@gmail.com"}, +] +license = {file = "LICENSE"} +keywords = [ + "PyTorch", + "functorch", + "JAX", + "Meta-Learning", + "Optimizer", + "Differentiable Optimizer", + "Functional Programming", +] +classifiers = [ + "Development Status :: 4 - Beta", + "License :: OSI Approved :: Apache Software License 2.0 (Apache-2.0)", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Operating System :: POSIX :: Linux", + "Environment :: GPU", + "Environment :: GPU :: NVIDIA CUDA", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Artificial Intelligence", +] +dependencies = [ + "torch == 1.12", + "jax[cpu] >= 0.3", + "numpy", + "graphviz", + "typing-extensions", +] +dynamic = [ + "version", +] + +[project.urls] +Homepage = "https://github.com/metaopt/TorchOpt" +Repository = "https://github.com/metaopt/TorchOpt" +Documentation = "https://torchopt.readthedocs.io" +"Bug Report" = "https://github.com/metaopt/TorchOpt/issues" + +[tool.setuptools.packages.find] +include = ["torchopt", "torchopt.*"] + +[tool.black] +safe = true +line-length = 100 +skip-string-normalization = true +target-version = ["py37", "py38", "py39", "py310"] + +[tool.isort] +profile = "black" +src_paths = ["torchopt", "examples", "tests"] +indent = 4 +line_length = 100 +lines_after_imports = 2 +multi_line_output = 3 + +[tool.mypy] +allow_redefinition = true +check_untyped_defs = true +disallow_incomplete_defs = false +disallow_untyped_defs = false +ignore_missing_imports = true +no_implicit_optional = true +pretty = true +show_error_codes = true +show_error_context = true +show_traceback = true +strict_equality = true +strict_optional = true +warn_no_return = true +warn_redundant_casts = true +warn_unreachable = true +warn_unused_configs = true +warn_unused_ignores = true + +[tool.pydocstyle] +convention = "google" + +[tool.doc8] +max-line-length = 500 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index c3438afe..00000000 --- a/setup.cfg +++ /dev/null @@ -1,42 +0,0 @@ -[black] -line-length = 100 -skip-string-normalization = True -target_version = ["py37"] - -[flake8] -exclude = - .git -indent_size = 4 - -[pydocstyle] -convention = google - -[isort] -profile = black -py_version=37 -indent = 4 -line_length = 100 -lines_after_imports = 2 -multi_line_output = 3 - -[mypy] -allow_redefinition = True -check_untyped_defs = True -disallow_incomplete_defs = False -disallow_untyped_defs = False -ignore_missing_imports = True -no_implicit_optional = True -pretty = True -show_error_codes = True -show_error_context = True -show_traceback = True -strict_equality = True -strict_optional = True -warn_no_return = True -warn_redundant_casts = True -warn_unreachable = True -warn_unused_configs = True -warn_unused_ignores = True - -[doc8] -max-line-length = 1000 diff --git a/setup.py b/setup.py index f399e14d..169a767c 100644 --- a/setup.py +++ b/setup.py @@ -80,51 +80,9 @@ def build_extension(self, ext): setup( - name='torchopt', version=version.__version__, - author='TorchOpt Contributors', - author_email='jieren9806@gmail.com, xidong.feng.20@ucl.ac.uk, benjaminliu.eecs@gmail.com', - description='A Jax-style optimizer for PyTorch.', - long_description=open('README.md', encoding='utf8').read(), - long_description_content_type='text/markdown', - license='Apache License Version 2.0', - keywords='Meta-Learning, PyTorch, Optimizer', - url='https://github.com/metaopt/TorchOpt', - packages=find_packages(include=['torchopt', 'torchopt.*']), package_data={'sharedlib': ['_lib/*.so']}, include_package_data=True, cmdclass={'build_ext': cmake_build_ext}, ext_modules=[CMakeExtension('torchopt._lib.adam_op', source_dir=HERE)], - setup_requires=[ # for `torch.utils.cpp_extension` - 'torch == 1.12', - 'numpy', - 'pybind11', - ], - install_requires=[ - 'torch == 1.12', - 'jax[cpu] >= 0.3', - 'numpy', - 'graphviz', - 'typing-extensions', - ], - python_requires='>= 3.7', - classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - 'Development Status :: 4 - Beta', - # Indicate who your project is intended for - 'Intended Audience :: Science/Research', - 'Intended Audience :: Developers', - 'Topic :: Scientific/Engineering :: Artificial Intelligence', - # Pick your license as you wish (should match "license" above) - 'License :: OSI Approved :: Apache Software License', - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - ], ) diff --git a/torchopt/_src/accelerated_op/__init__.py b/torchopt/_src/accelerated_op/__init__.py index 3eb1d44f..4c7f1cd9 100644 --- a/torchopt/_src/accelerated_op/__init__.py +++ b/torchopt/_src/accelerated_op/__init__.py @@ -13,12 +13,16 @@ # limitations under the License. # ============================================================================== +from typing import Iterable, Optional, Union + import torch from torchopt._src.accelerated_op.adam_op import AdamOp -def accelerated_op_available(devices=None): +def accelerated_op_available( + devices: Optional[Union[str, torch.device, Iterable[Union[str, torch.device]]]] = None +) -> bool: """Check the availability of accelerated optimizer.""" op = AdamOp() @@ -26,9 +30,14 @@ def accelerated_op_available(devices=None): devices = [torch.device('cuda'), torch.device('cpu')] elif isinstance(devices, torch.device): devices = [devices] + elif isinstance(devices, str): + devices = [torch.device(devices)] try: for device in devices: + device = torch.device(device) + if device.type == 'cuda' and not torch.cuda.is_available(): + return False updates = torch.tensor(1.0, device=device) op(updates, updates, updates, 1) return True diff --git a/torchopt/_src/accelerated_op/adam_op/adam_op.py b/torchopt/_src/accelerated_op/adam_op/adam_op.py index dac0697b..a59b00e6 100644 --- a/torchopt/_src/accelerated_op/adam_op/adam_op.py +++ b/torchopt/_src/accelerated_op/adam_op/adam_op.py @@ -30,7 +30,7 @@ class MuOp(torch.autograd.Function): # pylint: disable=abstract-method @staticmethod def jvp(ctx: Any, *grad_inputs: Any) -> Any: - # pylint: disable=line-too-long + # pylint: disable-next=line-too-long """Defines a formula for differentiating the operation with forward mode automatic differentiation.""" @staticmethod @@ -44,7 +44,7 @@ def forward(ctx: Any, *args: Any, **kwargs: Any) -> Any: @staticmethod def backward(ctx: Any, *args: Any) -> Any: - # pylint: disable=line-too-long + # pylint: disable-next=line-too-long """Defines a formula for differentiating the operation with backward mode automatic differentiation (alias to the :meth:`vjp` method).""" dmu = args[0] updates, mu = ctx.saved_tensors @@ -57,7 +57,7 @@ class NuOp(torch.autograd.Function): # pylint: disable=abstract-method @staticmethod def jvp(ctx: Any, *grad_inputs: Any) -> Any: - # pylint: disable=line-too-long + # pylint: disable-next=line-too-long """Defines a formula for differentiating the operation with forward mode automatic differentiation.""" @staticmethod @@ -71,7 +71,7 @@ def forward(ctx: Any, *args: Any, **kwargs: Any) -> Any: @staticmethod def backward(ctx: Any, *args: Any) -> Any: - # pylint: disable=line-too-long + # pylint: disable-next=line-too-long """Defines a formula for differentiating the operation with backward mode automatic differentiation (alias to the :meth:`vjp` function).""" dnu = args[0] updates, nu = ctx.saved_tensors @@ -84,7 +84,7 @@ class UpdatesOp(torch.autograd.Function): # pylint: disable=abstract-method @staticmethod def jvp(ctx: Any, *grad_inputs: Any) -> Any: - # pylint: disable=line-too-long + # pylint: disable-next=line-too-long """Defines a formula for differentiating the operation with forward mode automatic differentiation.""" @staticmethod @@ -98,7 +98,7 @@ def forward(ctx: Any, *args: Any, **kwargs: Any) -> Any: @staticmethod def backward(ctx: Any, *args: Any) -> Any: - # pylint: disable=line-too-long + # pylint: disable-next=line-too-long """Defines a formula for differentiating the operation with backward mode automatic differentiation (alias to the :meth:`vjp` function).""" dupdates = args[0] updates, new_mu, new_nu = ctx.saved_tensors @@ -106,7 +106,7 @@ def backward(ctx: Any, *args: Any) -> Any: result = adam_op.backwardUpdates(dupdates, updates, new_mu, new_nu, b1, b2, count) return result[0], result[1], None - # pylint: disable=too-many-arguments + # pylint: disable-next=too-many-arguments def __init__(self, b1=0.9, b2=0.999, eps=1e-8, eps_root=0.0, inplace=True): """The :meth:`__init__` function.""" self.b1 = b1 diff --git a/torchopt/version.py b/torchopt/version.py index 89c0c4c4..784a9a63 100644 --- a/torchopt/version.py +++ b/torchopt/version.py @@ -14,4 +14,4 @@ # ============================================================================== """TorchOpt: a high-performance optimizer library built upon PyTorch.""" -__version__ = '0.4.1' +__version__ = '0.4.2'