Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,12 @@ node_modules/
test_dp_test/
test_dp_test_*.out
*_detail.out

# Training and model output files
*.pth
*.ckpt*
checkpoint
lcurve.out
out.json
input_v2_compat.json
frozen_model.*
10 changes: 7 additions & 3 deletions deepmd/dpmodel/utils/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ def __init__(
self._networks = [None for ii in range(ntypes**ndim)]
for ii, network in enumerate(networks):
self[ii] = network
if len(networks):
if len(networks) and all(net is not None for net in networks):
self.check_completeness()

def check_completeness(self) -> None:
Expand Down Expand Up @@ -969,7 +969,9 @@ def __getitem__(self, key):
return self._networks[self._convert_key(key)]

def __setitem__(self, key, value) -> None:
if isinstance(value, self.network_type):
if value is None:
pass
elif isinstance(value, self.network_type):
pass
elif isinstance(value, dict):
value = self.network_type.deserialize(value)
Expand All @@ -993,7 +995,9 @@ def serialize(self) -> dict:
"ndim": self.ndim,
"ntypes": self.ntypes,
"network_type": network_type_name,
"networks": [nn.serialize() for nn in self._networks],
"networks": [
nn.serialize() if nn is not None else None for nn in self._networks
],
}

@classmethod
Expand Down
22 changes: 21 additions & 1 deletion deepmd/tf/fit/dipole.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

import numpy as np

from deepmd.env import (
GLOBAL_NP_FLOAT_PRECISION,
)
from deepmd.tf.common import (
cast_precision,
get_activation_func,
Expand Down Expand Up @@ -421,7 +424,9 @@ def serialize(self, suffix: str) -> dict:
"dim_case_embd": self.dim_case_embd,
"activation_function": self.activation_function_name,
"precision": self.fitting_precision.name,
"exclude_types": [],
"exclude_types": []
if self.sel_type is None
else [ii for ii in range(self.ntypes) if ii not in self.sel_type],
"nets": self.serialize_network(
ntypes=self.ntypes,
ndim=0 if self.mixed_types else 1,
Expand All @@ -434,6 +439,16 @@ def serialize(self, suffix: str) -> dict:
trainable=self.trainable,
suffix=suffix,
),
"@variables": {
"fparam_avg": self.fparam_avg,
"fparam_inv_std": self.fparam_inv_std,
"aparam_avg": self.aparam_avg,
"aparam_inv_std": self.aparam_inv_std,
"case_embd": None,
"bias_atom_e": np.zeros(
(self.ntypes, self.dim_rot_mat_1), dtype=GLOBAL_NP_FLOAT_PRECISION
),
Comment thread
njzjz marked this conversation as resolved.
},
"type_map": self.type_map,
}
return data
Expand All @@ -454,6 +469,11 @@ def deserialize(cls, data: dict, suffix: str):
"""
data = data.copy()
check_version_compatibility(data.pop("@version", 1), 3, 1)
exclude_types = data.pop("exclude_types", [])
if len(exclude_types) > 0:
data["sel_type"] = [
ii for ii in range(data["ntypes"]) if ii not in exclude_types
]
fitting = cls(**data)
fitting.fitting_net_variables = cls.deserialize_network(
data["nets"],
Expand Down
4 changes: 3 additions & 1 deletion deepmd/tf/fit/fitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ def deserialize_network(cls, data: dict, suffix: str = "") -> dict:
else:
raise ValueError(f"Invalid ndim: {fittings.ndim}")
network = fittings[net_idx]
assert network is not None
if network is None:
# Skip types that are not selected (when sel_type is used)
continue
for layer_idx, layer in enumerate(network.layers):
if layer_idx == len(network.layers) - 1:
layer_name = "final_layer"
Expand Down
70 changes: 69 additions & 1 deletion source/tests/consistent/fitting/test_dipole.py
Comment thread
njzjz marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
(True, False), # resnet_dt
("float64", "float32"), # precision
(True, False), # mixed_types
(None, [0]), # sel_type
)
class TestDipole(CommonTest, DipoleFittingTest, unittest.TestCase):
@property
Expand All @@ -69,20 +70,45 @@
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
return {
data = {
"neuron": [5, 5, 5],
"resnet_dt": resnet_dt,
"precision": precision,
"sel_type": sel_type,
"seed": 20240217,
}
return data

def pass_data_to_cls(self, cls, data) -> Any:
"""Pass data to the class."""
if cls not in (self.tf_class,):
sel_type = data.pop("sel_type", None)
if sel_type is not None:
all_types = list(range(self.ntypes))
exclude_types = [t for t in all_types if t not in sel_type]
data["exclude_types"] = exclude_types
return cls(**data, **self.additional_data)
Comment thread
njzjz marked this conversation as resolved.

@property
def skip_tf(self) -> bool:
(
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
# mixed_types + sel_type is not supported
return CommonTest.skip_tf or (mixed_types and sel_type is not None)

@property
def skip_pt(self) -> bool:
(
resnet_dt,
precision,
mixed_types,
sel_type,

Check notice

Code scanning / CodeQL

Unused local variable Note test

Variable sel_type is not used.

Copilot Autofix

AI 10 months ago

To fix the unused local variable error in the skip_pt property method of the TestDipole class (lines 107–113), remove the unpacking assignment to (resnet_dt, precision, mixed_types, sel_type) = self.param. This assignment is unnecessary as none of these variables are used in the body of the method. The only statement required is the return of CommonTest.skip_pt. You should edit lines 107–112 (the unpacking assignment), reducing the method to just:

@property
def skip_pt(self) -> bool:
    return CommonTest.skip_pt

There are no new methods, imports, or definitions needed for this change.

Suggested changeset 1
source/tests/consistent/fitting/test_dipole.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/source/tests/consistent/fitting/test_dipole.py b/source/tests/consistent/fitting/test_dipole.py
--- a/source/tests/consistent/fitting/test_dipole.py
+++ b/source/tests/consistent/fitting/test_dipole.py
@@ -104,12 +104,6 @@
 
     @property
     def skip_pt(self) -> bool:
-        (
-            resnet_dt,
-            precision,
-            mixed_types,
-            sel_type,
-        ) = self.param
         return CommonTest.skip_pt
 
     tf_class = DipoleFittingTF
EOF
@@ -104,12 +104,6 @@

@property
def skip_pt(self) -> bool:
(
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
return CommonTest.skip_pt

tf_class = DipoleFittingTF
Copilot is powered by AI and may make mistakes. Always verify output.
) = self.param
return CommonTest.skip_pt

Expand Down Expand Up @@ -112,6 +138,7 @@
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
return {
"ntypes": self.ntypes,
Expand All @@ -125,6 +152,7 @@
resnet_dt,
precision,
mixed_types,
sel_type,

Check notice

Code scanning / CodeQL

Unused local variable Note test

Variable sel_type is not used.

Copilot Autofix

AI 10 months ago

To fix the problem, we should simply remove sel_type from the left-hand side of the tuple unpacking in the build_tf method since it is not used within the method. This can be done by changing the tuple unpacking on line 151–155 from:

(
    resnet_dt,
    precision,
    mixed_types,
    sel_type,
) = self.param

to:

(
    resnet_dt,
    precision,
    mixed_types,
    _,
) = self.param

Alternatively, if unpacking all four values is not necessary (that is, if self.param provides four values but only three are used), then we can use _ to indicate that the last element is intentionally unused, matching Python convention for unused variables. No imports or extra code are necessary.

Suggested changeset 1
source/tests/consistent/fitting/test_dipole.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/source/tests/consistent/fitting/test_dipole.py b/source/tests/consistent/fitting/test_dipole.py
--- a/source/tests/consistent/fitting/test_dipole.py
+++ b/source/tests/consistent/fitting/test_dipole.py
@@ -152,7 +152,7 @@
             resnet_dt,
             precision,
             mixed_types,
-            sel_type,
+            _,
         ) = self.param
         return self.build_tf_fitting(
             obj,
EOF
@@ -152,7 +152,7 @@
resnet_dt,
precision,
mixed_types,
sel_type,
_,
) = self.param
return self.build_tf_fitting(
obj,
Copilot is powered by AI and may make mistakes. Always verify output.
) = self.param
return self.build_tf_fitting(
obj,
Expand All @@ -141,6 +169,7 @@
resnet_dt,
precision,
mixed_types,
sel_type,

Check notice

Code scanning / CodeQL

Unused local variable Note test

Variable sel_type is not used.

Copilot Autofix

AI 10 months ago

To fix the problem, remove the assignment to the unused variable sel_type in the tuple unpacking within the eval_pt method. Since only the first three elements (resnet_dt, precision, mixed_types) are used, the unpacking should be limited to these three variables. This can be accomplished by changing the tuple unpacking from four variables to three. Specifically, in eval_pt, change lines:

168:         (
169:             resnet_dt,
170:             precision,
171:             mixed_types,
172:             sel_type,
173:         ) = self.param

to:

168:         (
169:             resnet_dt,
170:             precision,
171:             mixed_types,
172:         ) = self.param

Alternatively, unpack all four but replace sel_type with _ to indicate a deliberately unused variable, but since there is no apparent need for it, simply dropping it is preferable here.

Suggested changeset 1
source/tests/consistent/fitting/test_dipole.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/source/tests/consistent/fitting/test_dipole.py b/source/tests/consistent/fitting/test_dipole.py
--- a/source/tests/consistent/fitting/test_dipole.py
+++ b/source/tests/consistent/fitting/test_dipole.py
@@ -169,7 +169,6 @@
             resnet_dt,
             precision,
             mixed_types,
-            sel_type,
         ) = self.param
         return (
             pt_obj(
EOF
@@ -169,7 +169,6 @@
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
return (
pt_obj(
Copilot is powered by AI and may make mistakes. Always verify output.
) = self.param
return (
pt_obj(
Expand All @@ -159,6 +188,7 @@
resnet_dt,
precision,
mixed_types,
sel_type,

Check notice

Code scanning / CodeQL

Unused local variable Note test

Variable sel_type is not used.

Copilot Autofix

AI 10 months ago

The best fix is to remove the assignment of ( resnet_dt, precision, mixed_types, sel_type, ) entirely from the beginning of the eval_dp method, since none of those variables are used in its body. This involves deleting lines 187–192. This visual and functional change aligns with the fix recommendations, which note that an unused assignment (with no-important right-hand side or side effects) should simply be deleted. No imports, method changes, or further edits are required.

Suggested changeset 1
source/tests/consistent/fitting/test_dipole.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/source/tests/consistent/fitting/test_dipole.py b/source/tests/consistent/fitting/test_dipole.py
--- a/source/tests/consistent/fitting/test_dipole.py
+++ b/source/tests/consistent/fitting/test_dipole.py
@@ -184,12 +184,6 @@
         )
 
     def eval_dp(self, dp_obj: Any) -> Any:
-        (
-            resnet_dt,
-            precision,
-            mixed_types,
-            sel_type,
-        ) = self.param
         return dp_obj(
             self.inputs,
             self.atype.reshape(1, -1),
EOF
@@ -184,12 +184,6 @@
)

def eval_dp(self, dp_obj: Any) -> Any:
(
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
return dp_obj(
self.inputs,
self.atype.reshape(1, -1),
Copilot is powered by AI and may make mistakes. Always verify output.
) = self.param
return dp_obj(
self.inputs,
Expand Down Expand Up @@ -200,6 +230,7 @@
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
if precision == "float64":
return 1e-10
Expand All @@ -215,10 +246,47 @@
resnet_dt,
precision,
mixed_types,
sel_type,
) = self.param
if precision == "float64":
return 1e-10
elif precision == "float32":
return 1e-4
else:
raise ValueError(f"Unknown precision: {precision}")

def test_tf_consistent_with_ref(self) -> None:
"""Test whether TF and reference are consistent."""
# Special handle for sel_types
Comment thread
njzjz marked this conversation as resolved.
if self.skip_tf:
self.skipTest("Unsupported backend")
ref_backend = self.get_reference_backend()
if ref_backend == self.RefBackend.TF:
self.skipTest("Reference is self")
ret1, data1 = self.get_reference_ret_serialization(ref_backend)
ret1 = self.extract_ret(ret1, ref_backend)
self.reset_unique_id()
tf_obj = self.tf_class.deserialize(data1, suffix=self.unique_id)
ret2, data2 = self.get_tf_ret_serialization_from_cls(tf_obj)
ret2 = self.extract_ret(ret2, self.RefBackend.TF)
if tf_obj.__class__.__name__.startswith(("Polar", "Dipole", "DOS")):
# tf, pt serialization mismatch
Comment thread
njzjz marked this conversation as resolved.
common_keys = set(data1.keys()) & set(data2.keys())
data1 = {k: data1[k] for k in common_keys}
data2 = {k: data2[k] for k in common_keys}

# not comparing version
data1.pop("@version")
data2.pop("@version")

if tf_obj.__class__.__name__.startswith("Polar"):
data1["@variables"].pop("bias_atom_e")
for ii, networks in enumerate(data2["nets"]["networks"]):
if networks is None:
data1["nets"]["networks"][ii] = None
np.testing.assert_equal(data1, data2)
for rr1, rr2 in zip(ret1, ret2):
np.testing.assert_allclose(
rr1.ravel()[: rr2.size], rr2.ravel(), rtol=self.rtol, atol=self.atol
)
assert rr1.dtype == rr2.dtype, f"{rr1.dtype} != {rr2.dtype}"