Skip to content
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

[WIP] Integration and test of RSS code #84

Merged
merged 40 commits into from
Aug 6, 2024
Merged

Conversation

YuanbinLiu
Copy link
Collaborator

@YuanbinLiu YuanbinLiu commented Jul 29, 2024

This PR primarily integrates the RSS code with the phonon code.

Todo list

  • Refactor the gap_fitting part in MLIPFitMaker, as it is kind of specific to GAP and phonon tasks.
  • Separate the DataPreprocessing job and the machine_learning_fit job because DataPreprocessing might need to be used with active learning later, and we need to ensure its flexibility.
  • Complete the interface to XPOT so that one can perform optimization and conduct pacemaker fitting.

@YuanbinLiu YuanbinLiu changed the title Integration and test of RSS code [WIP] Integration and test of RSS code Jul 29, 2024
Copy link
Collaborator

@jla-gardner jla-gardner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work here 😄

I've left a few comments regarding style - most of my points are applicable across the PR but I've made them in just one representative case.

The nequip_fitting and the default parameters you have selected seem reasonable to me!

random_seed: int = None,
):
"""
Job to sample training configurations from trajs of MD/RSS.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you consider changing instances of "trajs" to "trajectories"? To me, the former is a needless contraction, particularly in a docstring

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sounds good! It has been changed now.


Parameters
----------
selection_method : str, optional
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you are expecting one of several options, why not type hint this with Literal["cur", "bcur", ...]?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using type hint is indeed better. I have implemented that change.

- 'cur': Pure CUR selection.
- 'bcur': Boltzmann flat histogram in enthalpy, then CUR.
- 'random': Random selection.
- 'uniform': Uniform selection. Default is None. If None, then default to random.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why default to None here, when you could just default to "random"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, let‘s make it even simpler.

"energy_label": "energy",
}

if bcur_params is not None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the user specifies bcur_param={"soap_params": {"atom_sigma": 0.5}} - do you want to keep the rest of the default soap params? Or require the user to provide all of these.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it will only change the value of "atom_sigma". The rest of the default soap params will be kept. The user does not need to provide all parameters.

List of structures for sampling. Default is None.

traj_info : list, optional
List of dictionaries containing trajectory information. Each dictionary should
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type hint should be list[dict] here as a minimum I think. If you want to give more info, you could consider creating e.g. a TypedDict to indicate to the the typing tools that you are expecting these keys.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. This is done by traj_info: list[dict[str, Union[str, float]]] = None.

autoplex/data/common/jobs.py Outdated Show resolved Hide resolved
autoplex/data/common/jobs.py Outdated Show resolved Hide resolved
if recursive:
for element in atoms_object:
if isinstance(element, Iterable) and not isinstance(
element, (str, bytes, ase.atoms.Atoms, ase.Atoms)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here is not mirrored in the docstring

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just made some changes.

autoplex/fitting/common/jobs.py Outdated Show resolved Hide resolved
@@ -634,6 +650,9 @@ def m3gnet_fitting(
max_n: int = 4,
device: str = "cuda",
test_equal_to_val: bool = True,
ref_energy_name: str = "REF_energy",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thi nequip_fitting functions appears to do what it says on the tin, but is quite hacky. Rather than writing a raw text file to a file, have you considered yaml dumping a dictionary of the config instead?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still have a few rather hacky parts in the fitting part of autoplex. Any further suggestions or pull requests would be appreciated.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the short term, I think this is fine to be merged.

In the medium term, we could consider using the functions exposed in the nequip.scripts.train/deploy submodules to just run things from within python.

In the long term, a new fitting framework is being made that unifies a lot of these model architectures - integrating this will simplify things here significantly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very much agreed.

We should try to get a minimum viable product out first and then subsequently improve it. (I also very much hope this whole pytorch version and conflict mess between different fitting frameworks won't keep us too busy in the future. We might have to think about other installation strategies then.... )

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point and agree with all views. For nequip, we definitely can switch to yaml. But for J-ACE, I don't find a good solution.

@jla-gardner, do you think the hyperparameters listed for nequip are the most important ones? Besides these, do you think there's any other hyperparameter that might have been overlooked?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These hyperparameters are definitely the most important. Looks good to me!


import logging

logging.basicConfig(level=logging.DEBUG, format='[%(levelname)s] %(message)s')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, this will do. In a subsequent PR we should extract this into its own file, and adopt its use across the whole repo.

@QuantumChemist
Copy link
Collaborator

QuantumChemist commented Aug 2, 2024

@YuanbinLiu @QuantumChemist my suggestion for now would be: @QuantumChemist takes a closer look tomorrow and then both of you meet to clarify the last questions. For some reason, one can sometimes not see very well when whole code blocks have been moved to another file.

Most things have been cleared up. I will check the code to see if it still runs as intended. Still, to give my part of the approval to this PR, the following (EDIT!) three and an optional fourth criteria have to be met:

  • The unit tests have to be restored and adjusted to the code changes, especially if the new unit tests are not rss specific (then the rss unit tests are redundant)
  • a proper RSS static maker for VASP has to be written
  • type hints for every function.that isn't a Flow or job object (EDIT!)
  • separate files for the MLIP default settings (this is optional if it's not easily done)

@JaGeo
Copy link
Collaborator

JaGeo commented Aug 2, 2024

@YuanbinLiu I agree with @QuantumChemist here on the required changes.

  • Additionally, the documentation generation needs to be fixed. I don't know why the CI is failing. Unfortunately, this needs to be investigated as well.
  • In a subsequent PR, all changes in this PR should be reflected in the documentation and tutorials of the code
  • In another or the same subsequent PR, additional documentation for the RSS part should be added.

@JaGeo
Copy link
Collaborator

JaGeo commented Aug 2, 2024

One slight addition for the unit tests: I suggest having a common test file for all fitting-related unit tests. I think adding all tests to the RSS-related fitting tests is not a perfect solution, as I would not have expected all other tests for the fitting code to be in there as well.

Copy link
Collaborator

@JaGeo JaGeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just marked one of my requests now in the pull request itself.

Comment on lines 1 to 25
from __future__ import annotations
from autoplex.fitting.common.flows import MLIPFitMaker
import shutil
from pathlib import Path
from jobflow import run_locally


def test_gap_fit_maker(test_dir, memory_jobstore):

database_dir = test_dir / "fitting/rss_training_dataset/"

gapfit = MLIPFitMaker().make(
auto_delta=False,
glue_xml=False,
twob={"delta": 2.0, "cutoff": 4},
threeb={"n_sparse": 10},
preprocessing_data=False,
database_dir=database_dir
)

responses = run_locally(
gapfit, ensure_success=True, create_folders=True, store=memory_jobstore
)

assert Path(gapfit.output["mlip_path"].resolve(memory_jobstore)).exists()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest moving these tests to the general fitting part.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion! It is done.

@QuantumChemist
Copy link
Collaborator

Another thing that is also missing that I notice now are type hints for every function.that isn't a Flow or job object.

@JaGeo
Copy link
Collaborator

JaGeo commented Aug 2, 2024

Another thing that is also missing that I notice now are type hints for every function.that isn't a Flow or job object.

This could be the problem for the documentation generation, btw

@@ -213,7 +217,7 @@ def gap_fitting(
title="Data error metrics",
energy_limit=0.005,
force_limit=0.1,
species_list=species_list,
species_list=species_list, # species list is required here
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

species_list is required here to post_process GAP data

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest that maybe a new argument like pairplot: bool = None is better. If pairplot is used, we can use the existing function to get species_list instead of passing it (the process is quick). Because species_list does not seem related to all model fitting.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add this to our list of potential todos within an issue? Maybe to reach consensus here fast, we can keep the species_list for now and improve this later? @YuanbinLiu would this work for you?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, sounds sensible! Let's keep species_list at the moment.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add an Issue with your suggestion and then we can discuss this there! It can also be a more general issue if you have additional points!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Species_list will get related to all models, once such analysis plots are implemented for them as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just discuss this in a separate issue how to handle this. For now, let's be pragmatic.

Copy link
Collaborator

@QuantumChemist QuantumChemist left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some docstrings missing

Comment on lines +247 to +249
ref_energy_name: str = "REF_energy",
ref_force_name: str = "REF_forces",
ref_virial_name: str = "REF_virial",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstrings are missing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, they are added now.

Comment on lines +425 to +427
ref_energy_name: str = "REF_energy",
ref_force_name: str = "REF_forces",
ref_virial_name: str = "REF_virial",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstrings are missing

Comment on lines +698 to +700
ref_energy_name: str = "REF_energy",
ref_force_name: str = "REF_forces",
ref_virial_name: str = "REF_virial",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstrings missing

Comment on lines +1054 to +1056
ref_energy_name: str = "REF_energy",
ref_force_name: str = "REF_forces",
ref_virial_name: str = "REF_virial",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docstrings missing

@QuantumChemist
Copy link
Collaborator

QuantumChemist commented Aug 2, 2024

@YuanbinLiu I agree with @QuantumChemist here on the required changes.

* [ ]  Additionally, the documentation generation needs to be fixed. I don't know why the CI is failing. Unfortunately, this needs to be investigated as well.

* [ ]  In a subsequent PR, all changes in this PR should be reflected in the documentation and tutorials of the code

* [ ]  In another or the same subsequent PR, additional documentation for the RSS part should be added.

@YuanbinLiu @QuantumChemist my suggestion for now would be: @QuantumChemist takes a closer look tomorrow and then both of you meet to clarify the last questions. For some reason, one can sometimes not see very well when whole code blocks have been moved to another file.

Most things have been cleared up. I will check the code to see if it still runs as intended. Still, to give my part of the approval to this PR, the following (EDIT!) three and an optional fourth criteria have to be met:

* [ ]  The unit tests have to be restored and adjusted to the code changes, especially if the new unit tests are not rss specific (then the rss unit tests are redundant)

* [ ]  a proper RSS static maker for VASP has to be written

* [ ]  type hints for every function.that isn't a Flow or job object (EDIT!)

* [ ]  separate files for the  MLIP default settings (this is optional if it's not easily done)

I have now carefully checked and adjusted the code where needed. The only issues that are left now are the ones addressed here. Of course, as always, I'm happy to help with some of the changes, like e.g. the unit tests, if it's not possible for you to restore them by one click in the IDE etc. 😄

@QuantumChemist
Copy link
Collaborator

QuantumChemist commented Aug 3, 2024

I'd like to kindly remind everyone about our contribution guidelines as well regarding variable names, type-hints etc.:
https://github.com/JaGeo/autoplex/blob/main/docs/dev/contributing.md

Guidelines for contributions

  • Please write unit tests; this is a requirement for any added code to be accepted. (Automated testing will be performed using pytest; you can look into the tests folder for examples).
  • Please ensure high coverage of the code based on the tests (you can test this with coverage).
  • Please use numpy docstrings (use an IDE and switch on this docstring type; you can check examples in our code base; the docstring should be useful for other people) <---
  • Please ensure that type hints are added for each variable, function, class, and method (this helps code readability, especially if someone else wants to build on your code). <---
  • Please write the code in a way that gives users the option to change parameters (this is mainly applicable, for example, fitting protocols/flows). In other words, please avoid hardcoding settings or physical properties.
    Reasonable default values should be set, but the user needs to have the opportunity to modify them if they wish.

General code structure

  • We are currently aiming to follow the code structure below for each submodule (This is an initial idea; of course, this could change depending on the needs in the future)
    • autoplex/submodule/job.py (any jobs defined will be inside this module)
    • autoplex/submodule/flows.py (workflows defined will be hosted in this module)
    • autoplex/submodule/utils.py (all functions that act as utilities for defining flow or job, for example, a small subtask to calculate some metric or plotting, will be hosted in this module)

Formatting requirements

  • Variable names should be descriptive and should use snake case (variable_name, not VariableName). <---
  • If you define a Maker, please use python class naming convention (e.g., PhononMaker, RssMaker).

Commit guidelines

  1. pip install pre-commit.
  2. Next, run pre-commit install (this will install all the hooks from pre-commit-config.yaml)
  3. Step 1 and 2 needs to be done only once in the local repository
  4. Proceed with modifying the code and adding commits as usual. This should automatically run the linters.
  5. To manually run the pre-commit hooks on all files, just use pre-commit run --all-files
  6. To run pre-commit on a specific file, use pre-commit run --files path/to/your/modified/module/

@YuanbinLiu
Copy link
Collaborator Author

@YuanbinLiu @QuantumChemist my suggestion for now would be: @QuantumChemist takes a closer look tomorrow and then both of you meet to clarify the last questions. For some reason, one can sometimes not see very well when whole code blocks have been moved to another file.

Most things have been cleared up. I will check the code to see if it still runs as intended. Still, to give my part of the approval to this PR, the following (EDIT!) three and an optional fourth criteria have to be met:

  • The unit tests have to be restored and adjusted to the code changes, especially if the new unit tests are not rss specific (then the rss unit tests are redundant)
  • a proper RSS static maker for VASP has to be written
  • type hints for every function.that isn't a Flow or job object (EDIT!)
  • separate files for the MLIP default settings (this is optional if it's not easily done)

I will temporarily set aside the final suggestion in this PR for now, as we will consider it in the upcoming modifications to MLIPFitMaker.

@JaGeo
Copy link
Collaborator

JaGeo commented Aug 6, 2024

As I am on vacation, @QuantumChemist could you shortly check if everything looks good from your perspective and if you have further suggestions with regard to the three open points? Thank you!

@JaGeo
Copy link
Collaborator

JaGeo commented Aug 6, 2024

@YuanbinLiu the docs are still failing. Could you fix this as well?

@QuantumChemist
Copy link
Collaborator

As I am on vacation, @QuantumChemist could you shortly check if everything looks good from your perspective and if you have further suggestions with regard to the three open points? Thank you!

This looks really good at first glance, but Yuanbin has run out of Action time. Would you prefer me to merge this PR for now and start the fixes in a new PR or should I rather merge Yuanbin's rss branch into one of my branches and push that back to this PR once the last problems are fixed?

@JaGeo
Copy link
Collaborator

JaGeo commented Aug 6, 2024

I can merge but the other issues need to be addressed in a subsequent pull request in the following days. Only in this way we will avoid any issues with subsequent pull requests

@JaGeo JaGeo merged commit 9413e94 into autoatml:main Aug 6, 2024
@JaGeo
Copy link
Collaborator

JaGeo commented Aug 6, 2024

@YuanbinLiu Could you please adress the open points in a subsequent pull request? Maybe using a fork from @QuantumChemist or @naik-aakash ? Thank you!

@QuantumChemist
Copy link
Collaborator

@YuanbinLiu Could you please adress the open points in a subsequent pull request? Maybe using a fork from @QuantumChemist or @naik-aakash ? Thank you!

I made a new branch https://github.com/QuantumChemist/autoplex/tree/rss_fixes and will start a new PR then tomorrow.

@YuanbinLiu
Copy link
Collaborator Author

@YuanbinLiu Could you please adress the open points in a subsequent pull request? Maybe using a fork from @QuantumChemist or @naik-aakash ? Thank you!

Yes, for sure

@JaGeo
Copy link
Collaborator

JaGeo commented Aug 7, 2024

@YuanbinLiu thank you 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants