Skip to content

Commit 415dd82

Browse files
first attempt reorganizing mlff ci
1 parent 7ce3c51 commit 415dd82

File tree

17 files changed

+357
-357
lines changed

17 files changed

+357
-357
lines changed

.github/workflows/testing.yml

Lines changed: 65 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323

2424
- uses: pre-commit/action@v3.0.0
2525

26-
test-non-ase:
26+
test-forcefields:
2727
# prevent this action from running on forks
2828
if: github.repository == 'materialsproject/atomate2'
2929

@@ -39,8 +39,8 @@ jobs:
3939
shell: bash -l {0} # enables conda/mamba env activation by reading bash profile
4040
strategy:
4141
matrix:
42-
python-version: ["3.11", "3.12"]
43-
split: [1, 2, 3]
42+
python-version: ["3.12"]
43+
dep-group: ["generic", "torch-limited", "e3nn-limited"]
4444

4545
steps:
4646
- name: Check out repo
@@ -59,17 +59,15 @@ jobs:
5959

6060
- name: Install conda dependencies
6161
run: |
62-
micromamba install -n a2 -c conda-forge enumlib packmol bader --yes
62+
micromamba install -n a2 -c conda-forge packmol --yes
6363
6464
- name: Install dependencies
6565
run: |
6666
micromamba activate a2
6767
python -m pip install --upgrade pip
6868
mkdir -p ~/.abinit/pseudos
6969
cp -r tests/test_data/abinit/pseudos/ONCVPSP-PBE-SR-PDv0.4 ~/.abinit/pseudos
70-
uv pip install .[strict,strict-forcefields,abinit,approxneb,aims] --group tests
71-
uv pip install torch-runstats torch_dftd
72-
uv pip install --no-deps nequip==0.5.6
70+
uv pip install .[strict,strict-forcefields-${{ matrix.dep-group }},abinit,approxneb,aims] --group tests
7371
7472
- name: Install pymatgen from master if triggered by pymatgen repo dispatch
7573
if: github.event_name == 'repository_dispatch' && github.event.action == 'pymatgen-ci-trigger'
@@ -88,8 +86,15 @@ jobs:
8886
# However this `splitting-algorithm` means that tests cannot depend sensitively on the order they're executed in.
8987
run: |
9088
micromamba activate a2
91-
pytest -n auto --splits 3 --group ${{ matrix.split }} --durations-path tests/.pytest-split-durations --splitting-algorithm least_duration --ignore=tests/ase --ignore=tests/openff_md --ignore=tests/openmm_md --cov=atomate2 --cov-report=xml
89+
pytest -n auto --durations-path tests/forcefields --cov=atomate2 --cov-report=xml
9290
91+
- name: Forcefield tutorial
92+
if: matrix.dep-group == 'torch-limited'
93+
env:
94+
MP_API_KEY: ${{ secrets.MP_API_KEY }}
95+
run: |
96+
micromamba activate a2
97+
pytest -n auto --nbmake ./tutorials/force_fields
9398
9499
- uses: codecov/codecov-action@v1
95100
if: matrix.python-version == '3.11' && github.repository == 'materialsproject/atomate2'
@@ -98,7 +103,7 @@ jobs:
98103
name: coverage${{ matrix.split }}
99104
file: ./coverage.xml
100105

101-
test-openff:
106+
test-non-ase:
102107
# prevent this action from running on forks
103108
if: github.repository == 'materialsproject/atomate2'
104109

@@ -114,7 +119,8 @@ jobs:
114119
shell: bash -l {0} # enables conda/mamba env activation by reading bash profile
115120
strategy:
116121
matrix:
117-
python-version: ["3.11","3.12"]
122+
python-version: ["3.11", "3.12"]
123+
split: [1, 2, 3]
118124

119125
steps:
120126
- name: Check out repo
@@ -132,14 +138,18 @@ jobs:
132138
run: micromamba run -n a2 pip install uv
133139

134140
- name: Install conda dependencies
135-
run: | # TODO: migrate openff tests to use non smirnoff99frosst forcefields - requires old setuptools / pkg_resources
136-
micromamba install -n a2 -c conda-forge enumlib packmol bader openbabel openff-toolkit==0.16.2 openff-interchange==0.3.22 'setuptools<81' --yes
141+
run: |
142+
micromamba install -n a2 -c conda-forge enumlib packmol bader --yes
137143
138144
- name: Install dependencies
139145
run: |
140146
micromamba activate a2
141147
python -m pip install --upgrade pip
142-
uv pip install .[strict-openff] --group tests
148+
mkdir -p ~/.abinit/pseudos
149+
cp -r tests/test_data/abinit/pseudos/ONCVPSP-PBE-SR-PDv0.4 ~/.abinit/pseudos
150+
uv pip install .[strict,abinit,approxneb,aims] --group tests
151+
uv pip install torch-runstats torch_dftd
152+
uv pip install --no-deps nequip==0.5.6
143153
144154
- name: Install pymatgen from master if triggered by pymatgen repo dispatch
145155
if: github.event_name == 'repository_dispatch' && github.event.action == 'pymatgen-ci-trigger'
@@ -151,19 +161,27 @@ jobs:
151161
env:
152162
MP_API_KEY: ${{ secrets.MP_API_KEY }}
153163

164+
# regenerate durations file with `pytest --store-durations --durations-path tests/.pytest-split-durations`
165+
# Note the use of `--splitting-algorithm least_duration`.
166+
# This helps prevent a test split having no tests to run, and then the GH action failing, see:
167+
# https://github.com/jerry-git/pytest-split/issues/95
168+
# However this `splitting-algorithm` means that tests cannot depend sensitively on the order they're executed in.
154169
run: |
155170
micromamba activate a2
156-
pytest -n auto tests/{openff_md,openmm_md}
171+
pytest -n auto --splits 3 --group ${{ matrix.split }} --durations-path tests/.pytest-split-durations --splitting-algorithm least_duration --ignore=tests/ase --ignore=tests/openff_md --ignore=tests/openmm_md --ignore=tests/forcefields --cov=atomate2 --cov-report=xml
157172
158-
test-notebooks-and-ase:
173+
174+
- uses: codecov/codecov-action@v1
175+
if: matrix.python-version == '3.11' && github.repository == 'materialsproject/atomate2'
176+
with:
177+
token: ${{ secrets.CODECOV_TOKEN }}
178+
name: coverage${{ matrix.split }}
179+
file: ./coverage.xml
180+
181+
test-openff:
159182
# prevent this action from running on forks
160183
if: github.repository == 'materialsproject/atomate2'
161184

162-
# It seems like anything torch-dependent and tblite can't be installed in the same environment
163-
# without the tblite tests failing in CI, see, e.g.:
164-
# https://github.com/tblite/tblite/issues/116
165-
# Outside of CI, having torch installed but not loaded seems not to affect tblite
166-
# Set off ASE tests here, where tblite-dependent tests live
167185
services:
168186
local_mongodb:
169187
image: mongo:4.0
@@ -176,7 +194,7 @@ jobs:
176194
shell: bash -l {0} # enables conda/mamba env activation by reading bash profile
177195
strategy:
178196
matrix:
179-
python-version: ["3.11", "3.12"]
197+
python-version: ["3.11","3.12"]
180198

181199
steps:
182200
- name: Check out repo
@@ -194,46 +212,38 @@ jobs:
194212
run: micromamba run -n a2 pip install uv
195213

196214
- name: Install conda dependencies
197-
run: |
198-
micromamba install -n a2 -c conda-forge enumlib packmol openbabel --yes
215+
run: | # TODO: migrate openff tests to use non smirnoff99frosst forcefields - requires old setuptools / pkg_resources
216+
micromamba install -n a2 -c conda-forge enumlib packmol bader openbabel openff-toolkit==0.16.2 openff-interchange==0.3.22 'setuptools<81' --yes
199217
200218
- name: Install dependencies
201219
run: |
202220
micromamba activate a2
203221
python -m pip install --upgrade pip
204-
uv pip install .[strict,aims] --group tests
205-
uv pip install tblite>=0.4.0
222+
uv pip install .[strict-openff] --group tests
206223
207224
- name: Install pymatgen from master if triggered by pymatgen repo dispatch
208225
if: github.event_name == 'repository_dispatch' && github.event.action == 'pymatgen-ci-trigger'
209226
run: |
210227
micromamba activate a2
211228
uv pip install --upgrade 'git+https://github.com/materialsproject/pymatgen@${{ github.event.client_payload.pymatgen_ref }}'
212229
213-
- name: Test Notebooks
230+
- name: Test split ${{ matrix.split }}
214231
env:
215232
MP_API_KEY: ${{ secrets.MP_API_KEY }}
216-
run: |
217-
micromamba activate a2
218-
pytest -n auto --nbmake ./tutorials --ignore=./tutorials/openmm_tutorial.ipynb --ignore=./tutorials/force_fields --ignore=./tutorials/torchsim_tutorial.ipynb
219233

220-
- name: Test ASE
221-
env:
222-
MP_API_KEY: ${{ secrets.MP_API_KEY }}
223234
run: |
224235
micromamba activate a2
225-
pytest -n auto --splits 1 --group 1 --cov=atomate2 --cov-report=xml tests/ase
226-
227-
- uses: codecov/codecov-action@v1
228-
if: matrix.python-version == '3.11' && github.repository == 'materialsproject/atomate2'
229-
with:
230-
token: ${{ secrets.CODECOV_TOKEN }}
231-
file: ./coverage.xml
236+
pytest -n auto tests/{openff_md,openmm_md}
232237
233-
test-force-field-notebook:
238+
test-notebooks-and-ase:
234239
# prevent this action from running on forks
235240
if: github.repository == 'materialsproject/atomate2'
236241

242+
# It seems like anything torch-dependent and tblite can't be installed in the same environment
243+
# without the tblite tests failing in CI, see, e.g.:
244+
# https://github.com/tblite/tblite/issues/116
245+
# Outside of CI, having torch installed but not loaded seems not to affect tblite
246+
# Set off ASE tests here, where tblite-dependent tests live
237247
services:
238248
local_mongodb:
239249
image: mongo:4.0
@@ -263,45 +273,43 @@ jobs:
263273
- name: Install uv
264274
run: micromamba run -n a2 pip install uv
265275

276+
- name: Install conda dependencies
277+
run: |
278+
micromamba install -n a2 -c conda-forge enumlib packmol openbabel --yes
279+
266280
- name: Install dependencies
267281
run: |
268282
micromamba activate a2
269283
python -m pip install --upgrade pip
270-
mkdir -p ~/.abinit/pseudos
271-
cp -r tests/test_data/abinit/pseudos/ONCVPSP-PBE-SR-PDv0.4 ~/.abinit/pseudos
272-
uv pip install .[strict,strict-forcefields,abinit,aims] --group tests
273-
uv pip install torch-runstats
274-
uv pip install --no-deps nequip==0.5.6
284+
uv pip install .[strict,aims] --group tests
285+
uv pip install tblite>=0.4.0
275286
276287
- name: Install pymatgen from master if triggered by pymatgen repo dispatch
277288
if: github.event_name == 'repository_dispatch' && github.event.action == 'pymatgen-ci-trigger'
278289
run: |
279290
micromamba activate a2
280291
uv pip install --upgrade 'git+https://github.com/materialsproject/pymatgen@${{ github.event.client_payload.pymatgen_ref }}'
281292
282-
- name: Forcefield tutorial
293+
- name: Test Notebooks
283294
env:
284295
MP_API_KEY: ${{ secrets.MP_API_KEY }}
285-
286-
# regenerate durations file with `pytest --store-durations --durations-path tests/.pytest-split-durations`
287-
# Note the use of `--splitting-algorithm least_duration`.
288-
# This helps prevent a test split having no tests to run, and then the GH action failing, see:
289-
# https://github.com/jerry-git/pytest-split/issues/95
290-
# However this `splitting-algorithm` means that tests cannot depend sensitively on the order they're executed in.
291296
run: |
292297
micromamba activate a2
293-
pytest -n auto --nbmake ./tutorials/force_fields
298+
pytest -n auto --nbmake ./tutorials --ignore=./tutorials/openmm_tutorial.ipynb --ignore=./tutorials/force_fields --ignore=./tutorials/torchsim_tutorial.ipynb
294299
300+
- name: Test ASE
301+
env:
302+
MP_API_KEY: ${{ secrets.MP_API_KEY }}
303+
run: |
304+
micromamba activate a2
305+
pytest -n auto --splits 1 --group 1 --cov=atomate2 --cov-report=xml tests/ase
295306
296307
- uses: codecov/codecov-action@v1
297308
if: matrix.python-version == '3.11' && github.repository == 'materialsproject/atomate2'
298309
with:
299310
token: ${{ secrets.CODECOV_TOKEN }}
300-
name: coverage
301311
file: ./coverage.xml
302312

303-
304-
305313
test-torchsim:
306314
# prevent this action from running on forks
307315
if: github.repository == 'materialsproject/atomate2'
@@ -375,7 +383,7 @@ jobs:
375383
- name: Install dependencies
376384
run: |
377385
python -m pip install --upgrade pip
378-
pip install .[strict,strict-forcefields] --group docs
386+
pip install .[strict,strict-forcefields-generic] --group docs
379387
380388
- name: Build
381389
run: sphinx-build docs docs_build

docs/user/codes/vasp.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,11 +708,13 @@ gamma_only_static_maker = StaticMaker(input_set_generator=custom_gamma_only_set)
708708
For those who are more familiar with manual *k*-point generation, you can use a VASP-style KPOINTS file or string to set the *k*-points as well:
709709

710710
```py
711-
kpoints = Kpoints.from_str("""Uniform density Monkhorst-Pack mesh
711+
kpoints = Kpoints.from_str(
712+
"""Uniform density Monkhorst-Pack mesh
712713
0
713714
Monkhorst-pack
714715
5 5 5
715-
""")
716+
"""
717+
)
716718
custom_static_set = StaticSetGenerator(user_kpoints_settings=kpoints)
717719
```
718720

pyproject.toml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,22 +84,26 @@ strict-openff = [
8484
"openmm==8.4.0.post2",
8585
"pymatgen==2025.10.7", # EXERCISE CAUTION WHEN UPDATING - open ff is extremely sensitive to pymatgen version
8686
]
87-
strict-forcefields = [
87+
strict-forcefields-generic = [
8888
"calorine==3.3; python_version >= '3.12'",
8989
"calorine==3.1; python_version < '3.12'",
90-
"mace-torch==0.3.14",
91-
"matgl==2.0.6",
92-
"dgl<=2.4.0",
9390
"quippy-ase==0.10.1",
9491
"sevenn==0.10.4",
95-
"torch==2.2.0",
96-
"torchdata==0.7.1", # TODO: remove when issue fixed
9792
"deepmd-kit==3.1.2",
9893
"tensorflow-cpu==2.20.0",
9994
]
95+
strict-forcefields-torch-limited = [
96+
"matgl==2.0.6",
97+
"dgl<=2.4.0",
98+
"torchdata==0.7.1",
99+
"torch==2.2.0",
100+
]
101+
strict-forcefields-e3nn-limited = [
102+
"mace-torch==0.3.14",
103+
]
100104
strict = [
101-
"atomate2[strict-forcefields, cclib, phonons, lobster, openmm, mp, defects, ase, ase-ext]",
102-
"numpy<2.0",
105+
"atomate2[cclib, phonons, lobster, openmm, mp, defects, ase, ase-ext]",
106+
"numpy<2.0"
103107
]
104108

105109
[project.scripts]

tests/forcefields/conftest.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,31 @@
1010
import torch
1111
from emmet.core.utils import get_hash_blocked
1212

13+
from atomate2.forcefields.utils import MLFF, ase_calculator
14+
1315
if TYPE_CHECKING:
1416
from typing import Any
1517

18+
_INSTALLED_MLFF: dict[str, bool] = {MLFF.Forcefield.name: False}
19+
for mlff in (x for x in MLFF if x.value != "Forcefield"):
20+
try:
21+
_ = ase_calculator(mlff)
22+
_INSTALLED_MLFF[mlff.name] = True
23+
except (ImportError, ValueError):
24+
_INSTALLED_MLFF[mlff.name] = False
25+
except Exception: # noqa: BLE001
26+
# Some calculators, like GAP, require extra potential files
27+
# Generally, thesea re
28+
_INSTALLED_MLFF[mlff.name] = True
29+
30+
31+
def mlff_is_installed(mlff: str | MLFF) -> bool:
32+
if not isinstance(mlff, str | MLFF):
33+
raise TypeError(f"Unknown `MLFF = {MLFF}` type, {type(mlff)}")
34+
35+
ff: str = (MLFF(mlff.split("MLFF.", 1)[-1]) if isinstance(mlff, str) else mlff).name
36+
return _INSTALLED_MLFF[ff]
37+
1638

1739
def pytest_runtest_setup(item: Any) -> None:
1840
# MACE changes the default dtype, ensure consistent dtype here

tests/forcefields/flows/test_approx_neb.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010

1111
def test_approx_neb_from_endpoints(test_dir, clean_dir):
12+
pytest.importorskip("matgl")
13+
1214
vasp_aneb_dir = test_dir / "vasp" / "ApproxNEB"
1315

1416
endpoints = [
@@ -52,6 +54,7 @@ def test_approx_neb_from_endpoints(test_dir, clean_dir):
5254

5355

5456
def test_ext_load_approx_neb_initialization():
57+
pytest.importorskip("mace")
5558
calculator_meta = {
5659
"@module": "mace.calculators",
5760
"@callable": "mace_mp",

tests/forcefields/flows/test_elastic.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
def test_elastic_wf_with_mace(
1212
clean_dir, si_structure, test_dir, convenience_constructor: bool
1313
):
14+
pytest.importorskip("mace")
15+
1416
si_prim = SpacegroupAnalyzer(si_structure).get_primitive_standard_structure()
1517
model_path = f"{test_dir}/forcefields/mace/MACE.model"
1618
common_kwds = {
@@ -45,6 +47,7 @@ def test_elastic_wf_with_mace(
4547

4648

4749
def test_ext_load_elastic_initialization():
50+
pytest.importorskip("mace")
4851
calculator_meta = {
4952
"@module": "mace.calculators",
5053
"@callable": "mace_mp",

0 commit comments

Comments
 (0)