-
Notifications
You must be signed in to change notification settings - Fork 22
Feature/pacemaker implementation #485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e1d6ad2
96b2886
3d7326e
f7bbf62
4aebbd1
51b8650
ffa424a
10288d2
201d12b
943b00f
8a1b04e
4d691aa
3e66741
45ecc77
7de6ed8
cf27c74
91770a1
5585c47
2e0e7c0
ea285ce
f8dbae4
d0843b4
75465b8
1aca90d
78fcee5
51af9f8
02ec6fb
31c5fea
121bc0a
1a7fb65
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # This workflow will install pacemaker and its dependencies, run tests and lint with Python 3.10 | ||
|
|
||
| name: Testing Pacemaker (Python 3.10) | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| push: | ||
| branches: [ main ] | ||
| pull_request: | ||
| branches: [ main ] | ||
|
|
||
| jobs: | ||
| pacemaker-test: | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| PYTHON_VERSION: "3.10" | ||
|
|
||
| steps: | ||
| - name: Fetch Most Recent Docker Image Tag | ||
| run: | | ||
| TAG=$(curl -H "Accept: application/vnd.github.v3+json" \ | ||
| -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | ||
| https://api.github.com/orgs/autoatml/packages/container/autoplex%2Fautoplex-python-3.10/versions \ | ||
| | jq -r 'sort_by(.created_at) | reverse | .[0].metadata.container.tags[0]') | ||
| echo "VERSION=$TAG" >> $GITHUB_ENV | ||
|
|
||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Run Pacemaker Tests | ||
| run: | | ||
| docker pull ghcr.io/autoatml/autoplex/autoplex-python-3.10:${{ env.VERSION }} | ||
|
|
||
| docker run --rm \ | ||
| -v ${{ github.workspace }}:/workspace \ | ||
| -w /workspace \ | ||
| ghcr.io/autoatml/autoplex/autoplex-python-3.10:${{ env.VERSION }} \ | ||
| bash -c " | ||
| git config --global --add safe.directory /workspace && \ | ||
| python -m pip install --upgrade pip && \ | ||
| python -m uv cache clean && \ | ||
| python -m uv pip install 'protobuf<3.20' tensorflow==2.8.0 && \ | ||
| python -m uv pip install --no-deps git+https://github.com/ICAMS/TensorPotential.git@1e44b2558356800ae070658c0bb856ff9bf74538 && \ | ||
| python -m uv pip install --no-deps git+https://github.com/ICAMS/python-ace.git@d1c213a7d9c5b809a3ae83b2e5a916be26d921f0 && \ | ||
| python -m uv pip install --prerelease=allow '.[strict,tests,aims]' && \ | ||
| OMP_NUM_THREADS=1 pytest --cache-clear -vv -k 'PACE' | ||
| " |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -333,7 +333,7 @@ def process_rss( | |
| ASE Atoms object representing the atomic configuration. | ||
| mlip_type: str | ||
| Choose one specific MLIP type: | ||
| 'GAP' | 'J-ACE' | 'NequIP' | 'M3GNet' | 'MACE'. | ||
| 'GAP' | 'J-ACE' | 'P-ACE' | 'NequIP' | 'M3GNet' | 'MACE'. | ||
| mlip_path: str | Path | ||
| Path to the MLIP model. | ||
| output_file_name: str | ||
|
|
@@ -420,6 +420,29 @@ def process_rss( | |
| lmpcmds=cmds, atom_types=atom_types, log_file="test.log", keep_alive=True | ||
| ) | ||
|
|
||
| elif mlip_type == "P-ACE": | ||
|
|
||
| mlip_path_obj = Path(mlip_path) | ||
| potential_file = None | ||
|
|
||
| if mlip_path_obj.is_file(): | ||
| potential_file = mlip_path_obj | ||
| else: | ||
| target_file = mlip_path_obj / "output_potential.yaml" | ||
| if target_file.exists(): | ||
| potential_file = target_file | ||
|
|
||
| if potential_file is None: | ||
| raise FileNotFoundError( | ||
| f"Could not find 'output_potential.yaml' in {mlip_path} for P-ACE." | ||
| ) | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you try importing
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you Janine! All sound very good. I will quickly reply to your points regarding pacemaker installation / inplementation in this chat (and show more details in the following sperate chats). For the purpose: yes, we want to have a separate ACE-driven RSS flow that is independent of any GAP-RSS runs. I am not saying ACE will completely displace GAP (people can still run GAP-RSS if they want!), but we will have other MLIP options for the RSS process (ACE is particularlly important because it enables super large-scale MD simulations).
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great! Thanks! |
||
| from autoplex.fitting.common.utils import ( # noqa: PLC0415 | ||
| AutoplexPyACECalculator, | ||
| ) | ||
|
|
||
| pot = AutoplexPyACECalculator(basis_set=str(potential_file.resolve())) | ||
|
|
||
| elif mlip_type == "NEQUIP": | ||
| nequip_label = os.path.join(mlip_path, "deployed_nequip_model.pth") | ||
| if isolated_atom_energies: | ||
|
|
@@ -539,7 +562,7 @@ def build_traj(): | |
|
|
||
|
|
||
| def minimize_structures( | ||
| mlip_type: Literal["GAP", "J-ACE", "NEP", "NEQUIP", "M3GNET", "MACE"], | ||
| mlip_type: Literal["GAP", "J-ACE", "P-ACE", "NEP", "NEQUIP", "M3GNET", "MACE"], | ||
| mlip_path: str | Path, | ||
| iteration_index: str, | ||
| structures: list[Structure], | ||
|
|
@@ -566,7 +589,7 @@ def minimize_structures( | |
|
|
||
| Parameters | ||
| ---------- | ||
| mlip_type: Literal["GAP", "J-ACE", "NEP", "NEQUIP", "M3GNET", "MACE"] | ||
| mlip_type: Literal["GAP", "J-ACE", "P-ACE", "NEP", "NEQUIP", "M3GNET", "MACE"] | ||
| Choose one specific MLIP type to be fitted. | ||
| mlip_path: str | Path | ||
| Path to the MLIP model. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| mace_fitting, | ||
| nep_fitting, | ||
| nequip_fitting, | ||
| pace_fitting, | ||
| ) | ||
|
|
||
|
|
||
|
|
@@ -67,7 +68,7 @@ def machine_learning_fit( | |
| List of GPU indices to be used for fitting. Only used for NEP fitting. | ||
| mlip_type: str | ||
| Choose one specific MLIP type to be fitted: | ||
| 'GAP' | 'J-ACE' | 'NEQUIP' | 'NEP' | 'M3GNET' | 'MACE' | ||
| 'GAP' | 'J-ACE' | 'P-ACE' | 'NEQUIP' | 'NEP' | 'M3GNET' | 'MACE' | ||
| ref_energy_name: str | ||
| Reference energy name. | ||
| ref_force_name: str | ||
|
|
@@ -164,6 +165,51 @@ def machine_learning_fit( | |
| ) | ||
| mlip_paths.append(train_test_error["mlip_path"]) | ||
|
|
||
| elif mlip_type == "P-ACE": | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do the import here. |
||
| from autoplex.settings import PacemakerSettings # noqa: PLC0415 | ||
|
|
||
| pace_specific_keys = { | ||
| "cutoff", | ||
| "seed", | ||
| "metadata", | ||
| "potential", | ||
| "data", | ||
| "fit", | ||
| "backend", | ||
| } | ||
| pace_kwargs = {k: v for k, v in fit_kwargs.items() if k in pace_specific_keys} | ||
|
|
||
| pace_hypers = ( | ||
| PacemakerSettings(**pace_kwargs) if pace_kwargs else hyperparameters.P_ACE | ||
| ) | ||
|
|
||
| # if not species_list: | ||
| # if pace_hypers.potential and "elements" in pace_hypers.potential: | ||
| if ( | ||
| not species_list | ||
| and pace_hypers.potential | ||
| and "elements" in pace_hypers.potential | ||
| ): | ||
| species_list = pace_hypers.potential["elements"] | ||
|
|
||
| remaining_fit_kwargs = { | ||
| k: v for k, v in fit_kwargs.items() if k not in pace_specific_keys | ||
| } | ||
|
|
||
| train_test_error = pace_fitting( | ||
| db_dir=database_dir, | ||
| species_list=species_list, | ||
| hyperparameters=pace_hypers, | ||
| fit_kwargs=remaining_fit_kwargs, # Pass only non-P-ACE params | ||
| isolated_atom_energies=isolated_atom_energies, | ||
| ref_energy_name=ref_energy_name, | ||
| ref_force_name=ref_force_name, | ||
| ref_virial_name=ref_virial_name, | ||
| num_processes_fit=num_processes_fit, | ||
| ) | ||
| mlip_paths.append(train_test_error["mlip_path"]) | ||
|
|
||
| elif mlip_type == "NEP": | ||
| if gpu_identifier_indices is None: | ||
| gpu_identifier_indices = [0] | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.