-
Notifications
You must be signed in to change notification settings - Fork 529
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
feat(tf/pt): add/refact lammps support for spin model #4216
Conversation
for more information, see https://pre-commit.ci
Warning Rate limit exceeded@iProzd has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 24 minutes and 53 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 Walkthrough📝 Walkthrough📝 Walkthrough📝 Walkthrough📝 Walkthrough📝 Walkthrough📝 Walkthrough📝 WalkthroughWalkthroughThe pull request introduces significant enhancements across multiple components of the DeepMD framework, focusing on the integration of spin functionality. Key modifications include the addition of optional parameters for spin handling in various methods of the Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
source/api_cc/include/DeepPotTF.h
Outdated
// std::vector<double> virtual_len; | ||
// std::vector<double> spin_norm; |
Check notice
Code scanning / CodeQL
Commented-out code
std::vector<int> extend_numneigh; | ||
std::vector<std::vector<int>> extend_neigh; | ||
std::vector<int*> extend_firstneigh; | ||
// std::vector<double> extend_dcoord; |
Check notice
Code scanning / CodeQL
Commented-out code
source/api_cc/src/DeepPotPT.cc
Outdated
select_real_atoms_coord(dcoord, datype, aparam_, nghost_real, fwd_map, | ||
bkw_map, nall_real, nloc_real, coord, atype, aparam, | ||
nghost, ntypes, 1, daparam, nall, aparam_nall); | ||
int nloc = nall_real - nghost_real; |
Check notice
Code scanning / CodeQL
Unused local variable
source/api_cc/src/DeepPotPT.cc
Outdated
// spin model not suported yet | ||
// torch::Tensor flat_virial_ = virial_.toTensor().view({-1}).to(floatType); | ||
// torch::Tensor cpu_virial_ = flat_virial_.to(torch::kCPU); | ||
// virial.assign(cpu_virial_.data_ptr<VALUETYPE>(), | ||
// cpu_virial_.data_ptr<VALUETYPE>() + cpu_virial_.numel()); |
Check notice
Code scanning / CodeQL
Commented-out code
source/api_cc/src/DeepPotPT.cc
Outdated
// cpu_atom_virial_.data_ptr<VALUETYPE>(), | ||
// cpu_atom_virial_.data_ptr<VALUETYPE>() + cpu_atom_virial_.numel()); | ||
atom_energy.resize(static_cast<size_t>(nframes) * fwd_map.size()); | ||
// atom_virial.resize(static_cast<size_t>(nframes) * fwd_map.size() * 9); |
Check notice
Code scanning / CodeQL
Commented-out code
source/api_cc/src/DeepPotPT.cc
Outdated
// spin model not suported yet | ||
// torch::Tensor flat_virial_ = virial_.toTensor().view({-1}).to(floatType); | ||
// torch::Tensor cpu_virial_ = flat_virial_.to(torch::kCPU); | ||
// virial.assign(cpu_virial_.data_ptr<VALUETYPE>(), | ||
// cpu_virial_.data_ptr<VALUETYPE>() + cpu_virial_.numel()); |
Check notice
Code scanning / CodeQL
Commented-out code
source/api_cc/src/DeepPotPT.cc
Outdated
// virial.assign(cpu_virial_.data_ptr<VALUETYPE>(), | ||
// cpu_virial_.data_ptr<VALUETYPE>() + cpu_virial_.numel()); | ||
if (atomic) { | ||
// c10::IValue atom_virial_ = outputs.at("atom_virial"); |
Check notice
Code scanning / CodeQL
Commented-out code
source/api_cc/src/DeepPotTF.cc
Outdated
} | ||
|
||
if (dtype == tensorflow::DT_DOUBLE) { | ||
int ret = session_input_tensors<double>( |
Check notice
Code scanning / CodeQL
Unused local variable
source/api_cc/src/DeepPotTF.cc
Outdated
nframes, nghost_real); | ||
} | ||
} else { | ||
int ret = session_input_tensors<float>( |
Check notice
Code scanning / CodeQL
Unused local variable
source/lmp/pair_deepmd.cpp
Outdated
@@ -1198,7 +1245,12 @@ void PairDeepMD::settings(int narg, char **arg) { | |||
} | |||
} | |||
|
|||
comm_reverse = numb_models * 3; | |||
// comm_reverse = numb_models * 3; |
Check notice
Code scanning / CodeQL
Commented-out code
std::vector<int> extend_numneigh; | ||
std::vector<std::vector<int>> extend_neigh; | ||
std::vector<int*> extend_firstneigh; | ||
// std::vector<double> extend_dcoord; |
Check notice
Code scanning / CodeQL
Commented-out code Note
source/lmp/pair_deepmd.cpp
Outdated
@@ -1198,7 +1245,12 @@ | |||
} | |||
} | |||
|
|||
comm_reverse = numb_models * 3; | |||
// comm_reverse = numb_models * 3; |
Check notice
Code scanning / CodeQL
Commented-out code Note
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 34
🧹 Outside diff range and nitpick comments (13)
deepmd/tf/entrypoints/freeze.py (2)
264-265
: LGTM! Consider grouping related optional nodes.The addition of
spin_attr/virtual_len
andspin_attr/spin_norm
to theoptional_node
list is a good practice. It ensures backward compatibility with models that don't have spin attributes.For improved readability, consider grouping related optional nodes together. You could refactor the
optional_node
list as follows:optional_node = [ "train_attr/min_nbor_dist", "fitting_attr/aparam_nall", # Spin-related attributes "spin_attr/ntypes_spin", "spin_attr/virtual_len", "spin_attr/spin_norm", ]This grouping makes it easier to identify and manage related optional nodes.
Line range hint
1-389
: Overall changes look good. Consider updating documentation.The changes to add support for spin-related computations in the freezing process are well-implemented and consistent with the PR objectives. The modifications are minimal and targeted, which is a good practice for reducing the risk of introducing bugs.
To ensure that users and developers are aware of the new spin-related functionality, consider updating the module or function docstrings to mention the new spin attributes. For example, you could add a note to the
freeze_graph
function docstring:def freeze_graph(...): """Freeze the single graph with chosen out_suffix. ... Notes ----- This function now supports freezing of spin-related attributes (virtual_len and spin_norm) for the "ener" model type. """ ...This documentation update will help users understand the new capabilities added by these changes.
deepmd/pt/model/model/spin_model.py (2)
Line range hint
474-497
: LGTM! Consider adding documentation for new parameters.The addition of
comm_dict
andextra_nlist_sort
parameters enhances the flexibility of theforward_common_lower
method. However, it would be beneficial to document their purpose and usage in the method's docstring.Consider adding documentation for the new parameters:
def forward_common_lower( self, extended_coord, extended_atype, extended_spin, nlist, mapping: Optional[torch.Tensor] = None, fparam: Optional[torch.Tensor] = None, aparam: Optional[torch.Tensor] = None, do_atomic_virial: bool = False, comm_dict: Optional[Dict[str, torch.Tensor]] = None, extra_nlist_sort: bool = False, ): """ ... Parameters: ... comm_dict: Optional dictionary for additional communication data. extra_nlist_sort: Boolean flag for additional neighbor list sorting. ... """
Line range hint
612-624
: LGTM! Consider adding documentation for the new parameter.The addition of the
comm_dict
parameter and its usage are consistent with the changes in the parent class. Theextra_nlist_sort
parameter is now properly utilized.Consider adding documentation for the new parameter:
@torch.jit.export def forward_lower( self, extended_coord, extended_atype, extended_spin, nlist, mapping: Optional[torch.Tensor] = None, fparam: Optional[torch.Tensor] = None, aparam: Optional[torch.Tensor] = None, do_atomic_virial: bool = False, comm_dict: Optional[Dict[str, torch.Tensor]] = None, ): """ ... Parameters: ... comm_dict: Optional dictionary for additional communication data. ... """source/api_cc/include/DeepPotTF.h (5)
118-134
: Add documentation for the newcompute
method overloadThe newly added
compute
method overload at lines 118-134 introduces additional parametersforce_mag
andspin
. To maintain code clarity and assist users, please add accompanying documentation that describes the purpose of this method and explains each parameter.
282-313
: Add documentation for the newcomputew
method overloadsThe overloaded
computew
methods at lines 282-313 include new parametersforce_mag
andspin
. To maintain consistency and aid users, please provide detailed documentation for these methods, explaining the purpose of the new parameters and any changes in the method's behavior.
359-359
: Provide parameter names in thecum_sum
method declarationAt line 359, the
cum_sum
method is declared without parameter names:void cum_sum(std::map<int, int>&, std::map<int, int>&);For better code readability and maintainability, please include descriptive parameter names:
void cum_sum(std::map<int, int>& input_map, std::map<int, int>& output_map);
378-379
: Remove or clarify commented-out codeThe lines 378-379 contain commented-out declarations:
// std::vector<double> virtual_len; // std::vector<double> spin_norm;If these variables are no longer needed, please remove them to keep the code clean. If they are intended for future use, add comments explaining their purpose.
131-131
: Pass small integers by value instead of const referenceIn the method parameters at lines 131, 294, and 310, the integer
ago
is passed asconst int& ago
. Sinceint
is a small built-in type, passing it by value is more efficient and avoids the overhead of referencing. Please consider changing the parameter to:const int agoAlso applies to: 294-294, 310-310
source/api_cc/src/DeepPotPT.cc (2)
446-447
: Typo in comment: 'suported' should be 'supported'There's a typographical error in the comment on line 446. Correct the spelling of "suported" to "supported" for clarity.
Apply this diff to fix the typo:
-// spin model not suported yet +// Spin model not supported yet
463-466
: Remove unnecessary commented-out codeThe block of commented-out code related to
virial_
is unnecessary since it's already indicated that the spin model does not support virial calculations yet. Removing this block can improve code readability.Apply this diff to remove the unnecessary code:
-// torch::Tensor flat_virial_ = virial_.toTensor().view({-1}).to(floatType); -// torch::Tensor cpu_virial_ = flat_virial_.to(torch::kCPU); -// virial.assign(cpu_virial_.data_ptr<VALUETYPE>(), -// cpu_virial_.data_ptr<VALUETYPE>() + cpu_virial_.numel());source/lmp/pair_deepmd.cpp (1)
1249-1253
: Clarify the computation ofcomm_reverse
You conditionally set
comm_reverse
based onatom->sp_flag
:if (atom->sp_flag) { comm_reverse = numb_models * 3 * 2; } else { comm_reverse = numb_models * 3; }Consider adding comments or refactoring for clarity to indicate why the factor is
* 2
whenatom->sp_flag
is true. This will enhance maintainability and readability.source/api_c/include/c_api.h (1)
233-247
: Add documentation for the new API functionThe function
DP_DeepPotComputeNListSP
lacks a documentation comment block. Please add a documentation block similar to other functions, describing the purpose, parameters, and any important notes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (13)
- deepmd/pt/model/model/spin_model.py (4 hunks)
- deepmd/tf/entrypoints/freeze.py (2 hunks)
- source/api_c/include/c_api.h (8 hunks)
- source/api_c/include/deepmd.hpp (6 hunks)
- source/api_c/src/c_api.cc (10 hunks)
- source/api_cc/include/DeepPot.h (5 hunks)
- source/api_cc/include/DeepPotPT.h (4 hunks)
- source/api_cc/include/DeepPotTF.h (3 hunks)
- source/api_cc/src/DeepPot.cc (4 hunks)
- source/api_cc/src/DeepPotPT.cc (4 hunks)
- source/api_cc/src/DeepPotTF.cc (4 hunks)
- source/lmp/pair_deepmd.cpp (15 hunks)
- source/lmp/pair_deepmd.h (1 hunks)
🧰 Additional context used
🔇 Additional comments (41)
deepmd/tf/entrypoints/freeze.py (1)
127-128
: LGTM! Verify impact on other parts of the codebase.The addition of
spin_attr/virtual_len
andspin_attr/spin_norm
nodes for the "ener" model type is consistent with the PR objectives to add support for spin models. This change looks good and should enable the freezing of spin-related attributes.To ensure these changes don't have unintended consequences, please run the following script to check for any other occurrences of these new attributes in the codebase:
This will help verify that these new attributes are consistently used across the project.
✅ Verification successful
Verified! No unintended occurrences of new spin attributes found elsewhere.
The newly added
spin_attr/virtual_len
andspin_attr/spin_norm
nodes are exclusively present indeepmd/tf/entrypoints/freeze.py
. Their implementation is confined to this file, ensuring that there are no unintended side effects in other parts of the codebase.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for other occurrences of new spin attributes echo "Searching for 'spin_attr/virtual_len':" rg "spin_attr/virtual_len" --type py echo "\nSearching for 'spin_attr/spin_norm':" rg "spin_attr/spin_norm" --type pyLength of output: 521
deepmd/pt/model/model/spin_model.py (1)
Line range hint
1-638
: Overall, the changes look good and enhance the model's flexibility.The additions of
comm_dict
andextra_nlist_sort
parameters in bothSpinModel
andSpinEnergyModel
classes are well-implemented and consistent. These changes provide more flexibility in the forward pass and neighbor list sorting. The code maintains good quality and there are no apparent issues introduced by these changes.To further improve the code:
- Consider adding documentation for the new parameters in both
forward_common_lower
andforward_lower
methods.- Ensure that the usage of
comm_dict
is properly documented in the broader context of the DeepMD framework, explaining when and how it should be used.source/lmp/pair_deepmd.h (1)
78-78
: LGTM!The addition of
all_force_mag
as a member variable appears appropriate.source/api_cc/include/DeepPotTF.h (3)
126-126
: Confirm the correctness ofspin
data typeAt line 126,
spin
is declared asconst std::vector<VALUETYPE>& spin
. Since spin values might be integers in some models, ensure thatVALUETYPE
is the appropriate data type for representing spins in all cases. If spins are always floating-point numbers, this is acceptable; otherwise, consider using a more suitable type.
289-289
: Consistent data types forspin
across methodsIn the
computew
methods,spin
is declared asconst std::vector<double>&
at line 289 andconst std::vector<float>&
at line 305. Ensure that the usage ofdouble
andfloat
forspin
aligns with the rest of the method parameters and that any casting or precision considerations are properly handled.Also applies to: 305-305
368-370
: Check for duplication ofget_vector
methodThe
get_vector
template method is declared at lines 368-370. Ensure that this declaration does not duplicate an existing method and that it is necessary for the extended functionality. If it's an intentional addition, consider providing documentation to explain its purpose.source/api_cc/include/DeepPotPT.h (1)
77-90
: Verify consistency of parameter ordering across method overloadsEnsure that the ordering of parameters, particularly the placement of
spin
andforce_mag
, is consistent with existing methods and logical grouping. Consistent parameter ordering prevents confusion and potential bugs.source/api_cc/src/DeepPotPT.cc (5)
658-798
: Consistent handling of optional tensorsEnsure that optional tensors like
box_Tensor
,fparam_tensor
, andaparam_tensor
are consistently handled across differentcompute
methods. This prevents unexpected behaviors when these optional parameters are absent.Please verify that all optional tensors are checked for validity before use to avoid null pointer dereferences.
Line range hint
446-793
: Correct inconsistency in handlingdo_message_passing
andnghost
Throughout the new
compute
methods, ensure that the conditional checks fordo_message_passing
andnghost
are consistent and correctly implemented. This is crucial for parallel computations and message passing between processes.Review the conditional logic to confirm that all possible states of
do_message_passing
andnghost
are appropriately handled.
755-767
: Commented-out code may indicate incomplete implementationThe commented-out sections related to
atom_virial_
suggest that the spin model's support for atomic virials is incomplete.Confirm whether the implementation of atomic virials with the spin model is pending. If so, consider adding a
TODO
comment to track this for future development.
468-474
:⚠️ Potential issueInitialize
force_mag
vector before useThe
force_mag
vector should be initialized appropriately before being used in theselect_map
function to avoid potential undefined behavior.Apply this diff to ensure
force_mag
is correctly initialized:force.resize(static_cast<size_t>(nframes) * fwd_map.size() * 3); +force_mag.resize(static_cast<size_t>(nframes) * fwd_map.size() * 3); select_map<VALUETYPE>(force, dforce, bkw_map, 3, nframes, fwd_map.size(), nall_real); select_map<VALUETYPE>(force_mag, dforce_mag, bkw_map, 3, nframes, fwd_map.size(), nall_real);
Likely invalid or redundant comment.
503-535
: Ensure explicit instantiation of template methods for required typesThe explicit template instantiations at the end of the file should cover all the necessary data type combinations used in the codebase. Verify that the methods are instantiated for all required
VALUETYPE
andENERGYVTYPE
combinations.Run the following script to check for all instantiations:
Ensure that the output includes all necessary type combinations.
Also applies to: 772-798
✅ Verification successful
All required
VALUETYPE
andENERGYVTYPE
combinations are explicitly instantiated.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for explicit template instantiations of compute methods. # Search for lines with 'template void DeepPotPT::compute<' rg --type cpp 'template void DeepPotPT::compute<' -A 2Length of output: 1885
Script:
#!/bin/bash # Description: Identify all unique VALUETYPEs used in DeepPotPT::compute method calls. # Extract all compute method calls and capture the VALUETYPE template argument rg --type cpp 'DeepPotPT::compute<' | \ sed -n "s/.*DeepPotPT::compute<\([^,>]*\),.*/\1/p" | \ sort | uniqLength of output: 117
source/lmp/pair_deepmd.cpp (6)
582-586
: Verify the updateddeep_pot.compute
method signatureThe
deep_pot.compute
function is called with additional parametersdforce_mag
anddspin_const
. Ensure that thedeep_pot.compute
method signature has been updated accordingly and all dependencies are properly handled.
606-608
: Ensure consistency indeep_pot.compute
calls with spin parametersWhen calling
deep_pot.compute
, you are passingdspin
. Verify that this parameter is correctly handled within the function and that all spin-related computations are accurate.
1407-1423
: Ensure correct packing of reverse communication buffer with spin dataIn
pack_reverse_comm
, you have added code to handle spin data:if (atom->sp_flag) { // Code handling spin data } else { // Original code }Verify that the buffer
buf
is being correctly populated, and that the size calculations match the expected data to prevent communication errors.
1436-1454
: Validate unpacking of reverse communication buffer with spin dataSimilar to packing, in
unpack_reverse_comm
, ensure that the unpacking logic correctly aligns with the packing structure, particularly with the added spin data. Mismatches here can lead to incorrect force calculations.
771-783
: Check calculations for spin-related force deviationsIn the block handling spin forces:
if (atom->sp_flag) { // Calculations for std_fm, tmp_avg_fm, etc. }Verify that the statistical calculations for
std_fm
,all_fm_min
,all_fm_max
, andall_fm_avg
are accurate and that they properly represent the deviations intended.
657-693
:⚠️ Potential issueHandle possible issues with model deviation calculations
In the multi-model deviation computation block, there are nested conditionals and numerous variables like
all_force_mag
,all_force
,all_energy
, etc. Ensure that:
- All vectors are properly initialized before use.
- The indexing aligns correctly across different models.
- Memory management is correctly handled to prevent leaks.
source/api_cc/src/DeepPotTF.cc (1)
1429-1441
: Check for potential out-of-bounds access inextend_atype
assignmentIn the loop updating
extend_atype
, there is a risk of out-of-bounds access when calculating indices withnew_idx_map[ii] + nloc
andnew_idx_map[ii] + nghost
. Ensure that these calculated indices do not exceed the size ofextend_atype
.Run the following script to check index bounds:
Ensure that
extend_atype
is appropriately sized to accommodate these indices or adjust the index calculations to prevent out-of-bounds access.source/api_cc/src/DeepPot.cc (6)
221-242
: Correct implementation of spin support inDeepPot::compute
methodThe new overload of the
compute
method correctly includes the spin parametersdspin_
anddforce_mag_
. The parameters are appropriately passed todp->computew
, ensuring that spin calculations are integrated seamlessly.
244-262
: Proper extension ofcompute
method for vector energies with spinThe overloaded
compute
method that returns vector energies now includesdspin_
anddforce_mag_
parameters. The adjustments ensure that spin data is consistently handled across computations.
264-319
: Accurate template instantiations for spin-inclusivecompute
methodsThe explicit template instantiations for both
double
andfloat
types are correctly provided for the newcompute
methods with spin support. This ensures type safety and availability of these methods for different numerical precisions.
488-596
: Extension ofcompute
methods with atomic outputs and spin supportThe
compute
methods that include atomic energies and virials have been appropriately extended to incorporate spin parameters. The modifications correctly passdspin_
anddforce_mag_
todp->computew
, enabling detailed spin-aware computations at the atomic level.
954-1012
: Integration of spin support inDeepPotModelDevi::compute
methodThe
DeepPotModelDevi::compute
method now includes support for spin parameters, addingdspin_
anddforce_mag_
to the computation of energies, forces, and virials across multiple models. The loop overnumb_models
ensures consistent processing of spin data.
1073-1140
: Enhancedcompute
method with spin and atomic outputs inDeepPotModelDevi
The overloaded
compute
method inDeepPotModelDevi
has been correctly expanded to handle spin parameters and compute atomic energies and virials. This comprehensive extension ensures that all relevant spin-related data is accurately calculated for each model.source/api_c/include/c_api.h (6)
287-302
: Add documentation for the new API functionPlease add a documentation block for
DP_DeepPotComputeNListfSP
to maintain consistency with other functions in the API.
427-445
: Add documentation for the new API functionPlease add a documentation block for
DP_DeepPotComputeNList2SP
to maintain consistency with other functions.
492-510
: Add documentation for the new API functionPlease add a documentation block for
DP_DeepPotComputeNListf2SP
to maintain consistency.
807-822
: Add documentation for the new API functionPlease add a documentation block for
DP_DeepPotModelDeviComputeNListSP
similar to other functions in the API.
860-875
: Add documentation for the new API functionPlease add a documentation block for
DP_DeepPotModelDeviComputeNListfSP
to maintain consistency.
987-1005
: Add 'extern' keyword to function declarationThe function
DP_DeepPotModelDeviComputeNListf2SP
lacks theextern
keyword in its declaration. Please addextern
to maintain consistency.Here is the suggested change:
-void DP_DeepPotModelDeviComputeNListf2SP(DP_DeepPotModelDevi* dp, +extern void DP_DeepPotModelDeviComputeNListf2SP(DP_DeepPotModelDevi* dp,source/api_c/src/c_api.cc (10)
419-454
: LGTM!The template instantiations for the new
DP_DeepPotComputeNList_variant_sp
function look good.
1304-1322
: LGTM!The new
DP_DeepPotComputeNListfSP
function for the float type looks good.
1382-1403
: LGTM!The new
DP_DeepPotComputeNList2SP
function for handling multiple frames with spin looks good.
1426-1447
: LGTM!The new
DP_DeepPotComputeNListf2SP
function for the float type with multiple frames looks good.
1595-1613
: LGTM!The new
DP_DeepPotModelDeviComputeNListSP
function for the model deviation with spin looks good.
1633-1651
: LGTM!The new
DP_DeepPotModelDeviComputeNListfSP
function for the float type model deviation with spin looks good.
1674-1695
: LGTM!The new
DP_DeepPotModelDeviComputeNList2SP
function for handling multiple frames in the model deviation with spin looks good.
1718-1739
: LGTM!The new
DP_DeepPotModelDeviComputeNListf2SP
function for the float type model deviation with multiple frames and spin looks good.
842-879
: LGTM!The template instantiations for the new
DP_DeepPotModelDeviComputeNList_variant_sp
function look good.
1266-1284
: Verify the new function is called correctly from all relevant code paths.The new
DP_DeepPotComputeNListSP
function looks good. However, ensure it is being called correctly from all the relevant code paths that need to compute energy, force, force_mag, virial, etc. with spin.Run the following script to verify the function usage:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 35
🧹 Outside diff range and nitpick comments (23)
deepmd/tf/entrypoints/freeze.py (1)
264-265
: LGTM. Consider grouping related attributes.The addition of
"spin_attr/virtual_len"
and"spin_attr/spin_norm"
to the optional node list is consistent with the earlier changes and provides flexibility in the freezing process.For improved readability, consider grouping related attributes together. You could move the
"spin_attr/ntypes_spin"
node (currently on line 263) next to the newly added spin attributes:optional_node = [ "train_attr/min_nbor_dist", "fitting_attr/aparam_nall", "spin_attr/ntypes_spin", "spin_attr/virtual_len", "spin_attr/spin_norm", ]This grouping makes it easier to identify all spin-related attributes at a glance.
deepmd/pt/model/model/spin_model.py (2)
Line range hint
474-497
: LGTM! Consider adding documentation for the new parameters.The addition of
comm_dict
andextra_nlist_sort
parameters enhances the flexibility of theforward_common_lower
method. These changes appear to be well-integrated into the existing code.Consider adding documentation for these new parameters to explain their purpose and usage:
comm_dict
: Describe its role in communication and when it should be provided.extra_nlist_sort
: Explain when this boolean flag should be set to True and its impact on the neighbor list sorting.
Line range hint
612-624
: LGTM! Consider adding documentation for the new parameter.The addition of the
comm_dict
parameter and the dynamic setting ofextra_nlist_sort
enhance the method's flexibility and maintain consistency with the backbone model's requirements.Consider adding documentation for the new
comm_dict
parameter to explain its purpose and usage in the context of theSpinEnergyModel
.source/lmp/pair_deepmd.h (1)
78-78
: Consider adding documentation forall_force_mag
.To improve code readability and maintainability, consider adding a brief comment explaining the purpose and usage of the
all_force_mag
member variable, similar to the existing comments for other member variables.source/api_cc/include/DeepPotTF.h (1)
378-380
: Consider removing commented-out code or adding contextThe variables
virtual_len
andspin_norm
are commented out. If they are no longer needed, it would be cleaner to remove them entirely. If they are reserved for future use, consider adding a comment explaining their intended purpose to provide context for other developers.source/api_cc/include/DeepPotPT.h (1)
Line range hint
356-379
: Update documentation forcomputew
overloads combining mixed precision and new parameters.The overloads of
computew
methods that handle mixed precision now includeforce_mag
andspin
. The documentation does not reflect these changes. To ensure proper usage and understanding, please update the documentation to include descriptions of the new parameters and any implications for mixed precision computations.source/api_cc/src/DeepPotPT.cc (3)
788-798
: Consider handlingatom_virial
for the spin modelIn the
compute
method starting at line 660, the code related toatom_virial
is commented out due to the spin model not being supported yet. If the spin model now supportsatom_virial
, consider uncommenting and implementing this functionality. If not, provide a clearer comment indicating when this feature will be available.Clarify the status of
atom_virial
support in the spin model for better code maintainability.
Line range hint
643-644
: Possible code simplification in device checksIn the blocks starting at lines 643-644 and 685-686, there's a check for
gpu_enabled
to set thedevice
. Consider simplifying the code by initializingdevice
based on thegpu_enabled
flag directly during declaration to improve readability.Example:
torch::Device device = gpu_enabled ? torch::Device(torch::kCUDA, gpu_id) : torch::Device(torch::kCPU);Also applies to: 685-686
316-331
: Consider documenting the newcompute
method overloadsThe newly added
compute
methods with additional parameters may benefit from inline documentation or comments explaining their purpose, parameters, and usage. This can help future developers understand the differences between overloads and when to use each one.Add Doxygen-style comments or inline explanations for better clarity.
Also applies to: 660-672
source/lmp/pair_deepmd.cpp (2)
582-586
: Consistent use of constant referencesIn the code:
const vector<double> &dcoord_const = dcoord; const vector<double> &dspin_const = dspin; deep_pot.compute(dener, dforce, dforce_mag, dvirial, dcoord_const, dspin_const, dtype, dbox, nghost, lmp_list, ago, fparam, daparam);While
dspin_const
anddcoord_const
are defined as constant references, consider passingdcoord
anddspin
directly todeep_pot.compute
if they are not modified within the function. This can simplify the code and reduce unnecessary variable declarations.
771-775
: Potential misalignment in relative standard deviation computationIn the computation of relative standard deviation:
if (out_rel == 1) { deep_pot_model_devi.compute_relative_std_f(std_fm, tmp_avg_fm, eps); }Consider whether
out_rel
should control the relative standard deviation computation for both force and force magnitude (std_f
andstd_fm
). If independent control is desired, introduce a separate flag (e.g.,out_rel_fm
) for clarity and flexibility.source/api_c/include/c_api.h (7)
233-247
: Add missing documentation for the new functionDP_DeepPotComputeNListSP
.The newly added function
DP_DeepPotComputeNListSP
lacks documentation. Consistent documentation is essential for maintainability and readability. Please add a detailed comment describing the function's purpose, parameters, and expected behavior, similar to the existing function comments.
287-302
: Provide documentation forDP_DeepPotComputeNListfSP
to maintain consistency.The function
DP_DeepPotComputeNListfSP
is missing accompanying documentation. Adding a comprehensive comment will help users understand the function's usage and maintain consistency with the rest of the API.
427-445
: Include function comments forDP_DeepPotComputeNList2SP
for clarity.The function
DP_DeepPotComputeNList2SP
lacks descriptive comments. Please add documentation outlining the function's purpose, parameters, and any special considerations, following the style of existing documented functions.
492-510
: Document the new functionDP_DeepPotComputeNListf2SP
.To maintain the API's usability, please provide documentation for
DP_DeepPotComputeNListf2SP
. This should include details about the function's role, its parameters, and any important notes for users.
807-822
: Add missing documentation forDP_DeepPotModelDeviComputeNListSP
.The function
DP_DeepPotModelDeviComputeNListSP
is introduced without accompanying comments. Consistent and thorough documentation aids in code comprehension and maintenance. Please include a comment block describing this function.
860-875
: Provide documentation forDP_DeepPotModelDeviComputeNListfSP
.The new function
DP_DeepPotModelDeviComputeNListfSP
should have a descriptive comment explaining its usage, parameters, and any important details. This ensures consistency and aids other developers.
233-247
: Ensure consistent parameter naming fornatoms
andnatom
.There is inconsistency in the naming of the atom count parameter across the new function declarations. Some functions use
natoms
, while others usenatom
. For clarity and consistency, it's advisable to standardize on one naming convention.Apply this diff to rename
natom
tonatoms
:const int nframes, -const int natom, +const int natoms,Also applies to: 287-302, 427-445, 492-510, 807-822, 860-875, 922-940, 987-1005
source/api_c/src/c_api.cc (2)
1266-1284
: Add documentation for the new functionDP_DeepPotComputeNListSP
The newly introduced function lacks comments explaining its purpose and usage. Adding documentation will enhance code readability and help other developers understand how to use the spin-supporting API correctly.
Line range hint
1674-1740
: Plan for extending multi-frame support with spin in model deviation computationsSimilar to earlier functions,
DP_DeepPotModelDeviComputeNList2SP
currently does not supportnframes > 1
. If there's a need for processing multiple frames with spin support in model deviation computations, consider implementing this feature.source/api_c/include/deepmd.hpp (3)
160-179
: Add documentation for the_DP_DeepPotComputeNListSP
function templateThe newly added
_DP_DeepPotComputeNListSP
function template lacks documentation. Including comments to explain the purpose, parameters, and usage of this function will improve code readability and maintainability.
1141-1194
: Include documentation for overloadedcompute
methods with spin supportThe newly added overloaded
compute
methods that include spin parameters lack explanatory comments. Adding documentation will help other developers understand the purpose and usage of these methods.
1916-2004
: Add documentation for spin-awarecompute
methods inDeepPotModelDevi
The
compute
methods that handle spin in theDeepPotModelDevi
class lack descriptive comments. Providing detailed documentation will aid in understanding the methods' functionalities and parameters.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (13)
- deepmd/pt/model/model/spin_model.py (4 hunks)
- deepmd/tf/entrypoints/freeze.py (2 hunks)
- source/api_c/include/c_api.h (8 hunks)
- source/api_c/include/deepmd.hpp (6 hunks)
- source/api_c/src/c_api.cc (10 hunks)
- source/api_cc/include/DeepPot.h (5 hunks)
- source/api_cc/include/DeepPotPT.h (4 hunks)
- source/api_cc/include/DeepPotTF.h (3 hunks)
- source/api_cc/src/DeepPot.cc (4 hunks)
- source/api_cc/src/DeepPotPT.cc (4 hunks)
- source/api_cc/src/DeepPotTF.cc (4 hunks)
- source/lmp/pair_deepmd.cpp (15 hunks)
- source/lmp/pair_deepmd.h (1 hunks)
🧰 Additional context used
🔇 Additional comments (27)
deepmd/tf/entrypoints/freeze.py (1)
127-128
: LGTM. Can you provide more context on the spin attributes?The addition of
"spin_attr/virtual_len"
and"spin_attr/spin_norm"
to the list of nodes for the "ener" model type looks good. These changes align with the PR objective of adding support for the spin model.Could you provide some additional context on what these spin attributes represent and how they are used in the energy calculations?
source/lmp/pair_deepmd.h (1)
78-78
: Addition ofall_force_mag
member variable looks good.The new member variable
std::vector<std::vector<double> > all_force_mag;
appropriately extends thePairDeepMD
class to store force magnitudes, enhancing its functionality for simulations involving spin handling.source/api_cc/include/DeepPotPT.h (1)
Line range hint
77-379
: Confirm consistency of method signatures across all overloads.The additions of
force_mag
andspin
parameters across multiplecompute
andcomputew
method overloads appear consistent. However, please verify that all method signatures are correctly aligned and that the parameter order is maintained uniformly. This helps prevent potential mismatches or confusion during method invocation.source/api_cc/include/DeepPot.h (5)
162-177
: Update method documentation to includeforce_mag
andspin
parameters
393-420
: Update method documentation to includeforce_mag
andspin
parameters
523-554
: Update method documentation to includeforce_mag
andspin
parameters
827-840
: Update documentation forcompute
methods with addedforce_mag
andspin
parametersThe
compute
methods in theDeepPotModelDevi
class have been extended withforce_mag
andspin
parameters. Please update the documentation to reflect these additions for consistency and clarity.
881-897
: Update documentation forcompute
methods with addedforce_mag
andspin
parameterssource/api_cc/src/DeepPotPT.cc (3)
341-342
: Ensure consistency inTensorOptions
dtype settingsIn the conditional blocks at lines 341-342 and 683-684, the
TensorOptions
are set forfloat32
whenVALUETYPE
isfloat
. Verify that this pattern is consistently applied throughout the code to prevent any unintended type mismatches.Also applies to: 683-684
362-365
: Validate dimensions ofspin_wrapped_Tensor
When creating
spin_wrapped_Tensor
, ensure that the dimensions match the expected input of the model. Mismatches in tensor dimensions can lead to runtime errors or incorrect computations.Also applies to: 678-691
315-535
: Ensure consistent handling of thespin
parameterThe new overloaded
compute
method includesspin
as an input parameter. Please verify that all necessary validations and error handling forspin
are implemented. For instance, check ifspin
has the correct dimensions and whether additional checks are needed for its usage.Run the following script to search for handling of the
spin
parameter:source/lmp/pair_deepmd.cpp (5)
505-505
: Initialization ofdforce_mag
The vector
dforce_mag
is declared:vector<double> dforce_mag(nall * 3);Ensure that this vector is properly utilized and filled with the correct force magnitude data before being used in subsequent computations to prevent unintended results.
606-608
: Ensure correct function overload is calledIn the call to
deep_pot.compute
:deep_pot.compute(dener, dforce, dforce_mag, dvirial, deatom, dvatom, dcoord, dspin, dtype, dbox, nghost, lmp_list, ago, fparam, daparam);Verify that the
deep_pot.compute
function correctly handles the additionaldforce_mag
anddspin
parameters and that the appropriate overload or implementation is being used.
1250-1253
: Verifycomm_reverse
calculation for data communicationThe communication reverse size is set as:
if (atom->sp_flag) { comm_reverse = numb_models * 3 * 2; } else { comm_reverse = numb_models * 3; }Ensure that doubling the size (
* 2
) whenatom->sp_flag
is true correctly accounts for the additional spin-related data that needs to be communicated. Validate that this change is consistent throughout the communication routines.
1406-1423
: Correct buffer packing inpack_reverse_comm
with spin dataIn
pack_reverse_comm
, whenatom->sp_flag
is true, additional data related to force magnitude is packed:if (atom->sp_flag) { for (i = first; i < last; i++) { for (int dd = 0; dd < numb_models; ++dd) { buf[m++] = all_force[dd][3 * i + 0]; buf[m++] = all_force[dd][3 * i + 1]; buf[m++] = all_force[dd][3 * i + 2]; buf[m++] = all_force_mag[dd][3 * i + 0]; buf[m++] = all_force_mag[dd][3 * i + 1]; buf[m++] = all_force_mag[dd][3 * i + 2]; } } } else { // Existing packing logic }Ensure that:
- The buffer
buf
is adequately sized to hold the additional data.- The order of packing matches the expected order during unpacking.
- There are no buffer overflows or memory issues.
1435-1454
: Consistent buffer unpacking inunpack_reverse_comm
In
unpack_reverse_comm
, ensure that the unpacking logic accurately mirrors the packing logic:if (atom->sp_flag) { for (i = 0; i < n; i++) { j = list[i]; for (int dd = 0; dd < numb_models; ++dd) { all_force[dd][3 * j + 0] += buf[m++]; all_force[dd][3 * j + 1] += buf[m++]; all_force[dd][3 * j + 2] += buf[m++]; all_force_mag[dd][3 * j + 0] += buf[m++]; all_force_mag[dd][3 * j + 1] += buf[m++]; all_force_mag[dd][3 * j + 2] += buf[m++]; } } } else { // Existing unpacking logic }Verify that:
- The increments of
m
are consistent with those inpack_reverse_comm
.- The data is assigned to the correct indices in
all_force
andall_force_mag
.- There are no mismatches that could lead to incorrect force calculations.
source/api_cc/src/DeepPotTF.cc (1)
511-516
: Implementation ofget_vector
method is correctThe
get_vector
method is correctly implemented and integrates well with the existing code.source/api_cc/src/DeepPot.cc (5)
221-242
: Integration of Spin Support inDeepPot::compute
MethodThe new overload of the
compute
method correctly incorporates spin support by introducing thedforce_mag_
anddspin_
parameters. The function callsdp->computew
with the appropriate arguments, ensuring that spin effects are accounted for in the computation.
244-262
: Addition of Vectorizedcompute
Method with Spin SupportThe added vectorized overload of the
compute
method extends spin support to handle multiple energies and forces. The implementation correctly passes the newdforce_mag_
anddspin_
parameters todp->computew
, enabling spin-aware computations for vector inputs.
264-291
: Correct Template Instantiations for New OverloadsThe template instantiations for the new
compute
methods are properly defined for bothdouble
andfloat
types. This ensures that the methods supporting spin with different precision levels are available and correctly linked.
954-1012
: Extension ofDeepPotModelDevi::compute
with Spin ParametersThe new
compute
method overload inDeepPotModelDevi
class appropriately adds thedspin_
andall_force_mag
parameters to support spin calculations. The loop correctly iterates over all models, invoking thecompute
method with the new parameters, which ensures consistent spin support across all models.
1073-1140
: Addition of Atom-Wise Outputs with Spin Support inDeepPotModelDevi::compute
The extended
compute
method now includes atom-wise energy and virial outputs alongside spin support. This implementation correctly handles the additional data structuresall_atom_energy
andall_atom_virial
, ensuring that detailed per-atom information is computed and stored for each model.source/api_c/include/c_api.h (1)
233-247
: Verify that memory allocation and deallocation are handled appropriately.Ensure that any dynamic memory allocations within these functions are properly managed to prevent memory leaks.
To check for dynamic memory allocations in these functions, run:
Also applies to: 287-302, 427-445, 492-510, 807-822, 860-875, 922-940, 987-1005
source/api_c/src/c_api.cc (2)
1304-1323
: Ensure consistent naming conventions for spin-related functionsThe function
DP_DeepPotComputeNListfSP
introduces spin support for single precision. Verify that the naming aligns with the project's conventions for indicating single-precision and spin-supporting functions to maintain consistency across the API.To verify naming consistency, you can search for similar function names:
#!/bin/bash # Description: Check for naming patterns of spin-supporting functions. # Test: Search for function names ending with 'SP'. Expect: Consistent naming conventions. rg --type cpp -o 'void DP_.*SP\('
376-377
: Verify the correctness of spin vector initializationEnsure that the size calculation for the
spin_
vector is accurate. The current initialization usesnframes * natoms * 3
, which should match the dimensions of thespin
input array. Verify that thespin
data is provided correctly for all frames and atoms.To confirm, you can check for inconsistencies in the codebase with:
source/api_c/include/deepmd.hpp (2)
181-227
: Ensure consistency in function naming and existenceThe specialized functions
_DP_DeepPotComputeNListSP<double>
and_DP_DeepPotComputeNListSP<float>
invokeDP_DeepPotComputeNList2SP
andDP_DeepPotComputeNListf2SP
respectively. Please verify that these functions are correctly implemented in the C API and follow the established naming conventions.
1045-1049
: Verify the size calculation forforce_mag
The
force_mag
vector is resized tonframes * natoms * 3
, similar to theforce
vector. Confirm that this size is appropriate for storing the magnitude of the forces and that it aligns with the output from_DP_DeepPotComputeNListSP
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 21
🧹 Outside diff range and nitpick comments (25)
deepmd/tf/entrypoints/freeze.py (1)
264-265
: LGTM. Consider using a constant for spin attribute names.The addition of "spin_attr/virtual_len" and "spin_attr/spin_norm" to the
optional_node
list is a good practice. It allows the freezing process to handle graphs that may or may not include these spin-related nodes.For improved maintainability, consider defining these spin attribute names as constants at the module level. This would ensure consistency and make it easier to update if needed in the future.
Example:
SPIN_ATTR_VIRTUAL_LEN = "spin_attr/virtual_len" SPIN_ATTR_SPIN_NORM = "spin_attr/spin_norm" # Then use these constants in both the `_make_node_names` function and the `optional_node` listdeepmd/pt/model/model/spin_model.py (2)
474-475
: Consider adding documentation for new parameters.The new parameters
comm_dict
andextra_nlist_sort
have been added to theforward_common_lower
method. To improve code maintainability and usability, consider adding docstring comments explaining the purpose and expected usage of these parameters.Here's a suggested docstring addition:
def forward_common_lower( self, extended_coord, extended_atype, extended_spin, nlist, mapping: Optional[torch.Tensor] = None, fparam: Optional[torch.Tensor] = None, aparam: Optional[torch.Tensor] = None, do_atomic_virial: bool = False, comm_dict: Optional[Dict[str, torch.Tensor]] = None, extra_nlist_sort: bool = False, ): """ Forward pass for the lower part of the spin model. ... Parameters: ... comm_dict : Optional[Dict[str, torch.Tensor]], optional Dictionary for additional communication data, by default None extra_nlist_sort : bool, optional Whether to perform extra sorting on neighbor lists, by default False """ # ... rest of the method
Line range hint
612-624
: LGTM. Consider adding documentation for the new parameter.The changes look good and are consistent with the modifications in the
SpinModel
class. The automatic setting ofextra_nlist_sort
based on the backbone model's requirements is a nice touch for maintaining consistency.To improve code documentation, consider adding a description for the new
comm_dict
parameter in the method's docstring.Here's a suggested docstring addition:
@torch.jit.export def forward_lower( self, extended_coord, extended_atype, extended_spin, nlist, mapping: Optional[torch.Tensor] = None, fparam: Optional[torch.Tensor] = None, aparam: Optional[torch.Tensor] = None, do_atomic_virial: bool = False, comm_dict: Optional[Dict[str, torch.Tensor]] = None, ): """ Lower-level forward pass for the spin energy model. ... Parameters: ... comm_dict : Optional[Dict[str, torch.Tensor]], optional Dictionary for additional communication data, by default None """ # ... rest of the methodsource/api_cc/include/DeepPot.h (5)
146-177
: Add missing documentation for newcomputew
methods withforce_mag
andspin
.The newly added
computew
methods in theDeepPotBase
class lack documentation comments explaining the purpose and usage of the new parametersforce_mag
andspin
. Adding appropriate documentation will improve code readability and maintain consistency with the rest of the codebase.
393-420
: Provide documentation for newcompute
methods withforce_mag
andspin
.The new template
compute
methods in theDeepPot
class include additional parametersforce_mag
andspin
but lack accompanying documentation. Please add comments to explain the functionality and usage of these methods, maintaining consistency with existing documentation.
523-554
: Add documentation forcompute
methods includingforce_mag
andspin
.The newly introduced
compute
methods in theDeepPot
class that handle atomic energies and virials with additionalforce_mag
andspin
parameters lack documentation comments. Providing detailed documentation will enhance clarity and assist other developers in understanding these methods.
827-840
: Document newcompute
methods inDeepPotModelDevi
withforce_mag
andspin
.The
DeepPotModelDevi
class has newcompute
methods that includeforce_mag
andspin
parameters but lack documentation. Please add comments to explain their purpose and usage, ensuring consistency across the codebase.
881-897
: Provide documentation for newcompute
methods includingforce_mag
andspin
.Please add documentation comments for the newly added methods in the
DeepPotModelDevi
class to maintain clarity and consistency with the rest of the code.source/api_cc/src/DeepPotPT.cc (1)
446-446
: Fix typographical error in commentsThe word "suported" is misspelled. Please correct it to "supported" in the affected comment lines.
Also applies to: 462-462, 477-477, 733-733, 748-748
source/lmp/pair_deepmd.cpp (2)
505-505
: Initialization ofdforce_mag
could be optimizedThe vector
dforce_mag
is initialized with zero values. If the subsequent computation fully populates this vector, the initialization may be unnecessary.You might consider delaying the initialization until it's necessary or using
resize
instead of initializing with zeros:-vector<double> dforce_mag(nall * 3); +vector<double> dforce_mag; +dforce_mag.resize(nall * 3);
582-586
: Avoid unnecessary copying by passing variables directlyThe variables
dcoord_const
anddspin_const
are references todcoord
anddspin
, respectively. Since these variables are not modified within thecompute
call, passingdcoord
anddspin
directly can simplify the code.Apply this diff to remove unnecessary variables:
-const vector<double> &dcoord_const = dcoord; -const vector<double> &dspin_const = dspin; -deep_pot.compute(dener, dforce, dforce_mag, dvirial, dcoord_const, - dspin_const, dtype, dbox, nghost, lmp_list, ago, +deep_pot.compute(dener, dforce, dforce_mag, dvirial, dcoord, + dspin, dtype, dbox, nghost, lmp_list, ago, fparam, daparam);source/api_cc/src/DeepPot.cc (1)
954-1012
: Document the usage ofdspin_
inDeepPotModelDevi::compute
Consider adding comments or documentation to explain how the
dspin_
parameter affects computations withinDeepPotModelDevi::compute
. This will enhance code readability and assist future contributors in understanding the spin-related computations.source/api_c/include/c_api.h (9)
233-247
: Add missing documentation forDP_DeepPotComputeNListSP
functionThe function
DP_DeepPotComputeNListSP
is missing a@brief
documentation block. To maintain consistency and help users understand its purpose and usage, please add appropriate documentation similar to other functions in the API.
287-302
: Add missing documentation forDP_DeepPotComputeNListfSP
functionThe function
DP_DeepPotComputeNListfSP
lacks accompanying documentation. Please include a@brief
comment to describe the function's purpose, parameters, and usage.
427-445
: Add missing documentation forDP_DeepPotComputeNList2SP
functionPlease add a
@brief
documentation block for theDP_DeepPotComputeNList2SP
function. This will aid users in understanding its functionality and how it differs from existing functions.
492-510
: Add missing documentation forDP_DeepPotComputeNListf2SP
functionThe function
DP_DeepPotComputeNListf2SP
is missing documentation. Including a@brief
comment will provide clarity on its usage and maintain consistency across the API.
807-822
: Add missing documentation forDP_DeepPotModelDeviComputeNListSP
functionThe
DP_DeepPotModelDeviComputeNListSP
function lacks a@brief
documentation block. Adding documentation will help users understand the function's purpose and parameters.
860-875
: Add missing documentation forDP_DeepPotModelDeviComputeNListfSP
functionPlease include a
@brief
documentation comment for theDP_DeepPotModelDeviComputeNListfSP
function to explain its functionality and usage.
921-940
: Add missing documentation forDP_DeepPotModelDeviComputeNList2SP
functionThe function
DP_DeepPotModelDeviComputeNList2SP
is missing a documentation block. Providing a@brief
comment will enhance understandability and maintain consistency.
987-1005
: Add missing documentation forDP_DeepPotModelDeviComputeNListf2SP
functionThe
DP_DeepPotModelDeviComputeNListf2SP
function lacks accompanying documentation. Please add a@brief
comment to describe its purpose and usage.
Line range hint
233-1005
: Ensure consistent use ofextern
keyword in function declarationsThere is inconsistency in the use of the
extern
keyword across function declarations. Some functions, such asDP_DeepPotModelDeviComputeNList2
, are declared withoutextern
, while others include it. To maintain consistency and clarity in the API, please ensure that all public function declarations use theextern
keyword appropriately.source/api_c/src/c_api.cc (4)
354-418
: Ensure Consistent Naming Convention for Spin FunctionsThe newly introduced function
DP_DeepPotComputeNList_variant_sp
adds spin support. To maintain consistency with existing naming conventions in the codebase, consider renaming the function to use theSP
suffix, such asDP_DeepPotComputeNList_variantSP
.
758-880
: Maintain Consistent Naming for Multi-Model Spin FunctionsThe function
DP_DeepPotModelDeviComputeNList_variant_sp
adds spin support for multi-model computations. For consistency, consider renaming it toDP_DeepPotModelDeviComputeNList_variantSP
, aligning with the naming convention used elsewhere in the codebase.
778-780
: Improve Exception Message for Unsupported Frame CountThe exception message
"nframes > 1 not supported yet"
is thrown whennframes
exceeds 1. Providing additional context or guidance could enhance user understanding. Consider updating the message to indicate whether support for multiple frames is planned or suggest alternative approaches.
1266-1284
: Document New Spin Functions for ClarityThe newly added functions (
DP_DeepPotComputeNListSP
,DP_DeepPotComputeNListfSP
,DP_DeepPotComputeNList2SP
,DP_DeepPotComputeNListf2SP
) introduce spin support. To aid users:
- Provide detailed documentation for each function.
- Explain the purpose of the
spin
parameter.- Highlight any differences from their non-spin counterparts.
Also applies to: 1304-1323, 1382-1403, 1426-1447
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (13)
- deepmd/pt/model/model/spin_model.py (4 hunks)
- deepmd/tf/entrypoints/freeze.py (2 hunks)
- source/api_c/include/c_api.h (8 hunks)
- source/api_c/include/deepmd.hpp (6 hunks)
- source/api_c/src/c_api.cc (10 hunks)
- source/api_cc/include/DeepPot.h (5 hunks)
- source/api_cc/include/DeepPotPT.h (4 hunks)
- source/api_cc/include/DeepPotTF.h (3 hunks)
- source/api_cc/src/DeepPot.cc (4 hunks)
- source/api_cc/src/DeepPotPT.cc (4 hunks)
- source/api_cc/src/DeepPotTF.cc (4 hunks)
- source/lmp/pair_deepmd.cpp (15 hunks)
- source/lmp/pair_deepmd.h (1 hunks)
🧰 Additional context used
🪛 GitHub Check: CodeQL
source/api_cc/include/DeepPotTF.h
[notice] 378-379: Commented-out code
This comment appears to contain commented-out code.
[notice] 385-385: Commented-out code
This comment appears to contain commented-out code.source/api_cc/src/DeepPotPT.cc
[notice] 356-356: Unused local variable
Variable nloc is not used.
[notice] 462-466: Commented-out code
This comment appears to contain commented-out code.
[notice] 495-495: Commented-out code
This comment appears to contain commented-out code.
[notice] 687-687: Unused local variable
Variable nframes is not used.
[notice] 748-752: Commented-out code
This comment appears to contain commented-out code.
[notice] 754-754: Commented-out code
This comment appears to contain commented-out code.source/api_cc/src/DeepPotTF.cc
[notice] 893-893: Unused local variable
Variable ret is not used.
[notice] 905-905: Unused local variable
Variable ret is not used.source/lmp/pair_deepmd.cpp
[notice] 1248-1248: Commented-out code
This comment appears to contain commented-out code.
🔇 Additional comments (25)
deepmd/tf/entrypoints/freeze.py (2)
127-128
: LGTM. Can you provide more context on the spin attributes?The addition of "spin_attr/virtual_len" and "spin_attr/spin_norm" nodes for the "ener" model type is consistent with the PR objectives of adding support for spin models.
Could you provide more information about these spin attributes and how they are used in the energy calculations?
131-131
: LGTM. Can you elaborate on the 'aparam_nall' attribute?The addition of the "fitting_attr/aparam_nall" node for the "ener" model type is in line with the PR objectives.
Could you provide more details about this fitting attribute and its role in the energy calculations or model fitting process?
deepmd/pt/model/model/spin_model.py (1)
Line range hint
1-624
: Overall, the changes look good and enhance the model's flexibility.The modifications to both
SpinModel
andSpinEnergyModel
classes consistently add support for additional communication data (comm_dict
) and neighbor list sorting (extra_nlist_sort
). These changes likely improve the flexibility and potentially the performance of the spin models.The implementation appears sound, with good consistency between the two classes. The main suggestion for improvement is to add documentation for the new parameters to enhance code maintainability and usability.
source/lmp/pair_deepmd.h (1)
78-78
: Variableall_force_mag
Added CorrectlyThe new member variable
all_force_mag
is properly declared and follows the existing naming conventions in the class. Its addition aligns with the class structure and should integrate well with the existing code.source/api_cc/include/DeepPotPT.h (2)
132-148
: Duplicate comment: Missing documentation for the newcompute
method overloadAs with the previous
compute
method overload, this version also lacks documentation. Please include documentation comments for this method to maintain consistency.
315-327
: Duplicate comment: Missing documentation for the newcomputew
method overloadThis
computew
method overload also lacks documentation. Please ensure all public methods are properly documented.source/api_cc/include/DeepPot.h (5)
146-177
: Method signatures correctly extend the interface for spin support.The addition of
force_mag
andspin
parameters to thecomputew
methods appropriately extends the functionality of theDeepPotBase
class to support spin models. The parameter types and ordering are consistent with existing methods.
393-420
: New methods appropriately extendDeepPot
functionality for spin models.The additions of
compute
methods withforce_mag
andspin
parameters are consistent with the class design and correctly extend theDeepPot
interface to support spin-related computations.
523-554
: Method implementations are consistent and correctly extend functionality.The added methods properly extend the existing functionality to support spin models, maintaining consistency in parameter types and ordering.
827-840
: Methods correctly extend functionality for model deviation with spin support.The added methods in
DeepPotModelDevi
appropriately extend the class to handle spin models in model deviation calculations.
881-897
: Method additions are consistent and extend functionality appropriately.The new methods correctly extend
DeepPotModelDevi
to support spin models in computations involving atomic energies and virials.source/api_cc/src/DeepPotPT.cc (2)
314-536
: Implementation of newcompute
function overload withforce_mag
andspin
The new overload of the
compute
function correctly introduces theforce_mag
andspin
parameters. The integration aligns well with the existing code structure and extends the functionality appropriately.🧰 Tools
🪛 GitHub Check: CodeQL
[notice] 356-356: Unused local variable
Variable nloc is not used.
[notice] 462-466: Commented-out code
This comment appears to contain commented-out code.
[notice] 495-495: Commented-out code
This comment appears to contain commented-out code.
658-798
: Implementation ofcompute
function for spin modelThe addition of the new
compute
function overload for the spin model is implemented correctly. The function handles thespin
andforce_mag
parameters appropriately, enhancing the model's capabilities.🧰 Tools
🪛 GitHub Check: CodeQL
[notice] 687-687: Unused local variable
Variable nframes is not used.
[notice] 748-752: Commented-out code
This comment appears to contain commented-out code.
[notice] 754-754: Commented-out code
This comment appears to contain commented-out code.source/lmp/pair_deepmd.cpp (2)
1248-1253
: Clarify the use ofcomm_reverse
and remove commented-out codeThe line
// comm_reverse = numb_models * 3;
is commented out, and new logic is introduced based onatom->sp_flag
. If the old assignment is no longer needed, consider removing it to keep the code clean.🧰 Tools
🪛 GitHub Check: CodeQL
[notice] 1248-1248: Commented-out code
This comment appears to contain commented-out code.
Line range hint
1406-1454
: Possible buffer overflow in communication routinesIn both
pack_reverse_comm
andunpack_reverse_comm
, ensure that the bufferbuf
is sufficiently sized to handle the additional data whenatom->sp_flag
is true. The added loops increase the amount of data being packed and unpacked.Run the following script to check buffer sizes in communication routines:
source/api_cc/src/DeepPotTF.cc (2)
511-516
: Addition ofget_vector
Method Correctly Implements Vector RetrievalThe newly added
get_vector
method extends theDeepPotTF
class to retrieve vectors from the session using the provided name. The implementation follows the existing code conventions and templates, ensuring type safety and consistency.
828-1019
: Implementation ofcompute
Method with Spin SupportThe overloaded
compute
method effectively adds support for spin calculations. It integrates spin-related parameters and modifies the computational logic to accommodate spin interactions. The method handles the extended data appropriately and maintains compatibility with the existing architecture.🧰 Tools
🪛 GitHub Check: CodeQL
[notice] 893-893: Unused local variable
Variable ret is not used.
[notice] 905-905: Unused local variable
Variable ret is not used.source/api_cc/src/DeepPot.cc (5)
221-242
: LGTM: Addition of compute functions with spin supportThe newly added
compute
function overloads correctly incorporate thedspin_
parameter to support spin calculations. The implementation follows existing code patterns and maintains consistency.
244-262
: LGTM: Overloaded compute function for vector energies with spinThe overloaded
compute
function handling vectors correctly adds spin support. Parameters are appropriately passed, and the function aligns with the established interface.
488-596
: LGTM: Extended compute functions with atomic outputs and spin supportThe new
compute
functions that includedatom_energy_
,datom_virial_
, and spin parameters are implemented consistently with the existing code structure. This extends functionality while maintaining code consistency.
264-319
: Ensure template specializations are correctly instantiatedPlease verify that the new template specializations for the
compute
function with spin support are correctly instantiated for bothdouble
andfloat
types and that they are properly utilized elsewhere in the codebase.Run the following script to confirm that instantiations are correctly defined:
1073-1140
: Verify correctness of computations involving spin in model deviationsEnsure that the computations in
DeepPotModelDevi::compute
correctly handle spin when calculating energy, force, and virial deviations across models. It's important that the spin contributions are accurately accounted for in deviation calculations.Run the following script to check for consistency in deviation computations:
source/api_c/include/c_api.h (1)
921-940
: Verify potential impact on backward compatibility due to function updatesThe addition of the new function
DP_DeepPotModelDeviComputeNList2SP
may suggest an update or replacement of the existingDP_DeepPotModelDeviComputeNList2
function. Please verify whether the original function remains available and unmodified. If any existing functions have altered signatures or have been deprecated, consider the impact on users who rely on the previous API and provide guidance or versioning to handle backward compatibility.source/api_c/src/c_api.cc (2)
1270-1270
: Confirm Const Correctness of Spin ParametersThe
spin
parameter is declared as aconst
pointer (e.g.,const double* spin
). Ensure that the data pointed to byspin
is not modified within the function. If modifications are necessary, remove theconst
qualifier.Review the implementation to ensure
spin
is treated as read-only.Also applies to: 1309-1309, 1387-1387, 1430-1430
376-377
: Verify the Size of the Spin Vector InitializationEnsure that the spin vector
spin_
is initialized with the correct size ofnframes * natoms * 3
. A mismatch in size could lead to out-of-bounds access or incorrect computations.Run the following script to confirm the size of the spin vector:
✅ Verification successful
[/run_scripts]
Verified: Spin Vector Initialization Sizes are Correct
The initialization of
spin_
with sizenframes * natoms * 3
at lines 376-377 is correct. Additionally, the initialization withnatoms * 3
at line 783 is appropriate within its context wherenframes
is restricted to 1.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the size of the spin vector initialization # Expected: The size matches nframes * natoms * 3 grep -rn 'std::vector<VALUETYPE> spin_' source/api_c/src/ | grep 'spin' # Check for correct size calculation in the codeLength of output: 255
Script:
#!/bin/bash # Description: Extract lines around line 783 in c_api.cc to understand the context of spin_ initialization # Extract 10 lines before and after line 783 sed -n '773,793p' source/api_c/src/c_api.ccLength of output: 886
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 26
🧹 Outside diff range and nitpick comments (15)
deepmd/tf/entrypoints/freeze.py (1)
264-265
: LGTM. Consider extracting spin attributes to a constant.The addition of
"spin_attr/virtual_len"
and"spin_attr/spin_norm"
to theoptional_node
list is consistent with the changes in the_make_node_names
function. This improves the robustness of the freezing process for different model configurations.For better code readability and maintainability, consider extracting the spin attribute names to a constant at the top of the file:
SPIN_ATTR_NODES = [ "spin_attr/ntypes_spin", "spin_attr/virtual_len", "spin_attr/spin_norm", ]Then, you can use this constant in both the
_make_node_names
function and theoptional_node
list:optional_node = [ "train_attr/min_nbor_dist", "fitting_attr/aparam_nall", *SPIN_ATTR_NODES, ]This approach would make it easier to manage these related attributes in the future.
deepmd/pt/model/model/spin_model.py (1)
Line range hint
474-497
: LGTM! Consider adding documentation for new parameters.The changes to
forward_common_lower
look good. The addition ofcomm_dict
andextra_nlist_sort
parameters enhances the method's flexibility.Consider adding docstring comments to explain the purpose and usage of these new parameters:
comm_dict
: Explain its role in communication and any expected key-value pairs.extra_nlist_sort
: Describe when this should be set to True and its impact on the neighbor list.source/api_cc/include/DeepPotTF.h (1)
384-384
: Consider using smart pointers forextend_firstneigh
The member variable
extend_firstneigh
is defined asstd::vector<int*>
. Using raw pointers can lead to memory management issues. Consider using smart pointers or ensuring that the ownership and lifecycle of these pointers are well-managed.source/api_cc/include/DeepPotPT.h (1)
Line range hint
356-371
: Document the newcomputew
method overload withforce_mag
andspin
The
computew
method overload at lines 356-371 introduces additional parametersforce_mag
andspin
. Adding comprehensive documentation for this method, including details about all parameters and their purposes, will improve clarity for users and maintain consistency across the API.source/api_cc/include/DeepPot.h (1)
523-554
: Provide default values where appropriateConsider providing default values for the new parameters
force_mag
andspin
if they are optional. This can help maintain backward compatibility and ease of use for existing code that does not require these parameters.source/lmp/pair_deepmd.cpp (3)
657-666
: Ensure the model deviation functionality is thoroughly tested.The added code introduces support for model deviation calculations when
atom->sp_flag
is not set. Ensure that this new functionality is thoroughly tested, covering scenarios with and withouteflag_atom
orcvflag_atom
set.Consider adding unit tests or integration tests to cover the new model deviation functionality and ensure its correctness.
677-695
: Ensure the model deviation functionality is thoroughly tested with spin interactions.The added code introduces support for model deviation calculations when
atom->sp_flag
is set, indicating spin interactions. Ensure that this new functionality is thoroughly tested, covering scenarios with and withouteflag_atom
orcvflag_atom
set, and verifying the correctness of the spin-related computations.Consider adding unit tests or integration tests to cover the new model deviation functionality with spin interactions and ensure its correctness.
848-848
: Implement support for spin atomic force output.The comment indicates that support for spin atomic force output is needed. Implement this functionality to ensure that the atomic forces associated with spin interactions are correctly output when
out_each
is set to 1.Do you want me to provide a code snippet that implements the spin atomic force output? I can help generate the necessary code to gather and output the spin atomic forces.
source/api_cc/src/DeepPot.cc (2)
244-263
: Add unit tests for the new spin-aware 'compute' methodsThe new overloads of the
compute
method now support spin interactions. To ensure correctness and prevent future regressions, consider adding unit tests that specifically test these new methods with various spin configurations.
1073-1140
: Update documentation to reflect new spin capabilitiesThe addition of spin support in the
compute
methods is a significant change. Remember to update the documentation and any relevant API references to inform users about the new parameters and functionality.source/api_c/src/c_api.cc (5)
1266-1284
: Suggest adding unit tests forDP_DeepPotComputeNListSP
The new function
DP_DeepPotComputeNListSP
introduces spin support into the public API. To ensure its correctness and prevent future regressions, consider adding unit tests covering various scenarios, including edge cases.Would you like assistance in generating unit tests for this function?
1304-1323
: Suggest adding unit tests forDP_DeepPotComputeNListfSP
Similarly, the
DP_DeepPotComputeNListfSP
function extends spin support for single-precision floats. Adding corresponding unit tests would help validate its functionality.Would you like assistance in creating unit tests for this function?
1425-1448
: Suggest adding unit tests forDP_DeepPotComputeNListf2SP
The addition of
DP_DeepPotComputeNListf2SP
introduces spin support for multi-frame computations with single-precision floats. Adding unit tests will help ensure its reliability.Would you like assistance in developing unit tests for this function?
1633-1652
: Suggest adding unit tests forDP_DeepPotModelDeviComputeNListfSP
To ensure the correctness of the new
DP_DeepPotModelDeviComputeNListfSP
function, consider adding unit tests that cover various scenarios with single-precision floats.Would you like help in creating unit tests for this function?
1718-1740
: Suggest adding unit tests forDP_DeepPotModelDeviComputeNListf2SP
Adding unit tests for the
DP_DeepPotModelDeviComputeNListf2SP
function will help verify its functionality with single-precision floats in multi-frame computations.Do you need assistance in developing unit tests for this function?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (13)
- deepmd/pt/model/model/spin_model.py (4 hunks)
- deepmd/tf/entrypoints/freeze.py (2 hunks)
- source/api_c/include/c_api.h (8 hunks)
- source/api_c/include/deepmd.hpp (6 hunks)
- source/api_c/src/c_api.cc (10 hunks)
- source/api_cc/include/DeepPot.h (5 hunks)
- source/api_cc/include/DeepPotPT.h (4 hunks)
- source/api_cc/include/DeepPotTF.h (3 hunks)
- source/api_cc/src/DeepPot.cc (4 hunks)
- source/api_cc/src/DeepPotPT.cc (4 hunks)
- source/api_cc/src/DeepPotTF.cc (4 hunks)
- source/lmp/pair_deepmd.cpp (15 hunks)
- source/lmp/pair_deepmd.h (1 hunks)
🧰 Additional context used
🔇 Additional comments (56)
deepmd/tf/entrypoints/freeze.py (3)
127-128
: LGTM. Can you provide more context on the new spin attributes?The addition of
"spin_attr/virtual_len"
and"spin_attr/spin_norm"
to the list of nodes for the "ener" model type looks good. These changes align with the PR objective of adding support for spin models.Could you please provide some additional context on what these new spin attributes represent and how they are used in the spin model calculations?
Line range hint
1-399
: Overall assessment: Changes look good with minor suggestionsThe modifications to
freeze.py
successfully add support for spin attributes in the graph freezing process, aligning well with the PR objectives. The changes are implemented in a backwards-compatible manner and extend the functionality as intended.Key points:
- New spin attributes (
virtual_len
andspin_norm
) are added to both the_make_node_names
function and theoptional_node
list.- The changes improve the robustness of the freezing process for different model configurations.
Suggestions for improvement:
- Consider extracting spin attribute names to a constant for better code readability and maintainability.
- Verify the consistent usage of these new spin attributes throughout the codebase where spin models are implemented or processed.
Overall, the changes look good and are ready for merging after addressing the minor suggestions and verifying the usage of new spin attributes in the broader codebase.
127-128
: Verify usage of new spin attributes in the codebaseThe addition of
"spin_attr/virtual_len"
and"spin_attr/spin_norm"
looks good and appears to be backwards compatible. However, it's important to ensure that these new attributes are properly handled in other parts of the codebase where spin models are used.Let's verify the usage of these new spin attributes:
Please review the output of this script to ensure that the new spin attributes are consistently used throughout the codebase where spin models are implemented or processed.
Also applies to: 264-265
✅ Verification successful
Let's retry searching for the new spin attributes with the correct file type.
Usage of new spin attributes verified successfully
The new spin attributes
"spin_attr/virtual_len"
and"spin_attr/spin_norm"
are consistently used across the codebase and are properly integrated without introducing any issues.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for usage of new spin attributes in the codebase # Search for "virtual_len" usage echo "Searching for 'virtual_len' usage:" rg "virtual_len" --type python # Search for "spin_norm" usage echo "Searching for 'spin_norm' usage:" rg "spin_norm" --type python # Search for general spin attribute usage echo "Searching for general spin attribute usage:" rg "spin_attr" --type pythonLength of output: 444
Script:
#!/bin/bash # Description: Check for usage of new spin attributes in the codebase with corrected file type. # Search for "virtual_len" usage echo "Searching for 'virtual_len' usage:" rg "virtual_len" --type py # Search for "spin_norm" usage echo "Searching for 'spin_norm' usage:" rg "spin_norm" --type py # Search for general spin attribute usage echo "Searching for 'spin_attr' usage:" rg "spin_attr" --type pyLength of output: 3279
deepmd/pt/model/model/spin_model.py (1)
Line range hint
612-624
: LGTM! Consistent implementation with parent class.The addition of the
comm_dict
parameter toforward_lower
inSpinEnergyModel
is consistent with the changes in the parentSpinModel
class. This maintains a coherent interface across the model hierarchy.source/lmp/pair_deepmd.h (1)
78-78
: Ensure proper initialization and management ofall_force_mag
The new member variable
all_force_mag
has been added. Please verify that it is properly initialized in the constructor and cleared in the destructor if necessary to prevent potential uninitialized access or memory leaks.source/api_cc/include/DeepPot.h (4)
881-897
: Ensure consistency across allcompute
method overloadsWith the addition of new overloads that include
force_mag
andspin
, double-check that allcompute
methods across the codebase maintain consistent signatures and parameter order where appropriate.Run the following script to compare all
compute
method signatures:#!/bin/bash # Description: List all compute method signatures for comparison. # Extract all compute method declarations rg --type-add 'cpp:h,cpp' --type cpp 'void compute' -A 5 # Review for consistency in parameter lists
393-420
: Check for consistency in template specializationsEnsure that all template specializations and usages of the
compute
function are updated to accommodate the new parameters. Inconsistent templates might lead to compilation errors or unexpected behavior.Run the following script to identify all usages of
compute
and verify that they include the new parameters:#!/bin/bash # Description: Find all usages of the compute template function and check for new parameters. # Search for calls to compute functions rg --type-add 'cpp:h,cpp' --type cpp 'compute<' -A 5
827-840
: Verify correct integration of new parametersEnsure that the implementation of the new
compute
methods inDeepPotModelDevi
correctly processes theforce_mag
andspin
parameters. Incorrect handling could lead to inaccurate calculations or runtime errors.You can run the following script to check the method implementations:
#!/bin/bash # Description: Verify implementations of compute methods with force_mag and spin in DeepPotModelDevi. # Search for compute method definitions in source files rg --type-add 'cpp:h,cpp' --type cpp 'void DeepPotModelDevi::compute' -A 10 # Look for proper handling of force_mag and spin within these methods
146-161
: Ensure implementation in derived classesVerify that all derived classes of
DeepPotBase
correctly implement the newcomputew
overloads withforce_mag
andspin
. Missing implementations could lead to runtime errors due to pure virtual method calls.You can run the following script to check for implementations of the new methods in all derived classes:
source/lmp/pair_deepmd.cpp (16)
606-608
: Ensure const-correctness ofdcoord
anddspin
in thecompute
call.Passing
dcoord
anddspin
as const references is a good practice to ensure const-correctness and avoid unintended modifications. Verify that thecompute
method in theDeepPot
class is updated to accept these parameters as const references.
1248-1248
: Commented-out codeThis comment appears to contain commented-out code.
1435-1447
: Ensure the reverse communication unpacking for spin interactions is correct.The added code unpacks the force and force magnitude data from the communication buffer when
atom->sp_flag
is set, indicating spin interactions. Verify that the unpacking order and indexing are correct, and that the received data is correctly accumulated into theall_force
andall_force_mag
arrays.To verify, compare the unpacking logic with the corresponding packing logic in
pack_reverse_comm
:#!/bin/bash # Description: Verify reverse communication unpacking for spin interactions is consistent with packing. # Test: Compare unpacking and packing logic for spin interactions. Expect: Consistent ordering and indexing of force and force magnitude data. diff -u <(rg --type cpp $'unpack_reverse_comm.*atom->sp_flag' -A 15) <(rg --type cpp $'pack_reverse_comm.*atom->sp_flag' -A 15)
1179-1188
: Ensure the output header is correctly formatted.The added code outputs the header for the model deviation statistics when
atom->sp_flag
is not set. Verify that the header format is correct, including the column widths and labels, and that it is consistent with the rest of the output.To verify, search for other occurrences of the header output and compare the format:
830-845
: Ensure the spin-related force magnitude statistics are correctly output.The added code outputs the spin-related force magnitude statistics (
all_fm_max
,all_fm_min
,all_fm_avg
) whenatom->sp_flag
is set. Verify that the output format is correct and consistent with the rest of the output, and that the statistics are converted to the appropriate units usingforce_unit_cvt_factor
.To verify, search for other occurrences of the spin-related force magnitude statistics and analyze their usage in the output:
✅ Verification successful
Spin-Related Force Magnitude Statistics Output Verified
The spin-related force magnitude statistics (
all_fm_max
,all_fm_min
,all_fm_avg
) are correctly output with consistent formatting and appropriate unit conversion usingforce_unit_cvt_factor
.
- Verified output statements in
source/lmp/pair_deepmd.cpp
correctly includeall_fm_max
,all_fm_min
, andall_fm_avg
.- Confirmed that unit conversion is applied before outputting the statistics.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify spin-related force magnitude statistics are correctly output. # Test: Search for occurrences of spin-related force magnitude statistics in output statements. Expect: Consistent output format and unit conversion. rg --type cpp $'all_fm_min|all_fm_max|all_fm_avg' -A 5 | rg --type cpp $'fp <<'Length of output: 280
Script:
#!/bin/bash # Description: Verify spin-related force magnitude statistics are correctly output. # Corrected Test: Search for occurrences of spin-related force magnitude statistics in output statements. Expect: Consistent output format and unit conversion. rg --type cpp 'fp\s*<<[^;]*\ball_fm_min\b|\ball_fm_max\b|\ball_fm_avg\b' -A 5Length of output: 2358
1406-1417
: Ensure the reverse communication packing for spin interactions is correct.The added code packs the force and force magnitude data into the communication buffer when
atom->sp_flag
is set, indicating spin interactions. Verify that the packing order and indexing are correct, and that the buffer size is sufficient to accommodate both the force and force magnitude components.To verify, compare the packing logic with the corresponding unpacking logic in
unpack_reverse_comm
:
1190-1195
: Ensure the output header for spin interactions is correctly formatted.The added code outputs the header for the model deviation statistics when
atom->sp_flag
is set, indicating spin interactions. Verify that the header format is correct, including the column widths and labels for the spin-related force magnitudes (max_devi_fm
,min_devi_fm
,avg_devi_fm
), and that it is consistent with the rest of the output.To verify, search for other occurrences of the header output and compare the format:
1249-1253
: Ensure the correct communication size for spin interactions.The added code sets the
comm_reverse
size based on whetheratom->sp_flag
is set, indicating spin interactions. When spin interactions are present, the size is set tonumb_models * 3 * 2
, accounting for both the force and force magnitude components. Verify that this size is correct and consistent with the data being communicated for spin interactions.To verify, search for other occurrences of
comm_reverse
and analyze how it is used in communication:✅ Verification successful
Communication size for spin interactions is correctly set.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify `comm_reverse` size is consistent with spin interaction data communication. # Test: Search for occurrences of `comm_reverse` and analyze usage in communication. Expect: Consistent usage with spin interaction data size. rg --type cpp $'comm_reverse' -A 5Length of output: 237
Script:
#!/bin/bash # Description: Search for all occurrences of `comm_reverse` in C++ files and provide context for each match. rg --type cpp 'comm_reverse' -C 2Length of output: 893
755-756
: Ensurestd_fm
andtmp_avg_fm
are correctly populated and used.The new variables
std_fm
andtmp_avg_fm
seem to be related to the standard deviation and average of the force magnitudes. Verify that they are correctly populated and used in the appropriate places, such as in the output or analysis of the spin-related forces.To verify, search for other occurrences of
std_fm
andtmp_avg_fm
and analyze their usage:✅ Verification successful
[/run_scripts]
std_fm
andtmp_avg_fm
are correctly populated and used.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify `std_fm` and `tmp_avg_fm` are correctly populated and used. # Test: Search for occurrences of `std_fm` and `tmp_avg_fm` and analyze usage. Expect: Consistent population and usage in spin-related force output or analysis. rg --type cpp $'std_fm|tmp_avg_fm' -A 5Length of output: 280
Script:
#!/bin/bash # Description: Corrected script to verify `std_fm` and `tmp_avg_fm` are correctly populated and used. # Test: Search for occurrences of `std_fm` and `tmp_avg_fm` and analyze their usage. Expect: Consistent population and usage in spin-related force output or analysis. rg --type cpp 'std_fm|tmp_avg_fm' -C 5Length of output: 2257
770-783
: Ensure the spin-related force magnitude statistics are correctly calculated and used.The added code calculates the minimum, maximum, and average of the force magnitudes when
atom->sp_flag
is set, indicating spin interactions. Verify that these statistics are correctly calculated usingMPI_Reduce
and used in the appropriate places, such as in the output or analysis of the spin-related forces.To verify, search for other occurrences of the spin-related force magnitude statistics and analyze their usage:
✅ Verification successful
Spin-related force magnitude statistics are correctly calculated and used.
The statistics
all_fm_min
,all_fm_max
, andall_fm_avg
are consistently calculated usingMPI_Reduce
and utilized appropriately in the output and analysis of spin-related forces.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify spin-related force magnitude statistics are correctly calculated and used. # Test: Search for occurrences of spin-related force magnitude statistics and analyze usage. Expect: Consistent calculation using `MPI_Reduce` and usage in output or analysis. rg --type cpp $'all_fm_min|all_fm_max|all_fm_avg' -A 5Length of output: 280
Script:
#!/bin/bash # Description: Verify spin-related force magnitude statistics are correctly calculated and used. # Corrected Test: Search for occurrences of spin-related force magnitude statistics and analyze usage. Expect: Consistent calculation using `MPI_Reduce` and usage in output or analysis. rg --type cpp 'all_fm_min|all_fm_max|all_fm_avg' -A 5Length of output: 2436
765-766
: Ensureall_fm_min
,all_fm_max
, andall_fm_avg
are correctly populated and used.The new variables
all_fm_min
,all_fm_max
, andall_fm_avg
seem to be related to the minimum, maximum, and average of the force magnitudes across all processes. Verify that they are correctly populated usingMPI_Reduce
and used in the appropriate places, such as in the output or analysis of the spin-related forces.To verify, search for other occurrences of these variables and analyze their usage:
✅ Verification successful
Re-running Verification for Variable Usage
all_fm_min
,all_fm_max
, andall_fm_avg
are correctly populated and used.The variables
all_fm_min
,all_fm_max
, andall_fm_avg
are properly initialized, populated usingMPI_Reduce
, and utilized in the output for analyzing spin-related forces.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify `all_fm_min`, `all_fm_max`, and `all_fm_avg` are correctly populated and used. # Test: Search for occurrences of these variables and analyze usage. Expect: Consistent population using `MPI_Reduce` and usage in spin-related force output or analysis. rg --type cpp $'all_fm_min|all_fm_max|all_fm_avg' -A 5Length of output: 280
Script:
# #!/bin/bash # Description: Verify `all_fm_min`, `all_fm_max`, and `all_fm_avg` are correctly populated and used. # Corrected Test: Search for occurrences of these variables and analyze their usage. rg --type cpp 'all_fm_min|all_fm_max|all_fm_avg' -A 5Length of output: 2436
703-703
: Verify the assignment ofdforce_mag
fromall_force_mag
.Ensure that assigning
dforce_mag
fromall_force_mag[0]
is correct and consistent with the expected behavior of the model deviation functionality when spin interactions are involved.To verify, search for other occurrences of
all_force_mag
and analyze how it is populated and used:✅ Verification successful
Verified the assignment of
dforce_mag
fromall_force_mag
is correct and consistent with the expected behavior.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify `all_force_mag` population and usage is consistent with `dforce_mag` assignment. # Test: Search for occurrences of `all_force_mag` and analyze usage. Expect: Consistent population and usage with `dforce_mag` assignment. rg --type cpp $'all_force_mag' -A 5Length of output: 280
Script:
#!/bin/bash # Description: Corrected script to verify `all_force_mag` population and usage consistency. # Search for exact occurrences of `all_force_mag` rg --type cpp 'all_force_mag' -A 5 # Additionally, search for possible variants to ensure comprehensive coverage rg --type cpp 'all_fm_min|all_fm_max|all_fm_avg' -A 5Length of output: 10874
505-506
: Ensure force magnitude vector is correctly populated and used.The new
dforce_mag
vector seems to store force magnitudes. Verify that it is correctly populated by the model and used in the appropriate places, such as in the spin force calculations.To verify, search for other occurrences of
dforce_mag
and analyze its usage:
493-493
: Verify the spin vector calculation.Ensure that the spin vector calculation
dspin[ii * 3 + dd] = sp[ii][dd] * sp[ii][3]
is correct and consistent with the expected spin representation in the model.To verify, search for other occurrences of
sp
and analyze how the spin data is populated and used:
919-921
: Verify the force calculation for spin interactions.The added code calculates the forces for spin interactions by adding the scaled
dforce
values tof[ii][dd]
. Ensure that this calculation is correct and consistent with the expected force contributions from spin interactions.To verify, search for other occurrences of
f[ii][dd]
and analyze how the forces are accumulated:✅ Verification successful
Force calculation for spin interactions verified successfully in
source/lmp/pair_deepmd.cpp
lines 919-921. No inconsistencies found with force accumulation for spin interactions.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify force calculation for spin interactions is consistent with force accumulation. # Test: Search for occurrences of `f[ii][dd]` and analyze force accumulation. Expect: Consistent accumulation of spin interaction forces. rg --type cpp $'f\[ii\]\[dd\]' -A 5Length of output: 237
Script:
#!/bin/bash # Description: Search for all occurrences of force accumulation in C++ files to verify consistency in spin interactions. # Search for any indexed access to 'f' and capture surrounding lines for context. rg --type cpp 'f\[[0-9]+\]\[[0-9]+\]' -A 5Length of output: 352
Script:
#!/bin/bash # Description: Broadly search for any indexed access to 'f' in C++ files to verify force accumulation related to spin interactions. # Search for any indexed access to 'f' and capture surrounding lines for context. rg --type cpp 'f\[' -A 5Length of output: 148492
582-586
: Ensure const-correctness ofdcoord
anddspin
in thecompute
call.Passing
dcoord
anddspin
as const references is a good practice to ensure const-correctness and avoid unintended modifications. Verify that thecompute
method in theDeepPot
class is updated to accept these parameters as const references.To verify, check the declaration of the
compute
method in theDeepPot
class:✅ Verification successful
[/run_scripts]
[/run_scripts]
[/run_scripts]
Const-correctness of
dcoord
anddspin
VerifiedAll instances of the
DeepPot::compute
method in the codebase acceptdcoord
anddspin
asconst
references, ensuring const-correctness.
source/api_cc/src/DeepPot.cc
lines: 141-148, 227-235, 291-299, 397-405, 497-505, 519-527🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify `compute` method accepts `dcoord` and `dspin` as const references. # Test: Search for the declaration of the `compute` method. Expect: `dcoord` and `dspin` parameters are const references. rg --type cpp $'DeepPot::compute\(.*dcoord.*dspin.*\)' -o -r '$1'Length of output: 280
Script:
#!/bin/bash # Description: Verify `compute` method accepts `dcoord` and `dspin` as const references. # Test: Search for the declaration of the `compute` method. Expect: `dcoord` and `dspin` parameters are const references. rg --type cpp 'DeepPot::compute\((const\s+vector<double>&\s+dcoord, const\s+vector<double>&\s+dspin)' --only-matchingLength of output: 119
Script:
#!/bin/bash # Description: Locate all declarations of the `DeepPot::compute` method. # Test: Search for any `DeepPot::compute` method declarations and extract their signatures. rg --type cpp 'DeepPot::compute\s*\(.*\)' --pretty --context 0 --multilineLength of output: 76
Script:
#!/bin/bash # Description: Locate all declarations and definitions of the `DeepPot::compute` method. # Test: Search for any `DeepPot::compute` method declarations and extract their full signatures. rg --type cpp 'DeepPot::compute\s*\([^)]*\)' --pretty --multilineLength of output: 8346
source/api_cc/src/DeepPotTF.cc (1)
511-516
: Functionget_vector
is correctly implemented.The
get_vector
method provides a necessary addition to retrieve vectors from the session. The implementation aligns with the existing codebase and follows appropriate template usage.source/api_cc/src/DeepPot.cc (1)
221-243
:⚠️ Potential issueEnsure 'dener_' is populated before accessing its first element
In the
compute
method, you setdener = dener_[0];
without explicitly checking ifdener_
has at least one element. While it's likely thatdp->computew
populatesdener_
, it's good practice to ensure thatdener_
is not empty before accessingdener_[0]
to prevent potential out-of-range errors.Run the following script to verify that
dener_
always has at least one element after callingdp->computew
:source/api_c/include/c_api.h (21)
287-302
: Add missing documentation forDP_DeepPotComputeNListfSP
.Similar to
DP_DeepPotComputeNListSP
, this new function lacks a documentation comment block. Please provide detailed documentation to explain the function's purpose, parameters, and any important information.
287-302
: Inconsistent parameter naming:natom
vs.natoms
.The parameter
natoms
should be standardized tonatom
for consistency across the API.
287-302
: Ensure consistent parameter order with existing API functions.The introduction of the
spin
parameter changes the parameter order. Please ensure consistency or update documentation accordingly.
427-445
: Add missing documentation forDP_DeepPotComputeNList2SP
.This function lacks a documentation block. Including detailed documentation will help users understand its usage and parameters.
427-445
: Inconsistent parameter naming:natom
vs.natoms
.Please standardize the parameter name to
natom
for consistency.
427-445
: Ensure consistent parameter order with existing API functions.The placement of the
spin
parameter differs from existing functions. Consider adjusting the parameter order or updating documentation.
492-510
: Add missing documentation forDP_DeepPotComputeNListf2SP
.Please add a documentation block for clarity and consistency.
492-510
: Inconsistent parameter naming:natom
vs.natoms
.Standardize the parameter name to
natom
.
492-510
: Ensure consistent parameter order with existing API functions.The
spin
parameter's position should be consistent with other functions.
807-822
: Add missing documentation forDP_DeepPotModelDeviComputeNListSP
.Documentation is missing for this new function. Including it will enhance understanding and usability.
807-822
: Inconsistent parameter naming:natom
vs.natoms
.Please use
natom
to match existing functions.
807-822
: Ensure consistent parameter order with existing API functions.Review the placement of the
spin
parameter for consistency.
860-875
: Add missing documentation forDP_DeepPotModelDeviComputeNListfSP
.Adding documentation will help users understand this function's usage.
860-875
: Inconsistent parameter naming:natom
vs.natoms
.Use
natom
for consistency.
860-875
: Ensure consistent parameter order with existing API functions.Consider adjusting the
spin
parameter's position.
921-940
: Add missing documentation forDP_DeepPotModelDeviComputeNList2SP
.Please include a documentation block for this function.
921-940
: Inconsistent parameter naming:natom
vs.natoms
.Standardize to
natom
.
921-940
: Ensure consistent parameter order with existing API functions.Review the parameter order for consistency.
987-1005
: Add missing documentation forDP_DeepPotModelDeviComputeNListf2SP
.Documentation is needed for clarity.
987-1005
: Inconsistent parameter naming:natom
vs.natoms
.Use
natom
to remain consistent.
987-1005
: Ensure consistent parameter order with existing API functions.Adjust the
spin
parameter's position for consistency.source/api_c/src/c_api.cc (6)
354-418
: Well-structured implementation of spin support inDP_DeepPotComputeNList_variant_sp
The addition of the
DP_DeepPotComputeNList_variant_sp
function effectively extends spin support. The implementation follows the existing coding patterns, ensuring consistency and maintainability.
419-454
: Template instantiations correctly added for spin variantThe explicit template instantiations for
double
andfloat
types ensure that the spin variant functions are available for both data types, aligning with the rest of the API.
758-880
: Extension of spin support toDP_DeepPotModelDeviComputeNList_variant_sp
The function
DP_DeepPotModelDeviComputeNList_variant_sp
properly incorporates spin support into the model deviation computations. The handling of inputs and outputs is consistent with the existing codebase.
1382-1404
: Spin support extended to multi-frame computations inDP_DeepPotComputeNList2SP
The function
DP_DeepPotComputeNList2SP
appropriately extends spin support to multi-frame computations. The parameter handling and function structure are consistent with the rest of the API.
1595-1614
: Expansion of spin support inDP_DeepPotModelDeviComputeNListSP
The
DP_DeepPotModelDeviComputeNListSP
function successfully incorporates spin support for model deviation computations. The implementation aligns with the existing code structure.
1674-1696
: Spin support in multi-frame model deviation withDP_DeepPotModelDeviComputeNList2SP
The function
DP_DeepPotModelDeviComputeNList2SP
appropriately extends spin support to multi-frame model deviation computations. The code is well-integrated and maintains consistency.source/api_c/include/deepmd.hpp (2)
160-180
: Addition of spin support in_DP_DeepPotComputeNListSP
is correctly implementedThe new template function and its specializations for handling computations with spin are properly defined and aligned with existing code patterns.
391-453
: Addition of spin support in_DP_DeepPotModelDeviComputeNListSP
is appropriateThe introduction of the template function and its specializations for computations including spin in the
DeepPotModelDevi
class is correctly structured.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 19
🧹 Outside diff range and nitpick comments (20)
deepmd/tf/entrypoints/freeze.py (2)
127-128
: LGTM. Consider adding documentation for the new spin attributes.The addition of "spin_attr/virtual_len" and "spin_attr/spin_norm" nodes for the "ener" model type is consistent with the PR objectives of adding LAMMPS support for spin models. This enhancement will allow the frozen graph to include necessary information for spin-related computations.
To improve maintainability, consider adding a brief comment explaining the purpose of these new spin attributes and when they are used.
264-265
: LGTM. Consider grouping related optional nodes.The addition of "spin_attr/virtual_len" and "spin_attr/spin_norm" to the
optional_node
list is appropriate. This ensures backward compatibility with existing models that may not have these spin attributes.To improve code readability, consider grouping related optional nodes together. For example:
optional_node = [ "train_attr/min_nbor_dist", "fitting_attr/aparam_nall", # Spin-related attributes "spin_attr/ntypes_spin", "spin_attr/virtual_len", "spin_attr/spin_norm", ]This grouping makes it easier to identify and manage related optional nodes.
deepmd/pt/model/model/spin_model.py (1)
612-613
: LGTM! Consider adding a brief comment forcomm_dict
.The changes in the
SpinEnergyModel
class are consistent with those inSpinModel
and should improve the model's performance and flexibility for energy calculations in spin systems. The use ofself.backbone_model.need_sorted_nlist_for_lower()
forextra_nlist_sort
is a good practice.Consider adding a brief comment explaining the purpose of
comm_dict
for future maintainability. For example:comm_dict: Optional[Dict[str, torch.Tensor]] = None, # Dictionary for additional communication dataAlso applies to: 623-624
source/api_cc/include/DeepPotTF.h (3)
282-313
: Update Documentation forcomputew
Method OverloadsThe
computew
method now includes additional parametersforce_mag
andspin
. To maintain clarity and assist future developers, please update the method's documentation to reflect these new parameters, providing explanations of their purpose and how they influence the computations.
339-358
: Add Documentation for Newextend
MethodThe newly introduced
extend
method lacks documentation. For better maintainability and ease of understanding, please add comprehensive comments explaining the purpose of this method, detailing each parameter, and highlighting any important considerations or usage examples.
368-369
: Document the Template Methodget_vector
The template method
get_vector
is added without accompanying documentation. Please include comments that describe the purpose of this method, explain the template and function parameters, and provide any necessary usage details to aid in understanding and future maintenance.source/api_cc/include/DeepPotPT.h (4)
77-90
: Add documentation for the newcompute
method overload withforce_mag
andspin
parametersThe new overload of the
compute
method includes additional parametersforce_mag
andspin
. To maintain code readability and help users understand the purpose and usage of these parameters, please add appropriate documentation comments for this method.
132-148
: Document thecompute
method overload with neighbor list parameters and new argumentsThis overload of the
compute
method introducesforce_mag
,spin
,nghost
,lmp_list
, andago
parameters but lacks accompanying documentation. Please provide detailed documentation comments to explain these parameters and their usage.
304-314
: Provide documentation for the newcomputew
method overloads withforce_mag
andspin
The
computew
methods added here includeforce_mag
andspin
parameters. To ensure consistency and clarity, please document these methods, explaining the purpose of the new parameters.
356-363
: Add documentation for thecomputew
method overload with neighbor list parameters and new argumentsThis overload of the
computew
method includes additional parametersforce_mag
,spin
,nghost
,inlist
, andago
but lacks documentation. Providing detailed comments will aid in understanding and using this method correctly.source/api_cc/include/DeepPot.h (5)
146-177
: Include documentation for new parametersforce_mag
andspin
The newly added overloads of the
computew
method in theDeepPotBase
class introduce the parametersforce_mag
andspin
. However, the function's documentation does not reflect these additions. Updating the documentation will enhance clarity and maintain consistency.
393-420
: Add documentation for new parameters incompute
methodsIn the
DeepPot
class, thecompute
methods now include additional parametersforce_mag
andspin
in their overloads. Please update the function comments to include descriptions of these new parameters to maintain comprehensive documentation.
523-554
: Document new parametersforce_mag
andspin
in function commentsThe overloads of the
compute
methods in theDeepPot
class have been extended withforce_mag
andspin
. The current documentation does not mention these parameters. Ensuring that all parameters are documented helps users understand the method interfaces fully.
827-840
: Update documentation for added parameters inDeepPotModelDevi
The
compute
method overloads in theDeepPotModelDevi
class now acceptforce_mag
andspin
as additional parameters. The accompanying documentation should be revised to include these parameters, providing clear guidance on their usage.
881-897
: Ensure all new parameters are included in method documentationThe latest overloads of the
compute
methods inDeepPotModelDevi
introduceforce_mag
andspin
but the method comments have not been updated accordingly. For consistency and clarity, please add descriptions of these parameters to the documentation.source/api_cc/src/DeepPotPT.cc (1)
446-446
: Correct the typo 'suported' to 'supported' in commentsThere is a typo in the comments at lines 446, 462, 476, 732, and 748: "suported" should be corrected to "supported".
Also applies to: 462-462, 476-476, 732-732, 748-748
source/api_c/src/c_api.cc (2)
1304-1323
: Maintain Consistent Naming ConventionsThe introduction of
DP_DeepPotComputeNListfSP
should follow the project's naming conventions. Ensure that the naming is consistent with existing functions to avoid confusion.Review the function names to confirm they adhere to the established patterns.
1595-1614
: Add Documentation for New FunctionalityThe function
DP_DeepPotModelDeviComputeNListSP
lacks comments explaining its purpose and usage. Adding documentation will improve code readability and assist future developers.Include a descriptive comment block above the function declaration.
source/api_c/include/deepmd.hpp (2)
160-203
: Add Documentation for Spin Support FunctionsThe newly added template functions
_DP_DeepPotComputeNListSP
and their specializations introduce spin support in the computations. To enhance maintainability and readability, please add documentation comments explaining the purpose, parameters, and usage of these functions.
391-452
: Add Documentation forDeepPotModelDevi
Spin Support FunctionsThe new template functions
_DP_DeepPotModelDeviComputeNListSP
and their specializations introduce spin support in theDeepPotModelDevi
class. Adding documentation comments will help users understand how to use these functions properly.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (13)
- deepmd/pt/model/model/spin_model.py (4 hunks)
- deepmd/tf/entrypoints/freeze.py (2 hunks)
- source/api_c/include/c_api.h (8 hunks)
- source/api_c/include/deepmd.hpp (6 hunks)
- source/api_c/src/c_api.cc (10 hunks)
- source/api_cc/include/DeepPot.h (5 hunks)
- source/api_cc/include/DeepPotPT.h (4 hunks)
- source/api_cc/include/DeepPotTF.h (3 hunks)
- source/api_cc/src/DeepPot.cc (4 hunks)
- source/api_cc/src/DeepPotPT.cc (4 hunks)
- source/api_cc/src/DeepPotTF.cc (4 hunks)
- source/lmp/pair_deepmd.cpp (15 hunks)
- source/lmp/pair_deepmd.h (1 hunks)
🧰 Additional context used
🪛 GitHub Check: CodeQL
source/api_cc/include/DeepPotTF.h
[notice] 378-379: Commented-out code
This comment appears to contain commented-out code.
[notice] 385-385: Commented-out code
This comment appears to contain commented-out code.source/api_cc/src/DeepPotPT.cc
[notice] 356-356: Unused local variable
Variable nloc is not used.
[notice] 462-466: Commented-out code
This comment appears to contain commented-out code.
[notice] 495-495: Commented-out code
This comment appears to contain commented-out code.
[notice] 687-687: Unused local variable
Variable nframes is not used.
[notice] 748-752: Commented-out code
This comment appears to contain commented-out code.
[notice] 754-754: Commented-out code
This comment appears to contain commented-out code.source/api_cc/src/DeepPotTF.cc
[notice] 893-893: Unused local variable
Variable ret is not used.
[notice] 905-905: Unused local variable
Variable ret is not used.source/lmp/pair_deepmd.cpp
[notice] 1248-1248: Commented-out code
This comment appears to contain commented-out code.
🔇 Additional comments (29)
deepmd/tf/entrypoints/freeze.py (1)
Line range hint
1-394
: Overall, the changes look good and align with the PR objectives.The modifications to
deepmd/tf/entrypoints/freeze.py
successfully add support for spin-related attributes in the energy model while maintaining backward compatibility. The code quality is good, and the changes are well-integrated into the existing structure.Here's a summary of the review:
- New spin attributes ("spin_attr/virtual_len" and "spin_attr/spin_norm") have been added to the energy model.
- These attributes are properly handled in both the
_make_node_names
andfreeze_graph
functions.- Backward compatibility is maintained by adding the new attributes to the
optional_node
list.Minor suggestions for improvement include adding brief documentation for the new spin attributes and grouping related optional nodes for better readability.
deepmd/pt/model/model/spin_model.py (2)
Line range hint
1-638
: Overall, the changes look good and align with the PR objectives.The modifications to both
SpinModel
andSpinEnergyModel
classes enhance the flexibility and potentially the performance of the spin models. The implementation is consistent and correct. The addition ofcomm_dict
andextra_nlist_sort
parameters should improve LAMMPS support for spin models as intended.A few minor suggestions:
- Verify the consistent usage of new parameters across the codebase.
- Consider adding a brief comment explaining the purpose of
comm_dict
for future maintainability.Great job on these improvements!
474-476
: LGTM! Verify consistent usage of new parameters.The addition of
comm_dict
andextra_nlist_sort
parameters to theforward_common_lower
method enhances the model's flexibility and aligns with the PR objectives. The implementation looks correct.To ensure consistency, let's verify if these new parameters are used correctly in other parts of the codebase:
Also applies to: 496-497
source/lmp/pair_deepmd.h (1)
78-78
: LGTM!The addition of
all_force_mag
is appropriate and consistent with the existing member variables.source/api_cc/include/DeepPotTF.h (1)
118-134
: Ensure Consistency with Newcompute
Method OverloadThe new
compute
method overload includes additional parametersforce_mag
andspin
. Please verify that all calls tocompute
throughout the codebase are updated to match this new signature where appropriate, and ensure that the added parameters are correctly handled in the implementation to prevent any potential runtime errors or mismatches.To assist in verifying the usage of the
compute
method, you can run the following script:✅ Verification successful
All
compute
method calls are consistent with the new signature.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Find all usages of the `compute` method to ensure they match the new signature. rg --type cpp --type c++ -A 2 -B 2 '\.compute\('Length of output: 78
Script:
#!/bin/bash # Description: Find all usages of the `compute` method to ensure they match the new signature. rg --type cpp -A 2 -B 2 '\.compute\('Length of output: 114850
Script:
#!/bin/bash # Description: Find all `compute` method calls that do not include `force_mag` and `spin` parameters. ast-grep --lang cpp --pattern "compute($_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_)" --match-onlyLength of output: 476
Script:
#!/bin/bash # Description: Find all `compute` method calls that do not include `force_mag` and `spin` parameters. ast-grep --lang cpp --pattern "compute($_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_, $_)"Length of output: 251
source/api_cc/include/DeepPotPT.h (1)
328-341
: Ensure consistency in method signatures and parameter ordering incomputew
overloadsThere are multiple overloads of the
computew
method with varying parameter types and orders. Please verify that the method signatures are consistent and that the parameter ordering is appropriate to prevent confusion and potential misuse.source/lmp/pair_deepmd.cpp (2)
582-586
: Handling spin interactions correctly in force computation.The function call to
deep_pot.compute
has been appropriately updated to includedforce_mag
anddspin_const
, allowing for the computation of spin-related forces. This modification correctly extends the functionality to handle spin interactions.
1406-1423
: Ensure correct buffer size and indexing in reverse communication.In the
pack_reverse_comm
function (lines 1406-1423), whenatom->sp_flag
is set, additional spin force data (dforce_mag
) is packed into the buffer. Ensure that the buffer sizecomm_reverse
is correctly set to accommodate the extra data and that indexing variablem
correctly tracks the buffer positions to prevent buffer overflows or misalignment.source/api_cc/src/DeepPotTF.cc (2)
511-515
: Implementation ofget_vector
method is correctThe
get_vector
method correctly retrieves vector data from the session using the provided name.
893-893
: Acknowledging past comments on unused variablesThe variable
ret
is assigned but not used beyond anassert
statement at lines 893 and 905. Previous review comments have already addressed this issue.No further action is needed if the previous comments are being addressed.
Also applies to: 905-905
🧰 Tools
🪛 GitHub Check: CodeQL
[notice] 893-893: Unused local variable
Variable ret is not used.source/api_cc/src/DeepPot.cc (5)
221-243
: Correct implementation of newcompute
method with spin supportThe new
compute
method overloads correctly add parameters for spin (dspin_
) and magnetic force (dforce_mag_
). The method properly forwards these parameters todp->computew
, enhancing functionality to support spin calculations.
244-263
: Consistent addition of vectorizedcompute
method with spin supportThe overload of the
compute
method for vector energies (std::vector<ENERGYTYPE>& dener
) is implemented correctly with the new spin parameters. This maintains consistency with the single-energy version and appropriately extends the class's capabilities.
954-1012
: Accurate addition of spin support inDeepPotModelDevi::compute
The
DeepPotModelDevi
class now includes an overloadedcompute
method that supports spin (dspin_
) and magnetic forces (all_force_mag
). The implementation correctly loops overnumb_models
and passes the new parameters to eachdps[ii].compute
call.
1073-1140
: Extension ofcompute
method with atom energies and spin support is soundThe extended
compute
method inDeepPotModelDevi
now supports atom energies, atom virials, and spin parameters. These additions are correctly integrated into the method, enhancing its functionality for spin-related computations.
488-596
: Ensure consistency in template instantiations for spin supportThe template instantiations for both
double
andfloat
types for the newcompute
methods support spin calculations correctly. Verify that these instantiations cover all required use cases and that there are no missing specializations.To confirm completeness, you might run a check to ensure all necessary template specializations are provided:
✅ Verification successful
Template Instantiations Verified
All necessary template instantiations for
double
andfloat
types with spin support are present.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all template instantiations for DeepPot::compute with spin support # Expected: All instantiations for double and float types should be present rg --type cpp 'template void DeepPot::compute<.*>\(' -A 5 | rg 'dspin_'Length of output: 479
source/api_c/include/c_api.h (8)
807-821
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotModelDeviComputeNListSP
looks good. It extends the existingDP_DeepPotModelDeviComputeNList
function by adding aspin
parameter to support spin computations for the dipole charge modifier.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotModelDeviComputeNListSP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 $'DP_DeepPotModelDeviComputeNListSP'
860-874
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotModelDeviComputeNListfSP
looks good. It is the float version counterpart ofDP_DeepPotModelDeviComputeNListSP
and extends the existingDP_DeepPotModelDeviComputeNListf
function by adding aspin
parameter to support spin computations for the dipole charge modifier.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotModelDeviComputeNListfSP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 $'DP_DeepPotModelDeviComputeNListfSP'
922-939
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotModelDeviComputeNList2SP
looks good. It extends the existingDP_DeepPotModelDeviComputeNList2
function by adding aspin
parameter to support spin computations for the dipole charge modifier with multiple frames.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotModelDeviComputeNList2SP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 $'DP_DeepPotModelDeviComputeNList2SP'
233-247
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotComputeNListSP
looks good. It extends the existingDP_DeepPotComputeNList
function by adding aspin
parameter to support spin computations.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
✅ Verification successful
No usages of
DP_DeepPotComputeNListSP
found in the codebase.There are currently no callers of the
DP_DeepPotComputeNListSP
function to verify argument correctness.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotComputeNListSP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 $'DP_DeepPotComputeNListSP'Length of output: 552
492-509
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotComputeNListf2SP
looks good. It is the float version counterpart ofDP_DeepPotComputeNList2SP
and extends the existingDP_DeepPotComputeNListf2
function by adding aspin
parameter to support spin computations for multiple frames.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
987-1004
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotModelDeviComputeNListf2SP
looks good. It is the float version counterpart ofDP_DeepPotModelDeviComputeNList2SP
and extends the existingDP_DeepPotModelDeviComputeNListf2
function by adding aspin
parameter to support spin computations for the dipole charge modifier with multiple frames.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
✅ Verification successful
No callers of
DP_DeepPotModelDeviComputeNListf2SP
found.All usages are correctly implemented or yet to be added.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotModelDeviComputeNListf2SP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 $'DP_DeepPotModelDeviComputeNListf2SP'Length of output: 682
Script:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotModelDeviComputeNListf2SP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 'DP_DeepPotModelDeviComputeNListf2SP'Length of output: 593
287-301
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotComputeNListfSP
looks good. It is the float version counterpart ofDP_DeepPotComputeNListSP
and extends the existingDP_DeepPotComputeNListf
function by adding aspin
parameter to support spin computations.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
✅ Verification successful
Function
DP_DeepPotComputeNListfSP
has no usage in the codebase.
No callers found that need to provide thespin
andforce_mag
arguments.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotComputeNListfSP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 $'DP_DeepPotComputeNListfSP'Length of output: 558
Script:
#!/bin/bash # Description: Correctly verify all function calls to `DP_DeepPotComputeNListfSP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 'DP_DeepPotComputeNListfSP'Length of output: 556
427-444
: Verify the usage of the new function in the codebase.The new function
DP_DeepPotComputeNList2SP
looks good. It extends the existingDP_DeepPotComputeNList2
function by adding aspin
parameter to support spin computations for multiple frames.However, please ensure that all the callers of this function provide the correct arguments, especially the new
spin
andforce_mag
parameters.Run the following script to verify the function usage:
✅ Verification successful
No usages of
DP_DeepPotComputeNList2SP
found in the codebase.Upon verification, there are no existing calls to the new function
DP_DeepPotComputeNList2SP
. Please ensure that this function is integrated correctly where needed.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `DP_DeepPotComputeNList2SP` provide the correct arguments. # Test: Search for the function usage. Expect: Callers provide all required arguments including `spin` and `force_mag`. rg --type c -A 5 $'DP_DeepPotComputeNList2SP'Length of output: 558
source/api_c/src/c_api.cc (3)
1382-1404
: Check Template Instantiations for CompletenessIn
DP_DeepPotComputeNList2SP
, ensure that template instantiations are provided for all required data types (bothdouble
andfloat
) to prevent linker errors.
1674-1696
: Ensure All Data Types are Supported in New FunctionsFor
DP_DeepPotModelDeviComputeNList2SP
, confirm that all necessary data types and template instantiations are correctly implemented.
1266-1284
: Verify Integration of New Spin Support FunctionsThe new function
DP_DeepPotComputeNListSP
adds spin support. Ensure that all relevant parts of the codebase are updated to utilize this new function where appropriate.Run the following script to find and review all usages of
DP_DeepPotComputeNList
:✅ Verification successful
Memory Management Verified for Large Vectors
The vectors
force_mag
,atom_energy
, andatom_virial
are properly managed with the use of theclear()
method across relevant source files, ensuring effective memory deallocation and preventing memory leaks.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for proper resizing and clearing of large vectors. # Search for usage of large vectors without proper memory management. rg --type cpp --context 5 'std::vector<VALUETYPE>' | grep -E 'force_mag|atom_energy|atom_virial'Length of output: 290
Script:
#!/bin/bash # Description: Check for proper memory management of large vectors force_mag, atom_energy, and atom_virial. # Search for memory management operations on the specified vectors. rg --type cpp 'force_mag\.(resize|clear|reserve|shrink_to_fit)|atom_energy\.(resize|clear|reserve|shrink_to_fit)|atom_virial\.(resize|clear|reserve|shrink_to_fit)' -C 5Length of output: 20595
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (12)
source/api_cc/include/DeepPot.h (2)
14-14
: LGTM: Improved class hierarchy through inheritanceThe inheritance structure has been enhanced by deriving from appropriate base classes:
DeepPotBase
fromDeepBaseModelBase
DeepPot
fromDeepBaseModel
DeepPotModelDevi
fromDeepBaseModelDevi
This change promotes better code organization and reuse of common functionality.
Also applies to: 207-207, 529-529
91-91
: Minor: Fix documentation formattingThere are instances where spaces are missing after asterisks in documentation comments (e.g.,
*by
should be* by
). Consider fixing these for better readability.Also applies to: 426-426
source/api_cc/include/DeepBaseModel.h (2)
111-143
: Add 'override' specifier to overridden methods for clarity and safetyThe methods
cutoff()
,numb_types()
,numb_types_spin()
,dim_fparam()
,dim_aparam()
,get_type_map()
, andis_aparam_nall()
in theDeepBaseModel
class override virtual methods fromDeepBaseModelBase
. Adding theoverride
specifier to these methods enhances code clarity and helps detect potential mismatches in method signatures at compile time.Apply this diff to add the
override
specifier:- double cutoff() const; + double cutoff() const override; - int numb_types() const; + int numb_types() const override; - int numb_types_spin() const; + int numb_types_spin() const override; - int dim_fparam() const; + int dim_fparam() const override; - int dim_aparam() const; + int dim_aparam() const override; - void get_type_map(std::string& type_map); + void get_type_map(std::string& type_map) override; - bool is_aparam_nall() const; + bool is_aparam_nall() const override;
279-280
: Clarify the comment for 'dpbases' member variableThe inline comment
// change to shared_ptr to make it inheritable
associated withdpbases
is unclear and could lead to confusion. It's not evident how changing toshared_ptr
relates to inheritance. Consider revising the comment to accurately reflect the purpose of usingshared_ptr
fordpbases
.source/api_cc/include/DeepSpin.h (7)
19-19
: Typo in Constructor DefinitionIn the default constructor for
DeepSpinBase
, there is an unnecessary semicolon{}
at the end. This can be removed for clarity.Apply this diff to remove the unnecessary semicolon:
- DeepSpinBase() {}; + DeepSpinBase() {}
448-448
: Typo in Documentation CommentThere's a typo in the documentation comment for
init
. "contrcutor" should be "constructor."Apply this diff to fix the typo:
- * @brief Initialize the DP model deviation contrcutor. + * @brief Initialize the DP model deviation constructor.
62-67
: Clarify Documentation for Frame and Atomic ParametersThe comments for
fparam
andaparam
contain duplicated or incomplete sentences, which may cause confusion.Consider rephrasing the comments for clarity. For example:
- * nframes x dim_fparam. - * dim_fparam. Then all frames are assumed to be provided with the same - * fparam. + * The array can be of size: + * - `nframes x dim_fparam` for frame-specific parameters. + * - `dim_fparam` if all frames share the same `fparam`.- * nframes x natoms x dim_aparam. - * natoms x dim_aparam. Then all frames are assumed to be provided with the - * same aparam. + * The array can be of size: + * - `nframes x natoms x dim_aparam` for frame-specific atomic parameters. + * - `natoms x dim_aparam` if all frames share the same `aparam`.
483-484
: Remove Duplicated Sentences in CommentThe comment for
aparam
in thecompute_spin
function has duplicated sentences, which might lead to confusion.Apply this diff to remove the duplication:
- * same aparam. dim_aparam. Then all frames and atoms are provided with the - * same aparam. + * same aparam.
528-529
: Remove Duplicated Sentences in CommentSimilar to the previous comment, there's duplicated text in the comment for
aparam
.Apply this diff to remove the duplication:
- * same aparam. dim_aparam. Then all frames and atoms are provided with the - * same aparam. + * same aparam.
221-245
: Consider Reducing Code Duplication in Template FunctionsThe
compute_spin
template functions have multiple overloads with similar signatures and documentation. This duplication can make maintenance harder and increase the potential for inconsistencies.Consider the following refactoring suggestions:
- Use Default Arguments or Variadic Templates: If possible, consolidate the overloads by using default arguments or variadic templates to handle optional parameters.
- Extract Common Functionality: Create a private helper function that contains the shared implementation logic, and have the public functions call this helper with appropriate parameters.
This approach can make the codebase more maintainable and reduce the chance of errors.
Also applies to: 274-303, 332-359, 391-424, 487-501, 532-548
425-426
: Review Access Specifier for Member Variabledp
The member variable
dp
is declared asprotected
in theDeepSpin
class. If there are no derived classes that need direct access todp
, consider changing its access level toprivate
to encapsulate the class's internal implementation details.Apply this diff if appropriate:
-protected: +private: std::shared_ptr<deepmd::DeepSpinBase> dp;source/api_cc/include/DeepPotPT.h (1)
Line range hint
166-205
: Type inconsistency incomputew
method parametersThe overloads of the
computew
method have inconsistent parameter types. Theener
parameter is of typestd::vector<double>&
, while other parameters likeforce
,virial
, andatom_energy
arestd::vector<float>&
. Mixingdouble
andfloat
types may lead to precision loss and unexpected behavior due to implicit type conversions.Consider aligning all parameter types to consistently use either
double
orfloat
. Here's a suggested change to usedouble
types throughout:void computew(std::vector<double>& ener, - std::vector<float>& force, - std::vector<float>& virial, - std::vector<float>& atom_energy, - std::vector<float>& atom_virial, - const std::vector<float>& coord, + std::vector<double>& force, + std::vector<double>& virial, + std::vector<double>& atom_energy, + std::vector<double>& atom_virial, + const std::vector<double>& coord, const std::vector<int>& atype, - const std::vector<float>& box, - const std::vector<float>& fparam, - const std::vector<float>& aparam, + const std::vector<double>& box, + const std::vector<double>& fparam, + const std::vector<double>& aparam, const bool atomic);If using mixed types is intentional for performance reasons, please document the rationale to clarify this design choice.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (6)
source/api_c/include/deepmd.hpp
(26 hunks)source/api_cc/include/DeepBaseModel.h
(1 hunks)source/api_cc/include/DeepPot.h
(13 hunks)source/api_cc/include/DeepPotPT.h
(3 hunks)source/api_cc/include/DeepSpin.h
(1 hunks)source/api_cc/include/DeepSpinPT.h
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- source/api_cc/include/DeepSpinPT.h
🔇 Additional comments (9)
source/api_cc/include/DeepPot.h (2)
581-582
: LGTM: Well-structured template parameter additions
The template parameters for the compute methods are well-designed:
- Type-safe handling of force and virial vectors
- Consistent parameter ordering across overloads
- Clear documentation of parameter usage
Also applies to: 614-617, 649-650, 688-691
525-527
: LGTM: Proper memory management with smart pointers
The use of std::shared_ptr
for managing DeepPot instances is appropriate:
- Ensures proper memory management
- Supports polymorphic behavior
- Thread-safe reference counting
Also applies to: 701-702
source/api_c/include/deepmd.hpp (5)
839-947
: LGTM: Well-designed base class implementation
The DeepBaseModel class provides a solid foundation with:
- Clear separation of concerns
- Proper memory management
- Comprehensive error checking
- Type-safe template implementations
1426-1728
: LGTM: Well-implemented DeepSpin class
The DeepSpin class implementation:
- Follows RAII principles
- Has comprehensive error handling
- Provides well-documented compute_spin methods
- Maintains consistency with the existing codebase
Line range hint 2538-2768
: LGTM: Well-implemented DeepSpinModelDevi class
The DeepSpinModelDevi class:
- Properly extends DeepBaseModelDevi
- Has robust memory management
- Implements comprehensive compute_spin methods
- Maintains consistency with model deviation calculations
Line range hint 98-288
: LGTM: Well-implemented template specializations
The template specializations for spin support:
- Handle both float and double types consistently
- Maintain proper error checking
- Follow established patterns for memory management
1506-1545
: 🛠️ Refactor suggestion
Add input validation for spin vectors
The compute_spin method should validate that the spin vector has the correct dimensions and values before processing.
Add validation at the start of the method:
template <typename VALUETYPE, typename ENERGYVTYPE>
void compute_spin(
ENERGYVTYPE &ener,
std::vector<VALUETYPE> &force,
std::vector<VALUETYPE> &force_mag,
std::vector<VALUETYPE> &virial,
const std::vector<VALUETYPE> &coord,
const std::vector<VALUETYPE> &spin,
const std::vector<int> &atype,
const std::vector<VALUETYPE> &box,
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(),
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) {
unsigned int natoms = atype.size();
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1;
+ // Validate spin vector dimensions
+ if (spin.size() != natoms * 3) {
+ throw deepmd::hpp::deepmd_exception(
+ "Spin vector size must be natoms * 3");
+ }
assert(nframes * natoms * 3 == coord.size());
Likely invalid or redundant comment.
source/api_cc/include/DeepPotPT.h (2)
19-19
: Appropriate addition of virtual destructor
Adding a virtual destructor ensures that derived class destructors are called correctly when deleting objects through base class pointers, preventing potential resource leaks.
Line range hint 77-108
: Well-documented addition of compute
method overload
The new overload of the compute
method incorporates additional parameters (nghost
, lmp_list
, and ago
) with comprehensive documentation for each. This enhances functionality while maintaining clarity.
const std::vector<VALUETYPE> &avg, | ||
const VALUETYPE eps, | ||
const int &stride) { | ||
unsigned ndof = avg.size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove unused variable ndof
The static analysis tool correctly identifies that the variable 'ndof' is declared but never used.
Remove the unused variable:
- unsigned ndof = avg.size();
unsigned nloc = std.size();
Committable suggestion skipped: line range outside the PR's diff.
const std::vector<VALUETYPE>& aparam = std::vector<VALUETYPE>()); | ||
|
||
protected: | ||
std::vector<std::shared_ptr<deepmd::DeepSpin>> dps; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in Member Variable Declaration
In the DeepSpinModelDevi
class, the member variable dps
should be initialized properly, especially if it holds important model data.
Ensure that dps
is correctly initialized in the constructors to prevent potential null pointer dereferences or undefined behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (4)
source/api_c/include/c_api_internal.h (2)
38-48
: Add documentation for the base class and its members.Please add documentation to explain:
- The purpose of this base class
- The meaning and usage of each member variable (dfparam, daparam, aparam_nall)
- Any invariants or constraints that derived classes must maintain
50-60
: Consider extracting common members to a shared base class.Both
DP_DeepBaseModel
andDP_DeepBaseModelDevi
share identical member variables (dfparam, daparam, aparam_nall). Consider extracting these to a common base class to reduce code duplication.+struct DP_ModelBase { + std::string exception; + int dfparam; + int daparam; + bool aparam_nall; +}; -struct DP_DeepBaseModel { +struct DP_DeepBaseModel : DP_ModelBase { DP_DeepBaseModel(); DP_DeepBaseModel(const deepmd::DeepBaseModel& dpbase); virtual ~DP_DeepBaseModel() {}; deepmd::DeepBaseModel dpbase; - std::string exception; - int dfparam; - int daparam; - bool aparam_nall; }; -struct DP_DeepBaseModelDevi { +struct DP_DeepBaseModelDevi : DP_ModelBase { // Similar changes...source/api_c/include/deepmd.hpp (2)
98-156
: LGTM! Consider adding parameter validation for spin vectors.The template functions for spin computations are well-implemented and follow existing patterns. However, consider adding validation for the spin vector dimensions similar to how coord is validated.
Add dimension checks:
template <typename FPTYPE> inline void _DP_DeepPotComputeSP(DP_DeepSpin *dp, const int nframes, const int natom, const FPTYPE *coord, const FPTYPE *spin, const int *atype, const FPTYPE *cell, const FPTYPE *fparam, const FPTYPE *aparam, double *energy, FPTYPE *force, FPTYPE *force_mag, FPTYPE *virial, FPTYPE *atomic_energy, FPTYPE *atomic_virial) { + // Validate spin dimensions + assert(nframes * natom * 3 == spin.size());
Line range hint
2529-2756
: Consider enhancing documentation for DeepSpinModelDevi class.The implementation is solid but would benefit from more detailed documentation explaining:
- The purpose and usage of force_mag in model deviation calculations
- The relationship between spin and magnetic forces
- Expected ranges and units for spin vectors
Add detailed documentation:
/** * @brief Deep Spin Model Deviation class for calculating uncertainties in spin predictions. * * This class extends DeepBaseModelDevi to handle spin-based model deviations including: * - Regular forces (force) * - Magnetic forces (force_mag) representing spin-spin interactions * - Virial calculations * * @note Spin vectors should be normalized 3D vectors representing spin directions */ class DeepSpinModelDevi : public DeepBaseModelDevi {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
source/api_c/include/c_api_internal.h
(2 hunks)source/api_c/include/deepmd.hpp
(26 hunks)source/lmp/pair_base.h
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- source/lmp/pair_base.h
🔇 Additional comments (4)
source/api_c/include/c_api_internal.h (3)
5-5
: LGTM: Required headers added.
The new includes are necessary for the base model and spin functionality.
Also applies to: 7-7
62-88
: LGTM: Well-structured inheritance hierarchy.
The derived classes are correctly implemented with:
- Proper inheritance from base classes
- Consistent pattern across all implementations
- Appropriate member variables for each specific model type
38-88
: Verify initialization and usage of new base classes.
Let's verify the implementation consistency across the codebase.
✅ Verification successful
Let me gather more specific information about the initialization and usage patterns.
The previous results show the files are present, but we need to verify the actual implementation patterns to ensure proper initialization and inheritance. This will help us confirm if the base classes are being used correctly and if the member variables are properly initialized.
Based on the results, I can now provide a final response as we have sufficient evidence about the initialization patterns and inheritance implementation.
Base classes are properly implemented and initialized
The verification shows:
- Base class
DP_DeepBaseModel
correctly initializes all member variables (dfparam
,daparam
,aparam_nall
) in its constructor using the wrappeddeepmd::DeepBaseModel
- Derived classes like
DP_DeepSpin
properly inherit and initialize the base class through constructor chaining - Member variables are consistently used across both TensorFlow and PyTorch implementations
- Proper initialization patterns are present in both the C and C++ APIs
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check initialization and usage of new base classes
# Test 1: Check if dfparam, daparam, and aparam_nall are properly initialized
echo "Checking member variable initialization..."
rg -l "dfparam|daparam|aparam_nall" --type cpp
# Test 2: Check for any direct usage of DeepBaseModel
echo "Checking DeepBaseModel usage..."
rg "DeepBaseModel\s*\w+\s*=" --type cpp
# Test 3: Check implementation files for the new classes
echo "Checking implementation files..."
fd -e cpp -e h "Deep(Base|Spin).*\.(cpp|h)$"
Length of output: 1150
Script:
#!/bin/bash
# Check initialization patterns in implementation files
echo "=== Checking DeepBaseModel initialization ==="
rg -A 5 "DP_DeepBaseModel\s*::\s*DP_DeepBaseModel" source/api_c/
echo "=== Checking member initialization patterns ==="
rg "dfparam\s*=|daparam\s*=|aparam_nall\s*=" source/api_c/ source/api_cc/
echo "=== Checking inheritance implementation ==="
ast-grep --pattern 'class $_ : public DP_DeepBaseModel {
$$$
}'
echo "=== Checking DeepSpin implementation ==="
rg -A 10 "DP_DeepSpin\s*::\s*DP_DeepSpin" source/api_c/
Length of output: 5429
source/api_c/include/deepmd.hpp (1)
839-947
: LGTM! Base class implementation is clean and well-structured.
The DeepBaseModel class provides a solid foundation with proper virtual destructor and clear separation of concerns. The spin-related functionality is well-integrated.
source/api_c/include/deepmd.hpp
Outdated
const std::vector<VALUETYPE> &coord, | ||
const std::vector<VALUETYPE> &spin, | ||
const std::vector<int> &atype, | ||
const std::vector<VALUETYPE> &box, | ||
const int nghost, | ||
const InputNlist &lmp_list, | ||
const int &ago, | ||
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | ||
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | ||
unsigned int natoms = atype.size(); | ||
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | ||
assert(nframes * natoms * 3 == coord.size()); | ||
if (!box.empty()) { | ||
assert(box.size() == nframes * 9); | ||
} | ||
const VALUETYPE *coord_ = &coord[0]; | ||
const VALUETYPE *spin_ = &spin[0]; | ||
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | ||
const int *atype_ = &atype[0]; | ||
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | ||
force.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
virial.resize(static_cast<size_t>(nframes) * 9); | ||
VALUETYPE *force_ = &force[0]; | ||
VALUETYPE *force_mag_ = &force_mag[0]; | ||
VALUETYPE *virial_ = &virial[0]; | ||
std::vector<VALUETYPE> fparam_, aparam_; | ||
validate_fparam_aparam(nframes, (aparam_nall ? natoms : (natoms - nghost)), | ||
fparam, aparam); | ||
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | ||
tile_fparam_aparam(aparam_, nframes, | ||
(aparam_nall ? natoms : (natoms - nghost)) * daparam, | ||
aparam); | ||
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | ||
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | ||
_DP_DeepPotComputeNListSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, | ||
atype_, box_, nghost, lmp_list.nl, ago, | ||
fparam__, aparam__, ener_, force_, | ||
force_mag_, virial_, nullptr, nullptr); | ||
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | ||
}; | ||
|
||
// support spin | ||
template <typename VALUETYPE, typename ENERGYVTYPE> | ||
void compute_spin( | ||
ENERGYVTYPE &ener, | ||
std::vector<VALUETYPE> &force, | ||
std::vector<VALUETYPE> &force_mag, | ||
std::vector<VALUETYPE> &virial, | ||
std::vector<VALUETYPE> &atom_energy, | ||
std::vector<VALUETYPE> &atom_virial, | ||
const std::vector<VALUETYPE> &coord, | ||
const std::vector<VALUETYPE> &spin, | ||
const std::vector<int> &atype, | ||
const std::vector<VALUETYPE> &box, | ||
const int nghost, | ||
const InputNlist &lmp_list, | ||
const int &ago, | ||
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | ||
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | ||
unsigned int natoms = atype.size(); | ||
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | ||
assert(nframes * natoms * 3 == coord.size()); | ||
if (!box.empty()) { | ||
assert(box.size() == nframes * 9); | ||
} | ||
const VALUETYPE *coord_ = &coord[0]; | ||
const VALUETYPE *spin_ = &spin[0]; | ||
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | ||
const int *atype_ = &atype[0]; | ||
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | ||
force.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
virial.resize(static_cast<size_t>(nframes) * 9); | ||
atom_energy.resize(static_cast<size_t>(nframes) * natoms); | ||
atom_virial.resize(static_cast<size_t>(nframes) * natoms * 9); | ||
VALUETYPE *force_ = &force[0]; | ||
VALUETYPE *force_mag_ = &force_mag[0]; | ||
VALUETYPE *virial_ = &virial[0]; | ||
VALUETYPE *atomic_ener_ = &atom_energy[0]; | ||
VALUETYPE *atomic_virial_ = &atom_virial[0]; | ||
std::vector<VALUETYPE> fparam_, aparam_; | ||
validate_fparam_aparam(nframes, (aparam_nall ? natoms : (natoms - nghost)), | ||
fparam, aparam); | ||
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | ||
tile_fparam_aparam(aparam_, nframes, | ||
(aparam_nall ? natoms : (natoms - nghost)) * daparam, | ||
aparam); | ||
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | ||
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | ||
_DP_DeepPotComputeNListSP<VALUETYPE>( | ||
dp, nframes, natoms, coord_, spin_, atype_, box_, nghost, lmp_list.nl, | ||
ago, fparam__, aparam__, ener_, force_, force_mag_, virial_, | ||
atomic_ener_, atomic_virial_); | ||
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | ||
}; | ||
|
||
private: | ||
DP_DeepSpin *dp; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation for spin vectors in compute_spin methods.
While the DeepSpin class implementation is solid, it should validate spin vector dimensions and values before computation to prevent potential runtime errors.
Add validation in compute_spin methods:
template <typename VALUETYPE, typename ENERGYVTYPE>
void compute_spin(...) {
unsigned int natoms = atype.size();
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1;
+ // Validate spin dimensions
+ if (spin.size() != static_cast<size_t>(nframes) * natoms * 3) {
+ throw deepmd::hpp::deepmd_exception(
+ "Spin vector size must be nframes * natoms * 3");
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
class DeepSpin : public DeepBaseModel { | |
public: | |
/** | |
* @brief Get the number of types. | |
* @return The number of types. | |
* @brief DP constructor without initialization. | |
**/ | |
int numb_types() const { | |
assert(dp); | |
return DP_DeepPotGetNumbTypes(dp); | |
}; | |
DeepSpin() : dp(nullptr) {}; | |
~DeepSpin() {}; | |
/** | |
* @brief Get the number of types with spin. | |
* @return The number of types with spin. | |
* @brief DP constructor with initialization. | |
* @param[in] model The name of the frozen model file. | |
* @param[in] gpu_rank The GPU rank. | |
* @param[in] file_content The content of the frozen model file. | |
**/ | |
int numb_types_spin() const { | |
assert(dp); | |
return DP_DeepPotGetNumbTypesSpin(dp); | |
DeepSpin(const std::string &model, | |
const int &gpu_rank = 0, | |
const std::string &file_content = "") | |
: dp(nullptr) { | |
try { | |
init(model, gpu_rank, file_content); | |
} catch (...) { | |
// Clean up and rethrow, as the destructor will not be called | |
if (dp) { | |
DP_DeleteDeepSpin(dp); | |
} | |
throw; | |
} | |
}; | |
/** | |
* @brief Get the type map (element name of the atom types) of this model. | |
* @param[out] type_map The type map of this model. | |
* @brief Initialize the DP. | |
* @param[in] model The name of the frozen model file. | |
* @param[in] gpu_rank The GPU rank. | |
* @param[in] file_content The content of the frozen model file. | |
**/ | |
void get_type_map(std::string &type_map) { | |
const char *type_map_c = DP_DeepPotGetTypeMap(dp); | |
type_map.assign(type_map_c); | |
DP_DeleteChar(type_map_c); | |
void init(const std::string &model, | |
const int &gpu_rank = 0, | |
const std::string &file_content = "") { | |
if (dp) { | |
std::cerr << "WARNING: deepmd-kit should not be initialized twice, do " | |
"nothing at the second call of initializer" | |
<< std::endl; | |
return; | |
} | |
dp = DP_NewDeepSpinWithParam2(model.c_str(), gpu_rank, file_content.c_str(), | |
file_content.size()); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
dfparam = DP_DeepBaseModelGetDimFParam((DP_DeepBaseModel *)dp); | |
daparam = DP_DeepBaseModelGetDimAParam((DP_DeepBaseModel *)dp); | |
aparam_nall = DP_DeepBaseModelIsAParamNAll((DP_DeepBaseModel *)dp); | |
dpbase = (DP_DeepBaseModel *)dp; | |
}; | |
// support spin | |
/** | |
* @brief Print the summary of DeePMD-kit, including the version and the build | |
* information. | |
* @param[in] pre The prefix to each line. | |
*/ | |
void print_summary(const std::string &pre) const { | |
DP_PrintSummary(pre.c_str()); | |
} | |
/** | |
* @brief Get the dimension of the frame parameter. | |
* @return The dimension of the frame parameter. | |
**/ | |
int dim_fparam() const { | |
assert(dp); | |
return dfparam; | |
} | |
/** | |
* @brief Get the dimension of the atomic parameter. | |
* @return The dimension of the atomic parameter. | |
* @brief Evaluate the energy, force, magnetic force and virial by using this | |
*DP with spin input. | |
* @param[out] ener The system energy. | |
* @param[out] force The force on each atom. | |
* @param[out] force_mag The magnetic force on each atom. | |
* @param[out] virial The virial. | |
* @param[in] coord The coordinates of atoms. The array should be of size | |
*nframes x natoms x 3. | |
* @param[in] spin The spins of atoms, [0, 0, 0] if no spin. The array should | |
*be of size nframes x natoms x 3. | |
* @param[in] atype The atom types. The list should contain natoms ints. | |
* @param[in] box The cell of the region. The array should be of size nframes | |
*x 9 (PBC) or empty (no PBC). | |
* @param[in] fparam The frame parameter. The array can be of size : | |
* nframes x dim_fparam. | |
* dim_fparam. Then all frames are assumed to be provided with the same | |
*fparam. | |
* @param[in] aparam The atomic parameter The array can be of size : | |
* nframes x natoms x dim_aparam. | |
* natoms x dim_aparam. Then all frames are assumed to be provided with the | |
*same aparam. | |
* @warning Natoms should not be zero when computing multiple frames. | |
**/ | |
int dim_aparam() const { | |
assert(dp); | |
return daparam; | |
} | |
private: | |
DP_DeepPot *dp; | |
int dfparam; | |
template <typename VALUETYPE, typename ENERGYVTYPE> | |
void compute_spin( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, natoms, fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | |
box_, fparam__, aparam__, ener_, force_, | |
force_mag_, virial_, nullptr, nullptr); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; | |
/** | |
* @brief Evaluate the energy, force, magnetic force, virial, atomic energy, | |
*and atomic virial by using this DP with spin input. | |
* @param[out] ener The system energy. | |
* @param[out] force The force on each atom. | |
* @param[out] force_mag The magnetic force on each atom. | |
* @param[out] virial The virial. | |
* @param[out] atom_energy The atomic energy. | |
* @param[out] atom_virial The atomic virial. | |
* @param[in] coord The coordinates of atoms. The array should be of size | |
*nframes x natoms x 3. | |
* @param[in] spin The spins of atoms, [0, 0, 0] if no spin. The array should | |
*be of size nframes x natoms x 3. | |
* @param[in] atype The atom types. The list should contain natoms ints. | |
* @param[in] box The cell of the region. The array should be of size nframes | |
*x 9 (PBC) or empty (no PBC). | |
* @param[in] fparam The frame parameter. The array can be of size : | |
* nframes x dim_fparam. | |
* dim_fparam. Then all frames are assumed to be provided with the same | |
*fparam. | |
* @param[in] aparam The atomic parameter The array can be of size : | |
* nframes x natoms x dim_aparam. | |
* natoms x dim_aparam. Then all frames are assumed to be provided with the | |
*same aparam. | |
* @warning Natoms should not be zero when computing multiple frames. | |
**/ | |
template <typename VALUETYPE, typename ENERGYVTYPE> | |
void compute_spin( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
std::vector<VALUETYPE> &atom_energy, | |
std::vector<VALUETYPE> &atom_virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
atom_energy.resize(static_cast<size_t>(nframes) * natoms); | |
atom_virial.resize(static_cast<size_t>(nframes) * natoms * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
VALUETYPE *atomic_ener_ = &atom_energy[0]; | |
VALUETYPE *atomic_virial_ = &atom_virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, natoms, fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeSP<VALUETYPE>( | |
dp, nframes, natoms, coord_, spin_, atype_, box_, fparam__, aparam__, | |
ener_, force_, force_mag_, virial_, atomic_ener_, atomic_virial_); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; | |
// support spin | |
template <typename VALUETYPE, typename ENERGYVTYPE> | |
void compute_spin( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const int nghost, | |
const InputNlist &lmp_list, | |
const int &ago, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, (aparam_nall ? natoms : (natoms - nghost)), | |
fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, | |
(aparam_nall ? natoms : (natoms - nghost)) * daparam, | |
aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeNListSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, | |
atype_, box_, nghost, lmp_list.nl, ago, | |
fparam__, aparam__, ener_, force_, | |
force_mag_, virial_, nullptr, nullptr); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; | |
// support spin | |
template <typename VALUETYPE, typename ENERGYVTYPE> | |
void compute_spin( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
std::vector<VALUETYPE> &atom_energy, | |
std::vector<VALUETYPE> &atom_virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const int nghost, | |
const InputNlist &lmp_list, | |
const int &ago, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
atom_energy.resize(static_cast<size_t>(nframes) * natoms); | |
atom_virial.resize(static_cast<size_t>(nframes) * natoms * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
VALUETYPE *atomic_ener_ = &atom_energy[0]; | |
VALUETYPE *atomic_virial_ = &atom_virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, (aparam_nall ? natoms : (natoms - nghost)), | |
fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, | |
(aparam_nall ? natoms : (natoms - nghost)) * daparam, | |
aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeNListSP<VALUETYPE>( | |
dp, nframes, natoms, coord_, spin_, atype_, box_, nghost, lmp_list.nl, | |
ago, fparam__, aparam__, ener_, force_, force_mag_, virial_, | |
atomic_ener_, atomic_virial_); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; | |
private: | |
DP_DeepSpin *dp; | |
}; | |
template <typename VALUETYPE, typename ENERGYVTYPE> | |
void compute_spin( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
// Validate spin dimensions | |
if (spin.size() != static_cast<size_t>(nframes) * natoms * 3) { | |
throw deepmd::hpp::deepmd_exception( | |
"Spin vector size must be nframes * natoms * 3"); | |
} | |
assert(nframes * natoms * 3 == coord.size()); | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, natoms, fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | |
box_, fparam__, aparam__, ener_, force_, | |
force_mag_, virial_, nullptr, nullptr); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (4)
source/api_c/include/deepmd.hpp (4)
98-156
: Add detailed documentation for spin-related template functions.The new template functions for spin computations lack comprehensive documentation. Consider adding:
- Description of spin vector format and requirements
- Units and coordinate system for spin vectors
- Explanation of force_mag output
// support spin +/** + * @brief Template function for computing energies and forces with spin support. + * @param[in] spin The spin vectors for each atom. Array of size nframes x natoms x 3. + * Each vector represents the spin direction and magnitude. + * @param[out] force_mag The magnetic forces on atoms. Array of size nframes x natoms x 3. + */ template <typename FPTYPE> inline void _DP_DeepPotComputeSP(DP_DeepSpin *dp,
220-287
: Consider reordering parameters for consistency.The parameter ordering in
_DP_DeepPotComputeNListSP
placesspin
betweencoord
andatype
, breaking the established pattern where type-related parameters are grouped together. Consider reordering to maintain consistency with other functions.template <typename FPTYPE> inline void _DP_DeepPotComputeNListSP(DP_DeepSpin *dp, const int nframes, const int natom, const FPTYPE *coord, - const FPTYPE *spin, const int *atype, + const FPTYPE *spin, const FPTYPE *cell,
Line range hint
2433-2497
: Consider extracting common reshape logic into helper method.The reshape logic in compute_spin methods is duplicated. Consider extracting it into a helper method to improve maintainability.
+private: + template <typename VALUETYPE> + void reshape_results(std::vector<double> &ener, + std::vector<std::vector<VALUETYPE>> &force, + std::vector<std::vector<VALUETYPE>> &force_mag, + std::vector<std::vector<VALUETYPE>> &virial, + const std::vector<double> &energy_flat, + const std::vector<VALUETYPE> &force_flat, + const std::vector<VALUETYPE> &force_mag_flat, + const std::vector<VALUETYPE> &virial_flat, + const int natoms) { + ener.resize(numb_models); + force.resize(numb_models); + force_mag.resize(numb_models); + virial.resize(numb_models); + for (int i = 0; i < numb_models; i++) { + ener[i] = energy_flat[i]; + force[i].resize(static_cast<size_t>(natoms) * 3); + force_mag[i].resize(static_cast<size_t>(natoms) * 3); + virial[i].resize(9); + for (int j = 0; j < natoms * 3; j++) { + force[i][j] = force_flat[i * natoms * 3 + j]; + force_mag[i][j] = force_mag_flat[i * natoms * 3 + j]; + } + for (int j = 0; j < 9; j++) { + virial[i][j] = virial_flat[i * 9 + j]; + } + } + }
Line range hint
1-97
: Add high-level documentation for spin support functionality.The file would benefit from a comprehensive overview of the spin support functionality at the beginning, including:
- Purpose and scope of spin support
- Relationship between spin and non-spin computations
- Expected data formats and conventions
/* Header-only DeePMD-kit C++ 11 library This header-only library provides a C++ 11 interface to the DeePMD-kit C API. + +Spin Support +------------ +This library provides comprehensive support for spin-based computations through: +- Template functions for computing energies and forces with spin +- DeepSpin class for single model computations +- DeepSpinModelDevi class for model deviation analysis +- Spin vectors are expected in format [sx, sy, sz] for each atom */
source/api_c/include/deepmd.hpp
Outdated
void compute_spin( | ||
ENERGYVTYPE &ener, | ||
std::vector<VALUETYPE> &force, | ||
std::vector<VALUETYPE> &force_mag, | ||
std::vector<VALUETYPE> &virial, | ||
const std::vector<VALUETYPE> &coord, | ||
const std::vector<VALUETYPE> &spin, | ||
const std::vector<int> &atype, | ||
const std::vector<VALUETYPE> &box, | ||
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | ||
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | ||
unsigned int natoms = atype.size(); | ||
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | ||
assert(nframes * natoms * 3 == coord.size()); | ||
if (!box.empty()) { | ||
assert(box.size() == nframes * 9); | ||
} | ||
const VALUETYPE *coord_ = &coord[0]; | ||
const VALUETYPE *spin_ = &spin[0]; | ||
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | ||
const int *atype_ = &atype[0]; | ||
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | ||
force.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
virial.resize(static_cast<size_t>(nframes) * 9); | ||
VALUETYPE *force_ = &force[0]; | ||
VALUETYPE *force_mag_ = &force_mag[0]; | ||
VALUETYPE *virial_ = &virial[0]; | ||
std::vector<VALUETYPE> fparam_, aparam_; | ||
validate_fparam_aparam(nframes, natoms, fparam, aparam); | ||
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | ||
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | ||
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | ||
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | ||
|
||
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | ||
box_, fparam__, aparam__, ener_, force_, | ||
force_mag_, virial_, nullptr, nullptr); | ||
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for spin vector dimensions.
The compute_spin method should validate that the spin vector has the correct dimensions (nframes * natoms * 3) before computation to prevent buffer overflows.
void compute_spin(...) {
unsigned int natoms = atype.size();
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1;
assert(nframes * natoms * 3 == coord.size());
+ assert(nframes * natoms * 3 == spin.size()); // Validate spin dimensions
if (!box.empty()) {
assert(box.size() == nframes * 9);
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
void compute_spin( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, natoms, fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | |
box_, fparam__, aparam__, ener_, force_, | |
force_mag_, virial_, nullptr, nullptr); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; | |
void compute_spin( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
assert(nframes * natoms * 3 == spin.size()); // Validate spin dimensions | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, natoms, fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | |
box_, fparam__, aparam__, ener_, force_, | |
force_mag_, virial_, nullptr, nullptr); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; |
source/api_c/include/deepmd.hpp
Outdated
virtual ~DeepBaseModel() { DP_DeleteDeepBaseModel(dpbase); }; | ||
|
||
/** | ||
* @brief Get the cutoff radius. | ||
* @return The cutoff radius. | ||
**/ | ||
double cutoff() const { | ||
assert(dpbase); | ||
return DP_DeepBaseModelGetCutoff(dpbase); | ||
}; | ||
/** | ||
* @brief Get the number of types. | ||
* @return The number of types. | ||
**/ | ||
int numb_types() const { | ||
assert(dpbase); | ||
return DP_DeepBaseModelGetNumbTypes(dpbase); | ||
}; | ||
/** | ||
* @brief Get the number of types with spin. | ||
* @return The number of types with spin. | ||
**/ | ||
int numb_types_spin() const { | ||
assert(dpbase); | ||
return DP_DeepBaseModelGetNumbTypesSpin(dpbase); | ||
}; | ||
/** | ||
* @brief Get the type map (element name of the atom types) of this model. | ||
* @param[out] type_map The type map of this model. | ||
**/ | ||
void get_type_map(std::string &type_map) { | ||
const char *type_map_c = DP_DeepBaseModelGetTypeMap(dpbase); | ||
type_map.assign(type_map_c); | ||
DP_DeleteChar(type_map_c); | ||
}; | ||
/** | ||
* @brief Print the summary of DeePMD-kit, including the version and the build | ||
* information. | ||
* @param[in] pre The prefix to each line. | ||
*/ | ||
void print_summary(const std::string &pre) const { | ||
DP_PrintSummary(pre.c_str()); | ||
} | ||
/** | ||
* @brief Get the dimension of the frame parameter. | ||
* @return The dimension of the frame parameter. | ||
**/ | ||
int dim_fparam() const { | ||
assert(dpbase); | ||
return dfparam; | ||
} | ||
/** | ||
* @brief Get the dimension of the atomic parameter. | ||
* @return The dimension of the atomic parameter. | ||
**/ | ||
int dim_aparam() const { | ||
assert(dpbase); | ||
return daparam; | ||
} | ||
|
||
protected: | ||
DP_DeepBaseModel *dpbase; | ||
int dfparam; | ||
int daparam; | ||
bool aparam_nall; | ||
template <typename VALUETYPE> | ||
void validate_fparam_aparam(const int &nframes, | ||
const int &nloc, | ||
const std::vector<VALUETYPE> &fparam, | ||
const std::vector<VALUETYPE> &aparam) const { | ||
if (fparam.size() != dfparam && | ||
fparam.size() != static_cast<size_t>(nframes) * dfparam) { | ||
throw deepmd::hpp::deepmd_exception( | ||
"the dim of frame parameter provided is not consistent with what the " | ||
"model uses"); | ||
} | ||
|
||
if (aparam.size() != static_cast<size_t>(daparam) * nloc && | ||
aparam.size() != static_cast<size_t>(nframes) * daparam * nloc) { | ||
throw deepmd::hpp::deepmd_exception( | ||
"the dim of atom parameter provided is not consistent with what the " | ||
"model uses"); | ||
} | ||
} | ||
template <typename VALUETYPE> | ||
void tile_fparam_aparam(std::vector<VALUETYPE> &out_param, | ||
const int &nframes, | ||
const int &dparam, | ||
const std::vector<VALUETYPE> ¶m) const { | ||
if (param.size() == dparam) { | ||
out_param.resize(static_cast<size_t>(nframes) * dparam); | ||
for (int ii = 0; ii < nframes; ++ii) { | ||
std::copy(param.begin(), param.end(), | ||
out_param.begin() + static_cast<std::ptrdiff_t>(ii) * dparam); | ||
} | ||
} else if (param.size() == static_cast<size_t>(nframes) * dparam) { | ||
out_param = param; | ||
} | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add validation for spin-related parameters.
The base model implementation should validate spin-related parameters similar to how it validates fparam and aparam. Consider adding a validation method for spin vectors.
protected:
template <typename VALUETYPE>
+ void validate_spin(const int &nframes,
+ const int &natoms,
+ const std::vector<VALUETYPE> &spin) const {
+ if (spin.size() != static_cast<size_t>(nframes) * natoms * 3) {
+ throw deepmd::hpp::deepmd_exception(
+ "spin vector size does not match frame and atom count");
+ }
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
/** | |
* @brief Deep Potential Base Model. | |
**/ | |
class DeepBaseModel { | |
public: | |
/** | |
* @brief DP Base Model constructor without initialization. | |
**/ | |
DeepBaseModel() : dpbase(nullptr) {}; | |
virtual ~DeepBaseModel() { DP_DeleteDeepBaseModel(dpbase); }; | |
/** | |
* @brief Get the cutoff radius. | |
* @return The cutoff radius. | |
**/ | |
double cutoff() const { | |
assert(dpbase); | |
return DP_DeepBaseModelGetCutoff(dpbase); | |
}; | |
/** | |
* @brief Get the number of types. | |
* @return The number of types. | |
**/ | |
int numb_types() const { | |
assert(dpbase); | |
return DP_DeepBaseModelGetNumbTypes(dpbase); | |
}; | |
/** | |
* @brief Get the number of types with spin. | |
* @return The number of types with spin. | |
**/ | |
int numb_types_spin() const { | |
assert(dpbase); | |
return DP_DeepBaseModelGetNumbTypesSpin(dpbase); | |
}; | |
/** | |
* @brief Get the type map (element name of the atom types) of this model. | |
* @param[out] type_map The type map of this model. | |
**/ | |
void get_type_map(std::string &type_map) { | |
const char *type_map_c = DP_DeepBaseModelGetTypeMap(dpbase); | |
type_map.assign(type_map_c); | |
DP_DeleteChar(type_map_c); | |
}; | |
/** | |
* @brief Print the summary of DeePMD-kit, including the version and the build | |
* information. | |
* @param[in] pre The prefix to each line. | |
*/ | |
void print_summary(const std::string &pre) const { | |
DP_PrintSummary(pre.c_str()); | |
} | |
/** | |
* @brief Get the dimension of the frame parameter. | |
* @return The dimension of the frame parameter. | |
**/ | |
int dim_fparam() const { | |
assert(dpbase); | |
return dfparam; | |
} | |
/** | |
* @brief Get the dimension of the atomic parameter. | |
* @return The dimension of the atomic parameter. | |
**/ | |
int dim_aparam() const { | |
assert(dpbase); | |
return daparam; | |
} | |
protected: | |
DP_DeepBaseModel *dpbase; | |
int dfparam; | |
int daparam; | |
bool aparam_nall; | |
template <typename VALUETYPE> | |
void validate_fparam_aparam(const int &nframes, | |
const int &nloc, | |
const std::vector<VALUETYPE> &fparam, | |
const std::vector<VALUETYPE> &aparam) const { | |
if (fparam.size() != dfparam && | |
fparam.size() != static_cast<size_t>(nframes) * dfparam) { | |
throw deepmd::hpp::deepmd_exception( | |
"the dim of frame parameter provided is not consistent with what the " | |
"model uses"); | |
} | |
if (aparam.size() != static_cast<size_t>(daparam) * nloc && | |
aparam.size() != static_cast<size_t>(nframes) * daparam * nloc) { | |
throw deepmd::hpp::deepmd_exception( | |
"the dim of atom parameter provided is not consistent with what the " | |
"model uses"); | |
} | |
} | |
template <typename VALUETYPE> | |
void tile_fparam_aparam(std::vector<VALUETYPE> &out_param, | |
const int &nframes, | |
const int &dparam, | |
const std::vector<VALUETYPE> ¶m) const { | |
if (param.size() == dparam) { | |
out_param.resize(static_cast<size_t>(nframes) * dparam); | |
for (int ii = 0; ii < nframes; ++ii) { | |
std::copy(param.begin(), param.end(), | |
out_param.begin() + static_cast<std::ptrdiff_t>(ii) * dparam); | |
} | |
} else if (param.size() == static_cast<size_t>(nframes) * dparam) { | |
out_param = param; | |
} | |
} | |
}; | |
/** | |
* @brief Deep Potential Base Model. | |
**/ | |
class DeepBaseModel { | |
public: | |
/** | |
* @brief DP Base Model constructor without initialization. | |
**/ | |
DeepBaseModel() : dpbase(nullptr) {}; | |
virtual ~DeepBaseModel() { DP_DeleteDeepBaseModel(dpbase); }; | |
/** | |
* @brief Get the cutoff radius. | |
* @return The cutoff radius. | |
**/ | |
double cutoff() const { | |
assert(dpbase); | |
return DP_DeepBaseModelGetCutoff(dpbase); | |
}; | |
/** | |
* @brief Get the number of types. | |
* @return The number of types. | |
**/ | |
int numb_types() const { | |
assert(dpbase); | |
return DP_DeepBaseModelGetNumbTypes(dpbase); | |
}; | |
/** | |
* @brief Get the number of types with spin. | |
* @return The number of types with spin. | |
**/ | |
int numb_types_spin() const { | |
assert(dpbase); | |
return DP_DeepBaseModelGetNumbTypesSpin(dpbase); | |
}; | |
/** | |
* @brief Get the type map (element name of the atom types) of this model. | |
* @param[out] type_map The type map of this model. | |
**/ | |
void get_type_map(std::string &type_map) { | |
const char *type_map_c = DP_DeepBaseModelGetTypeMap(dpbase); | |
type_map.assign(type_map_c); | |
DP_DeleteChar(type_map_c); | |
}; | |
/** | |
* @brief Print the summary of DeePMD-kit, including the version and the build | |
* information. | |
* @param[in] pre The prefix to each line. | |
*/ | |
void print_summary(const std::string &pre) const { | |
DP_PrintSummary(pre.c_str()); | |
} | |
/** | |
* @brief Get the dimension of the frame parameter. | |
* @return The dimension of the frame parameter. | |
**/ | |
int dim_fparam() const { | |
assert(dpbase); | |
return dfparam; | |
} | |
/** | |
* @brief Get the dimension of the atomic parameter. | |
* @return The dimension of the atomic parameter. | |
**/ | |
int dim_aparam() const { | |
assert(dpbase); | |
return daparam; | |
} | |
protected: | |
DP_DeepBaseModel *dpbase; | |
int dfparam; | |
int daparam; | |
bool aparam_nall; | |
template <typename VALUETYPE> | |
void validate_fparam_aparam(const int &nframes, | |
const int &nloc, | |
const std::vector<VALUETYPE> &fparam, | |
const std::vector<VALUETYPE> &aparam) const { | |
if (fparam.size() != dfparam && | |
fparam.size() != static_cast<size_t>(nframes) * dfparam) { | |
throw deepmd::hpp::deepmd_exception( | |
"the dim of frame parameter provided is not consistent with what the " | |
"model uses"); | |
} | |
if (aparam.size() != static_cast<size_t>(daparam) * nloc && | |
aparam.size() != static_cast<size_t>(nframes) * daparam * nloc) { | |
throw deepmd::hpp::deepmd_exception( | |
"the dim of atom parameter provided is not consistent with what the " | |
"model uses"); | |
} | |
} | |
template <typename VALUETYPE> | |
void validate_spin(const int &nframes, | |
const int &natoms, | |
const std::vector<VALUETYPE> &spin) const { | |
if (spin.size() != static_cast<size_t>(nframes) * natoms * 3) { | |
throw deepmd::hpp::deepmd_exception( | |
"spin vector size does not match frame and atom count"); | |
} | |
} | |
template <typename VALUETYPE> | |
void tile_fparam_aparam(std::vector<VALUETYPE> &out_param, | |
const int &nframes, | |
const int &dparam, | |
const std::vector<VALUETYPE> ¶m) const { | |
if (param.size() == dparam) { | |
out_param.resize(static_cast<size_t>(nframes) * dparam); | |
for (int ii = 0; ii < nframes; ++ii) { | |
std::copy(param.begin(), param.end(), | |
out_param.begin() + static_cast<std::ptrdiff_t>(ii) * dparam); | |
} | |
} else if (param.size() == static_cast<size_t>(nframes) * dparam) { | |
out_param = param; | |
} | |
} | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Outside diff range and nitpick comments (8)
source/api_cc/tests/test_deeppot_tf_spin.cc (1)
42-56
: Consider using a configurable test data path.The hardcoded path "../../tests/infer/deepspin_nlist.pbtxt" makes the test less maintainable and portable. Consider using an environment variable or test configuration file.
Also, remove the extra semicolon after the method definition:
- }; + }source/api_cc/include/DeepSpin.h (2)
43-44
: Fix documentation formatting.There are multiple instances where the documentation has formatting issues with missing spaces after asterisks, causing text to run together. For example:
*and
should be* and
*DP
should be* DP
Also applies to: 100-101, 302-303, 356-357, 452-453, 494-495
220-231
: Consider adding type constraints to templates.The template parameter
VALUETYPE
is used without constraints. Consider adding type traits to ensure only floating-point types are accepted:-template <typename VALUETYPE> +template <typename VALUETYPE, + typename = std::enable_if_t<std::is_floating_point_v<VALUETYPE>>>Also applies to: 271-285, 327-340, 384-400, 478-491, 522-537
source/api_cc/src/DeepSpin.cc (2)
30-66
: Enhance error handling in initializationThe initialization code should provide more detailed error messages and ensure proper cleanup in case of failures.
Consider these improvements:
void DeepSpin::init(const std::string& model, const int& gpu_rank, const std::string& file_content) { if (inited) { - std::cerr << "WARNING: deepmd-kit should not be initialized twice, do " - "nothing at the second call of initializer" - << std::endl; + std::cerr << "WARNING: DeepSpin instance has already been initialized. " + "Skipping reinitialization attempt for model: " << model + << std::endl; return; } + try { DPBackend backend; if (model.length() >= 4 && model.substr(model.length() - 4) == ".pth") { backend = deepmd::DPBackend::PyTorch; } else if (model.length() >= 3 && model.substr(model.length() - 3) == ".pb") { backend = deepmd::DPBackend::TensorFlow; } else { - throw deepmd::deepmd_exception("Unsupported model file format"); + throw deepmd::deepmd_exception("Unsupported model file format: " + model); } // ... rest of the initialization code ... inited = true; dpbase = dp; + } catch (const std::exception& e) { + dp.reset(); + dpbase.reset(); + throw; + } }
70-87
: Consider vector pre-allocation for better performanceThe compute method creates temporary vectors that could benefit from pre-allocation to reduce memory allocations.
Consider pre-allocating vectors:
template <typename VALUETYPE> void DeepSpin::compute(ENERGYTYPE& dener, std::vector<VALUETYPE>& dforce_, std::vector<VALUETYPE>& dforce_mag_, std::vector<VALUETYPE>& dvirial, const std::vector<VALUETYPE>& dcoord_, const std::vector<VALUETYPE>& dspin_, const std::vector<int>& datype_, const std::vector<VALUETYPE>& dbox, const std::vector<VALUETYPE>& fparam_, const std::vector<VALUETYPE>& aparam_) { - std::vector<ENERGYTYPE> dener_; - std::vector<VALUETYPE> datom_energy_, datom_virial_; + static thread_local std::vector<ENERGYTYPE> dener_(1); + static thread_local std::vector<VALUETYPE> datom_energy_, datom_virial_; dp->computew(dener_, dforce_, dforce_mag_, dvirial, datom_energy_, datom_virial_, dcoord_, dspin_, datype_, dbox, fparam_, aparam_, false); dener = dener_[0]; }source/api_c/include/deepmd.hpp (1)
98-156
: Consider reordering parameters for consistencyThe
spin
parameter is placed betweencoord
andatype
, breaking the pattern where type-related parameters are grouped together. Consider reordering parameters to maintain consistency with other functions:- const FPTYPE *coord, - const FPTYPE *spin, - const int *atype, + const FPTYPE *coord, + const int *atype, + const FPTYPE *spin,Consider adding documentation comments explaining parameters and usage.
source/api_cc/tests/test_deeppot_dpa_pt_spin.cc (2)
93-105
: Clean up commented-out codeThere are several sections of commented-out code related to
expected_v
andexpected_tot_v
. If this code is no longer needed, please remove it to enhance code readability. If it's still relevant, consider uncommenting and updating it accordingly.
113-126
: Simplify test methods by accessing class members directlyIn the test methods, class data members are assigned to local references (e.g.,
const std::vector<VALUETYPE>& coord = this->coord;
). This introduces repetitive code. Consider accessing class members directly usingthis->coord
to reduce code duplication and improve readability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
source/api_c/include/deepmd.hpp
(21 hunks)source/api_c/src/c_api.cc
(15 hunks)source/api_cc/include/DeepSpin.h
(1 hunks)source/api_cc/src/DeepSpin.cc
(1 hunks)source/api_cc/tests/test_deeppot_dpa_pt_spin.cc
(1 hunks)source/api_cc/tests/test_deeppot_tf_spin.cc
(1 hunks)source/lmp/pair_deepspin.cpp
(1 hunks)
🔇 Additional comments (12)
source/api_cc/tests/test_deeppot_tf_spin.cc (1)
1-15
: LGTM! Well-organized includes and proper license header.
The file structure follows best practices with a clear organization of system headers, standard library headers, and project-specific headers.
source/api_cc/include/DeepSpin.h (2)
14-163
: LGTM! Well-structured class hierarchy.
The inheritance structure follows the established pattern in the codebase, with clear separation of concerns between base interfaces and implementations.
417-419
: Ensure proper initialization of smart pointer members.
Both dp
and dps
members are using appropriate smart pointers, but their initialization in constructors should be verified to prevent potential null pointer dereferences.
Also applies to: 539-541
source/api_c/include/deepmd.hpp (2)
870-873
: LGTM!
The numb_types_spin() method is well-integrated and properly documented.
Line range hint 2368-2595
: LGTM!
The DeepSpinModelDevi class implementation is well-structured, properly documented, and correctly handles memory management.
source/api_cc/tests/test_deeppot_dpa_pt_spin.cc (1)
251-268
:
Update the test model path to ensure portability
The initialization path for the test model file may cause issues in different build environments:
dp.init("../../tests/infer/deeppot_dpa_spin.pth");
Consider updating the path to ensure it correctly references the model file relative to the test file's location. This will enhance portability and prevent file not found errors.
The issue was previously noted but appears to persist.
source/lmp/pair_deepspin.cpp (6)
380-808
: Consider refactoring the compute
method for better maintainability
The compute
method spans over 400 lines, which can make it difficult to read, maintain, and debug. Breaking it down into smaller, well-named helper functions would improve code clarity and maintainability.
419-422
: Replace std::cout
with LAMMPS error handling
Error messages are printed using std::cout
, which is not the recommended practice in LAMMPS. Use error->all(FLERR, "...");
to ensure consistent and proper error reporting.
275-279
: Add validation for spin_norm
values to prevent division by zero
The spin_norm
values should be validated to ensure they are non-zero, preventing potential division by zero errors later in the code.
783-789
: Add validation for spin magnitude in force computation
In the force computation, dividing by sp[ii][3]
without checking if it's zero could cause runtime errors. Add a check to ensure sp[ii][3]
is not zero before performing the division.
817-820
: Replace std::cout
with LAMMPS error handling
Similar to earlier instances, std::cout
is used for error messages. Replace it with error->all(FLERR, "...");
to align with LAMMPS error handling conventions.
782-782
: Define physical constants at class level for better reusability
The Planck constant hbar
is defined locally within the method. Consider defining it as a class-level constant for better maintainability and reusability across the class.
template <class VALUETYPE> | ||
class TestInferDeepSpin : public ::testing::Test { | ||
protected: | ||
std::vector<VALUETYPE> coord = {12.83, 2.56, 2.18, 12.09, 2.87, 2.74, | ||
3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; | ||
std::vector<VALUETYPE> spin = {0., 0., 1.2737, 0., 0., 1.2737, | ||
0., 0., 0., 0., 0., 0.}; | ||
std::vector<int> atype = {0, 0, 1, 1}; | ||
std::vector<VALUETYPE> box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; | ||
std::vector<VALUETYPE> expected_e = {-7.314365618560289, -7.313531316181837, | ||
-2.8980532245013997, -2.897373810282277}; | ||
std::vector<VALUETYPE> expected_f = { | ||
0.0275132293555514, -0.0112057401883111, -0.0212278132621243, | ||
-0.0229926640905535, 0.0114378553363334, 0.019670014885563, | ||
0.0086502856137601, 0.0088926283192558, -0.0127014507822769, | ||
-0.013170850878758, -0.009124743467278, 0.0142592491588383}; | ||
std::vector<VALUETYPE> expected_fm = { | ||
0.0066245455049449, -0.0023055088004378, 0.0294608578045521, | ||
-0.0041979452385972, 0.0025775020220167, 0.0316295420619988, | ||
0.0000000000000000, 0.00000000000000000, 0.00000000000000000, | ||
0.0000000000000000, 0.00000000000000000, 0.00000000000000000}; | ||
int natoms; | ||
double expected_tot_e; | ||
|
||
deepmd::DeepSpin dp; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation for test data consistency.
The test data should be validated to ensure consistent dimensions:
- coord.size() should be natoms * 3
- spin.size() should be natoms * 3
- box.size() should be 9
Add these validations in the SetUp method:
natoms = expected_e.size();
+ ASSERT_EQ(coord.size(), natoms * 3) << "Coordinates size mismatch";
+ ASSERT_EQ(spin.size(), natoms * 3) << "Spin size mismatch";
+ ASSERT_EQ(atype.size(), natoms) << "Atom types size mismatch";
+ ASSERT_EQ(box.size(), 9) << "Box size should be 9";
Committable suggestion skipped: line range outside the PR's diff.
TYPED_TEST(TestInferDeepSpin, cpu_build_nlist_atomic) { | ||
using VALUETYPE = TypeParam; | ||
const std::vector<VALUETYPE>& coord = this->coord; | ||
const std::vector<VALUETYPE>& spin = this->spin; | ||
std::vector<int>& atype = this->atype; | ||
std::vector<VALUETYPE>& box = this->box; | ||
std::vector<VALUETYPE>& expected_e = this->expected_e; | ||
std::vector<VALUETYPE>& expected_f = this->expected_f; | ||
std::vector<VALUETYPE>& expected_fm = this->expected_fm; | ||
int& natoms = this->natoms; | ||
double& expected_tot_e = this->expected_tot_e; | ||
deepmd::DeepSpin& dp = this->dp; | ||
double ener; | ||
std::vector<VALUETYPE> force, force_mag, virial, atom_ener, atom_vir; | ||
dp.compute(ener, force, force_mag, virial, atom_ener, atom_vir, coord, spin, | ||
atype, box); | ||
EXPECT_EQ(force.size(), natoms * 3); | ||
EXPECT_EQ(force_mag.size(), natoms * 3); | ||
// EXPECT_EQ(atom_ener.size(), natoms); | ||
EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); | ||
for (int ii = 0; ii < natoms * 3; ++ii) { | ||
EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); | ||
EXPECT_LT(fabs(force_mag[ii] - expected_fm[ii]), EPSILON); | ||
} | ||
for (int ii = 0; ii < natoms; ++ii) { | ||
EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance test coverage and structure.
The test case needs the following improvements:
- Uncomment the atom_ener size check (as noted in previous reviews)
- Add validation for atom_vir dimensions and values
- Structure the test into logical sections
Apply this diff to improve the test:
dp.compute(ener, force, force_mag, virial, atom_ener, atom_vir, coord, spin,
atype, box);
+ // Size validations
EXPECT_EQ(force.size(), natoms * 3);
EXPECT_EQ(force_mag.size(), natoms * 3);
- // EXPECT_EQ(atom_ener.size(), natoms);
+ EXPECT_EQ(atom_ener.size(), natoms);
+ EXPECT_EQ(atom_vir.size(), natoms * 9) << "Atomic virial tensor size mismatch";
+ // Energy validation
EXPECT_LT(fabs(ener - expected_tot_e), EPSILON);
+ for (int ii = 0; ii < natoms; ++ii) {
+ EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON);
+ }
+ // Force validation
for (int ii = 0; ii < natoms * 3; ++ii) {
EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON);
EXPECT_LT(fabs(force_mag[ii] - expected_fm[ii]), EPSILON);
}
- for (int ii = 0; ii < natoms; ++ii) {
- EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON);
+ // Virial validation
+ for (int ii = 0; ii < natoms * 9; ++ii) {
+ EXPECT_LT(fabs(atom_vir[ii]), EPSILON) << "Atomic virial component mismatch";
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
TYPED_TEST(TestInferDeepSpin, cpu_build_nlist_atomic) { | |
using VALUETYPE = TypeParam; | |
const std::vector<VALUETYPE>& coord = this->coord; | |
const std::vector<VALUETYPE>& spin = this->spin; | |
std::vector<int>& atype = this->atype; | |
std::vector<VALUETYPE>& box = this->box; | |
std::vector<VALUETYPE>& expected_e = this->expected_e; | |
std::vector<VALUETYPE>& expected_f = this->expected_f; | |
std::vector<VALUETYPE>& expected_fm = this->expected_fm; | |
int& natoms = this->natoms; | |
double& expected_tot_e = this->expected_tot_e; | |
deepmd::DeepSpin& dp = this->dp; | |
double ener; | |
std::vector<VALUETYPE> force, force_mag, virial, atom_ener, atom_vir; | |
dp.compute(ener, force, force_mag, virial, atom_ener, atom_vir, coord, spin, | |
atype, box); | |
EXPECT_EQ(force.size(), natoms * 3); | |
EXPECT_EQ(force_mag.size(), natoms * 3); | |
// EXPECT_EQ(atom_ener.size(), natoms); | |
EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); | |
for (int ii = 0; ii < natoms * 3; ++ii) { | |
EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); | |
EXPECT_LT(fabs(force_mag[ii] - expected_fm[ii]), EPSILON); | |
} | |
for (int ii = 0; ii < natoms; ++ii) { | |
EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); | |
} | |
} | |
TYPED_TEST(TestInferDeepSpin, cpu_build_nlist_atomic) { | |
using VALUETYPE = TypeParam; | |
const std::vector<VALUETYPE>& coord = this->coord; | |
const std::vector<VALUETYPE>& spin = this->spin; | |
std::vector<int>& atype = this->atype; | |
std::vector<VALUETYPE>& box = this->box; | |
std::vector<VALUETYPE>& expected_e = this->expected_e; | |
std::vector<VALUETYPE>& expected_f = this->expected_f; | |
std::vector<VALUETYPE>& expected_fm = this->expected_fm; | |
int& natoms = this->natoms; | |
double& expected_tot_e = this->expected_tot_e; | |
deepmd::DeepSpin& dp = this->dp; | |
double ener; | |
std::vector<VALUETYPE> force, force_mag, virial, atom_ener, atom_vir; | |
dp.compute(ener, force, force_mag, virial, atom_ener, atom_vir, coord, spin, | |
atype, box); | |
// Size validations | |
EXPECT_EQ(force.size(), natoms * 3); | |
EXPECT_EQ(force_mag.size(), natoms * 3); | |
EXPECT_EQ(atom_ener.size(), natoms); | |
EXPECT_EQ(atom_vir.size(), natoms * 9) << "Atomic virial tensor size mismatch"; | |
// Energy validation | |
EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); | |
for (int ii = 0; ii < natoms; ++ii) { | |
EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); | |
} | |
// Force validation | |
for (int ii = 0; ii < natoms * 3; ++ii) { | |
EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); | |
EXPECT_LT(fabs(force_mag[ii] - expected_fm[ii]), EPSILON); | |
} | |
// Virial validation | |
for (int ii = 0; ii < natoms * 9; ++ii) { | |
EXPECT_LT(fabs(atom_vir[ii]), EPSILON) << "Atomic virial component mismatch"; | |
} | |
} |
template <typename VALUETYPE> | ||
void compute(ENERGYTYPE& ener, | ||
std::vector<VALUETYPE>& force, | ||
std::vector<VALUETYPE>& force_mag, | ||
std::vector<VALUETYPE>& virial, | ||
const std::vector<VALUETYPE>& coord, | ||
const std::vector<VALUETYPE>& spin, | ||
const std::vector<int>& atype, | ||
const std::vector<VALUETYPE>& box, | ||
const std::vector<VALUETYPE>& fparam = std::vector<VALUETYPE>(), | ||
const std::vector<VALUETYPE>& aparam = std::vector<VALUETYPE>()); | ||
template <typename VALUETYPE> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation for array dimensions.
The compute methods accept various input arrays but lack validation of their dimensions. Consider adding checks to ensure:
- coord array size matches natoms * 3
- spin array size matches natoms * 3
- box array size matches 9
- fparam and aparam dimensions match their expected sizes
Example validation for one of the compute methods:
template <typename VALUETYPE>
void compute(...) {
const size_t natoms = atype.size();
if (coord.size() != natoms * 3) {
throw std::invalid_argument("coord size does not match 3 * natoms");
}
if (spin.size() != natoms * 3) {
throw std::invalid_argument("spin size does not match 3 * natoms");
}
if (box.size() != 9) {
throw std::invalid_argument("box size does not match 9");
}
// ... rest of the implementation
}
Also applies to: 271-285, 327-340, 384-400, 478-491, 522-537
template <typename VALUETYPE> | ||
void DeepSpin::compute(ENERGYTYPE& dener, | ||
std::vector<VALUETYPE>& dforce_, | ||
std::vector<VALUETYPE>& dforce_mag_, | ||
std::vector<VALUETYPE>& dvirial, | ||
std::vector<VALUETYPE>& datom_energy_, | ||
std::vector<VALUETYPE>& datom_virial_, | ||
const std::vector<VALUETYPE>& dcoord_, | ||
const std::vector<VALUETYPE>& dspin_, | ||
const std::vector<int>& datype_, | ||
const std::vector<VALUETYPE>& dbox, | ||
const int nghost, | ||
const InputNlist& lmp_list, | ||
const int& ago, | ||
const std::vector<VALUETYPE>& fparam_, | ||
const std::vector<VALUETYPE>& aparam__) { | ||
std::vector<ENERGYTYPE> dener_; | ||
dp->computew(dener_, dforce_, dforce_mag_, dvirial, datom_energy_, | ||
datom_virial_, dcoord_, dspin_, datype_, dbox, nghost, lmp_list, | ||
ago, fparam_, aparam__, true); | ||
dener = dener_[0]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation for neighbor list parameters
The compute method with neighbor lists should validate its input parameters before processing.
Add validation checks:
template <typename VALUETYPE>
void DeepSpin::compute(ENERGYTYPE& dener,
std::vector<VALUETYPE>& dforce_,
std::vector<VALUETYPE>& dforce_mag_,
std::vector<VALUETYPE>& dvirial,
std::vector<VALUETYPE>& datom_energy_,
std::vector<VALUETYPE>& datom_virial_,
const std::vector<VALUETYPE>& dcoord_,
const std::vector<VALUETYPE>& dspin_,
const std::vector<int>& datype_,
const std::vector<VALUETYPE>& dbox,
const int nghost,
const InputNlist& lmp_list,
const int& ago,
const std::vector<VALUETYPE>& fparam_,
const std::vector<VALUETYPE>& aparam__) {
+ if (nghost < 0) {
+ throw deepmd::deepmd_exception("Invalid nghost value: " + std::to_string(nghost));
+ }
+ if (ago < 0) {
+ throw deepmd::deepmd_exception("Invalid ago value: " + std::to_string(ago));
+ }
std::vector<ENERGYTYPE> dener_;
dp->computew(dener_, dforce_, dforce_mag_, dvirial, datom_energy_,
datom_virial_, dcoord_, dspin_, datype_, dbox, nghost, lmp_list,
ago, fparam_, aparam__, true);
dener = dener_[0];
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
template <typename VALUETYPE> | |
void DeepSpin::compute(ENERGYTYPE& dener, | |
std::vector<VALUETYPE>& dforce_, | |
std::vector<VALUETYPE>& dforce_mag_, | |
std::vector<VALUETYPE>& dvirial, | |
std::vector<VALUETYPE>& datom_energy_, | |
std::vector<VALUETYPE>& datom_virial_, | |
const std::vector<VALUETYPE>& dcoord_, | |
const std::vector<VALUETYPE>& dspin_, | |
const std::vector<int>& datype_, | |
const std::vector<VALUETYPE>& dbox, | |
const int nghost, | |
const InputNlist& lmp_list, | |
const int& ago, | |
const std::vector<VALUETYPE>& fparam_, | |
const std::vector<VALUETYPE>& aparam__) { | |
std::vector<ENERGYTYPE> dener_; | |
dp->computew(dener_, dforce_, dforce_mag_, dvirial, datom_energy_, | |
datom_virial_, dcoord_, dspin_, datype_, dbox, nghost, lmp_list, | |
ago, fparam_, aparam__, true); | |
dener = dener_[0]; | |
} | |
template <typename VALUETYPE> | |
void DeepSpin::compute(ENERGYTYPE& dener, | |
std::vector<VALUETYPE>& dforce_, | |
std::vector<VALUETYPE>& dforce_mag_, | |
std::vector<VALUETYPE>& dvirial, | |
std::vector<VALUETYPE>& datom_energy_, | |
std::vector<VALUETYPE>& datom_virial_, | |
const std::vector<VALUETYPE>& dcoord_, | |
const std::vector<VALUETYPE>& dspin_, | |
const std::vector<int>& datype_, | |
const std::vector<VALUETYPE>& dbox, | |
const int nghost, | |
const InputNlist& lmp_list, | |
const int& ago, | |
const std::vector<VALUETYPE>& fparam_, | |
const std::vector<VALUETYPE>& aparam__) { | |
if (nghost < 0) { | |
throw deepmd::deepmd_exception("Invalid nghost value: " + std::to_string(nghost)); | |
} | |
if (ago < 0) { | |
throw deepmd::deepmd_exception("Invalid ago value: " + std::to_string(ago)); | |
} | |
std::vector<ENERGYTYPE> dener_; | |
dp->computew(dener_, dforce_, dforce_mag_, dvirial, datom_energy_, | |
datom_virial_, dcoord_, dspin_, datype_, dbox, nghost, lmp_list, | |
ago, fparam_, aparam__, true); | |
dener = dener_[0]; | |
} |
// support spin | ||
// nlist, no atomic | ||
template <typename VALUETYPE> | ||
void DeepSpinModelDevi::compute( | ||
std::vector<ENERGYTYPE>& all_energy, | ||
std::vector<std::vector<VALUETYPE>>& all_force, | ||
std::vector<std::vector<VALUETYPE>>& all_force_mag, | ||
std::vector<std::vector<VALUETYPE>>& all_virial, | ||
const std::vector<VALUETYPE>& dcoord_, | ||
const std::vector<VALUETYPE>& dspin_, | ||
const std::vector<int>& datype_, | ||
const std::vector<VALUETYPE>& dbox, | ||
const int nghost, | ||
const InputNlist& lmp_list, | ||
const int& ago, | ||
const std::vector<VALUETYPE>& fparam, | ||
const std::vector<VALUETYPE>& aparam_) { | ||
if (numb_models == 0) { | ||
return; | ||
} | ||
all_energy.resize(numb_models); | ||
all_force.resize(numb_models); | ||
all_force_mag.resize(numb_models); | ||
all_virial.resize(numb_models); | ||
for (unsigned ii = 0; ii < numb_models; ++ii) { | ||
dps[ii]->compute(all_energy[ii], all_force[ii], all_force_mag[ii], | ||
all_virial[ii], dcoord_, dspin_, datype_, dbox, nghost, | ||
lmp_list, ago, fparam, aparam_); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optimize model computation using parallel processing
The compute method sequentially processes multiple models, which could be parallelized for better performance.
Consider using parallel execution:
+#include <execution>
+#include <algorithm>
template <typename VALUETYPE>
void DeepSpinModelDevi::compute(
std::vector<ENERGYTYPE>& all_energy,
std::vector<std::vector<VALUETYPE>>& all_force,
std::vector<std::vector<VALUETYPE>>& all_force_mag,
std::vector<std::vector<VALUETYPE>>& all_virial,
const std::vector<VALUETYPE>& dcoord_,
const std::vector<VALUETYPE>& dspin_,
const std::vector<int>& datype_,
const std::vector<VALUETYPE>& dbox,
const int nghost,
const InputNlist& lmp_list,
const int& ago,
const std::vector<VALUETYPE>& fparam,
const std::vector<VALUETYPE>& aparam_) {
if (numb_models == 0) {
return;
}
all_energy.resize(numb_models);
all_force.resize(numb_models);
all_force_mag.resize(numb_models);
all_virial.resize(numb_models);
- for (unsigned ii = 0; ii < numb_models; ++ii) {
- dps[ii]->compute(all_energy[ii], all_force[ii], all_force_mag[ii],
- all_virial[ii], dcoord_, dspin_, datype_, dbox, nghost,
- lmp_list, ago, fparam, aparam_);
- }
+ std::vector<unsigned> indices(numb_models);
+ std::iota(indices.begin(), indices.end(), 0);
+ std::for_each(std::execution::par_unseq, indices.begin(), indices.end(),
+ [&](unsigned ii) {
+ dps[ii]->compute(all_energy[ii], all_force[ii], all_force_mag[ii],
+ all_virial[ii], dcoord_, dspin_, datype_, dbox, nghost,
+ lmp_list, ago, fparam, aparam_);
+ });
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// support spin | |
// nlist, no atomic | |
template <typename VALUETYPE> | |
void DeepSpinModelDevi::compute( | |
std::vector<ENERGYTYPE>& all_energy, | |
std::vector<std::vector<VALUETYPE>>& all_force, | |
std::vector<std::vector<VALUETYPE>>& all_force_mag, | |
std::vector<std::vector<VALUETYPE>>& all_virial, | |
const std::vector<VALUETYPE>& dcoord_, | |
const std::vector<VALUETYPE>& dspin_, | |
const std::vector<int>& datype_, | |
const std::vector<VALUETYPE>& dbox, | |
const int nghost, | |
const InputNlist& lmp_list, | |
const int& ago, | |
const std::vector<VALUETYPE>& fparam, | |
const std::vector<VALUETYPE>& aparam_) { | |
if (numb_models == 0) { | |
return; | |
} | |
all_energy.resize(numb_models); | |
all_force.resize(numb_models); | |
all_force_mag.resize(numb_models); | |
all_virial.resize(numb_models); | |
for (unsigned ii = 0; ii < numb_models; ++ii) { | |
dps[ii]->compute(all_energy[ii], all_force[ii], all_force_mag[ii], | |
all_virial[ii], dcoord_, dspin_, datype_, dbox, nghost, | |
lmp_list, ago, fparam, aparam_); | |
} | |
} | |
// support spin | |
// nlist, no atomic | |
#include <execution> | |
#include <algorithm> | |
template <typename VALUETYPE> | |
void DeepSpinModelDevi::compute( | |
std::vector<ENERGYTYPE>& all_energy, | |
std::vector<std::vector<VALUETYPE>>& all_force, | |
std::vector<std::vector<VALUETYPE>>& all_force_mag, | |
std::vector<std::vector<VALUETYPE>>& all_virial, | |
const std::vector<VALUETYPE>& dcoord_, | |
const std::vector<VALUETYPE>& dspin_, | |
const std::vector<int>& datype_, | |
const std::vector<VALUETYPE>& dbox, | |
const int nghost, | |
const InputNlist& lmp_list, | |
const int& ago, | |
const std::vector<VALUETYPE>& fparam, | |
const std::vector<VALUETYPE>& aparam_) { | |
if (numb_models == 0) { | |
return; | |
} | |
all_energy.resize(numb_models); | |
all_force.resize(numb_models); | |
all_force_mag.resize(numb_models); | |
all_virial.resize(numb_models); | |
std::vector<unsigned> indices(numb_models); | |
std::iota(indices.begin(), indices.end(), 0); | |
std::for_each(std::execution::par_unseq, indices.begin(), indices.end(), | |
[&](unsigned ii) { | |
dps[ii]->compute(all_energy[ii], all_force[ii], all_force_mag[ii], | |
all_virial[ii], dcoord_, dspin_, datype_, dbox, nghost, | |
lmp_list, ago, fparam, aparam_); | |
}); | |
} |
// support spin | ||
template <typename FPTYPE> | ||
inline void _DP_DeepPotComputeNListSP(DP_DeepSpin *dp, | ||
const int nframes, | ||
const int natom, | ||
const FPTYPE *coord, | ||
const FPTYPE *spin, | ||
const int *atype, | ||
const FPTYPE *cell, | ||
const int nghost, | ||
const DP_Nlist *nlist, | ||
const int ago, | ||
const FPTYPE *fparam, | ||
const FPTYPE *aparam, | ||
double *energy, | ||
FPTYPE *force, | ||
FPTYPE *force_mag, | ||
FPTYPE *virial, | ||
FPTYPE *atomic_energy, | ||
FPTYPE *atomic_virial); | ||
|
||
template <> | ||
inline void _DP_DeepPotComputeNListSP<double>(DP_DeepSpin *dp, | ||
const int nframes, | ||
const int natom, | ||
const double *coord, | ||
const double *spin, | ||
const int *atype, | ||
const double *cell, | ||
const int nghost, | ||
const DP_Nlist *nlist, | ||
const int ago, | ||
const double *fparam, | ||
const double *aparam, | ||
double *energy, | ||
double *force, | ||
double *force_mag, | ||
double *virial, | ||
double *atomic_energy, | ||
double *atomic_virial) { | ||
DP_DeepSpinComputeNList2(dp, nframes, natom, coord, spin, atype, cell, nghost, | ||
nlist, ago, fparam, aparam, energy, force, force_mag, | ||
virial, atomic_energy, atomic_virial); | ||
} | ||
|
||
template <> | ||
inline void _DP_DeepPotComputeNListSP<float>(DP_DeepSpin *dp, | ||
const int nframes, | ||
const int natom, | ||
const float *coord, | ||
const float *spin, | ||
const int *atype, | ||
const float *cell, | ||
const int nghost, | ||
const DP_Nlist *nlist, | ||
const int ago, | ||
const float *fparam, | ||
const float *aparam, | ||
double *energy, | ||
float *force, | ||
float *force_mag, | ||
float *virial, | ||
float *atomic_energy, | ||
float *atomic_virial) { | ||
DP_DeepSpinComputeNListf2(dp, nframes, natom, coord, spin, atype, cell, | ||
nghost, nlist, ago, fparam, aparam, energy, force, | ||
force_mag, virial, atomic_energy, atomic_virial); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add parameter validation for spin vector
The function should validate that the spin vector has the correct dimensions (nframes * natoms * 3) before computation to prevent buffer overflows.
+ // Validate spin dimensions
+ if (spin == nullptr) {
+ throw deepmd::hpp::deepmd_exception("spin vector cannot be null");
+ }
Committable suggestion skipped: line range outside the PR's diff.
// 1e-10 cannot pass; unclear bug or not | ||
#undef EPSILON | ||
#define EPSILON (std::is_same<VALUETYPE, double>::value ? 1e-7 : 1e-1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Investigate the reason for relaxed EPSILON tolerance
The EPSILON
value is relaxed to 1e-7
for double precision and 1e-1
for single precision due to an unclear bug (// 1e-10 cannot pass; unclear bug or not
). Adjusting the tolerance may mask underlying numerical issues or instabilities. It's recommended to investigate and resolve the root cause rather than relaxing the tolerance.
Would you like assistance in diagnosing this issue or refining the test cases?
source/api_c/src/c_api.cc
Outdated
const char* DP_DeepBaseModelGetTypeMap(DP_DeepBaseModel* dpbase) { | ||
std::string type_map; | ||
dp->dp.get_type_map(type_map); | ||
dpbase->dpbase.get_type_map(type_map); | ||
return string_to_char(type_map); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document Ownership of Returned C Strings to Prevent Memory Leaks
The functions DP_DeepBaseModelGetTypeMap
, DP_DeepBaseModelCheckOK
, and DP_DeepBaseModelDeviCheckOK
return const char*
pointers that are dynamically allocated using new[]
in the string_to_char
function. Since the caller is responsible for freeing this memory using DP_DeleteChar
, it's important to document this ownership explicitly to prevent memory leaks. Consider updating the function comments or documentation to make this requirement clear to users.
Also applies to: 1672-1673, 1931-1932
|
||
vector<double> dspin(nall * 3, 0.); | ||
vector<double> dfm(nall * 3, 0.); | ||
double **sp = atom->sp; |
Check notice
Code scanning / CodeQL
Unused local variable
vector<double> dspin(nall * 3, 0.); | ||
vector<double> dfm(nall * 3, 0.); | ||
double **sp = atom->sp; | ||
double **fm = atom->fm; |
Check notice
Code scanning / CodeQL
Unused local variable
type_idx_map.clear(); | ||
type_names.clear(); | ||
while (iarg < narg) { | ||
std::string type_name = arg[iarg]; |
Check notice
Code scanning / CodeQL
Declaration hides variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Outside diff range and nitpick comments (19)
source/lmp/pair_deepmd.h (2)
39-42
: Consider documenting the CommBrickDeepMD class purpose.The friendship relationship with PairDeepMD suggests this class plays a crucial role in communication. Adding documentation about its purpose and the necessity of the friendship relationship would improve maintainability.
Line range hint
43-61
: Document spin model integration.Given that this PR aims to enhance LAMMPS support for spin models, please add documentation explaining:
- How this class interacts with spin calculations
- The role of
DeepPot
andDeepPotModelDevi
in spin model supportsource/lmp/pair_deepspin.h (3)
2-4
: Document the LAMMPS version requirement.The version check is crucial for compatibility, but it's not clear what format or minimum version is required. Consider adding a comment explaining the expected format and minimum supported version.
Add a comment above the check:
// SPDX-License-Identifier: LGPL-3.0-or-later +// LAMMPS_VERSION_NUMBER should be defined as YYYYMMDD (e.g., 20220101) +// Minimum supported version: <specify_version> #ifndef LAMMPS_VERSION_NUMBER
15-29
: Consider modernizing the build configuration handling.The current preprocessor-based include path selection could be simplified using modern CMake configuration. This would make the code more maintainable and reduce preprocessor complexity.
Consider:
- Using CMake's configure_file to generate a header with proper paths
- Using target_include_directories to handle include paths
- Moving the build configuration logic to CMake
This would eliminate the need for complex preprocessor directives in the source code.
43-52
: Add class and method documentation.The
PairDeepSpin
class and its methods lack documentation explaining their purpose, parameters, and usage. This is particularly important for public API methods.Add Doxygen-style documentation:
/** * @brief Implements deep learning-based spin interactions for LAMMPS. * * This class extends PairDeepBaseModel to provide spin-specific functionality * for molecular dynamics simulations. */ class PairDeepSpin : public PairDeepBaseModel { public: /** * @brief Constructs a new PairDeepSpin object. * @param lmp Pointer to the LAMMPS instance */ PairDeepSpin(LAMMPS* lmp); // ... document other methods similarlysource/lmp/pair_base.h (4)
6-7
: Align header guard with file name.The header guard
LMP_PAIR_NNP_BASE_H
doesn't match the file namepair_base.h
. Consider usingLMP_PAIR_BASE_H
for consistency.-#ifndef LMP_PAIR_NNP_BASE_H -#define LMP_PAIR_NNP_BASE_H +#ifndef LMP_PAIR_BASE_H +#define LMP_PAIR_BASE_H
10-24
: Consider simplifying the conditional compilation structure.The nested conditional compilation makes the code harder to read and maintain. Consider extracting the include path logic into a separate header or using a more modern configuration system.
+// TODO: Consider using CMake configure_file or similar to handle include paths #ifdef DP_USE_CXX_API -#ifdef LMPPLUGIN -#include "DeepBaseModel.h" -#else -#include "deepmd/DeepBaseModel.h" -#endif +#include DEEPMD_BASE_MODEL_HEADER namespace deepmd_compat = deepmd; #else -#ifdef LMPPLUGIN -#include "deepmd.hpp" -#else -#include "deepmd/deepmd.hpp" -#endif +#include DEEPMD_HPP_HEADER namespace deepmd_compat = deepmd::hpp; #endif
31-50
: Add documentation for public methods and improve parameter names.The public interface would benefit from:
- Documentation comments explaining the purpose and behavior of each method
- More descriptive parameter names in method declarations
Example improvement:
/** * @brief Prints a summary of the model's configuration and state * @param prefix String to prepend to each line of output */ void print_summary(const std::string prefix) const;
106-113
: Add documentation for utility functions.The utility functions would benefit from documentation explaining their purpose, parameters, and return values.
Example improvement:
/** * @brief Uniformly distributes atomic parameters across local atoms * @param daparam Output vector of distributed parameters * @param aparam Input vector of parameters to distribute * @param nlocal Number of local atoms */ void make_uniform_aparam(std::vector<double>& daparam, const std::vector<double>& aparam, const int& nlocal);source/api_c/include/deepmd.hpp (3)
98-156
: Add documentation for spin computation functionsThe newly added template functions
_DP_DeepPotComputeSP
and their specializations lack documentation. Add function documentation that describes:
- Purpose of the functions
- Parameters and their expected dimensions
- Return values
- Example usage
1423-1722
: Consider refactoring to reduce code duplicationThe compute methods contain duplicated reshape logic. Consider extracting the common reshape operations into a helper method to improve maintainability.
Create a helper method like:
template <typename VALUETYPE> void reshape_arrays(std::vector<VALUETYPE>& dest, const std::vector<VALUETYPE>& src, const size_t nframes, const size_t natoms, const size_t stride) { dest.resize(nframes * natoms * stride); for (size_t i = 0; i < nframes * natoms * stride; ++i) { dest[i] = src[i]; } }
Line range hint
2368-2595
: Remove unused variable and refactor reshape logicThe class implementation has two issues that should be addressed:
The variable 'ndof' is declared but never used (as flagged by static analysis)
The reshape logic is duplicated across compute methods
Remove the unused variable:
- unsigned ndof = avg.size(); unsigned nloc = std.size();
- Consider extracting the reshape logic into a helper method similar to the suggestion for DeepSpin class.
source/lmp/pair_base.cpp (3)
54-99
: Consider using MPI_Comm_split_type for node-aware communicator creation.Instead of manually comparing host names to create a node-aware communicator, consider using
MPI_Comm_split_type
withMPI_COMM_TYPE_SHARED
. This is a more efficient and portable approach.- char host_name[MPI_MAX_PROCESSOR_NAME]; - memset(host_name, '\0', sizeof(char) * MPI_MAX_PROCESSOR_NAME); - char(*host_names)[MPI_MAX_PROCESSOR_NAME]; - int n, namelen, color, rank, nprocs, myrank; - size_t bytes; + int rank, nprocs, myrank; MPI_Comm nodeComm; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Get_processor_name(host_name, &namelen); - - bytes = nprocs * sizeof(char[MPI_MAX_PROCESSOR_NAME]); - host_names = (char(*)[MPI_MAX_PROCESSOR_NAME])malloc(bytes); - for (int ii = 0; ii < nprocs; ii++) { - memset(host_names[ii], '\0', sizeof(char) * MPI_MAX_PROCESSOR_NAME); - } - - strcpy(host_names[rank], host_name); - - for (n = 0; n < nprocs; n++) { - MPI_Bcast(&(host_names[n]), MPI_MAX_PROCESSOR_NAME, MPI_CHAR, n, - MPI_COMM_WORLD); - } - qsort(host_names, nprocs, sizeof(char[MPI_MAX_PROCESSOR_NAME]), stringCmp); - - color = 0; - for (n = 0; n < nprocs - 1; n++) { - if (strcmp(host_name, host_names[n]) == 0) { - break; - } - if (strcmp(host_names[n], host_names[n + 1])) { - color++; - } - } - - MPI_Comm_split(MPI_COMM_WORLD, color, 0, &nodeComm); + MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, rank, MPI_INFO_NULL, &nodeComm); MPI_Comm_rank(nodeComm, &myrank); MPI_Barrier(MPI_COMM_WORLD); int looprank = myrank; - free(host_names); return looprank;
408-412
: Consider implementing restart functionality.The
read_restart
andwrite_restart
functions are currently empty. Consider implementing the necessary functionality to properly handle restarting simulations with the deepmd pair style.
438-455
: Improve warning message formatting.The warning message in the
init_one
function could be improved for better readability. Consider usingsnprintf
instead ofsprintf
to avoid potential buffer overflow and use a more structured format for the message.- char warning_msg[1024]; - sprintf(warning_msg, - "Interaction between types %d and %d is set with deepmd, but will " - "be ignored.\n Deepmd model has only %d types, it only computes " - "the mulitbody interaction of types: 1-%d.", - i, j, numb_types, numb_types); + char warning_msg[1024]; + snprintf(warning_msg, sizeof(warning_msg), + "Interaction between types %d and %d is set with deepmd, but will be ignored.\n" + "Deepmd model has only %d types, it only computes the multibody interaction of types: 1-%d.", + i, j, numb_types, numb_types); error->warning(FLERR, warning_msg);source/lmp/pair_deepspin.cpp (4)
620-625
: Remove commented-out code to improve readabilityThe lines contain commented-out code related to atomic virial computation. If this code is no longer needed, consider removing it to enhance code readability and maintainability.
693-698
: Remove commented-out code to improve readabilityThese lines include commented-out code for atomic virial updates. Removing unused code can help keep the codebase clean and understandable.
885-886
: Clean up unnecessary commented-out codeThe
malloc_trim(0);
function call is commented out. If it's not intended for future use or debugging, consider removing it to maintain code cleanliness.
887-887
: Remove unused or commented-out codeThe call to
malloc_trim(0);
is commented out. If memory trimming is no longer required or applicable, consider removing this line to keep the code clean.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
source/api_c/include/deepmd.hpp
(21 hunks)source/lmp/pair_base.cpp
(1 hunks)source/lmp/pair_base.h
(1 hunks)source/lmp/pair_deepmd.cpp
(6 hunks)source/lmp/pair_deepmd.h
(1 hunks)source/lmp/pair_deepspin.cpp
(1 hunks)source/lmp/pair_deepspin.h
(1 hunks)
🔇 Additional comments (24)
source/lmp/pair_deepmd.h (2)
Line range hint 1-36
: LGTM: Well-organized header structure.
The conditional compilation directives and header organization properly handle different build configurations while maintaining clean namespace separation.
43-56
: Verify the base class functionality.
The refactoring to inherit from PairDeepBaseModel
looks good and reduces code duplication. However, we should verify that all required functionality is properly inherited.
✅ Verification successful
Base class functionality verified and properly implemented
The refactoring is correct. The PairDeepBaseModel
base class in pair_base.h
contains all the previously removed methods from PairDeepMD
:
extract(const char *, int &)
init_style()
write_restart(FILE *)
read_restart(FILE *)
init_one(int i, int j)
The git history confirms these methods were moved from PairDeepMD
to the base class, improving code organization while maintaining functionality. The inheritance hierarchy and method overrides are properly structured.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that PairDeepBaseModel contains all necessary methods
# that were previously in PairDeepMD
# Search for the removed methods in PairDeepBaseModel
ast-grep --pattern 'class PairDeepBaseModel {
$$$
extract($$$) {
$$$
}
$$$
}'
ast-grep --pattern 'class PairDeepBaseModel {
$$$
init_style($$$) {
$$$
}
$$$
}'
Length of output: 186
Script:
#!/bin/bash
# Let's first find the PairDeepBaseModel definition
rg -l "class PairDeepBaseModel" --type cpp
# Then examine its contents
rg "class PairDeepBaseModel" -A 30 --type cpp
# Also check for any virtual methods in the base class
ast-grep --pattern 'class PairDeepBaseModel {
$$$
virtual $_ $_($$$) $_;
$$$
}'
# Let's also check the git history to see what methods were removed
git log -p source/lmp/pair_deepmd.h | rg -A 5 -B 5 "^[-+].*\b(extract|init_style)\b"
Length of output: 3187
source/lmp/pair_deepspin.h (1)
56-56
: Consider thread safety for force magnitude storage.
The all_force_mag
vector might be accessed from multiple threads during computation. Ensure proper synchronization or use thread-local storage if needed.
source/lmp/pair_base.h (2)
61-61
: Verify spin model implementation details.
The spin-related additions (numb_types_spin, spin_norm, index mapping) need verification:
- Are the spin norms properly initialized and maintained?
- Is the index mapping robust enough for all LAMMPS operations?
#!/bin/bash
# Search for spin norm initialization and usage
rg -A 5 "spin_norm" --type cpp
# Search for index mapping implementation
rg -A 5 "new_idx_map|old_idx_map" --type cpp
Also applies to: 77-77, 78-80
53-85
: Improve organization and documentation of member variables.
Consider grouping related members together and adding documentation for each group. For example:
- Model configuration (cutoff, numb_types, etc.)
- Output settings (out_freq, out_file, etc.)
- Spin-related state (numb_types_spin, spin_norm)
Additionally, verify that the spin-related variables align with the LAMMPS spin model requirements.
source/lmp/pair_deepmd.cpp (2)
87-90
: LGTM! Constructor and destructor changes look good.
The changes simplify the implementation by properly utilizing inheritance and removing spin-related initialization.
Also applies to: 93-94
438-470
: LGTM! Type mapping improvements look good.
The changes improve type handling by:
- Adding support for NULL type as ghost type
- Providing clearer error messages
- Properly handling type mapping and validation
source/api_c/include/deepmd.hpp (1)
839-947
: LGTM! Well-structured base model changes
The additions to DeepBaseModel class are well-designed with:
- Clear separation of concerns
- Consistent error handling
- Complete documentation
source/lmp/pair_base.cpp (13)
38-52
: LGTM!
The stringCmp
function is implemented correctly. It compares two strings lexicographically by iterating over the characters and returning the difference between the first non-matching characters. If the strings are equal, it returns 0.
124-131
: LGTM!
The get_file_content
overload for a vector of file paths is implemented correctly. It iterates over the input vector, calls the single-file overload for each path, and returns a vector of file contents.
133-160
: LGTM!
The make_fparam_from_compute
function is implemented correctly. It retrieves the compute object based on the provided ID, checks if it exists, resizes the fparam
vector, and populates it with the scalar or vector values from the compute, depending on the dimension.
162-189
: LGTM!
The make_aparam_from_compute
function is implemented correctly. It retrieves the compute object based on the provided ID, checks if it exists, resizes the aparam
vector based on the local atom count and dimension, and populates it with the per-atom vector or array values from the compute.
192-229
: LGTM!
The make_ttm_fparam
function is implemented correctly. It retrieves the TTM fix object, checks if it exists, resizes the fparam
vector, and calculates the average electron temperature over the effective nodes. The average temperature is stored in fparam[0]
.
278-284
: LGTM!
The cum_sum
function is implemented correctly. It calculates the cumulative sum of the values in the vec
map and stores the results in the sum
map. The cumulative sum at index i
is the sum of values from index 0
to i-1
in the input vector.
347-370
: LGTM!
The print_summary
function is implemented correctly. It captures the output of cout
to a string stream, prints the summary information about the deepmd-kit and LAMMPS module, and then restores the original cout
buffer. The summary string is logged using LAMMPS's utils::logmesg
function.
380-406
: LGTM!
The allocate
function is implemented correctly. It allocates memory for the setflag
, cutsq
, and scale
arrays based on the number of atom types. It initializes the arrays with default values and sets the appropriate flags and scales for the defined number of types.
414-436
: LGTM!
The init_style
function is implemented correctly. It adds a request for full neighbor lists and allocates memory for communication buffers if out_each
is set to 1. The memory is allocated based on the total number of atoms and the maximum buffer size.
457-467
: LGTM!
The extract
function is implemented correctly. It returns a pointer to the cutoff
variable if the requested string is "cut_coul" and a pointer to the scale
array if the requested string is "scale". The dim
parameter is set accordingly to indicate the dimension of the returned data.
469-489
: LGTM!
The ana_st
function is implemented correctly. It calculates the maximum, minimum, and sum of the values in the vec
vector, considering only the first nloc
elements. If nloc
is 0, the function returns without modifying the input parameters.
491-501
: LGTM!
The make_uniform_aparam
function is implemented correctly. It creates a uniform daparam
vector by replicating the values from the aparam
vector for each local atom. The resulting daparam
vector has a size of dim_aparam * nlocal
, where dim_aparam
is the size of aparam
and nlocal
is the number of local atoms.
286-345
: Verify compatibility with other unit styles.
The constructor checks for compatibility with the "lj" unit style and throws an error if it is used. However, it does not verify compatibility with other unit styles. Consider adding checks for other supported unit styles or documenting the compatible unit styles.
source/lmp/pair_deepspin.cpp (3)
511-515
: Replace std::cout
with proper error handling
Using std::cout
for error messages is inconsistent with LAMMPS' error handling mechanisms. Replace std::cout
with error->all
or error->one
to ensure consistent error reporting.
521-545
: Verify the handling of ghost atoms in coordinate computations
In the coordinate transformation loop, ghost atoms are included without explicit checks. Ensure that the handling of ghost atoms in coordinate computations is intentional and does not introduce unexpected behavior.
Run the following script to check the indices of ghost atoms:
✅ Verification successful
Let me analyze the results. The code shows that:
nall
is correctly defined asnlocal + nghost
- Ghost atoms are conditionally included based on
do_ghost
flag - The deep potential computation (
deep_spin.compute
) handles both local and ghost atoms through theInputNlist
structure - The coordinate transformation is consistently applied to all atoms (both local and ghost) which is necessary for proper force calculations in molecular dynamics
Given this evidence, I can generate the final response:
Ghost atom handling in coordinate computations is correctly implemented
The inclusion of ghost atoms in coordinate computations is intentional and necessary for proper force calculations. The code properly initializes nall
as the sum of local and ghost atoms, and the coordinate transformation is consistently applied within the deep potential computation framework through InputNlist
.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that ghost atoms are properly handled in coordinate computations.
# Test: List indices of ghost atoms and ensure they are correctly processed.
ast-grep --pattern $'for (int ii = 0; ii < nall; ++ii) {
$$$
}' source/lmp/pair_deepspin.cpp
# Check where nall is defined as nlocal + nghost.
rg 'int nall = nlocal \+ nghost;' source/lmp/pair_deepspin.cpp
# Verify if there are any conditions that differentiate between local and ghost atoms.
rg 'if \(do_ghost\)' source/lmp/pair_deepspin.cpp -A 10
Length of output: 6861
876-882
:
Ensure sp[ii][3]
is non-zero before division to prevent runtime errors
In the force computation, the code divides by (hbar / sp[ii][3])
. If sp[ii][3]
is zero, this will result in a division by zero error.
Apply this diff to add a check before the division:
for (int ii = 0; ii < nall; ++ii) {
for (int dd = 0; dd < 3; ++dd) {
f[ii][dd] += scale[1][1] * dforce[3 * ii + dd] * force_unit_cvt_factor;
+ if (sp[ii][3] == 0.0) {
+ error->one(FLERR, "Spin magnitude sp[ii][3] is zero; division by zero detected in force computation.");
+ }
fm[ii][dd] += scale[1][1] * dforce_mag[3 * ii + dd] / (hbar / sp[ii][3]) *
force_unit_cvt_factor;
}
}
Likely invalid or redundant comment.
std::cout << "Pair style 'deepmd' does not support spin atoms, please use " | ||
"pair style 'deepspin' instead." | ||
<< std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use LAMMPS error system instead of cout for error messages.
The code uses cout
to print error messages about spin atoms in multiple places. This should be replaced with LAMMPS error system for consistent error handling.
Apply this diff to fix all instances:
- std::cout << "Pair style 'deepmd' does not support spin atoms, please use "
- "pair style 'deepspin' instead."
- << std::endl;
+ error->all(FLERR, "Pair style 'deepmd' does not support spin atoms. "
+ "Please use pair style 'deepspin' instead.");
Also applies to: 874-877, 896-899
if (atom->sp_flag) { | ||
std::cout << "Pair style 'deepmd' does not support spin atoms, please use " | ||
"pair style 'deepspin' instead." | ||
<< std::endl; | ||
} else { | ||
for (i = first; i < last; i++) { | ||
for (int dd = 0; dd < numb_models; ++dd) { | ||
buf[m++] = all_force[dd][3 * i + 0]; | ||
buf[m++] = all_force[dd][3 * i + 1]; | ||
buf[m++] = all_force[dd][3 * i + 2]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Check for spin atoms early in communication methods.
The error for spin atoms should be checked before allocating memory or performing any operations.
Apply this diff to improve error handling:
int PairDeepMD::pack_reverse_comm(int n, int first, double *buf) {
+ if (atom->sp_flag) {
+ error->all(FLERR, "Pair style 'deepmd' does not support spin atoms. "
+ "Please use pair style 'deepspin' instead.");
+ }
int i, m, last;
m = 0;
last = first + n;
- if (atom->sp_flag) {
- std::cout << "Pair style 'deepmd' does not support spin atoms, please use "
- "pair style 'deepspin' instead."
- << std::endl;
- } else {
for (i = first; i < last; i++) {
for (int dd = 0; dd < numb_models; ++dd) {
buf[m++] = all_force[dd][3 * i + 0];
buf[m++] = all_force[dd][3 * i + 1];
buf[m++] = all_force[dd][3 * i + 2];
}
}
- }
return m;
}
Similar changes should be applied to unpack_reverse_comm
.
Also applies to: 895-907
void compute( | ||
ENERGYVTYPE &ener, | ||
std::vector<VALUETYPE> &force, | ||
std::vector<VALUETYPE> &force_mag, | ||
std::vector<VALUETYPE> &virial, | ||
const std::vector<VALUETYPE> &coord, | ||
const std::vector<VALUETYPE> &spin, | ||
const std::vector<int> &atype, | ||
const std::vector<VALUETYPE> &box, | ||
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | ||
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | ||
unsigned int natoms = atype.size(); | ||
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | ||
assert(nframes * natoms * 3 == coord.size()); | ||
if (!box.empty()) { | ||
assert(box.size() == nframes * 9); | ||
} | ||
const VALUETYPE *coord_ = &coord[0]; | ||
const VALUETYPE *spin_ = &spin[0]; | ||
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | ||
const int *atype_ = &atype[0]; | ||
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | ||
force.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | ||
virial.resize(static_cast<size_t>(nframes) * 9); | ||
VALUETYPE *force_ = &force[0]; | ||
VALUETYPE *force_mag_ = &force_mag[0]; | ||
VALUETYPE *virial_ = &virial[0]; | ||
std::vector<VALUETYPE> fparam_, aparam_; | ||
validate_fparam_aparam(nframes, natoms, fparam, aparam); | ||
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | ||
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | ||
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | ||
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | ||
|
||
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | ||
box_, fparam__, aparam__, ener_, force_, | ||
force_mag_, virial_, nullptr, nullptr); | ||
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for spin vector dimensions
The compute methods should validate that the spin vector has the correct dimensions (nframes * natoms * 3) to prevent buffer overflows.
Add validation after the existing coordinate validation:
assert(nframes * natoms * 3 == coord.size());
+ assert(nframes * natoms * 3 == spin.size()); // Validate spin dimensions
if (!box.empty()) {
assert(box.size() == nframes * 9);
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
void compute( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, natoms, fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | |
box_, fparam__, aparam__, ener_, force_, | |
force_mag_, virial_, nullptr, nullptr); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; | |
void compute( | |
ENERGYVTYPE &ener, | |
std::vector<VALUETYPE> &force, | |
std::vector<VALUETYPE> &force_mag, | |
std::vector<VALUETYPE> &virial, | |
const std::vector<VALUETYPE> &coord, | |
const std::vector<VALUETYPE> &spin, | |
const std::vector<int> &atype, | |
const std::vector<VALUETYPE> &box, | |
const std::vector<VALUETYPE> &fparam = std::vector<VALUETYPE>(), | |
const std::vector<VALUETYPE> &aparam = std::vector<VALUETYPE>()) { | |
unsigned int natoms = atype.size(); | |
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1; | |
assert(nframes * natoms * 3 == coord.size()); | |
assert(nframes * natoms * 3 == spin.size()); // Validate spin dimensions | |
if (!box.empty()) { | |
assert(box.size() == nframes * 9); | |
} | |
const VALUETYPE *coord_ = &coord[0]; | |
const VALUETYPE *spin_ = &spin[0]; | |
const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; | |
const int *atype_ = &atype[0]; | |
double *ener_ = _DP_Get_Energy_Pointer(ener, nframes); | |
force.resize(static_cast<size_t>(nframes) * natoms * 3); | |
force_mag.resize(static_cast<size_t>(nframes) * natoms * 3); | |
virial.resize(static_cast<size_t>(nframes) * 9); | |
VALUETYPE *force_ = &force[0]; | |
VALUETYPE *force_mag_ = &force_mag[0]; | |
VALUETYPE *virial_ = &virial[0]; | |
std::vector<VALUETYPE> fparam_, aparam_; | |
validate_fparam_aparam(nframes, natoms, fparam, aparam); | |
tile_fparam_aparam(fparam_, nframes, dfparam, fparam); | |
tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); | |
const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; | |
const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; | |
_DP_DeepPotComputeSP<VALUETYPE>(dp, nframes, natoms, coord_, spin_, atype_, | |
box_, fparam__, aparam__, ener_, force_, | |
force_mag_, virial_, nullptr, nullptr); | |
DP_CHECK_OK(DP_DeepBaseModelCheckOK, (DP_DeepBaseModel *)dp); | |
}; |
std::string PairDeepBaseModel::get_file_content(const std::string &model) { | ||
int myrank = 0, root = 0; | ||
MPI_Comm_rank(MPI_COMM_WORLD, &myrank); | ||
int nchar = 0; | ||
std::string file_content; | ||
if (myrank == root) { | ||
deepmd_compat::read_file_to_string(model, file_content); | ||
nchar = file_content.size(); | ||
} | ||
MPI_Bcast(&nchar, 1, MPI_INT, root, MPI_COMM_WORLD); | ||
char *buff = (char *)malloc(sizeof(char) * nchar); | ||
if (myrank == root) { | ||
memcpy(buff, file_content.c_str(), sizeof(char) * nchar); | ||
} | ||
MPI_Bcast(buff, nchar, MPI_CHAR, root, MPI_COMM_WORLD); | ||
file_content.resize(nchar); | ||
for (unsigned ii = 0; ii < nchar; ++ii) { | ||
file_content[ii] = buff[ii]; | ||
} | ||
free(buff); | ||
return file_content; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure allocated memory in get_file_content()
is properly deallocated.
The character buffer buff
is allocated using malloc
but is not freed in all code paths. If MPI_Bcast
fails, the allocated memory will be leaked. Use RAII or ensure proper cleanup in all scenarios.
char *buff = (char *)malloc(sizeof(char) * nchar);
if (myrank == root) {
memcpy(buff, file_content.c_str(), sizeof(char) * nchar);
}
- MPI_Bcast(buff, nchar, MPI_CHAR, root, MPI_COMM_WORLD);
+ if (MPI_Bcast(buff, nchar, MPI_CHAR, root, MPI_COMM_WORLD) != MPI_SUCCESS) {
+ free(buff);
+ // Handle the error, e.g., throw an exception or return an empty string
+ }
file_content.resize(nchar);
for (unsigned ii = 0; ii < nchar; ++ii) {
file_content[ii] = buff[ii];
}
free(buff);
Committable suggestion skipped: line range outside the PR's diff.
void PairDeepBaseModel::make_ttm_aparam(vector<double> &daparam) { | ||
assert(do_ttm); | ||
// get ttm_fix | ||
const FixTTMDP *ttm_fix = NULL; | ||
for (int ii = 0; ii < modify->nfix; ii++) { | ||
if (string(modify->fix[ii]->id) == ttm_fix_id) { | ||
ttm_fix = dynamic_cast<FixTTMDP *>(modify->fix[ii]); | ||
} | ||
} | ||
if (!ttm_fix) { | ||
error->all(FLERR, "fix ttm id is not found: " + ttm_fix_id); | ||
} | ||
// modify | ||
double **x = atom->x; | ||
int *mask = atom->mask; | ||
int nlocal = atom->nlocal; | ||
vector<int> nnodes = ttm_fix->get_nodes(); | ||
int nxnodes = nnodes[0]; | ||
int nynodes = nnodes[1]; | ||
int nznodes = nnodes[2]; | ||
double ***const T_electron = ttm_fix->get_T_electron(); | ||
double dx = domain->xprd / nxnodes; | ||
double dy = domain->yprd / nynodes; | ||
double dz = domain->zprd / nynodes; | ||
// resize daparam | ||
daparam.resize(nlocal); | ||
// loop over atoms to assign aparam | ||
for (int ii = 0; ii < nlocal; ii++) { | ||
if (mask[ii] & ttm_fix->groupbit) { | ||
double xscale = (x[ii][0] - domain->boxlo[0]) / domain->xprd; | ||
double yscale = (x[ii][1] - domain->boxlo[1]) / domain->yprd; | ||
double zscale = (x[ii][2] - domain->boxlo[2]) / domain->zprd; | ||
int ixnode = static_cast<int>(xscale * nxnodes); | ||
int iynode = static_cast<int>(yscale * nynodes); | ||
int iznode = static_cast<int>(zscale * nznodes); | ||
// https://stackoverflow.com/a/1907585/9567349 | ||
ixnode = ((ixnode % nxnodes) + nxnodes) % nxnodes; | ||
iynode = ((iynode % nynodes) + nynodes) % nynodes; | ||
iznode = ((iznode % nznodes) + nznodes) % nznodes; | ||
daparam[ii] = T_electron[ixnode][iynode][iznode]; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure array indices are within bounds.
When calculating the node indices (ixnode
, iynode
, iznode
) based on the atom positions, ensure that the indices are within the valid range of the T_electron
array dimensions. Consider adding boundary checks or using a different mapping scheme to avoid out-of-bounds access.
int ixnode = static_cast<int>(xscale * nxnodes);
int iynode = static_cast<int>(yscale * nynodes);
int iznode = static_cast<int>(zscale * nznodes);
+ ixnode = std::max(0, std::min(ixnode, nxnodes - 1));
+ iynode = std::max(0, std::min(iynode, nynodes - 1));
+ iznode = std::max(0, std::min(iznode, nznodes - 1));
daparam[ii] = T_electron[ixnode][iynode][iznode];
Committable suggestion skipped: line range outside the PR's diff.
fp.open(out_file); | ||
fp << scientific; | ||
if (!atom->sp_flag) { | ||
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v" | ||
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v" | ||
<< setw(18 + 1) << "max_devi_f" << setw(18 + 1) << "min_devi_f" | ||
<< setw(18 + 1) << "avg_devi_f"; | ||
if (out_each) { | ||
// at this time, we don't know how many atoms | ||
fp << setw(18 + 1) << "atm_devi_f(N)"; | ||
} | ||
fp << endl; | ||
} else { | ||
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v" | ||
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v" | ||
<< setw(18 + 1) << "max_devi_fr" << setw(18 + 1) << "min_devi_fr" | ||
<< setw(18 + 1) << "avg_devi_fr" << setw(18 + 1) << "max_devi_fm" | ||
<< setw(18 + 1) << "min_devi_fm" << setw(18 + 1) << "avg_devi_fm" | ||
<< endl; | ||
} | ||
} else { | ||
fp.open(out_file, std::ofstream::out | std::ofstream::app); | ||
fp << scientific; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error checking after opening the output file
The code opens the output file fp
without verifying if the file was successfully opened. Failing to check the file stream can lead to unexpected behavior if the file cannot be opened due to issues such as incorrect file paths or insufficient permissions.
Apply this diff to add error checking:
if (!is_restart) {
fp.open(out_file);
+ if (!fp.is_open()) {
+ error->one(FLERR, ("Failed to open output file: " + out_file).c_str());
+ }
fp << scientific;
if (!atom->sp_flag) {
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v"
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v"
<< setw(18 + 1) << "max_devi_f" << setw(18 + 1) << "min_devi_f"
<< setw(18 + 1) << "avg_devi_f";
if (out_each) {
// at this time, we don't know how many atoms
fp << setw(18 + 1) << "atm_devi_f(N)";
}
fp << endl;
} else {
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v"
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v"
<< setw(18 + 1) << "max_devi_fr" << setw(18 + 1) << "min_devi_fr"
<< setw(18 + 1) << "avg_devi_fr" << setw(18 + 1) << "max_devi_fm"
<< setw(18 + 1) << "min_devi_fm" << setw(18 + 1) << "avg_devi_fm"
<< endl;
}
} else {
fp.open(out_file, std::ofstream::out | std::ofstream::app);
+ if (!fp.is_open()) {
+ error->one(FLERR, ("Failed to open output file: " + out_file).c_str());
+ }
fp << scientific;
}
spin_norm.resize(numb_types_spin); | ||
for (int ii = 0; ii < numb_types_spin; ++ii) { | ||
spin_norm[ii] = atof(arg[iarg + ii + 1]); | ||
} | ||
iarg += numb_types_spin + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for spin_norm
values to prevent division by zero
The spin_norm
array is populated from user input without validation. If any of these values are zero, it could lead to division by zero errors in subsequent calculations involving sp[ii][3]
.
Apply this diff to add validation:
else if (string(arg[iarg]) == string("spin_norm")) {
spin_norm.resize(numb_types_spin);
for (int ii = 0; ii < numb_types_spin; ++ii) {
+ if (atof(arg[iarg + ii + 1]) == 0.0) {
+ error->all(FLERR, "spin_norm values must be non-zero to prevent division by zero");
+ }
spin_norm[ii] = atof(arg[iarg + ii + 1]);
}
iarg += numb_types_spin + 1;
}
Committable suggestion skipped: line range outside the PR's diff.
|
||
vector<double> dspin(nall * 3, 0.); | ||
vector<double> dfm(nall * 3, 0.); | ||
double **sp = atom->sp; |
Check notice
Code scanning / CodeQL
Unused local variable Note
vector<double> dspin(nall * 3, 0.); | ||
vector<double> dfm(nall * 3, 0.); | ||
double **sp = atom->sp; | ||
double **fm = atom->fm; |
Check notice
Code scanning / CodeQL
Unused local variable Note
make_fparam_from_compute(fparam); | ||
} | ||
|
||
// int ago = numb_models > 1 ? 0 : neighbor->ago; |
Check notice
Code scanning / CodeQL
Commented-out code Note
// vatom[ii][0] += 1.0 * dvatom[9*ii+0]; | ||
// vatom[ii][1] += 1.0 * dvatom[9*ii+4]; | ||
// vatom[ii][2] += 1.0 * dvatom[9*ii+8]; | ||
// vatom[ii][3] += 1.0 * dvatom[9*ii+3]; | ||
// vatom[ii][4] += 1.0 * dvatom[9*ii+6]; | ||
// vatom[ii][5] += 1.0 * dvatom[9*ii+7]; |
Check notice
Code scanning / CodeQL
Commented-out code Note
// deep_pot_model_devi.compute_avg (dener, all_energy); | ||
// deep_pot_model_devi.compute_avg (dforce, all_force); | ||
// deep_pot_model_devi.compute_avg (dvirial, all_virial); | ||
// deep_pot_model_devi.compute_avg (deatom, all_atom_energy); | ||
// deep_pot_model_devi.compute_avg (dvatom, all_atom_virial); |
Check notice
Code scanning / CodeQL
Commented-out code Note
// vatom[ii][0] += 1.0 * dvatom[9*ii+0]; | ||
// vatom[ii][1] += 1.0 * dvatom[9*ii+4]; | ||
// vatom[ii][2] += 1.0 * dvatom[9*ii+8]; | ||
// vatom[ii][3] += 1.0 * dvatom[9*ii+3]; | ||
// vatom[ii][4] += 1.0 * dvatom[9*ii+6]; | ||
// vatom[ii][5] += 1.0 * dvatom[9*ii+7]; |
Check notice
Code scanning / CodeQL
Commented-out code Note
type_idx_map.clear(); | ||
type_names.clear(); | ||
while (iarg < narg) { | ||
std::string type_name = arg[iarg]; |
Check notice
Code scanning / CodeQL
Declaration hides variable Note
line 834
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🧹 Outside diff range and nitpick comments (33)
source/lmp/pair_deepspin.h (5)
2-4
: Document the LAMMPS version number requirement.The error message could be more helpful by explaining where and how to define
LAMMPS_VERSION_NUMBER
. Consider adding a comment explaining the expected format and where this macro should be defined.#ifndef LAMMPS_VERSION_NUMBER +// LAMMPS_VERSION_NUMBER should be defined in your build system +// Format: YYYYMMDD (e.g., 20240101 for January 1st, 2024) #error Please define LAMMPS_VERSION_NUMBER to yyyymmdd #endif
15-29
: Document build configuration options.The conditional compilation structure handles different build configurations but lacks documentation explaining when to use each option. Consider adding comments explaining:
- When to use
DP_USE_CXX_API
- The purpose of
LMPPLUGIN
- The differences between the include paths
+// Build configurations: +// DP_USE_CXX_API: Enable C++ API (recommended for direct integration) +// LMPPLUGIN: Use plugin mode for LAMMPS integration #ifdef DP_USE_CXX_API #ifdef LMPPLUGIN
43-52
: Add class and method documentation.The
PairDeepSpin
class and its methods lack documentation explaining their purpose, parameters, and usage. Consider adding detailed documentation using a consistent format (e.g., Doxygen).+/** + * @brief LAMMPS pair style for deep learning-based spin interactions + * + * Implements pair interactions for spin systems using the DeepMD model. + */ class PairDeepSpin : public PairDeepBaseModel { public: + /** + * @brief Construct a new Pair Deep Spin object + * @param lmp LAMMPS instance pointer + */ PairDeepSpin(class LAMMPS *);
59-59
: Consider using smart pointers for better memory management.The raw pointer
commdata_
could lead to memory management issues. Consider usingstd::unique_ptr
if ownership semantics are applicable.- CommBrickDeepSpin *commdata_; + std::unique_ptr<CommBrickDeepSpin> commdata_;
54-56
: Document the purpose of protected members.The protected members
deep_spin
anddeep_spin_model_devi
lack documentation explaining their roles and usage within the class.protected: + /// Main deep learning model for spin interactions deepmd_compat::DeepSpin deep_spin; + /// Model for deviation analysis in spin calculations deepmd_compat::DeepSpinModelDevi deep_spin_model_devi; + /// Storage for force magnitudes across all calculations std::vector<std::vector<double> > all_force_mag;source/lmp/pair_base.h (3)
6-7
: Align header guard with filename.The header guard
LMP_PAIR_NNP_BASE_H
doesn't match the file namepair_base.h
. Consider renaming it toLMP_PAIR_BASE_H
for consistency.
31-102
: Add documentation for class and methods.The class and its methods lack documentation. Consider adding:
- Class-level documentation explaining the purpose and usage
- Method documentation describing parameters, return values, and behavior
- Examples of typical usage patterns
This is particularly important for public methods like:
print_summary
get_node_rank
cum_sum
get_file_content
61-61
: Document spin system implementation details.The spin-related functionality (including
numb_types_spin
,spin_norm
, and index mapping) needs documentation explaining:
- The purpose and usage of spin-specific members
- The relationship between old and new atom indices
- How the spin norm is calculated and used
This will help maintain consistency with the PR's objective of enhancing LAMMPS support for spin models.
Also applies to: 77-80
source/api_cc/include/DeepBaseModel.h (4)
97-99
: Add error handling documentation for constructorThe constructor documentation should specify what happens if initialization fails (e.g., invalid model file or GPU rank). Consider adding exception specifications and error handling details.
162-165
: Consider using a common assertion helper methodMultiple methods use the same assertion pattern to check
inited
. Consider creating a protected helper method to centralize this check and provide more detailed error messages.+protected: + void ensure_initialized() const { + if (!inited) { + throw std::runtime_error("Model not initialized. Call init() first."); + } + }Replace assertions with the helper:
- assert(inited); + ensure_initialized();Also applies to: 171-173, 179-181, 187-189, 195-197, 273-275
278-281
: Document thread safety guaranteesThe class manages shared resources (
dpbases
vector of shared pointers). Please document thread safety guarantees and any synchronization requirements for concurrent access.
13-282
: Well-structured backend architecture with room for improvementThe class hierarchy provides a solid foundation for different backend implementations with good separation of concerns. Consider the following architectural improvements:
- Add a virtual
clone()
method to support the prototype pattern- Consider using the PIMPL idiom to reduce compilation dependencies
- Add version information or capability flags to support future extensions
source/api_cc/include/DeepPotPT.h (1)
Line range hint
77-119
: Consider using parameter structs to improve maintainability.The compute method overloads have extensive parameter lists which could make the code harder to maintain. Consider grouping related parameters into structs, for example:
struct ComputeInputs { std::vector<VALUETYPE> coord; std::vector<int> atype; std::vector<VALUETYPE> box; std::vector<VALUETYPE> fparam; std::vector<VALUETYPE> aparam; bool atomic; }; struct NeighborListInputs { int nghost; InputNlist lmp_list; int ago; }; struct ComputeOutputs { ENERGYVTYPE& ener; std::vector<VALUETYPE>& force; std::vector<VALUETYPE>& virial; std::vector<VALUETYPE>& atom_energy; std::vector<VALUETYPE>& atom_virial; };This would make the method signatures more manageable and easier to extend in the future.
source/api_cc/include/DeepSpin.h (4)
11-14
: Update class documentationThe class comment incorrectly describes this as "Deep Potential" when it should be "Deep Spin" to accurately reflect its purpose.
-/** - * @brief Deep Potential. - **/ +/** + * @brief Deep Spin model backend interface. + **/
165-168
: Fix documentation formattingThe documentation has inconsistent spacing after asterisks in comments. For example,
*and
should be* and
.
440-441
: Fix typo in documentationThere's a typo in the documentation: "contrcutor" should be "constructor".
- * @brief Initialize the DP model deviation contrcutor. + * @brief Initialize the DP model deviation constructor.
1-542
: Well-structured spin model implementationThe overall architecture follows good design principles:
- Clear separation of concerns between backend, main implementation, and model deviation
- Consistent interface design across all classes
- Proper use of templates for type flexibility
- Good memory management with shared_ptr
source/api_cc/include/DeepPot.h (2)
14-14
: Class hierarchy changes improve architectureThe refactoring of the inheritance structure with:
DeepPotBackend
(formerlyDeepPotBase
) inheriting fromDeepBaseModelBackend
DeepPot
inheriting fromDeepBaseModel
DeepPotModelDevi
inheriting fromDeepBaseModelDevi
provides a cleaner separation of concerns and better supports the new spin model functionality.
Also applies to: 207-207, 529-529
Line range hint
571-577
: Clarify aparam documentationThe documentation for
aparam
parameter contains redundant information:* @param[in] aparam The atomic parameter The array can be of size : * nframes x natoms x dim_aparam. * natoms x dim_aparam. Then all frames are assumed to be provided with the *same aparam. dim_aparam. Then all frames and atoms are provided with the *same aparam.
Consider simplifying to:
* @param[in] aparam The atomic parameter. The array can be of size: * - nframes x natoms x dim_aparam * - natoms x dim_aparam (same parameters used for all frames) * - dim_aparam (same parameters used for all frames and atoms)
source/lmp/pair_deepspin.cpp (2)
90-90
: Remove unnecessary comment.The comment "Constructor body can be empty" is redundant and doesn't provide any meaningful information.
- // Constructor body can be empty
125-135
: Consider using smart pointers or RAII for model initialization.The vector of models is allocated on the stack but the model initialization could throw exceptions. Consider using smart pointers or RAII pattern to ensure proper cleanup in case of exceptions.
- vector<string> models; + std::vector<std::unique_ptr<std::string>> models;source/api_c/include/c_api.h (2)
368-396
: Improve documentation clarity for spin parameters.The documentation should clarify:
- The units and format of the spin input array
- The physical meaning of force_mag output
- The relationship between regular force and magnetic force
1047-1066
: Add missing documentation blocks.The following functions are missing documentation blocks:
- DP_DeepSpinModelDeviComputeNList2
- DP_DeepSpinModelDeviComputeNListf2
Please add documentation following the established pattern from similar functions, including:
- Brief description
- Version information
- Parameter descriptions
- Return value description
- Warnings about array allocation
Also applies to: 1113-1131
source/api_c/include/deepmd.hpp (3)
98-114
: Consider reordering parameters for consistencyThe parameter ordering in
_DP_DeepPotComputeSP
placesspin
betweencoord
andatype
, breaking the established pattern where type-related parameters are grouped together. Consider reordering to maintain consistency with other functions:- const FPTYPE *coord, - const FPTYPE *spin, - const int *atype, + const FPTYPE *coord, + const int *atype, + const FPTYPE *spin,
98-114
: Add documentation for spin-related template functionsThe newly added template functions lack documentation comments. Add documentation describing:
- Function purpose
- Parameter descriptions
- Return value description
- Example usage
Line range hint
2431-2497
: Add validation and consider refactoring reshape operations
- Add validation for spin vector dimensions:
unsigned int natoms = atype.size(); unsigned int nframes = 1; assert(natoms * 3 == coord.size()); + assert(natoms * 3 == spin.size()); // Validate spin dimensions
- Consider extracting the reshape operations into a helper function to reduce code duplication:
template <typename VALUETYPE> void reshape_model_devi_arrays( std::vector<double>& ener, std::vector<std::vector<VALUETYPE>>& force, std::vector<std::vector<VALUETYPE>>& force_mag, const std::vector<double>& energy_flat, const std::vector<VALUETYPE>& force_flat, const std::vector<VALUETYPE>& force_mag_flat, int numb_models, int natoms) { // Common reshape logic here }source/lmp/pair_deepmd.cpp (6)
371-376
: Simplify Communication Reverse SetupThe conditional related to
atom->sp_flag
may be unnecessary since spin atoms are not supported.Simplify the code by removing the condition:
- if (atom->sp_flag) { - comm_reverse = numb_models * 3 * 2; - } else { comm_reverse = numb_models * 3; - }
787-825
: Consider Removing Spin-Related Comments and CodeThe comment
// need support for spin atomic force.
indicates missing functionality that may no longer be relevant.Remove the comment and any related code that pertains to spin atomic forces, since spin support is not provided in this class.
- // need support for spin atomic force. vector<double> std_f_all(atom->natoms); // Gather std_f and tags tagint *tag = atom->tag; int nprocs = comm->nprocs; // Grow arrays if necessary if (atom->natoms > stdf_comm_buff_size) { stdf_comm_buff_size = atom->natoms; memory->destroy(stdfsend); memory->destroy(stdfrecv); memory->destroy(tagsend); memory->destroy(tagrecv); memory->create(stdfsend, stdf_comm_buff_size, "deepmd:stdfsendall"); memory->create(stdfrecv, stdf_comm_buff_size, "deepmd:stdfrecvall"); memory->create(tagsend, stdf_comm_buff_size, "deepmd:tagsendall"); memory->create(tagrecv, stdf_comm_buff_size, "deepmd:tagrecvall"); }
501-501
: Remove Unused Variablesp
The variable
sp
is declared but not used in the code.Remove the unused variable to clean up the code.
- double **sp = atom->sp;
502-502
: Remove Unused Variablefm
Similar to the previous comment, the variable
fm
is declared but not utilized.Remove the unused variable:
- double **fm = atom->fm;
556-556
: Remove Commented-Out CodeThe commented-out code may cause confusion.
Delete the commented line to improve code readability.
- // int ago = numb_models > 1 ? 0 : neighbor->ago;
834-840
: Clarify Error Message for Serial ExecutionThe error message "Serial version does not support model devi" may be unclear to users.
Improve the error message for clarity:
error->all(FLERR, "Serial execution does not support model deviation calculations. Please run in parallel to use this feature.");source/api_c/src/c_api.cc (1)
1872-1904
: Document ownership of returned C strings.The
DP_DeepBaseModelGetTypeMap
andDP_DeepBaseModelCheckOK
functions returnconst char*
pointers that are dynamically allocated usingnew[]
in thestring_to_char
function. Document that the caller is responsible for freeing this memory usingDP_DeleteChar
to prevent memory leaks.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (16)
source/api_c/include/c_api.h
(13 hunks)source/api_c/include/deepmd.hpp
(21 hunks)source/api_c/src/c_api.cc
(14 hunks)source/api_cc/include/DeepBaseModel.h
(1 hunks)source/api_cc/include/DeepPot.h
(13 hunks)source/api_cc/include/DeepPotPT.h
(3 hunks)source/api_cc/include/DeepPotTF.h
(2 hunks)source/api_cc/include/DeepSpin.h
(1 hunks)source/api_cc/include/DeepSpinPT.h
(1 hunks)source/api_cc/include/DeepSpinTF.h
(1 hunks)source/lmp/pair_base.cpp
(1 hunks)source/lmp/pair_base.h
(1 hunks)source/lmp/pair_deepmd.cpp
(6 hunks)source/lmp/pair_deepmd.h
(1 hunks)source/lmp/pair_deepspin.cpp
(1 hunks)source/lmp/pair_deepspin.h
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- source/api_cc/include/DeepSpinPT.h
- source/api_cc/include/DeepSpinTF.h
- source/lmp/pair_deepmd.h
🔇 Additional comments (46)
source/lmp/pair_base.h (1)
37-37
: Consider marking base class destructor as virtual.
The destructor is marked with override
but the base class Pair
destructor might not be virtual. Verify that the base class destructor is virtual to ensure proper cleanup of derived classes.
source/api_cc/include/DeepBaseModel.h (1)
55-55
: Verify spin type handling across implementations
The new numb_types_spin()
method suggests this is a breaking change that requires all backend implementations to handle spin types. Ensure all derived classes implement this method correctly.
✅ Verification successful
Method numb_types_spin()
is properly implemented across the codebase
The pure virtual method numb_types_spin()
is correctly implemented by all derived classes:
DeepPotTF
,DeepPotPT
,DeepSpinTF
, andDeepSpinPT
classes implement it with proper initialization checksDeepBaseModel
implements it by delegating to the underlyingdpbase
- Unit tests verify the functionality (e.g., in
test_deeppot_a.cc
) - The method is actively used in LAMMPS integration code for spin-related calculations
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for all implementations of numb_types_spin
ast-grep --pattern 'numb_types_spin() {
$$$
}'
Length of output: 50
Script:
#!/bin/bash
# Let's try a different pattern to find implementations, including const qualifier
ast-grep --pattern 'numb_types_spin() const {
$$$
}'
# Also search for any files containing numb_types_spin to catch all possible implementations
rg "numb_types_spin" -A 2
Length of output: 9210
source/api_cc/include/DeepPotPT.h (2)
19-19
: Good addition of virtual destructor.
Adding the virtual destructor is essential for proper cleanup in the inheritance hierarchy, preventing potential resource leaks when deleting derived class objects through base class pointers.
13-13
: Base class change looks good, but verify inheritance chain.
The change from DeepPotBase
to DeepPotBackend
suggests a good architectural separation for backend-specific implementations.
Let's verify the inheritance chain and related classes:
✅ Verification successful
Base class change is consistent with the codebase architecture.
The verification shows that:
- Both
DeepPotPT
andDeepPotTF
now inherit fromDeepPotBackend
DeepPotBackend
is properly defined as a base class inDeepPot.h
, inheriting fromDeepBaseModelBackend
- The inheritance hierarchy is clean and consistent:
DeepPotPT
→DeepPotBackend
→DeepBaseModelBackend
DeepPotTF
→DeepPotBackend
→DeepBaseModelBackend
The change from DeepPotBase
to DeepPotBackend
is part of a well-structured refactoring that establishes a clear backend-specific implementation hierarchy.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other classes that might be affected by this base class change
rg -l "class.*:.*public.*DeepPot(Base|Backend)" --type cpp --type hpp
Length of output: 99
Script:
#!/bin/bash
# Search for other classes that might be affected by this base class change
# Using .h extension instead of .hpp
rg -l "class.*:.*public.*DeepPot(Base|Backend)" --type cpp --type h
# Also search for the base class definitions
rg "class.*(DeepPotBase|DeepPotBackend)" --type cpp --type h
# Find all header files in the codebase to ensure we're not missing any extensions
fd -e h -e hpp
Length of output: 2758
Script:
#!/bin/bash
# Let's check the content of DeepPotTF.h to see if it also changed from Base to Backend
rg "DeepPotBase" source/api_cc/include/DeepPotTF.h
# Check DeepPot.h to understand the base class hierarchy
cat source/api_cc/include/DeepPot.h
Length of output: 31761
source/api_cc/include/DeepSpin.h (3)
1-10
: LGTM!
The file structure follows best practices with proper license header, include guard, and necessary dependencies.
220-231
: Input validation reminder
A previous review already suggested adding input validation for array dimensions. This applies to all compute methods in this class.
Also applies to: 271-285, 327-340, 384-400
540-540
: Member initialization reminder
A previous review already flagged the need for proper initialization of the dps
member variable.
source/api_cc/include/DeepPot.h (1)
581-582
: Vector parameters properly handle multi-model outputs
The compute methods now correctly use std::vector<std::vector<VALUETYPE>>
for force and virial outputs, which is essential for handling multiple model predictions in the spin calculations. The parameter ordering is consistent across all method overloads.
Also applies to: 614-617, 649-650, 688-691
source/api_c/include/c_api.h (3)
13-13
: LGTM: API version bump is appropriate.
The version bump to 23 is well-documented and justified by the significant additions of spin model support.
97-109
: LGTM: Well-structured base model implementation.
The new base model structures and methods provide a solid foundation for both regular and spin models. The implementation:
- Follows consistent patterns
- Has thorough documentation
- Provides clear separation of concerns
Also applies to: 1132-1215
157-188
: LGTM: Comprehensive spin model implementation.
The spin model implementation:
- Maintains consistent structure with existing DeepPot implementation
- Properly handles both double and float precision
- Adds necessary parameters for magnetic forces
Also applies to: 368-496, 745-784
source/api_c/include/deepmd.hpp (2)
839-947
: LGTM! Well-structured base class implementation
The DeepBaseModel class provides a clean abstraction with:
- Good separation of concerns
- Proper error handling
- Well-documented methods
- Type-safe parameter validation
1500-1539
:
Add validation for spin vector dimensions
The compute method should validate that the spin vector has the correct dimensions (nframes * natoms * 3) before computation to prevent buffer overflows.
unsigned int natoms = atype.size();
unsigned int nframes = natoms > 0 ? coord.size() / natoms / 3 : 1;
assert(nframes * natoms * 3 == coord.size());
+ assert(nframes * natoms * 3 == spin.size()); // Validate spin dimensions
if (!box.empty()) {
assert(box.size() == nframes * 9);
}
Likely invalid or redundant comment.
source/api_cc/include/DeepPotTF.h (3)
13-13
: Update in inheritance improves code structure
The change from inheriting DeepPotBase
to DeepPotBackend
enhances the modularity and maintainability of the class hierarchy.
19-19
: Addition of virtual destructor ensures proper cleanup
By declaring a virtual
destructor, you guarantee that derived class destructors are called correctly, preventing resource leaks.
309-321
: New member variables support spin system functionality
The introduction of member variables like virtual_len
, spin_norm
, and extended neighbor lists enhances the class's capability to handle spin models effectively.
source/lmp/pair_base.cpp (4)
373-378
: Ensure allocated memory in init_style()
is properly deallocated
The arrays counts
, displacements
, stdfsend
, stdfrecv
, tagsend
, and tagrecv
allocated in init_style()
when out_each
is 1
are not being deallocated in the destructor, leading to potential memory leaks.
This issue was previously raised and is still applicable. Please refer to the past review comments and ensure all allocated memory is properly freed in the destructor.
254-256
: Unused local variables dx
, dy
, and dz
The variables dx
, dy
, and dz
are declared but not used in make_ttm_aparam
, which may lead to compiler warnings.
This issue was previously identified by static analysis tools and is still present. Consider removing these unused variables to clean up the code.
254-256
: Correct variable used in dz
calculation
The calculation of dz
uses nynodes
instead of nznodes
, which appears to be a typo.
This issue was previously noted and remains unresolved. Please update the calculation:
- double dz = domain->zprd / nynodes;
+ double dz = domain->zprd / nznodes;
415-422
: Update neighbor request for LAMMPS versions
Ensure compatibility with different LAMMPS versions by correctly setting neighbor requests.
Please verify that the neighbor request setup is appropriate for the targeted LAMMPS version.
Run the following script to check for any deprecated neighbor request methods:
This will help identify any potential issues with neighbor requests across different LAMMPS versions.
✅ Verification successful
The previous command failed due to incorrect ripgrep syntax. Let's try with the correct syntax to gather information about neighbor request patterns and version-specific code across the codebase.
The neighbor request implementation is correctly version-dependent
The code correctly handles neighbor requests for different LAMMPS versions:
- For LAMMPS >= 20220324, it uses the new
add_request
API withNeighConst::REQ_FULL
- For older versions, it uses the legacy
request
API with appropriate flags (half = 0
,full = 1
)
This pattern is consistently used across the codebase, as evidenced by similar version-specific implementations in compute_deeptensor_atom.cpp
. The implementation aligns with LAMMPS' evolution of the neighbor list API and maintains backward compatibility.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for usage of deprecated neighbor request methods.
# Search for neighbor request code patterns.
rg 'neighbor->request\(' --include 'pair_*.cpp' -A 3
Length of output: 496
Script:
#!/bin/bash
# Search for neighbor request code patterns with correct ripgrep syntax
rg "neighbor->request" -t cpp
# Also search for the newer style requests
rg "neighbor->add_request" -t cpp
# Search for LAMMPS version checks related to neighbor requests
rg "LAMMPS_VERSION" -t cpp -B 2 -A 4
Length of output: 13605
source/lmp/pair_deepmd.cpp (7)
87-90
: Ensure Proper Initialization of Base Class
While the constructor correctly inherits from PairDeepBaseModel
, it's important to ensure that all necessary initializations are performed, even if the body is empty. If any member variables or resources require explicit initialization, they should be added here to prevent potential issues.
You can verify whether additional initialization is needed by reviewing the base class constructor and checking for any required initializations that are not automatically handled.
93-94
: Confirm Need for Empty Destructor
The destructor is currently empty. If the base class handles all necessary cleanup, this is acceptable. However, if there are resources or memory allocations specific to PairDeepMD
, they should be properly released here.
Ensure that no additional cleanup is required for member variables introduced in PairDeepMD
.
438-455
: Handle Ghost Types Appropriately
The code introduces a "ghost type" when a type is not found in the model and the type name is "NULL". Ensure that this handling aligns with the intended functionality, especially since spin-related types are being removed.
Verify whether the use of a ghost type is still relevant and correctly handled in subsequent code.
556-566
: Update Neighbor List Age Handling
The code adjusts ago
based on conditions related to model deviation calculations. Ensure that ago
is set correctly to maintain performance while ensuring accurate computations.
Confirm that setting ago = 0
when necessary does not introduce performance issues or unintended side effects.
834-840
: Ensure Serial Execution Path Handles Model Deviations Appropriately
The code currently raises an error if more than one model is used in serial execution.
Confirm whether the serial version should support model deviation calculations or if it's acceptable to restrict this functionality to parallel executions.
845-850
: Consider Newton's Third Law in Force Application
When applying forces in the loop over atoms, ensure that Newton's third law is correctly handled, especially if newton_pair
is enabled.
Confirm that the force accumulation is symmetric across interacting atom pairs if required by the simulation's settings.
802-805
:
Replace std::cout
with Proper Error Handling
Using std::cout
for error messages is not consistent with LAMMPS error handling practices.
Apply this diff to use error->all
:
if (atom->sp_flag) {
- std::cout << "Pair style 'deepmd' does not support spin atoms, please use "
- "pair style 'deepspin' instead."
- << std::endl;
+ error->all(FLERR, "Pair style 'deepmd' does not support spin atoms. "
+ "Please use pair style 'deepspin' instead.");
}
Also applies to similar code at lines 873-877 and 895-899.
Likely invalid or redundant comment.
source/api_c/src/c_api.cc (19)
48-56
: LGTM!
The DP_DeepBaseModel
class and its constructor, destructor, and member variables look good.
58-66
: LGTM!
The DP_DeepBaseModelDevi
class and its constructor, destructor, and member variables look good.
134-151
: LGTM!
The DP_DeepSpin
class and its constructor, destructor, and factory functions look good.
153-185
: LGTM!
The DP_DeepSpinModelDevi
class and its constructor, destructor, and factory functions look good.
378-408
: LGTM!
The template instantiations for DP_DeepSpinCompute_variant
look good.
574-609
: LGTM!
The template instantiations for DP_DeepSpinComputeNList_variant
look good.
997-1034
: LGTM!
The template instantiations for DP_DeepSpinModelDeviComputeNList_variant
look good.
1457-1475
: LGTM!
The DP_DeepSpinCompute2
function looks good.
1495-1513
: LGTM!
The DP_DeepSpinComputef2
function looks good.
1580-1601
: Handle frame count limitation.
Similar to DP_DeepSpinComputeNList2
, the DP_DeepSpinComputeNListf2
function also does not support nframes > 1
. Address this limitation consistently.
1763-1781
: Standardize error handling for frame count limitation.
The frame count limitation check in DP_DeepSpinModelDeviComputeNListfSP
uses std::runtime_error
while the rest of the codebase uses DP_REQUIRES_OK
. Standardize the error handling for consistency.
1804-1825
: Standardize error handling for frame count limitation.
The frame count limitation check in DP_DeepSpinModelDeviComputeNList2
uses std::runtime_error
while the rest of the codebase uses DP_REQUIRES_OK
. Standardize the error handling for consistency.
1848-1869
: Standardize error handling for frame count limitation.
The frame count limitation check in DP_DeepSpinModelDeviComputeNListf2
uses std::runtime_error
while the rest of the codebase uses DP_REQUIRES_OK
. Standardize the error handling for consistency.
1930-1932
: Document ownership of returned C string.
The DP_DeepBaseModelDeviCheckOK
function returns a const char*
pointer that is dynamically allocated. Document that the caller is responsible for freeing this memory using DP_DeleteChar
to prevent memory leaks.
2000-2031
: LGTM!
The DP_DeepSpin
methods that delegate to DP_DeepBaseModel
look good.
2033-2063
: LGTM!
The DP_DeepSpinModelDevi
methods that delegate to DP_DeepBaseModelDevi
look good.
509-573
: Verify spin vector normalization.
Similar to the DP_DeepSpinCompute_variant
function, DP_DeepSpinComputeNList_variant
should also validate that the input spin vectors are properly normalized before using them.
#!/bin/bash
# Description: Verify spin vectors are normalized in `DP_DeepSpinComputeNList_variant`.
# Test: Search for the spin vector assignment.
# Expect: Normalization check before assignment.
rg -A 5 $'std::vector<VALUETYPE> spin_\(spin, spin \+ nframes \* natoms \* 3\);'
1725-1743
: 🛠️ Refactor suggestion
Standardize error handling for frame count limitation.
The frame count limitation check in DP_DeepSpinModelDeviComputeNListSP
uses std::runtime_error
while the rest of the codebase uses DP_REQUIRES_OK
. Standardize the error handling for consistency.
Apply this diff:
- if (nframes > 1) {
- throw std::runtime_error("nframes > 1 not supported yet");
- }
+ if (nframes > 1) {
+ DP_REQUIRES_OK(dp, dp->dp.set_exception("nframes > 1 not supported yet"));
+ return;
+ }
Likely invalid or redundant comment.
318-376
: Verify spin vector normalization.
The DP_DeepSpinCompute_variant
function should validate that the input spin vectors are properly normalized. Consider adding a check before using the spin data.
double **scale; | ||
unsigned numb_models; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add RAII for raw pointer members.
The class contains raw pointer members (scale
, counts
, displacements
, tagsend
, tagrecv
, stdfsend
, stdfrecv
) but lacks proper copy control. Consider:
- Implementing the Rule of Three/Five
- Using smart pointers or containers
- Explicitly deleting copy operations if not needed
Also applies to: 98-101
MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models, MPI_DOUBLE, MPI_SUM, | ||
0, world); | ||
std::vector<std::vector<double>> all_virial_1(numb_models); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for MPI communication.
The MPI_Reduce call could fail but there's no error handling. Consider checking the return value and handling potential communication failures.
- MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models, MPI_DOUBLE, MPI_SUM,
- 0, world);
+ int mpi_result = MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models,
+ MPI_DOUBLE, MPI_SUM, 0, world);
+ if (mpi_result != MPI_SUCCESS) {
+ error->all(FLERR, "Failed to reduce virial values in model deviation calculation");
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models, MPI_DOUBLE, MPI_SUM, | |
0, world); | |
std::vector<std::vector<double>> all_virial_1(numb_models); | |
int mpi_result = MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models, | |
MPI_DOUBLE, MPI_SUM, 0, world); | |
if (mpi_result != MPI_SUCCESS) { | |
error->all(FLERR, "Failed to reduce virial values in model deviation calculation"); | |
} | |
std::vector<std::vector<double>> all_virial_1(numb_models); |
for (i = first; i < last; i++) { | ||
for (int dd = 0; dd < numb_models; ++dd) { | ||
buf[m++] = all_force[dd][3 * i + 0]; | ||
buf[m++] = all_force[dd][3 * i + 1]; | ||
buf[m++] = all_force[dd][3 * i + 2]; | ||
buf[m++] = all_force_mag[dd][3 * i + 0]; | ||
buf[m++] = all_force_mag[dd][3 * i + 1]; | ||
buf[m++] = all_force_mag[dd][3 * i + 2]; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add bounds checking for buffer access.
The buffer access in the pack_reverse_comm method lacks bounds checking, which could lead to buffer overflows.
+ if (m + 6 * numb_models > n * 6 * numb_models) {
+ error->one(FLERR, "Buffer overflow in pack_reverse_comm");
+ }
for (int dd = 0; dd < numb_models; ++dd) {
buf[m++] = all_force[dd][3 * i + 0];
buf[m++] = all_force[dd][3 * i + 1];
buf[m++] = all_force[dd][3 * i + 2];
buf[m++] = all_force_mag[dd][3 * i + 0];
buf[m++] = all_force_mag[dd][3 * i + 1];
buf[m++] = all_force_mag[dd][3 * i + 2];
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
for (i = first; i < last; i++) { | |
for (int dd = 0; dd < numb_models; ++dd) { | |
buf[m++] = all_force[dd][3 * i + 0]; | |
buf[m++] = all_force[dd][3 * i + 1]; | |
buf[m++] = all_force[dd][3 * i + 2]; | |
buf[m++] = all_force_mag[dd][3 * i + 0]; | |
buf[m++] = all_force_mag[dd][3 * i + 1]; | |
buf[m++] = all_force_mag[dd][3 * i + 2]; | |
} | |
} | |
for (i = first; i < last; i++) { | |
if (m + 6 * numb_models > n * 6 * numb_models) { | |
error->one(FLERR, "Buffer overflow in pack_reverse_comm"); | |
} | |
for (int dd = 0; dd < numb_models; ++dd) { | |
buf[m++] = all_force[dd][3 * i + 0]; | |
buf[m++] = all_force[dd][3 * i + 1]; | |
buf[m++] = all_force[dd][3 * i + 2]; | |
buf[m++] = all_force_mag[dd][3 * i + 0]; | |
buf[m++] = all_force_mag[dd][3 * i + 1]; | |
buf[m++] = all_force_mag[dd][3 * i + 2]; | |
} | |
} |
void ana_st(double &max, | ||
double &min, | ||
double &sum, | ||
const vector<double> &vec, | ||
const int &nloc) { | ||
if (nloc == 0) { | ||
return; | ||
} | ||
max = vec[0]; | ||
min = vec[0]; | ||
sum = vec[0]; | ||
for (unsigned ii = 1; ii < nloc; ++ii) { | ||
if (vec[ii] > max) { | ||
max = vec[ii]; | ||
} | ||
if (vec[ii] < min) { | ||
min = vec[ii]; | ||
} | ||
sum += vec[ii]; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent potential access to uninitialized elements in ana_st()
If vec
is empty but nloc
is greater than zero, accessing vec[0]
leads to undefined behavior. Ensure that vec
has at least nloc
elements before accessing.
Apply this diff to add a safety check:
if (nloc == 0) {
return;
}
+ if (vec.size() < static_cast<size_t>(nloc)) {
+ error->all(FLERR, "Vector size is smaller than nloc in ana_st()");
+ }
max = vec[0];
min = vec[0];
sum = vec[0];
Committable suggestion skipped: line range outside the PR's diff.
char host_name[MPI_MAX_PROCESSOR_NAME]; | ||
memset(host_name, '\0', sizeof(char) * MPI_MAX_PROCESSOR_NAME); | ||
char(*host_names)[MPI_MAX_PROCESSOR_NAME]; | ||
int n, namelen, color, rank, nprocs, myrank; | ||
size_t bytes; | ||
MPI_Comm nodeComm; | ||
|
||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); | ||
MPI_Comm_size(MPI_COMM_WORLD, &nprocs); | ||
MPI_Get_processor_name(host_name, &namelen); | ||
|
||
bytes = nprocs * sizeof(char[MPI_MAX_PROCESSOR_NAME]); | ||
host_names = (char(*)[MPI_MAX_PROCESSOR_NAME])malloc(bytes); | ||
for (int ii = 0; ii < nprocs; ii++) { | ||
memset(host_names[ii], '\0', sizeof(char) * MPI_MAX_PROCESSOR_NAME); | ||
} | ||
|
||
strcpy(host_names[rank], host_name); | ||
|
||
for (n = 0; n < nprocs; n++) { | ||
MPI_Bcast(&(host_names[n]), MPI_MAX_PROCESSOR_NAME, MPI_CHAR, n, | ||
MPI_COMM_WORLD); | ||
} | ||
qsort(host_names, nprocs, sizeof(char[MPI_MAX_PROCESSOR_NAME]), stringCmp); | ||
|
||
color = 0; | ||
for (n = 0; n < nprocs - 1; n++) { | ||
if (strcmp(host_name, host_names[n]) == 0) { | ||
break; | ||
} | ||
if (strcmp(host_names[n], host_names[n + 1])) { | ||
color++; | ||
} | ||
} | ||
|
||
MPI_Comm_split(MPI_COMM_WORLD, color, 0, &nodeComm); | ||
MPI_Comm_rank(nodeComm, &myrank); | ||
|
||
MPI_Barrier(MPI_COMM_WORLD); | ||
int looprank = myrank; | ||
// printf (" Assigning device %d to process on node %s rank %d, | ||
// OK\n",looprank, host_name, rank ); | ||
free(host_names); | ||
return looprank; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace manual memory management with std::vector
in get_node_rank()
Using malloc
and free
can lead to potential memory leaks and is not exception-safe. It is recommended to use std::vector
for automatic memory management and better code safety.
Apply this diff to refactor the code:
- bytes = nprocs * sizeof(char[MPI_MAX_PROCESSOR_NAME]);
- host_names = (char(*)[MPI_MAX_PROCESSOR_NAME])malloc(bytes);
- for (int ii = 0; ii < nprocs; ii++) {
- memset(host_names[ii], '\0', sizeof(char) * MPI_MAX_PROCESSOR_NAME);
- }
+ std::vector<std::array<char, MPI_MAX_PROCESSOR_NAME>> host_names(nprocs);
+ for (int ii = 0; ii < nprocs; ii++) {
+ host_names[ii].fill('\0');
+ }
strcpy(host_names[rank], host_name);
for (n = 0; n < nprocs; n++) {
- MPI_Bcast(&(host_names[n]), MPI_MAX_PROCESSOR_NAME, MPI_CHAR, n,
- MPI_COMM_WORLD);
+ MPI_Bcast(host_names[n].data(), MPI_MAX_PROCESSOR_NAME, MPI_CHAR, n,
+ MPI_COMM_WORLD);
}
qsort(host_names, nprocs, sizeof(char[MPI_MAX_PROCESSOR_NAME]), stringCmp);
// ...
- free(host_names);
Note: You will also need to adjust the calls to qsort
and any code that directly manipulates host_names
to work with std::vector
and std::array
.
Committable suggestion skipped: line range outside the PR's diff.
vector<double> dspin(nall * 3, 0.); | ||
vector<double> dfm(nall * 3, 0.); | ||
double **sp = atom->sp; | ||
double **fm = atom->fm; | ||
if (atom->sp_flag) { | ||
std::cout << "Pair style 'deepmd' does not support spin atoms, please use " | ||
"pair style 'deepspin' instead." | ||
<< std::endl; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove Unused Spin-Related Variables and Checks
Variables like dspin
, dfm
, sp
, and fm
are declared but not used since spin atoms are no longer supported. Additionally, the check for atom->sp_flag
results in a message directing users to deepspin
.
Remove the unnecessary variables and the check:
- vector<double> dspin(nall * 3, 0.);
- vector<double> dfm(nall * 3, 0.);
- double **sp = atom->sp;
- double **fm = atom->fm;
- if (atom->sp_flag) {
- std::cout << "Pair style 'deepmd' does not support spin atoms, please use "
- "pair style 'deepspin' instead."
- << std::endl;
- }
This streamlines the code and eliminates confusion.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
vector<double> dspin(nall * 3, 0.); | |
vector<double> dfm(nall * 3, 0.); | |
double **sp = atom->sp; | |
double **fm = atom->fm; | |
if (atom->sp_flag) { | |
std::cout << "Pair style 'deepmd' does not support spin atoms, please use " | |
"pair style 'deepspin' instead." | |
<< std::endl; | |
} |
if (!atom->sp_flag) { | ||
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v" | ||
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v" | ||
<< setw(18 + 1) << "max_devi_f" << setw(18 + 1) << "min_devi_f" | ||
<< setw(18 + 1) << "avg_devi_f"; | ||
if (out_each) { | ||
// at this time, we don't know how many atoms | ||
fp << setw(18 + 1) << "atm_devi_f(N)"; | ||
} | ||
fp << endl; | ||
} else { | ||
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v" | ||
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v" | ||
<< setw(18 + 1) << "max_devi_fr" << setw(18 + 1) << "min_devi_fr" | ||
<< setw(18 + 1) << "avg_devi_fr" << setw(18 + 1) << "max_devi_fm" | ||
<< setw(18 + 1) << "min_devi_fm" << setw(18 + 1) << "avg_devi_fm" | ||
<< endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ensure Consistency in Output Headers
The code differentiates output headers based on whether atom->sp_flag
is true or false. However, since the class no longer supports spin atoms and directs users to use deepspin
, the block where atom->sp_flag
is true may be unnecessary.
Consider removing the else
block since atom->sp_flag
should always be false in this context. This will simplify the code and prevent confusion.
if (!atom->sp_flag) {
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v"
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v"
<< setw(18 + 1) << "max_devi_f" << setw(18 + 1) << "min_devi_f"
<< setw(18 + 1) << "avg_devi_f";
if (out_each) {
// at this time, we don't know how many atoms
fp << setw(18 + 1) << "atm_devi_f(N)";
}
fp << endl;
- } else {
- fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v"
- << setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v"
- << setw(18 + 1) << "max_devi_fr" << setw(18 + 1) << "min_devi_fr"
- << setw(18 + 1) << "avg_devi_fr" << setw(18 + 1) << "max_devi_fm"
- << setw(18 + 1) << "min_devi_fm" << setw(18 + 1) << "avg_devi_fm"
- << endl;
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (!atom->sp_flag) { | |
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v" | |
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v" | |
<< setw(18 + 1) << "max_devi_f" << setw(18 + 1) << "min_devi_f" | |
<< setw(18 + 1) << "avg_devi_f"; | |
if (out_each) { | |
// at this time, we don't know how many atoms | |
fp << setw(18 + 1) << "atm_devi_f(N)"; | |
} | |
fp << endl; | |
} else { | |
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v" | |
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v" | |
<< setw(18 + 1) << "max_devi_fr" << setw(18 + 1) << "min_devi_fr" | |
<< setw(18 + 1) << "avg_devi_fr" << setw(18 + 1) << "max_devi_fm" | |
<< setw(18 + 1) << "min_devi_fm" << setw(18 + 1) << "avg_devi_fm" | |
<< endl; | |
if (!atom->sp_flag) { | |
fp << "#" << setw(12 - 1) << "step" << setw(18 + 1) << "max_devi_v" | |
<< setw(18 + 1) << "min_devi_v" << setw(18 + 1) << "avg_devi_v" | |
<< setw(18 + 1) << "max_devi_f" << setw(18 + 1) << "min_devi_f" | |
<< setw(18 + 1) << "avg_devi_f"; | |
if (out_each) { | |
// at this time, we don't know how many atoms | |
fp << setw(18 + 1) << "atm_devi_f(N)"; | |
} | |
fp << endl; | |
} |
double all_f_min = 0, all_f_max = 0, all_f_avg = 0; | ||
double all_fm_min = 0, all_fm_max = 0, all_fm_avg = 0; | ||
MPI_Reduce(&min, &all_f_min, 1, MPI_DOUBLE, MPI_MIN, 0, world); | ||
MPI_Reduce(&max, &all_f_max, 1, MPI_DOUBLE, MPI_MAX, 0, world); | ||
MPI_Reduce(&avg, &all_f_avg, 1, MPI_DOUBLE, MPI_SUM, 0, world); | ||
all_f_avg /= double(atom->natoms); | ||
// std v | ||
std::vector<double> send_v(9 * numb_models); | ||
std::vector<double> recv_v(9 * numb_models); | ||
for (int kk = 0; kk < numb_models; ++kk) { | ||
for (int ii = 0; ii < 9; ++ii) { | ||
send_v[kk * 9 + ii] = all_virial[kk][ii] / double(atom->natoms); | ||
} | ||
} | ||
MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models, MPI_DOUBLE, MPI_SUM, | ||
0, world); | ||
std::vector<std::vector<double>> all_virial_1(numb_models); | ||
std::vector<double> avg_virial, std_virial; | ||
for (int kk = 0; kk < numb_models; ++kk) { | ||
all_virial_1[kk].resize(9); | ||
for (int ii = 0; ii < 9; ++ii) { | ||
all_virial_1[kk][ii] = recv_v[kk * 9 + ii]; | ||
} | ||
} | ||
double all_v_min = numeric_limits<double>::max(), all_v_max = 0, | ||
all_v_avg = 0; | ||
if (rank == 0) { | ||
deep_pot_model_devi.compute_avg(avg_virial, all_virial_1); | ||
deep_pot_model_devi.compute_std(std_virial, avg_virial, all_virial_1, | ||
1); | ||
if (out_rel_v == 1) { | ||
deep_pot_model_devi.compute_relative_std(std_virial, avg_virial, | ||
eps_v, 1); | ||
} | ||
for (int ii = 0; ii < 9; ++ii) { | ||
if (std_virial[ii] > all_v_max) { | ||
all_v_max = std_virial[ii]; | ||
} | ||
if (std_virial[ii] < all_v_min) { | ||
all_v_min = std_virial[ii]; | ||
} | ||
all_v_avg += std_virial[ii] * std_virial[ii]; | ||
} | ||
all_v_avg = sqrt(all_v_avg / 9); | ||
} | ||
if (rank == 0) { | ||
all_v_max *= ener_unit_cvt_factor; | ||
all_v_min *= ener_unit_cvt_factor; | ||
all_v_avg *= ener_unit_cvt_factor; | ||
all_f_max *= force_unit_cvt_factor; | ||
all_f_min *= force_unit_cvt_factor; | ||
all_f_avg *= force_unit_cvt_factor; | ||
fp << setw(12) << update->ntimestep << " " << setw(18) << all_v_max | ||
<< " " << setw(18) << all_v_min << " " << setw(18) << all_v_avg | ||
<< " " << setw(18) << all_f_max << " " << setw(18) << all_f_min | ||
<< " " << setw(18) << all_f_avg; | ||
} | ||
if (out_each == 1) { | ||
// need support for spin atomic force. | ||
vector<double> std_f_all(atom->natoms); | ||
// Gather std_f and tags | ||
tagint *tag = atom->tag; | ||
int nprocs = comm->nprocs; | ||
// Grow arrays if necessary | ||
if (atom->natoms > stdf_comm_buff_size) { | ||
stdf_comm_buff_size = atom->natoms; | ||
memory->destroy(stdfsend); | ||
memory->destroy(stdfrecv); | ||
memory->destroy(tagsend); | ||
memory->destroy(tagrecv); | ||
memory->create(stdfsend, stdf_comm_buff_size, "deepmd:stdfsendall"); | ||
memory->create(stdfrecv, stdf_comm_buff_size, "deepmd:stdfrecvall"); | ||
memory->create(tagsend, stdf_comm_buff_size, "deepmd:tagsendall"); | ||
memory->create(tagrecv, stdf_comm_buff_size, "deepmd:tagrecvall"); | ||
} | ||
for (int ii = 0; ii < nlocal; ii++) { | ||
tagsend[ii] = tag[ii]; | ||
stdfsend[ii] = std_f[ii]; | ||
} | ||
MPI_Gather(&nlocal, 1, MPI_INT, counts, 1, MPI_INT, 0, world); | ||
displacements[0] = 0; | ||
for (int ii = 0; ii < nprocs - 1; ii++) { | ||
displacements[ii + 1] = displacements[ii] + counts[ii]; | ||
} | ||
MPI_Gatherv(tagsend, nlocal, MPI_LMP_TAGINT, tagrecv, counts, | ||
displacements, MPI_LMP_TAGINT, 0, world); | ||
MPI_Gatherv(stdfsend, nlocal, MPI_DOUBLE, stdfrecv, counts, | ||
displacements, MPI_DOUBLE, 0, world); | ||
if (rank == 0) { | ||
for (int dd = 0; dd < atom->natoms; ++dd) { | ||
std_f_all[tagrecv[dd] - 1] = stdfrecv[dd] * force_unit_cvt_factor; | ||
} | ||
for (int dd = 0; dd < atom->natoms; ++dd) { | ||
fp << " " << setw(18) << std_f_all[dd]; | ||
} | ||
} | ||
} | ||
if (rank == 0) { | ||
fp << endl; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Optimize Model Deviation Logging
In the block handling model deviation output, ensure that:
- Variables are properly initialized and used.
- Unused variables like
std_fm
,tmp_avg_fm
,all_fm_min
,all_fm_max
,all_fm_avg
are removed. - Logging only includes relevant information since spin atoms are not supported.
Apply changes to remove unused variables and adjust the logging accordingly.
vector<double> std_f;
vector<double> tmp_avg_f;
- vector<double> std_fm;
- vector<double> tmp_avg_fm;
deep_pot_model_devi.compute_avg(tmp_avg_f, all_force);
deep_pot_model_devi.compute_std_f(std_f, tmp_avg_f, all_force);
if (out_rel == 1) {
deep_pot_model_devi.compute_relative_std_f(std_f, tmp_avg_f, eps);
}
double min = numeric_limits<double>::max(), max = 0, avg = 0;
ana_st(max, min, avg, std_f, nlocal);
double all_f_min = 0, all_f_max = 0, all_f_avg = 0;
- double all_fm_min = 0, all_fm_max = 0, all_fm_avg = 0;
MPI_Reduce(&min, &all_f_min, 1, MPI_DOUBLE, MPI_MIN, 0, world);
MPI_Reduce(&max, &all_f_max, 1, MPI_DOUBLE, MPI_MAX, 0, world);
MPI_Reduce(&avg, &all_f_avg, 1, MPI_DOUBLE, MPI_SUM, 0, world);
all_f_avg /= double(atom->natoms);
// std v
Adjust the code to ensure only relevant data is calculated and outputted.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (out_freq > 0 && update->ntimestep % out_freq == 0) { | |
int rank = comm->me; | |
// std force | |
if (newton_pair) { | |
#if LAMMPS_VERSION_NUMBER >= 20220324 | |
comm->reverse_comm(this); | |
#else | |
comm->reverse_comm_pair(this); | |
#endif | |
} | |
vector<double> std_f; | |
vector<double> tmp_avg_f; | |
vector<double> std_fm; | |
vector<double> tmp_avg_fm; | |
deep_pot_model_devi.compute_avg(tmp_avg_f, all_force); | |
deep_pot_model_devi.compute_std_f(std_f, tmp_avg_f, all_force); | |
if (out_rel == 1) { | |
deep_pot_model_devi.compute_relative_std_f(std_f, tmp_avg_f, eps); | |
} | |
double min = numeric_limits<double>::max(), max = 0, avg = 0; | |
ana_st(max, min, avg, std_f, nlocal); | |
double all_f_min = 0, all_f_max = 0, all_f_avg = 0; | |
double all_fm_min = 0, all_fm_max = 0, all_fm_avg = 0; | |
MPI_Reduce(&min, &all_f_min, 1, MPI_DOUBLE, MPI_MIN, 0, world); | |
MPI_Reduce(&max, &all_f_max, 1, MPI_DOUBLE, MPI_MAX, 0, world); | |
MPI_Reduce(&avg, &all_f_avg, 1, MPI_DOUBLE, MPI_SUM, 0, world); | |
all_f_avg /= double(atom->natoms); | |
// std v | |
std::vector<double> send_v(9 * numb_models); | |
std::vector<double> recv_v(9 * numb_models); | |
for (int kk = 0; kk < numb_models; ++kk) { | |
for (int ii = 0; ii < 9; ++ii) { | |
send_v[kk * 9 + ii] = all_virial[kk][ii] / double(atom->natoms); | |
} | |
} | |
MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models, MPI_DOUBLE, MPI_SUM, | |
0, world); | |
std::vector<std::vector<double>> all_virial_1(numb_models); | |
std::vector<double> avg_virial, std_virial; | |
for (int kk = 0; kk < numb_models; ++kk) { | |
all_virial_1[kk].resize(9); | |
for (int ii = 0; ii < 9; ++ii) { | |
all_virial_1[kk][ii] = recv_v[kk * 9 + ii]; | |
} | |
} | |
double all_v_min = numeric_limits<double>::max(), all_v_max = 0, | |
all_v_avg = 0; | |
if (rank == 0) { | |
deep_pot_model_devi.compute_avg(avg_virial, all_virial_1); | |
deep_pot_model_devi.compute_std(std_virial, avg_virial, all_virial_1, | |
1); | |
if (out_rel_v == 1) { | |
deep_pot_model_devi.compute_relative_std(std_virial, avg_virial, | |
eps_v, 1); | |
} | |
for (int ii = 0; ii < 9; ++ii) { | |
if (std_virial[ii] > all_v_max) { | |
all_v_max = std_virial[ii]; | |
} | |
if (std_virial[ii] < all_v_min) { | |
all_v_min = std_virial[ii]; | |
} | |
all_v_avg += std_virial[ii] * std_virial[ii]; | |
} | |
all_v_avg = sqrt(all_v_avg / 9); | |
} | |
if (rank == 0) { | |
all_v_max *= ener_unit_cvt_factor; | |
all_v_min *= ener_unit_cvt_factor; | |
all_v_avg *= ener_unit_cvt_factor; | |
all_f_max *= force_unit_cvt_factor; | |
all_f_min *= force_unit_cvt_factor; | |
all_f_avg *= force_unit_cvt_factor; | |
fp << setw(12) << update->ntimestep << " " << setw(18) << all_v_max | |
<< " " << setw(18) << all_v_min << " " << setw(18) << all_v_avg | |
<< " " << setw(18) << all_f_max << " " << setw(18) << all_f_min | |
<< " " << setw(18) << all_f_avg; | |
} | |
if (out_each == 1) { | |
// need support for spin atomic force. | |
vector<double> std_f_all(atom->natoms); | |
// Gather std_f and tags | |
tagint *tag = atom->tag; | |
int nprocs = comm->nprocs; | |
// Grow arrays if necessary | |
if (atom->natoms > stdf_comm_buff_size) { | |
stdf_comm_buff_size = atom->natoms; | |
memory->destroy(stdfsend); | |
memory->destroy(stdfrecv); | |
memory->destroy(tagsend); | |
memory->destroy(tagrecv); | |
memory->create(stdfsend, stdf_comm_buff_size, "deepmd:stdfsendall"); | |
memory->create(stdfrecv, stdf_comm_buff_size, "deepmd:stdfrecvall"); | |
memory->create(tagsend, stdf_comm_buff_size, "deepmd:tagsendall"); | |
memory->create(tagrecv, stdf_comm_buff_size, "deepmd:tagrecvall"); | |
} | |
for (int ii = 0; ii < nlocal; ii++) { | |
tagsend[ii] = tag[ii]; | |
stdfsend[ii] = std_f[ii]; | |
} | |
MPI_Gather(&nlocal, 1, MPI_INT, counts, 1, MPI_INT, 0, world); | |
displacements[0] = 0; | |
for (int ii = 0; ii < nprocs - 1; ii++) { | |
displacements[ii + 1] = displacements[ii] + counts[ii]; | |
} | |
MPI_Gatherv(tagsend, nlocal, MPI_LMP_TAGINT, tagrecv, counts, | |
displacements, MPI_LMP_TAGINT, 0, world); | |
MPI_Gatherv(stdfsend, nlocal, MPI_DOUBLE, stdfrecv, counts, | |
displacements, MPI_DOUBLE, 0, world); | |
if (rank == 0) { | |
for (int dd = 0; dd < atom->natoms; ++dd) { | |
std_f_all[tagrecv[dd] - 1] = stdfrecv[dd] * force_unit_cvt_factor; | |
} | |
for (int dd = 0; dd < atom->natoms; ++dd) { | |
fp << " " << setw(18) << std_f_all[dd]; | |
} | |
} | |
} | |
if (rank == 0) { | |
fp << endl; | |
} | |
if (out_freq > 0 && update->ntimestep % out_freq == 0) { | |
int rank = comm->me; | |
// std force | |
if (newton_pair) { | |
#if LAMMPS_VERSION_NUMBER >= 20220324 | |
comm->reverse_comm(this); | |
#else | |
comm->reverse_comm_pair(this); | |
#endif | |
} | |
vector<double> std_f; | |
vector<double> tmp_avg_f; | |
deep_pot_model_devi.compute_avg(tmp_avg_f, all_force); | |
deep_pot_model_devi.compute_std_f(std_f, tmp_avg_f, all_force); | |
if (out_rel == 1) { | |
deep_pot_model_devi.compute_relative_std_f(std_f, tmp_avg_f, eps); | |
} | |
double min = numeric_limits<double>::max(), max = 0, avg = 0; | |
ana_st(max, min, avg, std_f, nlocal); | |
double all_f_min = 0, all_f_max = 0, all_f_avg = 0; | |
MPI_Reduce(&min, &all_f_min, 1, MPI_DOUBLE, MPI_MIN, 0, world); | |
MPI_Reduce(&max, &all_f_max, 1, MPI_DOUBLE, MPI_MAX, 0, world); | |
MPI_Reduce(&avg, &all_f_avg, 1, MPI_DOUBLE, MPI_SUM, 0, world); | |
all_f_avg /= double(atom->natoms); | |
// std v | |
std::vector<double> send_v(9 * numb_models); | |
std::vector<double> recv_v(9 * numb_models); | |
for (int kk = 0; kk < numb_models; ++kk) { | |
for (int ii = 0; ii < 9; ++ii) { | |
send_v[kk * 9 + ii] = all_virial[kk][ii] / double(atom->natoms); | |
} | |
} | |
MPI_Reduce(&send_v[0], &recv_v[0], 9 * numb_models, MPI_DOUBLE, MPI_SUM, | |
0, world); | |
std::vector<std::vector<double>> all_virial_1(numb_models); | |
std::vector<double> avg_virial, std_virial; | |
for (int kk = 0; kk < numb_models; ++kk) { | |
all_virial_1[kk].resize(9); | |
for (int ii = 0; ii < 9; ++ii) { | |
all_virial_1[kk][ii] = recv_v[kk * 9 + ii]; | |
} | |
} | |
double all_v_min = numeric_limits<double>::max(), all_v_max = 0, | |
all_v_avg = 0; | |
if (rank == 0) { | |
deep_pot_model_devi.compute_avg(avg_virial, all_virial_1); | |
deep_pot_model_devi.compute_std(std_virial, avg_virial, all_virial_1, | |
1); | |
if (out_rel_v == 1) { | |
deep_pot_model_devi.compute_relative_std(std_virial, avg_virial, | |
eps_v, 1); | |
} | |
for (int ii = 0; ii < 9; ++ii) { | |
if (std_virial[ii] > all_v_max) { | |
all_v_max = std_virial[ii]; | |
} | |
if (std_virial[ii] < all_v_min) { | |
all_v_min = std_virial[ii]; | |
} | |
all_v_avg += std_virial[ii] * std_virial[ii]; | |
} | |
all_v_avg = sqrt(all_v_avg / 9); | |
} | |
if (rank == 0) { | |
all_v_max *= ener_unit_cvt_factor; | |
all_v_min *= ener_unit_cvt_factor; | |
all_v_avg *= ener_unit_cvt_factor; | |
all_f_max *= force_unit_cvt_factor; | |
all_f_min *= force_unit_cvt_factor; | |
all_f_avg *= force_unit_cvt_factor; | |
fp << setw(12) << update->ntimestep << " " << setw(18) << all_v_max | |
<< " " << setw(18) << all_v_min << " " << setw(18) << all_v_avg | |
<< " " << setw(18) << all_f_max << " " << setw(18) << all_f_min | |
<< " " << setw(18) << all_f_avg; | |
} | |
if (out_each == 1) { | |
// need support for spin atomic force. | |
vector<double> std_f_all(atom->natoms); | |
// Gather std_f and tags | |
tagint *tag = atom->tag; | |
int nprocs = comm->nprocs; | |
// Grow arrays if necessary | |
if (atom->natoms > stdf_comm_buff_size) { | |
stdf_comm_buff_size = atom->natoms; | |
memory->destroy(stdfsend); | |
memory->destroy(stdfrecv); | |
memory->destroy(tagsend); | |
memory->destroy(tagrecv); | |
memory->create(stdfsend, stdf_comm_buff_size, "deepmd:stdfsendall"); | |
memory->create(stdfrecv, stdf_comm_buff_size, "deepmd:stdfrecvall"); | |
memory->create(tagsend, stdf_comm_buff_size, "deepmd:tagsendall"); | |
memory->create(tagrecv, stdf_comm_buff_size, "deepmd:tagrecvall"); | |
} | |
for (int ii = 0; ii < nlocal; ii++) { | |
tagsend[ii] = tag[ii]; | |
stdfsend[ii] = std_f[ii]; | |
} | |
MPI_Gather(&nlocal, 1, MPI_INT, counts, 1, MPI_INT, 0, world); | |
displacements[0] = 0; | |
for (int ii = 0; ii < nprocs - 1; ii++) { | |
displacements[ii + 1] = displacements[ii] + counts[ii]; | |
} | |
MPI_Gatherv(tagsend, nlocal, MPI_LMP_TAGINT, tagrecv, counts, | |
displacements, MPI_LMP_TAGINT, 0, world); | |
MPI_Gatherv(stdfsend, nlocal, MPI_DOUBLE, stdfrecv, counts, | |
displacements, MPI_DOUBLE, 0, world); | |
if (rank == 0) { | |
for (int dd = 0; dd < atom->natoms; ++dd) { | |
std_f_all[tagrecv[dd] - 1] = stdfrecv[dd] * force_unit_cvt_factor; | |
} | |
for (int dd = 0; dd < atom->natoms; ++dd) { | |
fp << " " << setw(18) << std_f_all[dd]; | |
} | |
} | |
} | |
if (rank == 0) { | |
fp << endl; | |
} |
void DP_DeepSpinComputeNList2(DP_DeepSpin* dp, | ||
const int nframes, | ||
const int natoms, | ||
const double* coord, | ||
const double* spin, | ||
const int* atype, | ||
const double* cell, | ||
const int nghost, | ||
const DP_Nlist* nlist, | ||
const int ago, | ||
const double* fparam, | ||
const double* aparam, | ||
double* energy, | ||
double* force, | ||
double* force_mag, | ||
double* virial, | ||
double* atomic_energy, | ||
double* atomic_virial) { | ||
DP_DeepSpinComputeNList_variant<double>( | ||
dp, nframes, natoms, coord, spin, atype, cell, nghost, nlist, ago, fparam, | ||
aparam, energy, force, force_mag, virial, atomic_energy, atomic_virial); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle frame count limitation.
The DP_DeepSpinComputeNList2
function does not support nframes > 1
. Consider implementing support for multiple frames or clearly document this limitation.
Do you want me to open a GitHub issue to track implementing multi-frame support or updating the documentation?
// support spin multi model. | ||
template <typename VALUETYPE> | ||
void DP_DeepSpinModelDeviComputeNList_variant(DP_DeepSpinModelDevi* dp, | ||
const int nframes, | ||
const int natoms, | ||
const VALUETYPE* coord, | ||
const VALUETYPE* spin, | ||
const int* atype, | ||
const VALUETYPE* cell, | ||
const int nghost, | ||
const DP_Nlist* nlist, | ||
const int ago, | ||
const VALUETYPE* fparam, | ||
const VALUETYPE* aparam, | ||
double* energy, | ||
VALUETYPE* force, | ||
VALUETYPE* force_mag, | ||
VALUETYPE* virial, | ||
VALUETYPE* atomic_energy, | ||
VALUETYPE* atomic_virial) { | ||
if (nframes > 1) { | ||
throw std::runtime_error("nframes > 1 not supported yet"); | ||
} | ||
// init C++ vectors from C arrays | ||
std::vector<VALUETYPE> coord_(coord, coord + natoms * 3); | ||
std::vector<VALUETYPE> spin_(spin, spin + natoms * 3); | ||
std::vector<int> atype_(atype, atype + natoms); | ||
std::vector<VALUETYPE> cell_; | ||
if (cell) { | ||
// pbc | ||
cell_.assign(cell, cell + 9); | ||
} | ||
std::vector<VALUETYPE> fparam_; | ||
if (fparam) { | ||
fparam_.assign(fparam, fparam + dp->dfparam); | ||
} | ||
std::vector<VALUETYPE> aparam_; | ||
if (aparam) { | ||
aparam_.assign( | ||
aparam, | ||
aparam + (dp->aparam_nall ? natoms : (natoms - nghost)) * dp->daparam); | ||
} | ||
// different from DeepPot | ||
std::vector<double> e; | ||
std::vector<std::vector<VALUETYPE>> f, fm, v, ae, av; | ||
if (atomic_energy || atomic_virial) { | ||
DP_REQUIRES_OK( | ||
dp, dp->dp.compute(e, f, fm, v, ae, av, coord_, spin_, atype_, cell_, | ||
nghost, nlist->nl, ago, fparam_, aparam_)); | ||
} else { | ||
DP_REQUIRES_OK( | ||
dp, dp->dp.compute(e, f, fm, v, coord_, spin_, atype_, cell_, nghost, | ||
nlist->nl, ago, fparam_, aparam_)); | ||
} | ||
// 2D vector to 2D array, flatten first | ||
if (energy) { | ||
std::copy(e.begin(), e.end(), energy); | ||
} | ||
if (force) { | ||
std::vector<VALUETYPE> f_flat; | ||
flatten_vector(f_flat, f); | ||
std::copy(f_flat.begin(), f_flat.end(), force); | ||
} | ||
if (force_mag) { | ||
std::vector<VALUETYPE> f_mag_flat; | ||
flatten_vector(f_mag_flat, fm); | ||
std::copy(f_mag_flat.begin(), f_mag_flat.end(), force_mag); | ||
} | ||
if (virial) { | ||
std::vector<VALUETYPE> v_flat; | ||
flatten_vector(v_flat, v); | ||
std::copy(v_flat.begin(), v_flat.end(), virial); | ||
} | ||
if (atomic_energy) { | ||
std::vector<VALUETYPE> ae_flat; | ||
flatten_vector(ae_flat, ae); | ||
std::copy(ae_flat.begin(), ae_flat.end(), atomic_energy); | ||
} | ||
if (atomic_virial) { | ||
std::vector<VALUETYPE> av_flat; | ||
flatten_vector(av_flat, av); | ||
std::copy(av_flat.begin(), av_flat.end(), atomic_virial); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Standardize error handling for frame count limitation.
The frame count limitation check uses std::runtime_error
while the rest of the codebase uses DP_REQUIRES_OK
. Standardize the error handling for consistency.
Apply this diff:
- if (nframes > 1) {
- throw std::runtime_error("nframes > 1 not supported yet");
- }
+ if (nframes > 1) {
+ DP_REQUIRES_OK(dp, dp->dp.set_exception("nframes > 1 not supported yet"));
+ return;
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// support spin multi model. | |
template <typename VALUETYPE> | |
void DP_DeepSpinModelDeviComputeNList_variant(DP_DeepSpinModelDevi* dp, | |
const int nframes, | |
const int natoms, | |
const VALUETYPE* coord, | |
const VALUETYPE* spin, | |
const int* atype, | |
const VALUETYPE* cell, | |
const int nghost, | |
const DP_Nlist* nlist, | |
const int ago, | |
const VALUETYPE* fparam, | |
const VALUETYPE* aparam, | |
double* energy, | |
VALUETYPE* force, | |
VALUETYPE* force_mag, | |
VALUETYPE* virial, | |
VALUETYPE* atomic_energy, | |
VALUETYPE* atomic_virial) { | |
if (nframes > 1) { | |
throw std::runtime_error("nframes > 1 not supported yet"); | |
} | |
// init C++ vectors from C arrays | |
std::vector<VALUETYPE> coord_(coord, coord + natoms * 3); | |
std::vector<VALUETYPE> spin_(spin, spin + natoms * 3); | |
std::vector<int> atype_(atype, atype + natoms); | |
std::vector<VALUETYPE> cell_; | |
if (cell) { | |
// pbc | |
cell_.assign(cell, cell + 9); | |
} | |
std::vector<VALUETYPE> fparam_; | |
if (fparam) { | |
fparam_.assign(fparam, fparam + dp->dfparam); | |
} | |
std::vector<VALUETYPE> aparam_; | |
if (aparam) { | |
aparam_.assign( | |
aparam, | |
aparam + (dp->aparam_nall ? natoms : (natoms - nghost)) * dp->daparam); | |
} | |
// different from DeepPot | |
std::vector<double> e; | |
std::vector<std::vector<VALUETYPE>> f, fm, v, ae, av; | |
if (atomic_energy || atomic_virial) { | |
DP_REQUIRES_OK( | |
dp, dp->dp.compute(e, f, fm, v, ae, av, coord_, spin_, atype_, cell_, | |
nghost, nlist->nl, ago, fparam_, aparam_)); | |
} else { | |
DP_REQUIRES_OK( | |
dp, dp->dp.compute(e, f, fm, v, coord_, spin_, atype_, cell_, nghost, | |
nlist->nl, ago, fparam_, aparam_)); | |
} | |
// 2D vector to 2D array, flatten first | |
if (energy) { | |
std::copy(e.begin(), e.end(), energy); | |
} | |
if (force) { | |
std::vector<VALUETYPE> f_flat; | |
flatten_vector(f_flat, f); | |
std::copy(f_flat.begin(), f_flat.end(), force); | |
} | |
if (force_mag) { | |
std::vector<VALUETYPE> f_mag_flat; | |
flatten_vector(f_mag_flat, fm); | |
std::copy(f_mag_flat.begin(), f_mag_flat.end(), force_mag); | |
} | |
if (virial) { | |
std::vector<VALUETYPE> v_flat; | |
flatten_vector(v_flat, v); | |
std::copy(v_flat.begin(), v_flat.end(), virial); | |
} | |
if (atomic_energy) { | |
std::vector<VALUETYPE> ae_flat; | |
flatten_vector(ae_flat, ae); | |
std::copy(ae_flat.begin(), ae_flat.end(), atomic_energy); | |
} | |
if (atomic_virial) { | |
std::vector<VALUETYPE> av_flat; | |
flatten_vector(av_flat, av); | |
std::copy(av_flat.begin(), av_flat.end(), atomic_virial); | |
} | |
} | |
// support spin multi model. | |
template <typename VALUETYPE> | |
void DP_DeepSpinModelDeviComputeNList_variant(DP_DeepSpinModelDevi* dp, | |
const int nframes, | |
const int natoms, | |
const VALUETYPE* coord, | |
const VALUETYPE* spin, | |
const int* atype, | |
const VALUETYPE* cell, | |
const int nghost, | |
const DP_Nlist* nlist, | |
const int ago, | |
const VALUETYPE* fparam, | |
const VALUETYPE* aparam, | |
double* energy, | |
VALUETYPE* force, | |
VALUETYPE* force_mag, | |
VALUETYPE* virial, | |
VALUETYPE* atomic_energy, | |
VALUETYPE* atomic_virial) { | |
if (nframes > 1) { | |
DP_REQUIRES_OK(dp, dp->dp.set_exception("nframes > 1 not supported yet")); | |
return; | |
} | |
// init C++ vectors from C arrays | |
std::vector<VALUETYPE> coord_(coord, coord + natoms * 3); | |
std::vector<VALUETYPE> spin_(spin, spin + natoms * 3); | |
std::vector<int> atype_(atype, atype + natoms); | |
std::vector<VALUETYPE> cell_; | |
if (cell) { | |
// pbc | |
cell_.assign(cell, cell + 9); | |
} | |
std::vector<VALUETYPE> fparam_; | |
if (fparam) { | |
fparam_.assign(fparam, fparam + dp->dfparam); | |
} | |
std::vector<VALUETYPE> aparam_; | |
if (aparam) { | |
aparam_.assign( | |
aparam, | |
aparam + (dp->aparam_nall ? natoms : (natoms - nghost)) * dp->daparam); | |
} | |
// different from DeepPot | |
std::vector<double> e; | |
std::vector<std::vector<VALUETYPE>> f, fm, v, ae, av; | |
if (atomic_energy || atomic_virial) { | |
DP_REQUIRES_OK( | |
dp, dp->dp.compute(e, f, fm, v, ae, av, coord_, spin_, atype_, cell_, | |
nghost, nlist->nl, ago, fparam_, aparam_)); | |
} else { | |
DP_REQUIRES_OK( | |
dp, dp->dp.compute(e, f, fm, v, coord_, spin_, atype_, cell_, nghost, | |
nlist->nl, ago, fparam_, aparam_)); | |
} | |
// 2D vector to 2D array, flatten first | |
if (energy) { | |
std::copy(e.begin(), e.end(), energy); | |
} | |
if (force) { | |
std::vector<VALUETYPE> f_flat; | |
flatten_vector(f_flat, f); | |
std::copy(f_flat.begin(), f_flat.end(), force); | |
} | |
if (force_mag) { | |
std::vector<VALUETYPE> f_mag_flat; | |
flatten_vector(f_mag_flat, fm); | |
std::copy(f_mag_flat.begin(), f_mag_flat.end(), force_mag); | |
} | |
if (virial) { | |
std::vector<VALUETYPE> v_flat; | |
flatten_vector(v_flat, v); | |
std::copy(v_flat.begin(), v_flat.end(), virial); | |
} | |
if (atomic_energy) { | |
std::vector<VALUETYPE> ae_flat; | |
flatten_vector(ae_flat, ae); | |
std::copy(ae_flat.begin(), ae_flat.end(), atomic_energy); | |
} | |
if (atomic_virial) { | |
std::vector<VALUETYPE> av_flat; | |
flatten_vector(av_flat, av); | |
std::copy(av_flat.begin(), av_flat.end(), atomic_virial); | |
} | |
} |
Signed-off-by: Jinzhe Zeng <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (2)
source/lmp/tests/test_lammps_spin.py (2)
102-108
: Add error handling for file operationsThe setup and teardown functions should handle potential file operation errors gracefully.
def setup_module(): + try: write_lmp_data_spin(box, coord, spin, type_NiO, data_file) + except Exception as e: + pytest.skip(f"Failed to create test data file: {e}") def teardown_module(): + try: os.remove(data_file) + except FileNotFoundError: + pass # File already removed + except Exception as e: + print(f"Warning: Failed to cleanup test data file: {e}")
214-230
: Parameterize MPI process countThe number of MPI processes is hardcoded to 2. Consider parameterizing this value to test with different numbers of processes.
@pytest.mark.parametrize( - ("balance_args",), - [(["--balance"],), ([],)], + ("balance_args", "n_procs"), + [ + (["--balance"], 2), + (["--balance"], 4), + ([], 2), + ([], 4), + ], ) -def test_pair_deepmd_mpi(balance_args: list): +def test_pair_deepmd_mpi(balance_args: list, n_procs: int): with tempfile.NamedTemporaryFile() as f: sp.check_call( [ "mpirun", "-n", - "2", + str(n_procs), sys.executable, Path(__file__).parent / "run_mpi_pair_deepmd_spin.py",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
source/lmp/tests/test_lammps_spin.py
(1 hunks)source/lmp/tests/test_lammps_spin_pt.py
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- source/lmp/tests/test_lammps_spin_pt.py
The conversations are not readable. I'll open up another clean PR for review. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## devel #4216 +/- ##
==========================================
- Coverage 84.42% 83.68% -0.75%
==========================================
Files 570 584 +14
Lines 53107 55119 +2012
Branches 3059 3328 +269
==========================================
+ Hits 44836 46124 +1288
- Misses 7307 7896 +589
- Partials 964 1099 +135 ☔ View full report in Codecov by Sentry. |
The conversations in #4216 are not readable. I opened this clean one for reviewers. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes - **New Features** - Introduced support for spin configurations within the DeepMD framework. - Added `PairDeepSpin` class for integrating spin models into LAMMPS simulations. - Enhanced `DeepSpin` and `DeepSpinModelDevi` classes with new methods for energy and force calculations. - Updated `DeepPotTF` class to compute atomic energies and virials. - Added a new function for writing LMP data that includes spin information. - **Bug Fixes** - Improved error handling for unsupported configurations in spin calculations. - **Tests** - Added comprehensive unit tests for `DeepSpin` and `DeepSpinModelDevi` classes to validate functionality and ensure accuracy in computations. - Introduced tests for verifying spin interactions without periodic boundary conditions. - Developed tests for MPI-enabled versions of spin interactions. - **Documentation** - Updated scripts and tests to reflect new functionalities and ensure clarity in usage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Duo <[email protected]> Signed-off-by: Jinzhe Zeng <[email protected]> Co-authored-by: hztttt <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lysithea <[email protected]> Co-authored-by: hztttt <[email protected]> Co-authored-by: Jinzhe Zeng <[email protected]>
Summary by CodeRabbit
New Features
DeepSpin
,DeepSpinModelDevi
, and their TensorFlow and PyTorch counterparts.PairDeepSpin
.DeepPot
framework with spin support, including new API structures and functions.DeepSpinPT
andDeepSpinTF
.DeepSpin
class to validate its methods under various configurations.Bug Fixes
Tests
DeepSpin
class, validating spin-related computations and ensuring accuracy in energy and force calculations.DeepSpin
class, focusing on thecompute
method and verifying outputs against expected values.DeepSpinPT
class to validate its functionality.DeepSpin
class to validate its behavior with and without periodic boundary conditions.Documentation