Skip to content

Commit

Permalink
Csse pyd2 test use multiple schema versions (#454)
Browse files Browse the repository at this point in the history
* start 5 modes testing

* more tests

* fix import and checks

* fix typo

* try xtb

* xtb and mrchem

* sdftd3

* more tests

* few fixes?

* test_programs

* all but stdsuite

* stdsuite

* fix alignment tests

* docker and prop

* docker

* docker2

* docker3

* docker4

* docker5

* docker6

* docker7

* docker8

* back and np fixed

* tidy up
  • Loading branch information
loriab authored Oct 14, 2024
1 parent 8753f9c commit bb75987
Show file tree
Hide file tree
Showing 30 changed files with 1,122 additions and 422 deletions.
14 changes: 12 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
# label: QCore
# runs-on: ubuntu-latest
# pytest: ""
# Note: removed Sep 2024 b/c too hard to reconcile w/pyd v2
# Note: removed Sep 2024 b/c too hard to reconcile w/pyd v2. Manby approves.

- conda-env: nwchem
python-version: 3.8
Expand Down Expand Up @@ -114,6 +114,12 @@ jobs:
runs-on: ubuntu-latest
pytest: ""

#- conda-env: nwchem
# python-version: "3.10"
# label: TeraChem
# runs-on: ubuntu-20.04
# pytest: ""

name: "🐍 ${{ matrix.cfg.python-version }} • ${{ matrix.cfg.label }} • ${{ matrix.cfg.runs-on }}"
runs-on: ${{ matrix.cfg.runs-on }}

Expand Down Expand Up @@ -144,11 +150,15 @@ jobs:
run: |
qcore --accept-license
#docker.io/mtzgroup/terachem:latest
#Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

- name: Special Config - QCElemental Dep
#if: false
run: |
conda remove qcelemental --force
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_pyd2_shimclasses' --no-deps
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_pyd2_converterclasses' --no-deps
# note: conda remove --force, not mamba remove --force b/c https://github.com/mamba-org/mamba/issues/412
# alt. is micromamba but not yet ready for setup-miniconda https://github.com/conda-incubator/setup-miniconda/issues/75
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ repos:
- id: black
language_version: python3.12
args: [--line-length=120]
exclude: 'test_|versioneer.py|examples/.*|docs/.*|devtools/.*'
exclude: 'versioneer.py|examples/.*|docs/.*|devtools/.*'
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
Expand Down
9 changes: 6 additions & 3 deletions qcengine/programs/tests/standard_suite_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@

import numpy as np
import pytest
from qcelemental.models import AtomicInput
from qcelemental.molutil import compute_scramble
from qcelemental.testing import compare, compare_values

import qcengine as qcng
from qcengine.programs.util import mill_qcvars
from qcengine.testing import checkver_and_convert

from .standard_suite_contracts import *
from .standard_suite_ref import answer_hash, std_suite

pp = pprint.PrettyPrinter(width=120)


def runner_asserter(inp, ref_subject, method, basis, tnm, scramble, frame):
def runner_asserter(inp, ref_subject, method, basis, tnm, scramble, frame, models):

qcprog = inp["call"]
qc_module_in = inp["qc_module"] # returns "<qcprog>"|"<qcprog>-<module>" # input-specified routing
Expand Down Expand Up @@ -124,7 +124,7 @@ def runner_asserter(inp, ref_subject, method, basis, tnm, scramble, frame):

# <<< Prepare Calculation and Call API >>>

atin = AtomicInput(
atin = models.AtomicInput(
**{
"molecule": subject,
"driver": driver,
Expand All @@ -142,13 +142,16 @@ def runner_asserter(inp, ref_subject, method, basis, tnm, scramble, frame):
if "error" in inp:
errtype, errmatch, reason = inp["error"]
with pytest.raises(errtype) as e:
atin = checkver_and_convert(atin, tnm, "pre")
qcng.compute(atin, qcprog, raise_error=True, return_dict=True, task_config=local_options)

assert re.search(errmatch, str(e.value)), f"Not found: {errtype} '{errmatch}' in {e.value}"
# _recorder(qcprog, qc_module_in, driver, method, reference, fcae, scf_type, corl_type, "error", "nyi: " + reason)
return

atin = checkver_and_convert(atin, tnm, "pre")
wfn = qcng.compute(atin, qcprog, raise_error=True, task_config=local_options)
wfn = checkver_and_convert(wfn, tnm, "post")

print("WFN")
pp.pprint(wfn.dict())
Expand Down
17 changes: 10 additions & 7 deletions qcengine/programs/tests/test_adcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,29 @@
from qcelemental.testing import compare_values

import qcengine as qcng
from qcengine.testing import using
from qcengine.testing import checkver_and_convert, schema_versions, using


@pytest.fixture
def h2o():
return qcel.models.Molecule.from_data(
"""
def h2o_data():
return """
O 0.0 0.000 -0.129
H 0.0 -1.494 1.027
H 0.0 1.494 1.027
"""
)


@using("adcc")
def test_run(h2o):
inp = qcel.models.AtomicInput(
def test_run(h2o_data, schema_versions, request):
models, _ = schema_versions
h2o = models.Molecule.from_data(h2o_data)

inp = models.AtomicInput(
molecule=h2o, driver="properties", model={"method": "adc2", "basis": "sto-3g"}, keywords={"n_singlets": 3}
)
inp = checkver_and_convert(inp, request.node.name, "pre")
ret = qcng.compute(inp, "adcc", raise_error=True, local_options={"ncores": 1}, return_dict=True)
ret = checkver_and_convert(ret, request.node.name, "post")

ref_excitations = np.array([0.0693704245883876, 0.09773854881340478, 0.21481589246935925])
ref_hf_energy = -74.45975898670224
Expand Down
25 changes: 19 additions & 6 deletions qcengine/programs/tests/test_alignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
import qcelemental as qcel

from qcengine.programs.tests.standard_suite_ref import std_molecules, std_refs
from qcengine.testing import using
from qcengine.testing import schema_versions, using

from .standard_suite_runner import runner_asserter
from .test_standard_suite import _processor


@pytest.fixture
def clsd_open_pmols():
def clsd_open_pmols(schema_versions):
models, _ = schema_versions
frame_not_important = {
name[:-4]: qcel.models.Molecule.from_data(smol, name=name[:-4])
name[:-4]: models.Molecule.from_data(smol, name=name[:-4])
for name, smol in std_molecules.items()
if name.endswith("-xyz")
}
frame_part_of_spec = {
name[:-4] + "-fixed": qcel.models.Molecule.from_data(smol + "\nno_com\nno_reorient\n", name=name[:-4])
name[:-4] + "-fixed": models.Molecule.from_data(smol + "\nno_com\nno_reorient\n", name=name[:-4])
for name, smol in std_molecules.items()
if name.endswith("-xyz")
}
Expand Down Expand Up @@ -92,7 +93,19 @@ def clsd_open_pmols():
# yapf: enable
],
)
def test_hf_alignment(inp, scramble, frame, driver, basis, subjects, clsd_open_pmols, request):
def test_hf_alignment(inp, scramble, frame, driver, basis, subjects, clsd_open_pmols, request, schema_versions):
runner_asserter(
*_processor(inp, "", basis, subjects, clsd_open_pmols, request, driver, "hf", scramble=scramble, frame=frame)
*_processor(
inp,
"",
basis,
subjects,
clsd_open_pmols,
request,
schema_versions[0],
driver,
"hf",
scramble=scramble,
frame=frame,
)
)
48 changes: 33 additions & 15 deletions qcengine/programs/tests/test_canonical_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
from pathlib import Path

import pytest
from qcelemental.models import AtomicInput

import qcengine as qcng
from qcengine.testing import has_program, using
from qcengine.testing import checkver_and_convert, has_program, schema_versions, using

_canonical_methods = [
# needs attn ("adcc", {"method": "adc2", "basis": "6-31G"}, {"n_triplets": 3}),
Expand All @@ -38,14 +37,15 @@
]


def _get_molecule(program, method):
def _get_molecule(program, method, molcls):
if program in ["openmm", "terachem_pbs"]:
return qcng.get_molecule("water")
dmol = qcng.get_molecule("water", return_dict=True)
elif program == "gamess" and method == "ccsd(t)":
return qcng.get_molecule("water")
dmol = qcng.get_molecule("water", return_dict=True)
else:
return qcng.get_molecule("hydrogen")
dmol = qcng.get_molecule("hydrogen", return_dict=True)

return molcls(**dmol)

@pytest.mark.parametrize(
"memory_trickery",
Expand All @@ -64,7 +64,7 @@ def _get_molecule(program, method):
],
)
@pytest.mark.parametrize("program, model, keywords", _canonical_methods)
def test_local_options_memory_gib(program, model, keywords, memory_trickery, request):
def test_local_options_memory_gib(program, model, keywords, memory_trickery, schema_versions, request):
"""Ensure memory handling implemented in harness (if applicable).
For available harnesses, run minimal calc at specific total node memory, both through runtime
Expand All @@ -80,11 +80,13 @@ def test_local_options_memory_gib(program, model, keywords, memory_trickery, req
* If this test doesn't work, implement or adjust ``config.memory`` in your harness.
"""
models, _ = schema_versions

if not has_program(program):
pytest.skip(f"Program '{program}' not found.")

harness = qcng.get_program(program)
molecule = _get_molecule(program, model["method"])
molecule = _get_molecule(program, model["method"], models.Molecule)

addl_keywords = memory_trickery.get(program, memory_trickery)
use_keywords = {**keywords, **addl_keywords}
Expand All @@ -102,8 +104,12 @@ def test_local_options_memory_gib(program, model, keywords, memory_trickery, req

# << Run

inp = AtomicInput(molecule=molecule, driver="energy", model=model, keywords=use_keywords)
inp = models.AtomicInput(molecule=molecule, driver="energy", model=model, keywords=use_keywords)

inp = checkver_and_convert(inp, request.node.name, "pre")
ret = qcng.compute(inp, program, raise_error=True, task_config=config.dict())
ret = checkver_and_convert(ret, request.node.name, "post")

pprint.pprint(ret.dict(), width=200)
assert ret.success is True

Expand All @@ -126,7 +132,7 @@ def test_local_options_memory_gib(program, model, keywords, memory_trickery, req


@pytest.mark.parametrize("program, model, keywords", _canonical_methods)
def test_local_options_scratch(program, model, keywords):
def test_local_options_scratch(program, model, keywords, schema_versions, request):
"""Ensure scratch handling implemented in harness (if applicable).
For available harnesses, run minimal calc at specific scratch directory name (randomly generated
Expand All @@ -146,11 +152,13 @@ def test_local_options_scratch(program, model, keywords):
``config.scratch_messy`` in your harness.
"""
models, _ = schema_versions

if not has_program(program):
pytest.skip(f"Program '{program}' not found.")

harness = qcng.get_program(program)
molecule = _get_molecule(program, model["method"])
molecule = _get_molecule(program, model["method"], models.Molecule)

# << Config

Expand All @@ -166,8 +174,12 @@ def test_local_options_scratch(program, model, keywords):

# << Run

inp = AtomicInput(molecule=molecule, driver="energy", model=model, keywords=keywords)
inp = models.AtomicInput(molecule=molecule, driver="energy", model=model, keywords=keywords)

inp = checkver_and_convert(inp, request.node.name, "pre")
ret = qcng.compute(inp, program, raise_error=True, task_config=config.dict())
ret = checkver_and_convert(ret, request.node.name, "post")

pprint.pprint(ret.dict(), width=200)
assert ret.success is True

Expand Down Expand Up @@ -212,7 +224,7 @@ def test_local_options_scratch(program, model, keywords):

@pytest.mark.parametrize("ncores", [1, 3])
@pytest.mark.parametrize("program, model, keywords", _canonical_methods)
def test_local_options_ncores(program, model, keywords, ncores):
def test_local_options_ncores(program, model, keywords, ncores, schema_versions, request):
"""Ensure multithreading implemented in harness (if applicable) or multithreaded runs don't
break harness (if inapplicable).
Expand All @@ -228,11 +240,13 @@ def test_local_options_ncores(program, model, keywords, ncores):
* If this test doesn't work, implement or adjust ``config.ncores`` in your harness.
"""
models, _ = schema_versions

if not has_program(program):
pytest.skip(f"Program '{program}' not found.")

harness = qcng.get_program(program)
molecule = _get_molecule(program, model["method"])
molecule = _get_molecule(program, model["method"], models.Molecule)

# << Config

Expand All @@ -246,8 +260,12 @@ def test_local_options_ncores(program, model, keywords, ncores):

# << Run

inp = AtomicInput(molecule=molecule, driver="energy", model=model, keywords=keywords)
inp = models.AtomicInput(molecule=molecule, driver="energy", model=model, keywords=keywords)

inp = checkver_and_convert(inp, request.node.name, "pre")
ret = qcng.compute(inp, program, raise_error=True, task_config=config.dict())
ret = checkver_and_convert(ret, request.node.name, "post")

pprint.pprint(ret.dict(), width=200)
assert ret.success is True

Expand Down
15 changes: 10 additions & 5 deletions qcengine/programs/tests/test_canonical_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@

import pytest
import qcelemental as qcel
from qcelemental.models import AtomicInput

import qcengine as qcng
from qcengine.testing import has_program, using
from qcengine.testing import checkver_and_convert, has_program, schema_versions, using

from .test_canonical_config import _canonical_methods, _get_molecule


@pytest.mark.parametrize("native", ["none", "input", "all"])
@pytest.mark.parametrize("program, model, keywords", _canonical_methods)
def test_protocol_native(program, model, keywords, native):
def test_protocol_native(program, model, keywords, native, schema_versions, request):
"""Ensure native_files protocol implemented in harness.
For harnesses, run minimal gradient calc with different protocol settings; check expected
Expand All @@ -26,11 +25,13 @@ def test_protocol_native(program, model, keywords, native):
* If this test doesn't work, implement or adjust ``native_files`` in your harness.
"""
models, _ = schema_versions

if not has_program(program):
pytest.skip(f"Program '{program}' not found.")

harness = qcng.get_program(program)
molecule = _get_molecule(program, model["method"])
molecule = _get_molecule(program, model["method"], models.Molecule)

# << Config

Expand All @@ -47,8 +48,12 @@ def test_protocol_native(program, model, keywords, native):

# << Run

inp = AtomicInput(molecule=molecule, driver="gradient", model=model, keywords=keywords, protocols=protocols)
inp = models.AtomicInput(molecule=molecule, driver="gradient", model=model, keywords=keywords, protocols=protocols)

inp = checkver_and_convert(inp, request.node.name, "pre")
ret = qcng.compute(inp, program, raise_error=True, local_options=config.dict())
ret = checkver_and_convert(ret, request.node.name, "post")

pprint.pprint(ret.dict(), width=200)
assert ret.success is True

Expand Down
Loading

0 comments on commit bb75987

Please sign in to comment.