Skip to content

Commit

Permalink
Upgraded to qcio Generics data structures.
Browse files Browse the repository at this point in the history
  • Loading branch information
coltonbh committed Jun 14, 2024
1 parent a3dea06 commit 391e762
Show file tree
Hide file tree
Showing 14 changed files with 764 additions and 740 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repos:
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.3.0
rev: 24.4.2
hooks:
- id: black
- repo: https://github.com/charliermarsh/ruff-pre-commit
Expand Down
7 changes: 4 additions & 3 deletions chemcloud/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
import tomli_w
from qcio.utils import json_dumps

from chemcloud.models import FutureOutput, FutureOutputGroup, QCIOInputs
from chemcloud.models import FutureOutput, FutureOutputGroup

from .config import Settings, settings
from .models import QCIOInputsOrList


class _RequestsClient:
Expand Down Expand Up @@ -280,14 +281,14 @@ def _result_id_to_future_result(self, input_data, result_id):

def compute(
self,
inp_obj: QCIOInputs,
inp_obj: QCIOInputsOrList,
params: Optional[Dict[str, Any]] = None,
) -> Union[FutureOutput, FutureOutputGroup]:
"""Submit a computation to ChemCloud"""
result_id = self._authenticated_request(
"post",
"/compute",
data=json_dumps(inp_obj),
data=json_dumps(inp_obj), # type: ignore
params=params or {},
)
return self._result_id_to_future_result(inp_obj, result_id)
Expand Down
30 changes: 15 additions & 15 deletions chemcloud/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,18 @@

from pydantic import field_validator
from pydantic.main import BaseModel
from qcio import (
DualProgramInput,
FileInput,
FileOutput,
OptimizationOutput,
ProgramFailure,
ProgramInput,
SinglePointOutput,
)
from qcio import DualProgramInput, FileInput, ProgramInput, ProgramOutput
from typing_extensions import TypeAlias

from .exceptions import TimeoutError

GROUP_ID_PREFIX = "group-"

# Convenience types
QCIOInputs = Union[ProgramInput, FileInput, DualProgramInput]
QCIOInputsOrList = Union[QCIOInputs, List[QCIOInputs]]
QCIOOutputs = Union[FileOutput, SinglePointOutput, OptimizationOutput, ProgramFailure]
QCIOOutputsOrList = Union[QCIOOutputs, List[QCIOOutputs]]
QCIOInputs: TypeAlias = Union[ProgramInput, FileInput, DualProgramInput]
QCIOInputsOrList: TypeAlias = Union[QCIOInputs, List[QCIOInputs]]
QCIOOutputs: TypeAlias = ProgramOutput
QCIOOutputsOrList: TypeAlias = Union[QCIOOutputs, List[QCIOOutputs]]


class TaskStatus(str, Enum):
Expand All @@ -33,6 +26,7 @@ class TaskStatus(str, Enum):
#: Task state is unknown (assumed pending since you know the id).
PENDING = "PENDING"
COMPLETE = "COMPLETE"
FAILURE = "FAILURE"


class FutureOutputBase(BaseModel, ABC):
Expand Down Expand Up @@ -60,7 +54,7 @@ def get(
self,
timeout: Optional[float] = None, # in seconds
interval: float = 1.0,
) -> QCIOOutputsOrList:
) -> Optional[QCIOOutputsOrList]:
"""Block until a calculation is complete and return the result.
Parameters:
Expand All @@ -80,7 +74,13 @@ def get(

start_time = time()

while not self.result:
# self._state check prevents 401 errors from ChemCloud when the job completed
# but the server failed to return a result (e.g., due to .program_output not)
# being set correctly by qcio/BigChem.
# TODO: Make a clearer contract between Server and Client re: states. This got
# a bit messy as I switched mimicking celery states to the more simplified setup
# I have now. This can be simplified further.
while not self.result and self._state not in {"COMPLETE", "FAILURE"}:
# Calling self.status returns status and sets self.result if task complete
self.status
if timeout:
Expand Down
5 changes: 5 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [unreleased]

### Changed

- Upgraded to `qcio` Generics data structures.
- Upgraded `black` from `^23.0.0` to `^24.0.0`.

## [0.8.3] - 2023-10-20

### Changed
Expand Down
20 changes: 12 additions & 8 deletions examples/energy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from qcio import Molecule, ProgramInput, SinglePointOutput
from qcio import Molecule, ProgramInput, ProgramOutput

from chemcloud import CCClient

Expand All @@ -19,11 +19,15 @@
calctype="energy", # Or "gradient" or "hessian"
keywords={},
)
future_result = client.compute("psi4", prog_inp, collect_files=True)
output: SinglePointOutput = future_result.get()
# SinglePointOutput object containing all returned data
print(output.stdout)
print(output)
future_result = client.compute("terachem", prog_inp, collect_files=True)
prog_output: ProgramOutput = future_result.get()
# ProgramOutput object containing all returned data
print(prog_output.stdout)
print(prog_output)
# The energy value requested
print(output.return_result)
print(output.files.keys())

if prog_output.success:
print(prog_output.results.energy)
print(prog_output.files.keys())
else:
print(prog_output.traceback)
6 changes: 3 additions & 3 deletions examples/energy_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
keywords={},
)
future_result = client.compute("psi4", [prog_inp] * 2)
output = future_result.get()
# Array of SinglePointOutput objects containing all returned data
print(output)
prog_output = future_result.get()
# Array of ProgramOutput objects containing all returned data
print(prog_output)
14 changes: 7 additions & 7 deletions examples/energy_wfn_input.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from qcio import Molecule, ProgramInput, SinglePointOutput
from qcio import Molecule, ProgramInput, ProgramOutput

from chemcloud import CCClient

Expand All @@ -23,10 +23,10 @@
},
)
future_result = client.compute("terachem", prog_inp)
output: SinglePointOutput = future_result.get()
# SinglePointOutput object containing all returned data
print(output.stdout)
print(output)
prog_output: ProgramOutput = future_result.get()
# ProgramOutput object containing all returned data
print(prog_output.stdout)
print(prog_output)
# The energy value requested
print(output.return_result)
print(output.files.keys())
print(prog_output.return_result)
print(prog_output.files.keys())
8 changes: 4 additions & 4 deletions examples/optimization_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
prog_inp = DualProgramInput(
molecule=water,
calctype="optimization",
keywords={"maxiter": 3},
keywords={"maxiter": 25},
subprogram="psi4",
subprogram_args={"model": {"method": "b3lyp", "basis": "6-31g"}},
)


# Submit calculation
future_result = client.compute("geometric", [prog_inp] * 2)
output = future_result.get()
future_result = client.compute("geometric", prog_inp)
prog_output = future_result.get()

# Array of OptimizationOutput objects
print(output)
print(prog_output)
14 changes: 7 additions & 7 deletions examples/parallel_frequency_analysis.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from qcio import DualProgramInput, Molecule, SinglePointOutput
from qcio import DualProgramInput, Molecule, ProgramOutput

from chemcloud import CCClient

Expand All @@ -23,10 +23,10 @@

# Submit calculation
future_result = client.compute("bigchem", prog_inp)
output: SinglePointOutput = future_result.get()
prog_output: ProgramOutput = future_result.get()

# SinglePointOutput object containing all returned data
print(output)
print(f"Wavenumbers: {output.results.freqs_wavenumber}")
print(output.results.normal_modes_cartesian)
print(output.results.gibbs_free_energy)
# ProgramOutput object containing all returned data
print(prog_output)
print(f"Wavenumbers: {prog_output.results.freqs_wavenumber}")
print(prog_output.results.normal_modes_cartesian)
print(prog_output.results.gibbs_free_energy)
16 changes: 8 additions & 8 deletions examples/parallel_hessian.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from qcio import DualProgramInput, Molecule, SinglePointOutput
from qcio import DualProgramInput, Molecule, ProgramOutput

from chemcloud import CCClient

Expand All @@ -23,12 +23,12 @@

# Submit calculation
future_result = client.compute("bigchem", prog_inp)
output: SinglePointOutput = future_result.get()
prog_output: ProgramOutput = future_result.get()

# SinglePointOutput object containing all returned data
print(output)
print(output.results.hessian)
# ProgramOutput object containing all returned data
print(prog_output)
print(prog_output.results.hessian)
# Frequency data always included too
print(f"Wavenumbers: {output.results.freqs_wavenumber}")
print(output.results.normal_modes_cartesian)
print(output.results.gibbs_free_energy)
print(f"Wavenumbers: {prog_output.results.freqs_wavenumber}")
print(prog_output.results.normal_modes_cartesian)
print(prog_output.results.gibbs_free_energy)
Loading

0 comments on commit 391e762

Please sign in to comment.