Skip to content

Commit

Permalink
feat: descriptor provide get_rcut_smth and get_env_protection (#3761)
Browse files Browse the repository at this point in the history
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **New Features**
- Introduced methods to enhance the calculation of smooth decay radius
and environment matrix protection across various descriptor modules.
This will improve the precision and reliability of environmental
interactions in models.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Han Wang <[email protected]>
Co-authored-by: Han Wang <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored May 11, 2024
1 parent 063de8a commit 3a6d2c4
Show file tree
Hide file tree
Showing 18 changed files with 234 additions and 3 deletions.
16 changes: 16 additions & 0 deletions deepmd/dpmodel/descriptor/dpa1.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.se_atten.get_rcut()

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.se_atten.get_rcut_smth()

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return self.se_atten.get_nsel()
Expand Down Expand Up @@ -336,6 +340,10 @@ def mixed_types(self) -> bool:
"""
return self.se_atten.mixed_types()

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.se_atten.get_env_protection()

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down Expand Up @@ -635,6 +643,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return sum(self.sel)
Expand Down Expand Up @@ -687,6 +699,10 @@ def mixed_types(self) -> bool:
"""
return True

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

@property
def dim_out(self):
"""Returns the output dimension of this descriptor."""
Expand Down
8 changes: 8 additions & 0 deletions deepmd/dpmodel/descriptor/dpa2.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return sum(self.sel)
Expand Down Expand Up @@ -404,6 +408,10 @@ def mixed_types(self) -> bool:
"""
return True

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
17 changes: 17 additions & 0 deletions deepmd/dpmodel/descriptor/hybrid.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
import math
from typing import (
Any,
Dict,
Expand Down Expand Up @@ -96,6 +97,12 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return np.max([descrpt.get_rcut() for descrpt in self.descrpt_list]).item()

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
# may not be a good idea...
# Note: Using the minimum rcut_smth might not be appropriate in all scenarios. Consider using a different approach or provide detailed documentation on why the minimum value is chosen.
return np.min([descrpt.get_rcut_smth() for descrpt in self.descrpt_list]).item()

def get_sel(self) -> List[int]:
"""Returns the number of selected atoms for each type."""
if self.mixed_types():
Expand Down Expand Up @@ -127,6 +134,16 @@ def mixed_types(self):
"""
return any(descrpt.mixed_types() for descrpt in self.descrpt_list)

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix. All descriptors should be the same."""
all_protection = [descrpt.get_env_protection() for descrpt in self.descrpt_list]
same_as_0 = [math.isclose(ii, all_protection[0]) for ii in all_protection]
if not all(same_as_0):
raise ValueError(
"Hybrid descriptor requires the same environment matrix protection for all descriptors. Found differing values."
)
return all_protection[0]

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
10 changes: 10 additions & 0 deletions deepmd/dpmodel/descriptor/make_base_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
pass

@abstractmethod
def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
pass

@abstractmethod
def get_sel(self) -> List[int]:
"""Returns the number of selected neighboring atoms for each type."""
Expand Down Expand Up @@ -86,6 +91,11 @@ def mixed_types(self) -> bool:
"""
pass

@abstractmethod
def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
pass

@abstractmethod
def share_params(self, base_class, shared_level, resume=False):
"""
Expand Down
8 changes: 8 additions & 0 deletions deepmd/dpmodel/descriptor/se_e2_a.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ def get_rcut(self):
"""Returns cutoff radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_sel(self):
"""Returns cutoff radius."""
return self.sel
Expand All @@ -247,6 +251,10 @@ def mixed_types(self):
"""
return False

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
8 changes: 8 additions & 0 deletions deepmd/dpmodel/descriptor/se_r.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ def get_rcut(self):
"""Returns cutoff radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_sel(self):
"""Returns cutoff radius."""
return self.sel
Expand All @@ -203,6 +207,10 @@ def mixed_types(self):
"""
return False

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
10 changes: 10 additions & 0 deletions deepmd/pt/model/descriptor/descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
pass

@abstractmethod
def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
pass

@abstractmethod
def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
Expand Down Expand Up @@ -88,6 +93,11 @@ def get_dim_emb(self) -> int:
"""Returns the embedding dimension."""
pass

@abstractmethod
def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
pass

def compute_input_stats(
self,
merged: Union[Callable[[], List[dict]], List[dict]],
Expand Down
8 changes: 8 additions & 0 deletions deepmd/pt/model/descriptor/dpa1.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.se_atten.get_rcut()

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.se_atten.get_rcut_smth()

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return self.se_atten.get_nsel()
Expand Down Expand Up @@ -316,6 +320,10 @@ def mixed_types(self) -> bool:
"""
return self.se_atten.mixed_types()

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.se_atten.get_env_protection()

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
10 changes: 10 additions & 0 deletions deepmd/pt/model/descriptor/dpa2.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ def __init__(

self.tebd_dim = repinit_tebd_dim
self.rcut = self.repinit.get_rcut()
self.rcut_smth = self.repinit.get_rcut_smth()
self.ntypes = ntypes
self.sel = self.repinit.sel
# set trainable
Expand All @@ -373,6 +374,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return sum(self.sel)
Expand Down Expand Up @@ -408,6 +413,11 @@ def mixed_types(self) -> bool:
"""
return True

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
# the env_protection of repinit is the same as that of the repformer
return self.repinit.get_env_protection()

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
17 changes: 17 additions & 0 deletions deepmd/pt/model/descriptor/hybrid.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
import math
from typing import (
Any,
Dict,
Expand Down Expand Up @@ -101,6 +102,12 @@ def get_rcut(self) -> float:
# do not use numpy here - jit is not happy
return max([descrpt.get_rcut() for descrpt in self.descrpt_list])

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
# may not be a good idea...
# Note: Using the minimum rcut_smth might not be appropriate in all scenarios. Consider using a different approach or provide detailed documentation on why the minimum value is chosen.
return min([descrpt.get_rcut_smth() for descrpt in self.descrpt_list])

def get_sel(self) -> List[int]:
"""Returns the number of selected atoms for each type."""
if self.mixed_types():
Expand Down Expand Up @@ -132,6 +139,16 @@ def mixed_types(self):
"""
return any(descrpt.mixed_types() for descrpt in self.descrpt_list)

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix. All descriptors should be the same."""
all_protection = [descrpt.get_env_protection() for descrpt in self.descrpt_list]
same_as_0 = [math.isclose(ii, all_protection[0]) for ii in all_protection]
if not all(same_as_0):
raise ValueError(
"Hybrid descriptor requires the same environment matrix protection for all descriptors. Found differing values."
)
return all_protection[0]

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
8 changes: 8 additions & 0 deletions deepmd/pt/model/descriptor/repformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return sum(self.sel)
Expand Down Expand Up @@ -358,6 +362,10 @@ def mixed_types(self) -> bool:
"""
return True

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

@property
def dim_out(self):
"""Returns the output dimension of this descriptor."""
Expand Down
16 changes: 16 additions & 0 deletions deepmd/pt/model/descriptor/se_a.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.sea.get_rcut()

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.sea.get_rcut_smth()

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return self.sea.get_nsel()
Expand All @@ -132,6 +136,10 @@ def mixed_types(self):
"""
return self.sea.mixed_types()

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.sea.get_env_protection()

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down Expand Up @@ -400,6 +408,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return sum(self.sel)
Expand Down Expand Up @@ -436,6 +448,10 @@ def mixed_types(self) -> bool:
"""
return False

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

@property
def dim_out(self):
"""Returns the output dimension of this descriptor."""
Expand Down
8 changes: 8 additions & 0 deletions deepmd/pt/model/descriptor/se_atten.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return sum(self.sel)
Expand Down Expand Up @@ -338,6 +342,10 @@ def mixed_types(self) -> bool:
"""
return True

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

@property
def dim_out(self):
"""Returns the output dimension of this descriptor."""
Expand Down
8 changes: 8 additions & 0 deletions deepmd/pt/model/descriptor/se_r.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ def get_rcut(self) -> float:
"""Returns the cut-off radius."""
return self.rcut

def get_rcut_smth(self) -> float:
"""Returns the radius where the neighbor information starts to smoothly decay to 0."""
return self.rcut_smth

def get_nsel(self) -> int:
"""Returns the number of selected atoms in the cut-off radius."""
return sum(self.sel)
Expand Down Expand Up @@ -160,6 +164,10 @@ def mixed_types(self) -> bool:
"""
return False

def get_env_protection(self) -> float:
"""Returns the protection of building environment matrix."""
return self.env_protection

def share_params(self, base_class, shared_level, resume=False):
"""
Share the parameters of self to the base_class with shared_level during multitask training.
Expand Down
Loading

0 comments on commit 3a6d2c4

Please sign in to comment.