From 38bb60b4fd2ca04683701378d4b1fee392456d1d Mon Sep 17 00:00:00 2001 From: Janosh Riebesell Date: Thu, 8 Feb 2024 09:11:41 +0100 Subject: [PATCH] Fix release CI (#122) * update pre-commit hooks * pre-commit run --all-files * update GHA runner to macos-14 and pypa/cibuildwheel@v2.16.5 fixes release job, see https://github.com/pypa/cibuildwheel/issues/1740 --- .github/workflows/test.yml | 8 +- .pre-commit-config.yaml | 8 +- chgnet/utils/common_utils.py | 2 +- examples/basics.ipynb | 42 +++++------ examples/crystaltoolkit_relax_viewer.ipynb | 20 ++--- examples/fine_tuning.ipynb | 88 +++++++++++----------- pyproject.toml | 2 - tests/test_relaxation.py | 9 ++- 8 files changed, 91 insertions(+), 88 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3f0c747..af4e50e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-14, windows-latest] runs-on: ${{ matrix.os }} steps: @@ -29,7 +29,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: "3.10" cache: pip cache-dependency-path: pyproject.toml @@ -81,7 +81,7 @@ jobs: if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.task == 'release') strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, macos-14, windows-latest] python-version: ["39", "310", "311"] runs-on: ${{ matrix.os }} steps: @@ -89,7 +89,7 @@ jobs: uses: actions/checkout@v4 - name: Build wheels - uses: pypa/cibuildwheel@v2.16.2 + uses: pypa/cibuildwheel@v2.16.5 env: CIBW_BUILD: cp${{ matrix.python-version }}-* CIBW_ARCHS_MACOS: universal2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad6d3fe..5a50ba8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ default_install_hook_types: [pre-commit, commit-msg] repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.14 + rev: v0.2.1 hooks: - id: ruff args: [--fix] @@ -30,13 +30,13 @@ repos: args: [--check-filenames] - repo: https://github.com/kynan/nbstripout - rev: 0.6.1 + rev: 0.7.1 hooks: - id: nbstripout args: [--drop-empty-cells, --keep-output] - repo: https://github.com/pre-commit/mirrors-prettier - rev: v4.0.0-alpha.7 + rev: v4.0.0-alpha.8 hooks: - id: prettier args: [--write] # edit files in-place @@ -46,7 +46,7 @@ repos: - svelte - repo: https://github.com/pre-commit/mirrors-eslint - rev: v9.0.0-alpha.1 + rev: v9.0.0-alpha.2 hooks: - id: eslint types: [file] diff --git a/chgnet/utils/common_utils.py b/chgnet/utils/common_utils.py index 7407c0f..dd05ac2 100644 --- a/chgnet/utils/common_utils.py +++ b/chgnet/utils/common_utils.py @@ -73,7 +73,7 @@ def read_json(filepath: str) -> dict: filepath (str): file name of json to read. Returns: - dictionary stored in fjson + dict: data stored in filepath """ with open(filepath) as file: return json.load(file) diff --git a/examples/basics.ipynb b/examples/basics.ipynb index cedde93..030f091 100644 --- a/examples/basics.ipynb +++ b/examples/basics.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "f8c75a16", + "id": "0", "metadata": {}, "source": [ "# This notebook shows example to load the CHGNet for prediction\n" @@ -11,7 +11,7 @@ { "cell_type": "code", "execution_count": null, - "id": "87432e22", + "id": "1", "metadata": {}, "outputs": [], "source": [ @@ -25,7 +25,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7ead933c", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -42,7 +42,7 @@ }, { "cell_type": "markdown", - "id": "16eeae1e", + "id": "3", "metadata": {}, "source": [ "### Read structure from a json or cif file\n" @@ -51,7 +51,7 @@ { "cell_type": "code", "execution_count": null, - "id": "208fa4aa", + "id": "4", "metadata": {}, "outputs": [ { @@ -94,7 +94,7 @@ }, { "cell_type": "markdown", - "id": "abcc09b4", + "id": "5", "metadata": {}, "source": [ "### Define Model\n" @@ -103,7 +103,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c04a0993", + "id": "6", "metadata": {}, "outputs": [ { @@ -123,7 +123,7 @@ }, { "cell_type": "markdown", - "id": "961d51fc", + "id": "7", "metadata": {}, "source": [ "# Predict energy, force, stress, magmom\n" @@ -132,7 +132,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2c7c1997", + "id": "8", "metadata": { "pycharm": { "name": "#%%\n" @@ -181,7 +181,7 @@ }, { "cell_type": "markdown", - "id": "2258f2f5", + "id": "9", "metadata": {}, "source": [ "# Structure Optimization\n" @@ -190,7 +190,7 @@ { "cell_type": "code", "execution_count": null, - "id": "27dac383", + "id": "10", "metadata": {}, "outputs": [ { @@ -211,7 +211,7 @@ { "cell_type": "code", "execution_count": null, - "id": "04bc3159", + "id": "11", "metadata": {}, "outputs": [ { @@ -270,7 +270,7 @@ }, { "cell_type": "markdown", - "id": "06f7e84c", + "id": "12", "metadata": {}, "source": [ "# Molecular Dynamics\n" @@ -279,7 +279,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1a59a5b5", + "id": "13", "metadata": {}, "outputs": [ { @@ -316,7 +316,7 @@ }, { "cell_type": "markdown", - "id": "c6a10ec8", + "id": "14", "metadata": {}, "source": [ "# Magmom Visualization\n" @@ -325,7 +325,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2d5c2f93", + "id": "15", "metadata": {}, "outputs": [ { @@ -344,7 +344,7 @@ { "cell_type": "code", "execution_count": null, - "id": "db4c9f16", + "id": "16", "metadata": {}, "outputs": [ { @@ -368,7 +368,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a0fe8e50", + "id": "17", "metadata": {}, "outputs": [ { @@ -784,7 +784,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c96fb111", + "id": "18", "metadata": {}, "outputs": [], "source": [ @@ -797,7 +797,7 @@ { "cell_type": "code", "execution_count": null, - "id": "71ac47b1", + "id": "19", "metadata": {}, "outputs": [ { @@ -1862,7 +1862,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.6" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/examples/crystaltoolkit_relax_viewer.ipynb b/examples/crystaltoolkit_relax_viewer.ipynb index 120f162..e8e762a 100644 --- a/examples/crystaltoolkit_relax_viewer.ipynb +++ b/examples/crystaltoolkit_relax_viewer.ipynb @@ -3,7 +3,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "f8c75a16", + "id": "0", "metadata": {}, "source": [ "# Crystaltoolkit Relaxation Viewer\n", @@ -14,7 +14,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "a51da8f4", + "id": "1", "metadata": {}, "source": [ "Running the last cell in this notebook should spin up a `dash` app that looks like this:\n", @@ -25,7 +25,7 @@ { "cell_type": "code", "execution_count": null, - "id": "156e8031", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -42,7 +42,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7ead933c", + "id": "3", "metadata": {}, "outputs": [], "source": [ @@ -53,7 +53,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e6792912", + "id": "4", "metadata": {}, "outputs": [], "source": [ @@ -72,7 +72,7 @@ { "cell_type": "code", "execution_count": null, - "id": "208fa4aa", + "id": "5", "metadata": {}, "outputs": [ { @@ -100,7 +100,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5d6e9fcc", + "id": "6", "metadata": {}, "outputs": [ { @@ -218,7 +218,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c04ebd43", + "id": "7", "metadata": {}, "outputs": [], "source": [ @@ -235,7 +235,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e7a91576", + "id": "8", "metadata": {}, "outputs": [ { @@ -256,7 +256,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c9f16422", + "id": "9", "metadata": {}, "outputs": [ { diff --git a/examples/fine_tuning.ipynb b/examples/fine_tuning.ipynb index 4984dba..04ea00f 100644 --- a/examples/fine_tuning.ipynb +++ b/examples/fine_tuning.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "f8c75a16", + "id": "0", "metadata": {}, "source": [ "# Fine-tune the pretrained CHGNet for better accuracy\n" @@ -11,7 +11,7 @@ { "cell_type": "code", "execution_count": null, - "id": "efcadf94", + "id": "1", "metadata": {}, "outputs": [], "source": [ @@ -25,7 +25,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7ead933c", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -38,7 +38,7 @@ }, { "cell_type": "markdown", - "id": "16eeae1e", + "id": "3", "metadata": {}, "source": [ "## 0. Parse DFT outputs to CHGNet readable formats\n" @@ -46,7 +46,7 @@ }, { "cell_type": "markdown", - "id": "286c110a", + "id": "4", "metadata": {}, "source": [ "CHGNet is interfaced to [Pymatgen](https://pymatgen.org/), the training samples (normally coming from different DFTs like VASP),\n", @@ -58,7 +58,7 @@ { "cell_type": "code", "execution_count": null, - "id": "72ada11a", + "id": "5", "metadata": { "pycharm": { "name": "#%%\n" @@ -75,7 +75,7 @@ }, { "cell_type": "markdown", - "id": "b8b3a8cd", + "id": "6", "metadata": {}, "source": [ "After the DFT calculations are parsed, we can save the parsed structures and labels to disk,\n", @@ -90,7 +90,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a9a74cae", + "id": "7", "metadata": { "pycharm": { "name": "#%%\n" @@ -128,7 +128,7 @@ }, { "cell_type": "markdown", - "id": "61c551cd", + "id": "8", "metadata": {}, "source": [ "For other types of DFT calculations, please refer to their interfaces\n", @@ -143,7 +143,7 @@ }, { "cell_type": "markdown", - "id": "e1611921", + "id": "9", "metadata": {}, "source": [ "## 1. Prepare Training Data\n" @@ -151,7 +151,7 @@ }, { "cell_type": "markdown", - "id": "9ec2524a", + "id": "10", "metadata": {}, "source": [ "Below we will create a dummy fine-tuning dataset by using CHGNet prediction with some random noise.\n", @@ -161,7 +161,7 @@ { "cell_type": "code", "execution_count": null, - "id": "667d849f", + "id": "11", "metadata": {}, "outputs": [], "source": [ @@ -198,7 +198,7 @@ }, { "cell_type": "markdown", - "id": "052536e6", + "id": "12", "metadata": {}, "source": [ "Note that the stress output from CHGNet is in unit of GPa, here the -10 unit conversion\n", @@ -208,7 +208,7 @@ }, { "cell_type": "markdown", - "id": "aea8393e", + "id": "13", "metadata": {}, "source": [ "## 2. Define DataSet\n" @@ -217,7 +217,7 @@ { "cell_type": "code", "execution_count": null, - "id": "dd9f19e3", + "id": "14", "metadata": {}, "outputs": [], "source": [ @@ -227,7 +227,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3e96c4ac", + "id": "15", "metadata": {}, "outputs": [ { @@ -253,7 +253,7 @@ }, { "cell_type": "markdown", - "id": "d1dc5ad3", + "id": "16", "metadata": {}, "source": [ "The training set is used to optimize the CHGNet through gradient descent, the validation set is used to see validation error at the end of each epoch, and the test set is used to see the final test error at the end of training. The test set can be optional.\n", @@ -265,7 +265,7 @@ }, { "cell_type": "markdown", - "id": "99445e44", + "id": "17", "metadata": {}, "source": [ "## 3. Define model and trainer\n" @@ -274,7 +274,7 @@ { "cell_type": "code", "execution_count": null, - "id": "de1e77bf", + "id": "18", "metadata": {}, "outputs": [ { @@ -296,7 +296,7 @@ }, { "cell_type": "markdown", - "id": "e3afbc75", + "id": "19", "metadata": {}, "source": [ "It's optional to freeze the weights inside some layers. This is a common technique to retain the learned knowledge during fine-tuning in large pretrained neural networks. You can choose the layers you want to freeze.\n" @@ -305,7 +305,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e69c71b0", + "id": "20", "metadata": {}, "outputs": [], "source": [ @@ -327,7 +327,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e52511a9", + "id": "21", "metadata": {}, "outputs": [], "source": [ @@ -347,7 +347,7 @@ }, { "cell_type": "markdown", - "id": "6f47fca4", + "id": "22", "metadata": {}, "source": [ "## 4. Start training\n" @@ -356,7 +356,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2a990258", + "id": "23", "metadata": {}, "outputs": [ { @@ -396,7 +396,7 @@ }, { "cell_type": "markdown", - "id": "169de30e", + "id": "24", "metadata": {}, "source": [ "After training, the trained model can be found in the directory of today's date. Or it can be accessed by:\n" @@ -405,7 +405,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2fa383b4", + "id": "25", "metadata": {}, "outputs": [], "source": [ @@ -415,7 +415,7 @@ }, { "cell_type": "markdown", - "id": "abcc09b4", + "id": "26", "metadata": {}, "source": [ "## Extras 1: GGA / GGA+U compatibility\n" @@ -423,7 +423,7 @@ }, { "cell_type": "markdown", - "id": "0a977284", + "id": "27", "metadata": {}, "source": [ "### Q: Why and when do you care about this?\n", @@ -440,7 +440,7 @@ { "cell_type": "code", "execution_count": null, - "id": "cf8c3e44", + "id": "28", "metadata": {}, "outputs": [ { @@ -460,7 +460,7 @@ }, { "cell_type": "markdown", - "id": "cce51fa9", + "id": "29", "metadata": {}, "source": [ "You can look for the energy correction applied to each element in :\n", @@ -472,7 +472,7 @@ }, { "cell_type": "markdown", - "id": "a575d6a8", + "id": "30", "metadata": {}, "source": [ "To demystify `MaterialsProject2020Compatibility`, basically all that's happening is:\n" @@ -481,7 +481,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2262bbd0", + "id": "31", "metadata": {}, "outputs": [ { @@ -506,7 +506,7 @@ }, { "cell_type": "markdown", - "id": "4f5a7346", + "id": "32", "metadata": {}, "source": [ "You can also apply the `MaterialsProject2020Compatibility` through pymatgen\n" @@ -515,7 +515,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8169c61c", + "id": "33", "metadata": {}, "outputs": [ { @@ -542,7 +542,7 @@ }, { "cell_type": "markdown", - "id": "deeb3814", + "id": "34", "metadata": {}, "source": [ "Now use this corrected energy as labels to tune CHGNet, you're good to go!\n" @@ -550,7 +550,7 @@ }, { "cell_type": "markdown", - "id": "5c36fe61", + "id": "35", "metadata": {}, "source": [ "## Extras 2: AtomRef\n" @@ -558,7 +558,7 @@ }, { "cell_type": "markdown", - "id": "dbb93bc0", + "id": "36", "metadata": {}, "source": [ "### Q: Why and when do you care about this?\n", @@ -572,7 +572,7 @@ }, { "cell_type": "markdown", - "id": "b23ac75e", + "id": "37", "metadata": {}, "source": [ "### A quick and easy way to turn on training of AtomRef in the trainer (this is by default off):\n" @@ -581,7 +581,7 @@ { "cell_type": "code", "execution_count": null, - "id": "16d96ffc", + "id": "38", "metadata": {}, "outputs": [ { @@ -621,7 +621,7 @@ }, { "cell_type": "markdown", - "id": "442112f9", + "id": "39", "metadata": {}, "source": [ "### The more regorous way is to solve for the per-atom contribution by linear regression in your fine-tuning dataset\n" @@ -630,7 +630,7 @@ { "cell_type": "code", "execution_count": null, - "id": "aeaf7838", + "id": "40", "metadata": {}, "outputs": [ { @@ -665,7 +665,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a1caed7a", + "id": "41", "metadata": {}, "outputs": [], "source": [ @@ -696,7 +696,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4aa551c1", + "id": "42", "metadata": {}, "outputs": [ { @@ -721,7 +721,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28726cd6", + "id": "43", "metadata": {}, "outputs": [ { diff --git a/pyproject.toml b/pyproject.toml index 0319d88..f53c599 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,8 +85,6 @@ select = [ ignore = [ "ANN001", # TODO add missing type annotations "ANN003", - "ANN101", # Missing type annotation for self in method - "ANN102", "B019", # Use of functools.lru_cache on methods can lead to memory leaks "BLE001", "C408", # unnecessary-collection-call diff --git a/tests/test_relaxation.py b/tests/test_relaxation.py index 768b00c..e25e84d 100644 --- a/tests/test_relaxation.py +++ b/tests/test_relaxation.py @@ -1,5 +1,6 @@ from __future__ import annotations +import os import re from typing import TYPE_CHECKING, Literal @@ -44,12 +45,16 @@ def test_relaxation( no_cuda = mark.skipif(not torch.cuda.is_available(), reason="No CUDA device") -no_mps = mark.skipif(not torch.backends.mps.is_available(), reason="No MPS device") +# skip in macos-14 M1 CI due to OOM error (TODO investigate if +# PYTORCH_MPS_HIGH_WATERMARK_RATIO can fix) +no_mps = mark.skipif( + not torch.backends.mps.is_available() or "CI" in os.environ, reason="No MPS device" +) @mark.parametrize( "use_device", ["cpu", param("cuda", marks=no_cuda), param("mps", marks=no_mps)] ) -def test_structure_optimizer_passes_kwargs_to_model(use_device) -> None: +def test_structure_optimizer_passes_kwargs_to_model(use_device: str) -> None: relaxer = StructOptimizer(use_device=use_device) assert re.match(rf"{use_device}(:\d+)?", relaxer.calculator.device)