Skip to content

Commit

Permalink
Csse pyd2 506e (#456)
Browse files Browse the repository at this point in the history
* program harnesses to v2

* mostly fixed up

* fix nwc

* qcer

* more fix

* fix qcel to fix qchem

* docs

* docs2

* docs3

* docs4

* docs again

* why the error

* release a few pins

* next rnd

* docs

* suppress some warnings

* rest of test lanes
  • Loading branch information
loriab authored Oct 30, 2024
1 parent ff59b7b commit 2966cc3
Show file tree
Hide file tree
Showing 57 changed files with 241 additions and 164 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ jobs:
#if: false
run: |
conda remove qcelemental --force
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_pyd2_converterclasses' --no-deps
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_pyd2_warnings' --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 Expand Up @@ -236,6 +236,12 @@ jobs:
add-pip-as-python-dependency: true
channels: conda-forge

- 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_warnings' --no-deps
- name: Environment Information
run: |
conda info
Expand All @@ -244,6 +250,8 @@ jobs:
- name: Build Documentation
run: |
python -m pip install . --no-deps
python -c "import qcelemental as q;print(q.__file__, q.__version__)"
python -c "import qcengine as q;print(q.__file__, q.__version__)"
cd docs
make html
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/docs-cf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ channels:
dependencies:
- python
- networkx
- pydantic=2
- pydantic=2.5
- pydantic-settings
- numpy
- pint
Expand Down
2 changes: 1 addition & 1 deletion docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Changelog
vX.Y.0 / 2024-MM-DD (Unreleased)
--------------------
--------------------------------

Breaking Changes
++++++++++++++++
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = [] #'_static']

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
Expand Down
5 changes: 5 additions & 0 deletions docs/source/single_compute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ By default the job is given resources relating to the compute environment it is
>>> ret = qcng.compute(inp, "psi4", local_options={"memory": 2, "ncores": 3})
By default, the job returns a QCSchema Result of the same ``schema_version`` as the Input (v1 if Input version can't be determined). To request a specific version back, use the ``return_version`` keyword:

.. code:: python
>>> ret = qcng.compute(inp, "psi4", return_version=2)
Results
Expand Down
3 changes: 2 additions & 1 deletion qcengine/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def parse_args():
run_procedure = subparsers.add_parser(
"run-procedure",
parents=[parent_parser],
help="Run a procedure on a given task. Output is printed as a JSON blob.",
help="Run a procedure on a given task. Output is printed as a JSON blob. "
"Since v0.50.0, favor 'run', even for procedures.",
)
run_procedure.add_argument("procedure", type=str, help="The procedure to run.")
run_procedure.add_argument(
Expand Down
16 changes: 10 additions & 6 deletions qcengine/compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from typing import TYPE_CHECKING, Any, Dict, Optional, Union

import qcelemental
from qcelemental.models import AtomicInput, AtomicResult, FailedOperation, OptimizationResult # TODO

from .config import get_config
from .exceptions import InputError, RandomError
Expand All @@ -15,14 +14,13 @@

if TYPE_CHECKING:
from pydantic.main import BaseModel
from qcelemental.models import AtomicResult


__all__ = ["compute", "compute_procedure"]


def _process_failure_and_return(model, return_dict, raise_error):
if isinstance(model, FailedOperation):
if isinstance(model, (qcelemental.models.v1.FailedOperation, qcelemental.models.v2.FailedOperation)):
if raise_error:
raise InputError(model.error.error_message)
elif return_dict:
Expand Down Expand Up @@ -71,6 +69,12 @@ def compute(
result
AtomicResult, OptimizationResult, FailedOperation, etc., or Dict representation of any object type
A QCSchema representation of the requested output, type depends on return_dict key.
.. versionadded:: 0.50.0
input_data can newly be QCSchema v2 as well as longstanding v1.
The compute_procedure is newly incorporated into compute.
The *return_version* parameter was added.
"""

try:
Expand Down Expand Up @@ -123,11 +127,11 @@ def compute(


def compute_procedure(*args, **kwargs):
vchanges = qcelemental.models.common_models._qcsk_v2_default_v1_importpathschange
from qcelemental.models.common_models import _qcsk_v2_default_v1_importpathschange

warnings.warn(
f"Using the `compute_procedure` function is deprecated in favor of using `compute`, "
"and as soon as version {vchanges} it will stop working.",
"Using the `compute_procedure` function is deprecated in favor of using `compute`, "
f"and as soon as version {_qcsk_v2_default_v1_importpathschange} it will stop working.",
category=FutureWarning,
stacklevel=2,
)
Expand Down
13 changes: 7 additions & 6 deletions qcengine/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,16 @@ class NodeDescriptor(BaseModel):
# Cluster options
is_batch_node: bool = Field(
False,
description="""Whether the node running QCEngine is a batch node
description=r"""Whether the node running QCEngine is a batch node
Some clusters are configured such that tasks are launched from a special "batch" or "MOM" onto the compute nodes.
The compute nodes on such clusters often have a different CPU architecture than the batch nodes and
often are unable to launch MPI tasks, which has two implications:
1) QCEngine must make *all* calls to an executable via ``mpirun`` because the executables might not
be able to run on the batch node.
2) QCEngine must run on the batch node to be able to launch tasks on the more than one compute nodes
1. QCEngine must make *all* calls to an executable via ``mpirun`` because the executables might not
be able to run on the batch node.
2. QCEngine must run on the batch node to be able to launch tasks on the more than one compute nodes
``is_batch_node`` is used when creating the task configuration as a means of determining whether
``mpiexec_command`` must always be used even for serial jobs (e.g., getting the version number)
""",
Expand Down
4 changes: 1 addition & 3 deletions qcengine/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import traceback
from typing import Any, Dict, Optional

from qcelemental.models import AtomicInput


class QCEngineException(Exception):
"""
Expand Down Expand Up @@ -106,7 +104,7 @@ def detect_error(cls, outputs: Dict[str, str]):
"""
raise NotImplementedError()

def create_keyword_update(self, input_data: AtomicInput) -> Dict[str, Any]:
def create_keyword_update(self, input_data: "AtomicInput") -> Dict[str, Any]:
"""Create an keyword used to the update the dictionary given observed error
Parameters
Expand Down
2 changes: 1 addition & 1 deletion qcengine/procedures/berny.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Any, ClassVar, Dict, Union

import numpy as np
from qcelemental.models import FailedOperation, OptimizationInput, OptimizationResult
from qcelemental.models.v2 import FailedOperation, OptimizationInput, OptimizationResult
from qcelemental.util import which_import

import qcengine
Expand Down
2 changes: 1 addition & 1 deletion qcengine/procedures/geometric.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any, ClassVar, Dict, Union

from qcelemental.models import OptimizationInput, OptimizationResult
from qcelemental.models.v2 import OptimizationInput, OptimizationResult
from qcelemental.util import safe_version, which_import

from .model import ProcedureHarness
Expand Down
6 changes: 3 additions & 3 deletions qcengine/procedures/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ def _build_model(

# for now, the two dictionaries look the same, so cast to the one we want
# note that this prevents correctly identifying the user schema version when dict passed in, so either as_v1/None or as_v2 will fail
mdl = model_wrapper(data, v1_model) # TODO v2
mdl = model_wrapper(data, v1_model)

input_schema_version = mdl.schema_version
if return_input_schema_version:
return mdl.convert_v(1), input_schema_version # non-psi4 return_dict=False fail w/o this
return mdl.convert_v(2), input_schema_version
else:
return mdl.convert_v(1)
return mdl.convert_v(2)

def get_version(self) -> str:
"""Finds procedure, extracts version, returns normalized version string.
Expand Down
2 changes: 1 addition & 1 deletion qcengine/procedures/nwchem_opt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any, ClassVar, Dict, Union

from qcelemental.models import AtomicInput, OptimizationInput, OptimizationResult, Provenance
from qcelemental.models.v2 import AtomicInput, OptimizationInput, OptimizationResult, Provenance

from qcengine.config import TaskConfig
from qcengine.exceptions import InputError, UnknownError
Expand Down
2 changes: 1 addition & 1 deletion qcengine/procedures/nwchem_opt/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from decimal import Decimal
from typing import List, Tuple

from qcelemental.models import AtomicResult, Molecule, OptimizationInput, Provenance
from qcelemental.models.v2 import AtomicResult, Molecule, OptimizationInput, Provenance
from qcelemental.util import unnp

from qcengine.programs.nwchem.harvester import harvest_outfile_pass
Expand Down
3 changes: 2 additions & 1 deletion qcengine/procedures/optking.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any, ClassVar, Dict, Union

from qcelemental.models import OptimizationInput, OptimizationResult
from qcelemental.models.v2 import OptimizationInput, OptimizationResult
from qcelemental.util import safe_version, which_import

from .model import ProcedureHarness
Expand Down Expand Up @@ -40,6 +40,7 @@ def compute(self, input_model: "OptimizationInput", config: "TaskConfig") -> "Op
if self.found(raise_error=True):
import optking

input_data = input_model.convert_v(1)
input_data = input_model.dict()

# Set retries to two if zero while respecting local_config
Expand Down
15 changes: 9 additions & 6 deletions qcengine/procedures/torsiondrive.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Tuple, Union

import numpy as np
from qcelemental.models import FailedOperation, Molecule
from qcelemental.models.procedures import OptimizationInput, OptimizationResult, TorsionDriveInput, TorsionDriveResult
from qcelemental.models.v2 import FailedOperation, Molecule
from qcelemental.models.v2.procedures import (
OptimizationInput,
OptimizationResult,
TorsionDriveInput,
TorsionDriveResult,
)
from qcelemental.util import which_import

from .model import ProcedureHarness
Expand Down Expand Up @@ -173,7 +178,7 @@ def _spawn_optimization(
object.
"""

from qcengine import compute_procedure
from qcengine import compute

input_molecule = input_model.initial_molecule[0].copy(deep=True).dict()
input_molecule["geometry"] = np.array(job).reshape(len(input_molecule["symbols"]), 3)
Expand Down Expand Up @@ -204,9 +209,7 @@ def _spawn_optimization(
initial_molecule=input_molecule,
)

return compute_procedure(
input_data, procedure=input_model.optimization_spec.procedure, task_config=config.dict()
)
return compute(input_data, program=input_model.optimization_spec.procedure, task_config=config.dict())

@staticmethod
def _find_final_results(
Expand Down
8 changes: 5 additions & 3 deletions qcengine/programs/adcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@
"""
from typing import TYPE_CHECKING, Any, ClassVar, Dict

from qcelemental.models import AtomicResult, BasisSet, Provenance
from qcelemental.models.v2 import AtomicResult, BasisSet, Provenance
from qcelemental.util import safe_version, which_import

from ..exceptions import InputError, UnknownError
from .model import ProgramHarness
from .qcvar_identities_resources import build_atomicproperties

if TYPE_CHECKING:
from qcelemental.models import AtomicInput
from qcelemental.models.v2 import AtomicInput

from ..config import TaskConfig

#


class AdccHarness(ProgramHarness):
"""Interface for adcc project."""

_defaults: ClassVar[Dict[str, Any]] = {
"name": "adcc",
"scratch": False,
Expand Down Expand Up @@ -113,7 +115,7 @@ def compute(self, input_model: "AtomicInput", config: "TaskConfig") -> "AtomicRe
except Exception as e:
raise UnknownError(str(e))

input_data = input_model.dict(encoding="json")
input_data = input_model.model_dump(encoding="json")
output_data = input_data.copy()
output_data["success"] = compute_success

Expand Down
4 changes: 2 additions & 2 deletions qcengine/programs/aimnet2.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from typing import TYPE_CHECKING, Any, ClassVar, Dict

from qcelemental.models import AtomicResult, Provenance
from qcelemental.models.v2 import AtomicResult, Provenance
from qcelemental.util import safe_version, which_import

from qcengine.exceptions import InputError
from qcengine.programs.model import ProgramHarness

if TYPE_CHECKING:
from qcelemental.models import AtomicInput
from qcelemental.models.v2 import AtomicInput

from qcengine.config import TaskConfig

Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/cfour/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import numpy as np
import qcelemental as qcel
from qcelemental.models import Molecule
from qcelemental.models.v2 import Molecule
from qcelemental.molparse import regex

from ..util import PreservingDict, load_hessian
Expand Down
4 changes: 2 additions & 2 deletions qcengine/programs/cfour/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import Any, ClassVar, Dict, Optional, Tuple

import numpy as np
from qcelemental.models import AtomicInput, AtomicResult, BasisSet, Provenance
from qcelemental.models.v2 import AtomicInput, AtomicResult, BasisSet, Provenance
from qcelemental.util import safe_version, which

from ...exceptions import InputError, UnknownError
Expand All @@ -23,7 +23,7 @@


class CFOURHarness(ProgramHarness):
"""
"""Interface for CFOUR project.
Notes
-----
Expand Down
5 changes: 3 additions & 2 deletions qcengine/programs/dftd3.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import numpy as np
import qcelemental as qcel
from qcelemental.models import AtomicResult, FailedOperation, Provenance
from qcelemental.models.v2 import AtomicResult, FailedOperation, Provenance
from qcelemental.util import safe_version, which

from ..exceptions import InputError, ResourceError, UnknownError
Expand All @@ -20,7 +20,7 @@
from .model import ProgramHarness

if TYPE_CHECKING:
from qcelemental.models import AtomicInput
from qcelemental.models.v2 import AtomicInput

from ..config import TaskConfig

Expand All @@ -29,6 +29,7 @@


class DFTD3Harness(ProgramHarness):
"""Interface for DFTD3 executable project."""

_defaults: ClassVar[Dict[str, Any]] = {
"name": "DFTD3",
Expand Down
Loading

0 comments on commit 2966cc3

Please sign in to comment.