Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a7e4760
change to almostEqual in UT to avoid difference at FP precision (#1048)
amcadmus Aug 28, 2021
5f8989b
fix hybrid descriptor training error (#1052)
njzjz Aug 28, 2021
1dd6e97
add compatibility to `dp freeze` (#1055)
njzjz Aug 29, 2021
8dbc211
fix device UT error (#1056)
denghuilu Aug 29, 2021
26b4492
copy `all_virial` for float precision (#1069)
njzjz Aug 31, 2021
37fe14c
upgrade os.system to subporcess.popen method (#1066)
denghuilu Aug 31, 2021
8cf52fd
use `np.testing.assert_almost_equal` for array comparing (#1059)
njzjz Aug 31, 2021
4c10232
set `allow_growth` in `default_tf_session_config` (#1067)
njzjz Aug 31, 2021
75160c7
fix Fail to build on macos: explicit instantiation of 'deepmd::Region…
amcadmus Aug 31, 2021
63baa30
undo reset lcurve.out during the model compression process (#1080)
denghuilu Sep 1, 2021
91787ab
use @loader_path on macos instead of $ORIGIN (#1078)
njzjz Sep 1, 2021
385dcd6
fix typo: `lcueve.out`->`lcurve.out` (#1077)
njzjz Sep 1, 2021
c716b9f
Model compression checkpoint (#1076)
denghuilu Sep 1, 2021
03a05bd
Enable parallel training UT in GitHub CI. (#1075)
shishaochen Sep 1, 2021
9dcc816
Fix shape mismatch when type_embedding is enabled and type_one_side i…
shishaochen Sep 1, 2021
5e96c57
Revert "get library extension suffix from built-in method (#1036)" (#…
njzjz Sep 1, 2021
d68171a
reduce `rcut` and `sel` in the example of `se_e3` (#1082)
njzjz Sep 1, 2021
da5f688
create cross-references in docstring (#1083)
njzjz Sep 1, 2021
c824ff6
add ABC for descriptors (#1081)
njzjz Sep 2, 2021
aab124f
Fix a potential slice bug in se_t descriptor (#1087)
denghuilu Sep 3, 2021
e2fc5e3
make compress work for hybrid descriptor composed of se_e2_a (#1094)
njzjz Sep 4, 2021
a5bdd14
interface for deepmd with the centroids atoms, full 3x3 "atomic-viria…
DavideTisi Sep 4, 2021
32ccbb5
Fix gradient not averaged when parallel training. (#1104)
shishaochen Sep 6, 2021
d5a0f6f
Enable init-frz-model support for the original model (#1102)
denghuilu Sep 6, 2021
8727956
merge duplicated NeighborStat.get_stat (#1103)
njzjz Sep 6, 2021
dd3c1de
Update doc for init-frz-model (#1107)
denghuilu Sep 7, 2021
904ec11
fix bug of single precision model compression (#1110)
denghuilu Sep 7, 2021
2a71494
fix bug of single precision transfer (#1111)
denghuilu Sep 7, 2021
1fbf474
fix LAMMPS_VERSION_NUMBER condition (#1116)
njzjz Sep 8, 2021
60797e0
Fix missing `std::numeric_limits` (#1113)
chazeon Sep 8, 2021
97be2f5
support init_frz_model for hybrid descriptor (#1112)
njzjz Sep 8, 2021
ed36276
fix data_modifier OOM problem when set size is too large (#1117)
amcadmus Sep 8, 2021
1526587
fix bugs of dipole charge modifier: binary str and missing frozen nod…
amcadmus Sep 10, 2021
e263aa3
fix "Call to method DeepTensor.__init__ with too many arguments" (#1125)
njzjz Sep 10, 2021
95a0340
Merge branch 'master' into devel
amcadmus Sep 10, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/test_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,9 @@ jobs:
CXX: g++-${{ matrix.gcc }}
TENSORFLOW_VERSION: ${{ matrix.tf }}
- run: dp --version
- name: Prepare parallel runtime
if: ${{ matrix.tf == '' }}
run: |
sudo apt install libopenmpi-dev openmpi-bin
HOROVOD_WITHOUT_GLOO=1 HOROVOD_WITH_TENSORFLOW=1 pip install horovod mpi4py
- run: pytest --cov=deepmd source/tests && codecov
344 changes: 344 additions & 0 deletions deepmd/descriptor/descriptor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Tuple

import numpy as np
from deepmd.env import tf


class Descriptor(ABC):
r"""The abstract class for descriptors. All specific descriptors should
be based on this class.

The descriptor :math:`\mathcal{D}` describes the environment of an atom,
which should be a function of coordinates and types of its neighbour atoms.

Notes
-----
Only methods and attributes defined in this class are generally public,
that can be called by other classes.
"""

@abstractmethod
def get_rcut(self) -> float:
"""
Returns the cut-off radius.

Returns
-------
float
the cut-off radius

Notes
-----
This method must be implemented, as it's called by other classes.
"""

@abstractmethod
def get_ntypes(self) -> int:
"""
Returns the number of atom types.

Returns
-------
int
the number of atom types

Notes
-----
This method must be implemented, as it's called by other classes.
"""

@abstractmethod
def get_dim_out(self) -> int:
"""
Returns the output dimension of this descriptor.

Returns
-------
int
the output dimension of this descriptor

Notes
-----
This method must be implemented, as it's called by other classes.
"""

def get_dim_rot_mat_1(self) -> int:
"""
Returns the first dimension of the rotation matrix. The rotation is of shape
dim_1 x 3

Returns
-------
int
the first dimension of the rotation matrix
"""
# TODO: I think this method should be implemented as it's called by dipole and
# polar fitting network. However, currently not all descriptors have this
# method.
raise NotImplementedError

def get_nlist(self) -> Tuple[tf.Tensor, tf.Tensor, List[int], List[int]]:
"""
Returns neighbor information.

Returns
-------
nlist : tf.Tensor
Neighbor list
rij : tf.Tensor
The relative distance between the neighbor and the center atom.
sel_a : list[int]
The number of neighbors with full information
sel_r : list[int]
The number of neighbors with only radial information
"""
# TODO: I think this method should be implemented as it's called by energy
# model. However, se_ar and hybrid doesn't have this method.
raise NotImplementedError

@abstractmethod
def compute_input_stats(self,
data_coord: List[np.ndarray],
data_box: List[np.ndarray],
data_atype: List[np.ndarray],
natoms_vec: List[np.ndarray],
mesh: List[np.ndarray],
input_dict: Dict[str, List[np.ndarray]]
) -> None:
"""
Compute the statisitcs (avg and std) of the training data. The input will be
normalized by the statistics.

Parameters
----------
data_coord : list[np.ndarray]
The coordinates. Can be generated by
:meth:`deepmd.model.model_stat.make_stat_input`
data_box : list[np.ndarray]
The box. Can be generated by
:meth:`deepmd.model.model_stat.make_stat_input`
data_atype : list[np.ndarray]
The atom types. Can be generated by :meth:`deepmd.model.model_stat.make_stat_input`
natoms_vec : list[np.ndarray]
The vector for the number of atoms of the system and different types of
atoms. Can be generated by :meth:`deepmd.model.model_stat.make_stat_input`
mesh : list[np.ndarray]
The mesh for neighbor searching. Can be generated by
:meth:`deepmd.model.model_stat.make_stat_input`
input_dict : dict[str, list[np.ndarray]]
Dictionary for additional input

Notes
-----
This method must be implemented, as it's called by other classes.
"""

@abstractmethod
def build(self,
coord_: tf.Tensor,
atype_: tf.Tensor,
natoms: tf.Tensor,
box_: tf.Tensor,
mesh: tf.Tensor,
input_dict: Dict[str, Any],
reuse: bool = None,
suffix: str = '',
) -> tf.Tensor:
"""
Build the computational graph for the descriptor.

Parameters
----------
coord_ : tf.Tensor
The coordinate of atoms
atype_ : tf.Tensor
The type of atoms
natoms : tf.Tensor
The number of atoms. This tensor has the length of Ntypes + 2
natoms[0]: number of local atoms
natoms[1]: total number of atoms held by this processor
natoms[i]: 2 <= i < Ntypes+2, number of type i atoms
box : tf.Tensor
The box of frames
mesh : tf.Tensor
For historical reasons, only the length of the Tensor matters.
if size of mesh == 6, pbc is assumed.
if size of mesh == 0, no-pbc is assumed.
input_dict : dict[str, Any]
Dictionary for additional inputs
reuse : bool, optional
The weights in the networks should be reused when get the variable.
suffix : str, optional
Name suffix to identify this descriptor

Returns
-------
descriptor: tf.Tensor
The output descriptor

Notes
-----
This method must be implemented, as it's called by other classes.
"""

def enable_compression(self,
min_nbor_dist: float,
model_file: str = 'frozon_model.pb',
table_extrapolate: float = 5.,
table_stride_1: float = 0.01,
table_stride_2: float = 0.1,
check_frequency: int = -1,
suffix: str = "",
) -> None:
"""
Reveive the statisitcs (distance, max_nbor_size and env_mat_range) of the
training data.

Parameters
----------
min_nbor_dist : float
The nearest distance between atoms
model_file : str, default: 'frozon_model.pb'
The original frozen model, which will be compressed by the program
table_extrapolate : float, default: 5.
The scale of model extrapolation
table_stride_1 : float, default: 0.01
The uniform stride of the first table
table_stride_2 : float, default: 0.1
The uniform stride of the second table
check_frequency : int, default: -1
The overflow check frequency
suffix : str, optional
The suffix of the scope

Notes
-----
This method is called by others when the descriptor supported compression.
"""
raise NotImplementedError(
"Descriptor %s doesn't support compression!" % type(self).__name__)

@abstractmethod
def prod_force_virial(self,
atom_ener: tf.Tensor,
natoms: tf.Tensor
) -> Tuple[tf.Tensor, tf.Tensor, tf.Tensor]:
"""
Compute force and virial.

Parameters
----------
atom_ener : tf.Tensor
The atomic energy
natoms : tf.Tensor
The number of atoms. This tensor has the length of Ntypes + 2
natoms[0]: number of local atoms
natoms[1]: total number of atoms held by this processor
natoms[i]: 2 <= i < Ntypes+2, number of type i atoms

Returns
-------
force : tf.Tensor
The force on atoms
virial : tf.Tensor
The total virial
atom_virial : tf.Tensor
The atomic virial
"""

def get_feed_dict(self,
coord_: tf.Tensor,
atype_: tf.Tensor,
natoms: tf.Tensor,
box: tf.Tensor,
mesh: tf.Tensor
) -> Dict[str, tf.Tensor]:
"""
Generate the feed_dict for current descriptor

Parameters
----------
coord_ : tf.Tensor
The coordinate of atoms
atype_ : tf.Tensor
The type of atoms
natoms : tf.Tensor
The number of atoms. This tensor has the length of Ntypes + 2
natoms[0]: number of local atoms
natoms[1]: total number of atoms held by this processor
natoms[i]: 2 <= i < Ntypes+2, number of type i atoms
box : tf.Tensor
The box. Can be generated by deepmd.model.make_stat_input
mesh : tf.Tensor
For historical reasons, only the length of the Tensor matters.
if size of mesh == 6, pbc is assumed.
if size of mesh == 0, no-pbc is assumed.

Returns
-------
feed_dict : dict[str, tf.Tensor]
The output feed_dict of current descriptor
"""
feed_dict = {
't_coord:0' :coord_,
't_type:0' :atype_,
't_natoms:0' :natoms,
't_box:0' :box,
't_mesh:0' :mesh
}
return feed_dict

def init_variables(self,
model_file: str,
suffix : str = "",
) -> None:
"""
Init the embedding net variables with the given dict

Parameters
----------
model_file : str
The input model file
suffix : str, optional
The suffix of the scope

Notes
-----
This method is called by others when the descriptor supported initialization from the given variables.
"""
raise NotImplementedError(
"Descriptor %s doesn't support initialization from the given variables!" % type(self).__name__)

def get_tensor_names(self, suffix : str = "") -> Tuple[str]:
"""Get names of tensors.

Parameters
----------
suffix : str
The suffix of the scope

Returns
-------
Tuple[str]
Names of tensors
"""
raise NotImplementedError("Descriptor %s doesn't support this property!" % type(self).__name__)

def pass_tensors_from_frz_model(self,
*tensors : tf.Tensor,
) -> None:
"""
Pass the descrpt_reshape tensor as well as descrpt_deriv tensor from the frz graph_def

Parameters
----------
*tensors : tf.Tensor
passed tensors

Notes
-----
The number of parameters in the method must be equal to the numbers of returns in
:meth:`get_tensor_names`.
"""
raise NotImplementedError("Descriptor %s doesn't support this method!" % type(self).__name__)
Loading