From 23c1f10d12d441fb5bccbd2a3f9702764bdc7097 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 20 Mar 2023 02:42:17 -0400 Subject: [PATCH 1/4] support fparam and aparam for C API Signed-off-by: Jinzhe Zeng --- source/api_c/include/c_api.h | 50 +- source/api_c/include/c_api_internal.h | 4 + source/api_c/include/deepmd.hpp | 248 +++- source/api_c/src/c_api.cc | 38 +- .../tests/test_deeppot_a_fparam_aparam.cc | 381 +++++ .../test_deeppot_a_fparam_aparam_nframes.cc | 1297 +++++++++++++++++ 6 files changed, 1941 insertions(+), 77 deletions(-) create mode 100644 source/api_c/tests/test_deeppot_a_fparam_aparam.cc create mode 100644 source/api_c/tests/test_deeppot_a_fparam_aparam_nframes.cc diff --git a/source/api_c/include/c_api.h b/source/api_c/include/c_api.h index d36bd2206d..341b2f853d 100644 --- a/source/api_c/include/c_api.h +++ b/source/api_c/include/c_api.h @@ -202,8 +202,10 @@ extern void DP_DeepPotComputeNListf(DP_DeepPot* dp, * @param[in] atype The atom types. The array should contain natoms ints. * @param[in] box The cell of the region. The array should be of size 9. Pass *NULL if pbc is not used. - * @param[in] fparam The frame parameters. (not work at this time) - * @param[in] aparam The atom parameters. (not work at this time) + * @param[in] fparam The frame parameters. The array can be of size nframes x + *dim_fparam. + * @param[in] aparam The atom parameters. The array can be of size nframes x + *dim_aparam. * @param[out] energy Output energy. * @param[out] force Output force. The array should be of size natoms x 3. * @param[out] virial Output virial. The array should be of size 9. @@ -239,8 +241,10 @@ extern void DP_DeepPotCompute2(DP_DeepPot* dp, * @param[in] atype The atom types. The array should contain natoms ints. * @param[in] box The cell of the region. The array should be of size 9. Pass *NULL if pbc is not used. - * @param[in] fparam The frame parameters. (not work at this time) - * @param[in] aparam The atom parameters. (not work at this time) + * @param[in] fparam The frame parameters. The array can be of size nframes x + *dim_fparam. + * @param[in] aparam The atom parameters. The array can be of size nframes x + *dim_aparam. * @param[out] energy Output energy. * @param[out] force Output force. The array should be of size natoms x 3. * @param[out] virial Output virial. The array should be of size 9. @@ -280,8 +284,10 @@ extern void DP_DeepPotComputef2(DP_DeepPot* dp, * @param[in] nghost The number of ghost atoms. * @param[in] nlist The neighbor list. * @param[in] ago Update the internal neighbour list if ago is 0. - * @param[in] fparam The frame parameters. (not work at this time) - * @param[in] aparam The atom parameters. (not work at this time) + * @param[in] fparam The frame parameters. The array can be of size nframes x + *dim_fparam. + * @param[in] aparam The atom parameters. The array can be of size nframes x + *dim_aparam. * @param[out] energy Output energy. * @param[out] force Output force. The array should be of size natoms x 3. * @param[out] virial Output virial. The array should be of size 9. @@ -324,8 +330,10 @@ extern void DP_DeepPotComputeNList2(DP_DeepPot* dp, * @param[in] nghost The number of ghost atoms. * @param[in] nlist The neighbor list. * @param[in] ago Update the internal neighbour list if ago is 0. - * @param[in] fparam The frame parameters. (not work at this time) - * @param[in] aparam The atom parameters. (not work at this time) + * @param[in] fparam The frame parameters. The array can be of size nframes x + *dim_fparam. + * @param[in] aparam The atom parameters. The array can be of size nframes x + *dim_aparam. * @param[out] energy Output energy. * @param[out] force Output force. The array should be of size natoms x 3. * @param[out] virial Output virial. The array should be of size 9. @@ -365,8 +373,10 @@ extern void DP_DeepPotComputeNListf2(DP_DeepPot* dp, *ints. * @param[in] box The cell of the region. The array should be of size 9. Pass *NULL if pbc is not used. - * @param[in] fparam The frame parameters. (not work at this time) - * @param[in] aparam The atom parameters. (not work at this time) + * @param[in] fparam The frame parameters. The array can be of size nframes x + *dim_fparam. + * @param[in] aparam The atom parameters. The array can be of size nframes x + *dim_aparam. * @param[out] energy Output energy. * @param[out] force Output force. The array should be of size natoms x 3. * @param[out] virial Output virial. The array should be of size 9. @@ -402,8 +412,10 @@ extern void DP_DeepPotComputeMixedType(DP_DeepPot* dp, *ints. * @param[in] box The cell of the region. The array should be of size 9. Pass *NULL if pbc is not used. - * @param[in] fparam The frame parameters. (not work at this time) - * @param[in] aparam The atom parameters. (not work at this time) + * @param[in] fparam The frame parameters. The array can be of size nframes x + *dim_fparam. + * @param[in] aparam The atom parameters. The array can be of size nframes x + *dim_aparam. * @param[out] energy Output energy. * @param[out] force Output force. The array should be of size natoms x 3. * @param[out] virial Output virial. The array should be of size 9. @@ -551,6 +563,20 @@ double DP_DeepPotGetCutoff(DP_DeepPot* dp); */ int DP_DeepPotGetNumbTypes(DP_DeepPot* dp); +/** + * @brief Get the dimension of frame parameters of a DP. + * @param[in] dp The DP to use. + * @return The dimension of frame parameters of the DP. + */ +int DP_DeepPotGetDimFParam(DP_DeepPot* dp); + +/** + * @brief Get the dimension of atomic parameters of a DP. + * @param[in] dp The DP to use. + * @return The dimension of atomic parameters of the DP. + */ +int DP_DeepPotGetDimAParam(DP_DeepPot* dp); + /** * @brief Get the type map of a DP. * @param[in] dp The DP to use. diff --git a/source/api_c/include/c_api_internal.h b/source/api_c/include/c_api_internal.h index 741f1e88e3..e52b3c9e67 100644 --- a/source/api_c/include/c_api_internal.h +++ b/source/api_c/include/c_api_internal.h @@ -38,6 +38,8 @@ struct DP_DeepPot { deepmd::DeepPot dp; std::string exception; + int dfparam; + int daparam; }; struct DP_DeepPotModelDevi { @@ -46,6 +48,8 @@ struct DP_DeepPotModelDevi { deepmd::DeepPotModelDevi dp; std::string exception; + int dfparam; + int daparam; }; struct DP_DeepTensor { diff --git a/source/api_c/include/deepmd.hpp b/source/api_c/include/deepmd.hpp index cf7285fb41..8fd158573c 100644 --- a/source/api_c/include/deepmd.hpp +++ b/source/api_c/include/deepmd.hpp @@ -586,6 +586,8 @@ class DeepPot { } dp = DP_NewDeepPotWithParam(model.c_str(), gpu_rank, file_content.c_str()); DP_CHECK_OK(DP_DeepPotCheckOK, dp); + dfparam = DP_DeepPotGetDimFParam(dp); + daparam = DP_DeepPotGetDimAParam(dp); }; /** @@ -598,14 +600,25 @@ class DeepPot { * @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. **/ template - void compute(ENERGYVTYPE &ener, - std::vector &force, - std::vector &virial, - const std::vector &coord, - const std::vector &atype, - const std::vector &box) { + void compute( + ENERGYVTYPE &ener, + std::vector &force, + std::vector &virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const std::vector &fparam = std::vector(), + const std::vector &aparam = std::vector()) { unsigned int natoms = atype.size(); unsigned int nframes = coord.size() / natoms / 3; assert(nframes * natoms * 3 == coord.size()); @@ -620,9 +633,12 @@ class DeepPot { virial.resize(nframes * 9); VALUETYPE *force_ = &force[0]; VALUETYPE *virial_ = &virial[0]; + validate_fparam_aparam(nframes, natoms, fparam, aparam); + tile_fparam_aparam(fparam_, nframes, dfparam, fparam); + tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); _DP_DeepPotCompute(dp, nframes, natoms, coord_, atype_, box_, - nullptr, nullptr, ener_, force_, virial_, + fparam_, aparam_, ener_, force_, virial_, nullptr, nullptr); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; @@ -639,16 +655,27 @@ class DeepPot { * @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. **/ template - void compute(ENERGYVTYPE &ener, - std::vector &force, - std::vector &virial, - std::vector &atom_energy, - std::vector &atom_virial, - const std::vector &coord, - const std::vector &atype, - const std::vector &box) { + void compute( + ENERGYVTYPE &ener, + std::vector &force, + std::vector &virial, + std::vector &atom_energy, + std::vector &atom_virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const std::vector &fparam = std::vector(), + const std::vector &aparam = std::vector()) { unsigned int natoms = atype.size(); unsigned int nframes = coord.size() / natoms / 3; assert(nframes * natoms * 3 == coord.size()); @@ -668,9 +695,12 @@ class DeepPot { VALUETYPE *virial_ = &virial[0]; VALUETYPE *atomic_ener_ = &atom_energy[0]; VALUETYPE *atomic_virial_ = &atom_virial[0]; + validate_fparam_aparam(nframes, natoms, fparam, aparam); + tile_fparam_aparam(fparam_, nframes, dfparam, fparam); + tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); _DP_DeepPotCompute(dp, nframes, natoms, coord_, atype_, box_, - nullptr, nullptr, ener_, force_, virial_, + fparam_, aparam_, ener_, force_, virial_, atomic_ener_, atomic_virial_); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; @@ -689,17 +719,28 @@ class DeepPot { * @param[in] nghost The number of ghost atoms. * @param[in] nlist The neighbor list. * @param[in] ago Update the internal neighbour list if ago is 0. + * @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. **/ template - void compute(ENERGYVTYPE &ener, - std::vector &force, - std::vector &virial, - const std::vector &coord, - const std::vector &atype, - const std::vector &box, - const int nghost, - const InputNlist &lmp_list, - const int &ago) { + void compute( + ENERGYVTYPE &ener, + std::vector &force, + std::vector &virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list, + const int &ago, + const std::vector &fparam = std::vector(), + const std::vector &aparam = std::vector()) { unsigned int natoms = atype.size(); unsigned int nframes = coord.size() / natoms / 3; assert(nframes * natoms * 3 == coord.size()); @@ -714,10 +755,13 @@ class DeepPot { virial.resize(nframes * 9); VALUETYPE *force_ = &force[0]; VALUETYPE *virial_ = &virial[0]; + validate_fparam_aparam(nframes, natoms - nghost, fparam, aparam); + tile_fparam_aparam(fparam_, nframes, dfparam, fparam); + tile_fparam_aparam(aparam_, nframes, (natoms - nghost) * daparam, aparam); _DP_DeepPotComputeNList( dp, nframes, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, - nullptr, nullptr, ener_, force_, virial_, nullptr, nullptr); + fparam_, aparam_, ener_, force_, virial_, nullptr, nullptr); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; /** @@ -736,19 +780,30 @@ class DeepPot { * @param[in] nghost The number of ghost atoms. * @param[in] nlist The neighbor list. * @param[in] ago Update the internal neighbour list if ago is 0. + * @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. **/ template - void compute(ENERGYVTYPE &ener, - std::vector &force, - std::vector &virial, - std::vector &atom_energy, - std::vector &atom_virial, - const std::vector &coord, - const std::vector &atype, - const std::vector &box, - const int nghost, - const InputNlist &lmp_list, - const int &ago) { + void compute( + ENERGYVTYPE &ener, + std::vector &force, + std::vector &virial, + std::vector &atom_energy, + std::vector &atom_virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list, + const int &ago, + const std::vector &fparam = std::vector(), + const std::vector &aparam = std::vector()) { unsigned int natoms = atype.size(); unsigned int nframes = coord.size() / natoms / 3; assert(nframes * natoms * 3 == coord.size()); @@ -768,10 +823,13 @@ class DeepPot { VALUETYPE *virial_ = &virial[0]; VALUETYPE *atomic_ener_ = &atom_energy[0]; VALUETYPE *atomic_virial_ = &atom_virial[0]; + validate_fparam_aparam(nframes, natoms - nghost, fparam, aparam); + tile_fparam_aparam(fparam_, nframes, dfparam, fparam); + tile_fparam_aparam(aparam_, nframes, (natoms - nghost) * daparam, aparam); _DP_DeepPotComputeNList( dp, nframes, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, - nullptr, nullptr, ener_, force_, virial_, atomic_ener_, atomic_virial_); + fparam_, aparam_, ener_, force_, virial_, atomic_ener_, atomic_virial_); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; /** @@ -786,15 +844,26 @@ class DeepPot { * @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. **/ template - void compute_mixed_type(ENERGYVTYPE &ener, - std::vector &force, - std::vector &virial, - const int &nframes, - const std::vector &coord, - const std::vector &atype, - const std::vector &box) { + void compute_mixed_type( + ENERGYVTYPE &ener, + std::vector &force, + std::vector &virial, + const int &nframes, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const std::vector &fparam = std::vector(), + const std::vector &aparam = std::vector()) { unsigned int natoms = atype.size() / nframes; assert(nframes * natoms * 3 == coord.size()); if (!box.empty()) { @@ -808,9 +877,12 @@ class DeepPot { virial.resize(nframes * 9); VALUETYPE *force_ = &force[0]; VALUETYPE *virial_ = &virial[0]; + validate_fparam_aparam(nframes, natoms, fparam, aparam); + tile_fparam_aparam(fparam_, nframes, dfparam, fparam); + tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); _DP_DeepPotComputeMixedType(dp, nframes, natoms, coord_, atype_, - box_, nullptr, nullptr, ener_, + box_, fparam_, aparam_, ener_, force_, virial_, nullptr, nullptr); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; @@ -828,17 +900,28 @@ class DeepPot { * @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. **/ template - void compute_mixed_type(ENERGYVTYPE &ener, - std::vector &force, - std::vector &virial, - std::vector &atom_energy, - std::vector &atom_virial, - const int &nframes, - const std::vector &coord, - const std::vector &atype, - const std::vector &box) { + void compute_mixed_type( + ENERGYVTYPE &ener, + std::vector &force, + std::vector &virial, + std::vector &atom_energy, + std::vector &atom_virial, + const int &nframes, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const std::vector &fparam = std::vector(), + const std::vector &aparam = std::vector()) { unsigned int natoms = atype.size() / nframes; assert(nframes * natoms * 3 == coord.size()); if (!box.empty()) { @@ -857,9 +940,12 @@ class DeepPot { VALUETYPE *virial_ = &virial[0]; VALUETYPE *atomic_ener_ = &atom_energy[0]; VALUETYPE *atomic_virial_ = &atom_virial[0]; + validate_fparam_aparam(nframes, natoms, fparam, aparam); + tile_fparam_aparam(fparam_, nframes, dfparam, fparam); + tile_fparam_aparam(aparam_, nframes, natoms * daparam, aparam); _DP_DeepPotComputeMixedType( - dp, nframes, natoms, coord_, atype_, box_, nullptr, nullptr, ener_, + dp, nframes, natoms, coord_, atype_, box_, fparam_, aparam_, ener_, force_, virial_, atomic_ener_, atomic_virial_); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; @@ -896,9 +982,59 @@ class DeepPot { 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. + **/ + int dim_aparam() const { + assert(dp); + return daparam; + } private: DP_DeepPot *dp; + int dfparam; + int daparam; + template + void validate_fparam_aparam(const int &nframes, + const int &nloc, + const std::vector &fparam, + const std::vector &aparam) const { + if (fparam.size() != dfparam && fparam.size() != nframes * dfparam) { + throw deepmd::hpp::deepmd_exception( + "the dim of frame parameter provided is not consistent with what the " + "model uses"); + } + + if (aparam.size() != daparam * nloc && + aparam.size() != nframes * daparam * nloc) { + throw deepmd::hpp::deepmd_exception( + "the dim of atom parameter provided is not consistent with what the " + "model uses"); + } + } + template + void tile_fparam_aparam(std::vector &out_param, + const int &nframes, + const int &dparam, + const std::vector ¶m) const { + if (param.size() == dparam) { + out_param.resize(nframes * dparam); + for (int ii = 0; ii < nframes; ++ii) { + std::copy(param.begin(), param.end(), out_param.begin() + ii * dparam); + } + } else if (param.size() == nframes * dparam) { + out_param = param; + } + } }; /** diff --git a/source/api_c/src/c_api.cc b/source/api_c/src/c_api.cc index ffe860545c..f04f485ccb 100644 --- a/source/api_c/src/c_api.cc +++ b/source/api_c/src/c_api.cc @@ -25,13 +25,15 @@ DP_Nlist* DP_NewNlist(int inum_, } DP_DeepPot::DP_DeepPot() {} -DP_DeepPot::DP_DeepPot(deepmd::DeepPot& dp) : dp(dp) {} +DP_DeepPot::DP_DeepPot(deepmd::DeepPot& dp) : dp(dp) { + dfparam = dp.dim_aparam(); + daparam = dp.dim_fparam(); +} DP_DeepPot* DP_NewDeepPot(const char* c_model) { std::string model(c_model); - deepmd::DeepPot dp(model); - DP_DeepPot* new_dp = new DP_DeepPot(dp); - return new_dp; + DP_NEW_OK(DP_DeepPot, deepmd::DeepPot dp(model); + DP_DeepPot* new_dp = new DP_DeepPot(dp); return new_dp;) } DP_DeepPot* DP_NewDeepPotWithParam(const char* c_model, @@ -45,7 +47,10 @@ DP_DeepPot* DP_NewDeepPotWithParam(const char* c_model, DP_DeepPotModelDevi::DP_DeepPotModelDevi() {} DP_DeepPotModelDevi::DP_DeepPotModelDevi(deepmd::DeepPotModelDevi& dp) - : dp(dp) {} + : dp(dp) { + dfparam = dp.dim_aparam(); + daparam = dp.dim_fparam(); +} DP_DeepPotModelDevi* DP_NewDeepPotModelDevi(const char** c_models, int n_models) { @@ -119,10 +124,14 @@ inline void DP_DeepPotCompute_variant(DP_DeepPot* dp, // pbc cell_.assign(cell, cell + nframes * 9); } + std::vector fparam_(fparam, fparam + nframes * dp->dfparam); + std::vector aparam_(aparam, + aparam + nframes * natoms * dp->daparam); std::vector e; std::vector f, v, ae, av; - DP_REQUIRES_OK(dp, dp->dp.compute(e, f, v, ae, av, coord_, atype_, cell_)); + DP_REQUIRES_OK(dp, dp->dp.compute(e, f, v, ae, av, coord_, atype_, cell_, + fparam_, aparam_)); // copy from C++ vectors to C arrays, if not NULL pointer if (energy) std::copy(e.begin(), e.end(), energy); if (force) std::copy(f.begin(), f.end(), force); @@ -184,11 +193,14 @@ inline void DP_DeepPotComputeNList_variant(DP_DeepPot* dp, // pbc cell_.assign(cell, cell + nframes * 9); } + std::vector fparam_(fparam, fparam + nframes * dp->dfparam); + std::vector aparam_(aparam, + aparam + nframes * natoms * dp->daparam); std::vector e; std::vector f, v, ae, av; DP_REQUIRES_OK(dp, dp->dp.compute(e, f, v, ae, av, coord_, atype_, cell_, - nghost, nlist->nl, ago)); + nghost, nlist->nl, ago, fparam_, aparam_)); // copy from C++ vectors to C arrays, if not NULL pointer if (energy) std::copy(e.begin(), e.end(), energy); if (force) std::copy(f.begin(), f.end(), force); @@ -253,11 +265,15 @@ inline void DP_DeepPotComputeMixedType_variant(DP_DeepPot* dp, // pbc cell_.assign(cell, cell + nframes * 9); } + std::vector fparam_(fparam, fparam + nframes * dp->dfparam); + std::vector aparam_(aparam, + aparam + nframes * natoms * dp->daparam); std::vector e; std::vector f, v, ae, av; - DP_REQUIRES_OK(dp, dp->dp.compute_mixed_type(e, f, v, ae, av, nframes, coord_, - atype_, cell_)); + DP_REQUIRES_OK( + dp, dp->dp.compute_mixed_type(e, f, v, ae, av, nframes, coord_, atype_, + cell_, fparam_, aparam_)); // copy from C++ vectors to C arrays, if not NULL pointer if (energy) std::copy(e.begin(), e.end(), energy); if (force) std::copy(f.begin(), f.end(), force); @@ -883,6 +899,10 @@ double DP_DeepPotGetCutoff(DP_DeepPot* dp) { return dp->dp.cutoff(); } int DP_DeepPotGetNumbTypes(DP_DeepPot* dp) { return dp->dp.numb_types(); } +int DP_DeepPotGetDimFParam(DP_DeepPot* dp) { return dp->dfparam; } + +int DP_DeepPotGetDimAParam(DP_DeepPot* dp) { return dp->daparam; } + const char* DP_DeepPotCheckOK(DP_DeepPot* dp) { return string_to_char(dp->exception); } diff --git a/source/api_c/tests/test_deeppot_a_fparam_aparam.cc b/source/api_c/tests/test_deeppot_a_fparam_aparam.cc new file mode 100644 index 0000000000..c2247a868d --- /dev/null +++ b/source/api_c/tests/test_deeppot_a_fparam_aparam.cc @@ -0,0 +1,381 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "deepmd.hpp" +#include "test_utils.h" + +template +class TestInferDeepPotAFParamAParam : public ::testing::Test { + protected: + std::vector coord = {12.83, 2.56, 2.18, 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; + std::vector atype = {0, 0, 0, 0, 0, 0}; + std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; + std::vector fparam = {0.25852028}; + std::vector aparam = {0.25852028, 0.25852028, 0.25852028, + 0.25852028, 0.25852028, 0.25852028}; + std::vector expected_e = { + -1.038271183039953804e-01, -7.285433575272914908e-02, + -9.467600174099155552e-02, -1.467050086239614082e-01, + -7.660561620618722145e-02, -7.277295998502930630e-02}; + std::vector expected_f = { + 6.622266817497907132e-02, 5.278739055693523058e-02, + 2.265727495541422845e-02, -2.606047850915838363e-02, + -4.538811686410718776e-02, 1.058247569147072187e-02, + 1.679392490937766935e-01, -2.257828022687320690e-03, + -4.490145670355452645e-02, -1.148364103573685929e-01, + -1.169790466695089237e-02, 6.140402504113953025e-02, + -8.078778132132799494e-02, -5.838878056243369807e-02, + 6.773639989682191109e-02, -1.247724708090079161e-02, + 6.494523955924384750e-02, -1.174787188812918687e-01}; + std::vector expected_v = { + -1.589185553287162656e-01, 2.586163333170100279e-03, + -1.575127933809472624e-04, -1.855360380105876630e-02, + 1.949822090859933826e-02, -1.006552056166355388e-02, + 3.177029853276916449e-02, 1.714349636720383010e-03, + -1.290389175187874483e-03, -8.553510339477603253e-02, + -5.654637257232508415e-03, -1.286954833787038420e-02, + 2.464156457499515687e-02, -2.398202886026797043e-02, + -1.957110465239037672e-02, 2.233492928605742764e-02, + 6.107843207824020099e-03, 1.707078295947736047e-03, + -1.653994088976195043e-01, 3.894358678172111371e-02, + -2.169595969759342477e-02, 6.819704294738503786e-03, + -5.018242039618424008e-03, 2.640664428663210429e-03, + -1.985298275686078057e-03, -3.638421609610945767e-02, + 2.342932331075030239e-02, -8.501331914753691710e-02, + -2.181253413538992297e-03, 4.311300069651782287e-03, + -1.910329328333908129e-03, -1.808810159508548836e-03, + -1.540075281450827612e-03, -1.173703213175551763e-02, + -2.596306629910121507e-03, 6.705025662372287101e-03, + -9.038455005073858795e-02, 3.011717773578577451e-02, + -5.083054073419784880e-02, -2.951210292616929069e-03, + 2.342445652898489383e-02, -4.091207474993674431e-02, + -1.648470649301832236e-02, -2.872261885460645689e-02, + 4.763924972552112391e-02, -8.300036532764677732e-02, + 1.020429228955421243e-03, -1.026734151199098881e-03, + 5.678534096113684732e-02, 1.273635718045938205e-02, + -1.530143225195957322e-02, -1.061671865629566225e-01, + -2.486859433265622629e-02, 2.875323131744185121e-02}; + int natoms; + double expected_tot_e; + std::vector expected_tot_v; + + deepmd::hpp::DeepPot dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/fparam_aparam.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb(file_name, "fparam_aparam.pb"); + + dp.init("fparam_aparam.pb"); + + natoms = expected_e.size(); + EXPECT_EQ(natoms * 3, expected_f.size()); + EXPECT_EQ(natoms * 9, expected_v.size()); + expected_tot_e = 0.; + expected_tot_v.resize(9); + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + for (int ii = 0; ii < natoms; ++ii) { + expected_tot_e += expected_e[ii]; + } + for (int ii = 0; ii < natoms; ++ii) { + for (int dd = 0; dd < 9; ++dd) { + expected_tot_v[dd] += expected_v[ii * 9 + dd]; + } + } + }; + + void TearDown() override { remove("fparam_aparam.pb"); }; +}; + +TYPED_TEST_SUITE(TestInferDeepPotAFParamAParam, ValueTypes); + +TYPED_TEST(TestInferDeepPotAFParamAParam, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + double ener; + std::vector force, virial; + dp.compute(ener, force, virial, coord, atype, box, fparam, aparam); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFParamAParam, cpu_build_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + double ener; + std::vector force, virial, atom_ener, atom_vir; + dp.compute(ener, force, virial, atom_ener, atom_vir, coord, atype, box, + fparam, aparam); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + EXPECT_EQ(atom_ener.size(), natoms); + EXPECT_EQ(atom_vir.size(), natoms * 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFParamAParam, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, + atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + + double ener; + std::vector force_, virial; + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + ener = 0.; + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall - nloc, + inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFParamAParam, cpu_lmp_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, + atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + + double ener; + std::vector force_, atom_ener_, atom_vir_, virial; + std::vector force, atom_ener, atom_vir; + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, + box, nall - nloc, inlist, 0, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + EXPECT_EQ(atom_ener.size(), natoms); + EXPECT_EQ(atom_vir.size(), natoms * 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } + + ener = 0.; + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + std::fill(atom_ener_.begin(), atom_ener_.end(), 0.0); + std::fill(atom_vir_.begin(), atom_vir_.end(), 0.0); + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, + box, nall - nloc, inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + EXPECT_EQ(atom_ener.size(), natoms); + EXPECT_EQ(atom_vir.size(), natoms * 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFParamAParam, cpu_lmp_nlist_2rc) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, + atype, box, rc * 2); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + + double ener; + std::vector force_(nall * 3, 0.0), virial(9, 0.0); + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + ener = 0.; + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall - nloc, + inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms * 3); + EXPECT_EQ(virial.size(), 9); + + 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); + } + for (int ii = 0; ii < 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} diff --git a/source/api_c/tests/test_deeppot_a_fparam_aparam_nframes.cc b/source/api_c/tests/test_deeppot_a_fparam_aparam_nframes.cc new file mode 100644 index 0000000000..6c7558402e --- /dev/null +++ b/source/api_c/tests/test_deeppot_a_fparam_aparam_nframes.cc @@ -0,0 +1,1297 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "deepmd.hpp" +#include "test_utils.h" + +template +class TestInferDeepPotAFparamAparamNFrames : public ::testing::Test { + protected: + std::vector coord = { + 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, 3.51, 2.51, 2.60, 4.27, 3.22, 1.56, + 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; + std::vector atype = {0, 0, 0, 0, 0, 0}; + std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13., + 13., 0., 0., 0., 13., 0., 0., 0., 13.}; + std::vector fparam = {0.25852028, 0.25852028}; + std::vector aparam = { + 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, + 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028, 0.25852028}; + std::vector expected_e = { + -1.038271183039953804e-01, -7.285433575272914908e-02, + -9.467600174099155552e-02, -1.467050086239614082e-01, + -7.660561620618722145e-02, -7.277295998502930630e-02, + -1.038271183039953804e-01, -7.285433575272914908e-02, + -9.467600174099155552e-02, -1.467050086239614082e-01, + -7.660561620618722145e-02, -7.277295998502930630e-02}; + std::vector expected_f = { + 6.622266817497907132e-02, 5.278739055693523058e-02, + 2.265727495541422845e-02, -2.606047850915838363e-02, + -4.538811686410718776e-02, 1.058247569147072187e-02, + 1.679392490937766935e-01, -2.257828022687320690e-03, + -4.490145670355452645e-02, -1.148364103573685929e-01, + -1.169790466695089237e-02, 6.140402504113953025e-02, + -8.078778132132799494e-02, -5.838878056243369807e-02, + 6.773639989682191109e-02, -1.247724708090079161e-02, + 6.494523955924384750e-02, -1.174787188812918687e-01, + 6.622266817497907132e-02, 5.278739055693523058e-02, + 2.265727495541422845e-02, -2.606047850915838363e-02, + -4.538811686410718776e-02, 1.058247569147072187e-02, + 1.679392490937766935e-01, -2.257828022687320690e-03, + -4.490145670355452645e-02, -1.148364103573685929e-01, + -1.169790466695089237e-02, 6.140402504113953025e-02, + -8.078778132132799494e-02, -5.838878056243369807e-02, + 6.773639989682191109e-02, -1.247724708090079161e-02, + 6.494523955924384750e-02, -1.174787188812918687e-01}; + std::vector expected_v = { + -1.589185553287162656e-01, 2.586163333170100279e-03, + -1.575127933809472624e-04, -1.855360380105876630e-02, + 1.949822090859933826e-02, -1.006552056166355388e-02, + 3.177029853276916449e-02, 1.714349636720383010e-03, + -1.290389175187874483e-03, -8.553510339477603253e-02, + -5.654637257232508415e-03, -1.286954833787038420e-02, + 2.464156457499515687e-02, -2.398202886026797043e-02, + -1.957110465239037672e-02, 2.233492928605742764e-02, + 6.107843207824020099e-03, 1.707078295947736047e-03, + -1.653994088976195043e-01, 3.894358678172111371e-02, + -2.169595969759342477e-02, 6.819704294738503786e-03, + -5.018242039618424008e-03, 2.640664428663210429e-03, + -1.985298275686078057e-03, -3.638421609610945767e-02, + 2.342932331075030239e-02, -8.501331914753691710e-02, + -2.181253413538992297e-03, 4.311300069651782287e-03, + -1.910329328333908129e-03, -1.808810159508548836e-03, + -1.540075281450827612e-03, -1.173703213175551763e-02, + -2.596306629910121507e-03, 6.705025662372287101e-03, + -9.038455005073858795e-02, 3.011717773578577451e-02, + -5.083054073419784880e-02, -2.951210292616929069e-03, + 2.342445652898489383e-02, -4.091207474993674431e-02, + -1.648470649301832236e-02, -2.872261885460645689e-02, + 4.763924972552112391e-02, -8.300036532764677732e-02, + 1.020429228955421243e-03, -1.026734151199098881e-03, + 5.678534096113684732e-02, 1.273635718045938205e-02, + -1.530143225195957322e-02, -1.061671865629566225e-01, + -2.486859433265622629e-02, 2.875323131744185121e-02, + -1.589185553287162656e-01, 2.586163333170100279e-03, + -1.575127933809472624e-04, -1.855360380105876630e-02, + 1.949822090859933826e-02, -1.006552056166355388e-02, + 3.177029853276916449e-02, 1.714349636720383010e-03, + -1.290389175187874483e-03, -8.553510339477603253e-02, + -5.654637257232508415e-03, -1.286954833787038420e-02, + 2.464156457499515687e-02, -2.398202886026797043e-02, + -1.957110465239037672e-02, 2.233492928605742764e-02, + 6.107843207824020099e-03, 1.707078295947736047e-03, + -1.653994088976195043e-01, 3.894358678172111371e-02, + -2.169595969759342477e-02, 6.819704294738503786e-03, + -5.018242039618424008e-03, 2.640664428663210429e-03, + -1.985298275686078057e-03, -3.638421609610945767e-02, + 2.342932331075030239e-02, -8.501331914753691710e-02, + -2.181253413538992297e-03, 4.311300069651782287e-03, + -1.910329328333908129e-03, -1.808810159508548836e-03, + -1.540075281450827612e-03, -1.173703213175551763e-02, + -2.596306629910121507e-03, 6.705025662372287101e-03, + -9.038455005073858795e-02, 3.011717773578577451e-02, + -5.083054073419784880e-02, -2.951210292616929069e-03, + 2.342445652898489383e-02, -4.091207474993674431e-02, + -1.648470649301832236e-02, -2.872261885460645689e-02, + 4.763924972552112391e-02, -8.300036532764677732e-02, + 1.020429228955421243e-03, -1.026734151199098881e-03, + 5.678534096113684732e-02, 1.273635718045938205e-02, + -1.530143225195957322e-02, -1.061671865629566225e-01, + -2.486859433265622629e-02, 2.875323131744185121e-02}; + int natoms; + int nframes = 2; + std::vector expected_tot_e; + std::vector expected_tot_v; + + deepmd::hpp::DeepPot dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/fparam_aparam.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/fparam_aparam.pbtxt", + "fparam_aparam.pb"); + + dp.init("fparam_aparam.pb"); + + natoms = expected_e.size() / nframes; + EXPECT_EQ(nframes * natoms * 3, expected_f.size()); + EXPECT_EQ(nframes * natoms * 9, expected_v.size()); + expected_tot_e.resize(nframes); + expected_tot_v.resize(nframes * 9); + std::fill(expected_tot_e.begin(), expected_tot_e.end(), 0.); + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + for (int kk = 0; kk < nframes; ++kk) { + for (int ii = 0; ii < natoms; ++ii) { + expected_tot_e[kk] += expected_e[kk * natoms + ii]; + } + for (int ii = 0; ii < natoms; ++ii) { + for (int dd = 0; dd < 9; ++dd) { + expected_tot_v[kk * 9 + dd] += + expected_v[kk * natoms * 9 + ii * 9 + dd]; + } + } + } + }; + + void TearDown() override { remove("fparam_aparam.pb"); }; +}; + +TYPED_TEST_SUITE(TestInferDeepPotAFparamAparamNFrames, ValueTypes); + +TYPED_TEST(TestInferDeepPotAFparamAparamNFrames, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + std::vector ener; + std::vector force, virial; + dp.compute(ener, force, virial, coord, atype, box, fparam, aparam); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFrames, cpu_build_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + std::vector ener; + std::vector force, virial, atom_ener, atom_vir; + dp.compute(ener, force, virial, atom_ener, atom_vir, coord, atype, box, + fparam, aparam); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + EXPECT_EQ(atom_ener.size(), nframes * natoms); + EXPECT_EQ(atom_vir.size(), nframes * natoms * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFrames, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + std::vector ener; + std::vector force_, virial; + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + std::fill(ener.begin(), ener.end(), 0.0); + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFrames, cpu_lmp_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + std::vector ener; + std::vector force_, atom_ener_, atom_vir_, virial; + std::vector force, atom_ener, atom_vir; + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy2, atype_cpy, + box, nall - nloc, inlist, 0, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1, nframes); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + EXPECT_EQ(atom_ener.size(), nframes * natoms); + EXPECT_EQ(atom_vir.size(), nframes * natoms * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } + + std::fill(ener.begin(), ener.end(), 0.0); + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + std::fill(atom_ener_.begin(), atom_ener_.end(), 0.0); + std::fill(atom_vir_.begin(), atom_vir_.end(), 0.0); + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy2, atype_cpy, + box, nall - nloc, inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1, nframes); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + EXPECT_EQ(atom_ener.size(), nframes * natoms); + EXPECT_EQ(atom_vir.size(), nframes * natoms * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFrames, cpu_lmp_nlist_2rc) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc * 2); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + std::vector ener; + std::vector force_(nall * 3, 0.0), virial(nframes * 9, 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + std::fill(ener.begin(), ener.end(), 0.0); + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFrames, cpu_lmp_nlist_type_sel) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + + // add vir atoms + int nvir = 2; + std::vector coord_vir(nvir * 3); + std::vector atype_vir(nvir, 2); + std::vector aparam_vir(nvir * 1); + for (int ii = 0; ii < nvir; ++ii) { + coord_vir[ii] = coord[ii]; + } + for (int ii = 0; ii < nvir; ++ii) { + aparam_vir[ii] = aparam[ii]; + } + coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); + atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); + natoms += nvir; + std::vector expected_f_vir(nvir * 3, 0.0); + // two frames + expected_f.insert(expected_f.begin(), expected_f_vir.begin(), + expected_f_vir.end()); + expected_f.insert(expected_f.begin() + natoms * 3, expected_f_vir.begin(), + expected_f_vir.end()); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + + // build nlist + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + aparam.insert(aparam.begin(), aparam_vir.begin(), aparam_vir.end()); + aparam.insert(aparam.begin() + nloc, aparam_vir.begin(), aparam_vir.end()); + + // dp compute + std::vector ener; + std::vector force_(nall * 3, 0.0), virial(nframes * 9, 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + // fold back + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFrames, + cpu_lmp_nlist_type_sel_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + + // add vir atoms + int nvir = 2; + std::vector coord_vir(nvir * 3); + std::vector atype_vir(nvir, 2); + std::vector aparam_vir(nvir * 2); + for (int ii = 0; ii < nvir; ++ii) { + coord_vir[ii] = coord[ii]; + } + for (int ii = 0; ii < nvir * 2; ++ii) { + aparam_vir[ii] = aparam[ii]; + } + coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); + atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); + aparam.insert(aparam.begin(), aparam_vir.begin(), aparam_vir.end()); + natoms += nvir; + std::vector expected_f_vir(nvir * 3, 0.0); + // two frames + expected_f.insert(expected_f.begin(), expected_f_vir.begin(), + expected_f_vir.end()); + expected_f.insert(expected_f.begin() + natoms * 3, expected_f_vir.begin(), + expected_f_vir.end()); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + + // build nlist + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + // dp compute + std::vector ener; + std::vector force_(nall * 3, 0.0), virial(nframes * 9, 0.0), + atomic_energy, atomic_virial; + dp.compute(ener, force_, virial, atomic_energy, atomic_virial, coord_cpy2, + atype_cpy, box, nall - nloc, inlist, 0, fparam, aparam); + // fold back + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +template +class TestInferDeepPotAFparamAparamNFramesSingleParam : public ::testing::Test { + protected: + std::vector coord = { + 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, 3.51, 2.51, 2.60, 4.27, 3.22, 1.56, + 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; + std::vector atype = {0, 0, 0, 0, 0, 0}; + std::vector box = {13., 0., 0., 0., 13., 0., 0., 0., 13., + 13., 0., 0., 0., 13., 0., 0., 0., 13.}; + std::vector fparam = {0.25852028}; + std::vector aparam = {0.25852028, 0.25852028, 0.25852028, + 0.25852028, 0.25852028, 0.25852028}; + std::vector expected_e = { + -1.038271183039953804e-01, -7.285433575272914908e-02, + -9.467600174099155552e-02, -1.467050086239614082e-01, + -7.660561620618722145e-02, -7.277295998502930630e-02, + -1.038271183039953804e-01, -7.285433575272914908e-02, + -9.467600174099155552e-02, -1.467050086239614082e-01, + -7.660561620618722145e-02, -7.277295998502930630e-02}; + std::vector expected_f = { + 6.622266817497907132e-02, 5.278739055693523058e-02, + 2.265727495541422845e-02, -2.606047850915838363e-02, + -4.538811686410718776e-02, 1.058247569147072187e-02, + 1.679392490937766935e-01, -2.257828022687320690e-03, + -4.490145670355452645e-02, -1.148364103573685929e-01, + -1.169790466695089237e-02, 6.140402504113953025e-02, + -8.078778132132799494e-02, -5.838878056243369807e-02, + 6.773639989682191109e-02, -1.247724708090079161e-02, + 6.494523955924384750e-02, -1.174787188812918687e-01, + 6.622266817497907132e-02, 5.278739055693523058e-02, + 2.265727495541422845e-02, -2.606047850915838363e-02, + -4.538811686410718776e-02, 1.058247569147072187e-02, + 1.679392490937766935e-01, -2.257828022687320690e-03, + -4.490145670355452645e-02, -1.148364103573685929e-01, + -1.169790466695089237e-02, 6.140402504113953025e-02, + -8.078778132132799494e-02, -5.838878056243369807e-02, + 6.773639989682191109e-02, -1.247724708090079161e-02, + 6.494523955924384750e-02, -1.174787188812918687e-01}; + std::vector expected_v = { + -1.589185553287162656e-01, 2.586163333170100279e-03, + -1.575127933809472624e-04, -1.855360380105876630e-02, + 1.949822090859933826e-02, -1.006552056166355388e-02, + 3.177029853276916449e-02, 1.714349636720383010e-03, + -1.290389175187874483e-03, -8.553510339477603253e-02, + -5.654637257232508415e-03, -1.286954833787038420e-02, + 2.464156457499515687e-02, -2.398202886026797043e-02, + -1.957110465239037672e-02, 2.233492928605742764e-02, + 6.107843207824020099e-03, 1.707078295947736047e-03, + -1.653994088976195043e-01, 3.894358678172111371e-02, + -2.169595969759342477e-02, 6.819704294738503786e-03, + -5.018242039618424008e-03, 2.640664428663210429e-03, + -1.985298275686078057e-03, -3.638421609610945767e-02, + 2.342932331075030239e-02, -8.501331914753691710e-02, + -2.181253413538992297e-03, 4.311300069651782287e-03, + -1.910329328333908129e-03, -1.808810159508548836e-03, + -1.540075281450827612e-03, -1.173703213175551763e-02, + -2.596306629910121507e-03, 6.705025662372287101e-03, + -9.038455005073858795e-02, 3.011717773578577451e-02, + -5.083054073419784880e-02, -2.951210292616929069e-03, + 2.342445652898489383e-02, -4.091207474993674431e-02, + -1.648470649301832236e-02, -2.872261885460645689e-02, + 4.763924972552112391e-02, -8.300036532764677732e-02, + 1.020429228955421243e-03, -1.026734151199098881e-03, + 5.678534096113684732e-02, 1.273635718045938205e-02, + -1.530143225195957322e-02, -1.061671865629566225e-01, + -2.486859433265622629e-02, 2.875323131744185121e-02, + -1.589185553287162656e-01, 2.586163333170100279e-03, + -1.575127933809472624e-04, -1.855360380105876630e-02, + 1.949822090859933826e-02, -1.006552056166355388e-02, + 3.177029853276916449e-02, 1.714349636720383010e-03, + -1.290389175187874483e-03, -8.553510339477603253e-02, + -5.654637257232508415e-03, -1.286954833787038420e-02, + 2.464156457499515687e-02, -2.398202886026797043e-02, + -1.957110465239037672e-02, 2.233492928605742764e-02, + 6.107843207824020099e-03, 1.707078295947736047e-03, + -1.653994088976195043e-01, 3.894358678172111371e-02, + -2.169595969759342477e-02, 6.819704294738503786e-03, + -5.018242039618424008e-03, 2.640664428663210429e-03, + -1.985298275686078057e-03, -3.638421609610945767e-02, + 2.342932331075030239e-02, -8.501331914753691710e-02, + -2.181253413538992297e-03, 4.311300069651782287e-03, + -1.910329328333908129e-03, -1.808810159508548836e-03, + -1.540075281450827612e-03, -1.173703213175551763e-02, + -2.596306629910121507e-03, 6.705025662372287101e-03, + -9.038455005073858795e-02, 3.011717773578577451e-02, + -5.083054073419784880e-02, -2.951210292616929069e-03, + 2.342445652898489383e-02, -4.091207474993674431e-02, + -1.648470649301832236e-02, -2.872261885460645689e-02, + 4.763924972552112391e-02, -8.300036532764677732e-02, + 1.020429228955421243e-03, -1.026734151199098881e-03, + 5.678534096113684732e-02, 1.273635718045938205e-02, + -1.530143225195957322e-02, -1.061671865629566225e-01, + -2.486859433265622629e-02, 2.875323131744185121e-02}; + int natoms; + int nframes = 2; + std::vector expected_tot_e; + std::vector expected_tot_v; + + deepmd::hpp::DeepPot dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/fparam_aparam.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/fparam_aparam.pbtxt", + "fparam_aparam.pb"); + + dp.init("fparam_aparam.pb"); + + natoms = expected_e.size() / nframes; + EXPECT_EQ(nframes * natoms * 3, expected_f.size()); + EXPECT_EQ(nframes * natoms * 9, expected_v.size()); + expected_tot_e.resize(nframes); + expected_tot_v.resize(nframes * 9); + std::fill(expected_tot_e.begin(), expected_tot_e.end(), 0.); + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + for (int kk = 0; kk < nframes; ++kk) { + for (int ii = 0; ii < natoms; ++ii) { + expected_tot_e[kk] += expected_e[kk * natoms + ii]; + } + for (int ii = 0; ii < natoms; ++ii) { + for (int dd = 0; dd < 9; ++dd) { + expected_tot_v[kk * 9 + dd] += + expected_v[kk * natoms * 9 + ii * 9 + dd]; + } + } + } + }; + + void TearDown() override { remove("fparam_aparam.pb"); }; +}; + +TYPED_TEST_SUITE(TestInferDeepPotAFparamAparamNFramesSingleParam, ValueTypes); + +TYPED_TEST(TestInferDeepPotAFparamAparamNFramesSingleParam, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + std::vector ener; + std::vector force, virial; + dp.compute(ener, force, virial, coord, atype, box, fparam, aparam); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFramesSingleParam, + cpu_build_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + std::vector ener; + std::vector force, virial, atom_ener, atom_vir; + dp.compute(ener, force, virial, atom_ener, atom_vir, coord, atype, box, + fparam, aparam); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + EXPECT_EQ(atom_ener.size(), nframes * natoms); + EXPECT_EQ(atom_vir.size(), nframes * natoms * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFramesSingleParam, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + std::vector ener; + std::vector force_, virial; + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + std::fill(ener.begin(), ener.end(), 0.0); + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFramesSingleParam, + cpu_lmp_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + std::vector ener; + std::vector force_, atom_ener_, atom_vir_, virial; + std::vector force, atom_ener, atom_vir; + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy2, atype_cpy, + box, nall - nloc, inlist, 0, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1, nframes); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + EXPECT_EQ(atom_ener.size(), nframes * natoms); + EXPECT_EQ(atom_vir.size(), nframes * natoms * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } + + std::fill(ener.begin(), ener.end(), 0.0); + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + std::fill(atom_ener_.begin(), atom_ener_.end(), 0.0); + std::fill(atom_vir_.begin(), atom_vir_.end(), 0.0); + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy2, atype_cpy, + box, nall - nloc, inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1, nframes); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + EXPECT_EQ(atom_ener.size(), nframes * natoms); + EXPECT_EQ(atom_vir.size(), nframes * natoms * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms; ++ii) { + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 9; ++ii) { + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFramesSingleParam, cpu_lmp_nlist_2rc) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc * 2); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + std::vector ener; + std::vector force_(nall * 3, 0.0), virial(nframes * 9, 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + std::fill(ener.begin(), ener.end(), 0.0); + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 1, fparam, aparam); + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFramesSingleParam, + cpu_lmp_nlist_type_sel) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + + // add vir atoms + int nvir = 2; + std::vector coord_vir(nvir * 3); + std::vector atype_vir(nvir, 2); + std::vector aparam_vir(nvir * 1); + for (int ii = 0; ii < nvir; ++ii) { + coord_vir[ii] = coord[ii]; + } + for (int ii = 0; ii < nvir; ++ii) { + aparam_vir[ii] = aparam[ii]; + } + coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); + atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); + natoms += nvir; + std::vector expected_f_vir(nvir * 3, 0.0); + // two frames + expected_f.insert(expected_f.begin(), expected_f_vir.begin(), + expected_f_vir.end()); + expected_f.insert(expected_f.begin() + natoms * 3, expected_f_vir.begin(), + expected_f_vir.end()); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + + // build nlist + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + aparam.insert(aparam.begin(), aparam_vir.begin(), aparam_vir.end()); + + // dp compute + std::vector ener; + std::vector force_(nall * 3, 0.0), virial(nframes * 9, 0.0); + dp.compute(ener, force_, virial, coord_cpy2, atype_cpy, box, nall - nloc, + inlist, 0, fparam, aparam); + // fold back + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAFparamAparamNFramesSingleParam, + cpu_lmp_nlist_type_sel_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& fparam = this->fparam; + std::vector& aparam = this->aparam; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + int& nframes = this->nframes; + std::vector& expected_tot_e = this->expected_tot_e; + std::vector& expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + + // add vir atoms + int nvir = 2; + std::vector coord_vir(nvir * 3); + std::vector atype_vir(nvir, 2); + std::vector aparam_vir(nvir); + for (int ii = 0; ii < nvir; ++ii) { + coord_vir[ii] = coord[ii]; + } + for (int ii = 0; ii < nvir; ++ii) { + aparam_vir[ii] = aparam[ii]; + } + coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); + atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); + aparam.insert(aparam.begin(), aparam_vir.begin(), aparam_vir.end()); + natoms += nvir; + std::vector expected_f_vir(nvir * 3, 0.0); + // two frames + expected_f.insert(expected_f.begin(), expected_f_vir.begin(), + expected_f_vir.end()); + expected_f.insert(expected_f.begin() + natoms * 3, expected_f_vir.begin(), + expected_f_vir.end()); + std::vector coord_first(coord.begin(), coord.begin() + 3 * natoms); + std::vector box_first(box.begin(), box.begin() + 9); + + // build nlist + int nloc = coord_first.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord_first, atype, box_first, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + std::vector coord_cpy2(nframes * nall * 3); + for (int ii = 0; ii < nframes; ++ii) { + for (int jj = 0; jj < nall * 3; ++jj) { + coord_cpy2[ii * nall * 3 + jj] = coord_cpy[jj]; + } + } + + // dp compute + std::vector ener; + std::vector force_(nall * 3, 0.0), virial(nframes * 9, 0.0), + atomic_energy, atomic_virial; + dp.compute(ener, force_, virial, atomic_energy, atomic_virial, coord_cpy2, + atype_cpy, box, nall - nloc, inlist, 0, fparam, aparam); + // fold back + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3, nframes); + + EXPECT_EQ(ener.size(), nframes); + EXPECT_EQ(force.size(), nframes * natoms * 3); + EXPECT_EQ(virial.size(), nframes * 9); + + for (int ii = 0; ii < nframes; ++ii) { + EXPECT_LT(fabs(ener[ii] - expected_tot_e[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * natoms * 3; ++ii) { + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for (int ii = 0; ii < nframes * 3 * 3; ++ii) { + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} From 0e3128a3c314307e4d5a639ed17f31a50266a191 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 20 Mar 2023 04:06:50 -0400 Subject: [PATCH 2/4] fix errors Signed-off-by: Jinzhe Zeng --- source/api_c/include/deepmd.hpp | 35 +++++++++++++++++++++++++-------- source/api_c/src/c_api.cc | 33 ++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/source/api_c/include/deepmd.hpp b/source/api_c/include/deepmd.hpp index 8fd158573c..6f2740077b 100644 --- a/source/api_c/include/deepmd.hpp +++ b/source/api_c/include/deepmd.hpp @@ -633,12 +633,15 @@ class DeepPot { virial.resize(nframes * 9); VALUETYPE *force_ = &force[0]; VALUETYPE *virial_ = &virial[0]; + std::vector 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_DeepPotCompute(dp, nframes, natoms, coord_, atype_, box_, - fparam_, aparam_, ener_, force_, virial_, + fparam__, aparam__, ener_, force_, virial_, nullptr, nullptr); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; @@ -695,12 +698,15 @@ class DeepPot { VALUETYPE *virial_ = &virial[0]; VALUETYPE *atomic_ener_ = &atom_energy[0]; VALUETYPE *atomic_virial_ = &atom_virial[0]; + std::vector 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_DeepPotCompute(dp, nframes, natoms, coord_, atype_, box_, - fparam_, aparam_, ener_, force_, virial_, + fparam__, aparam__, ener_, force_, virial_, atomic_ener_, atomic_virial_); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; @@ -755,13 +761,16 @@ class DeepPot { virial.resize(nframes * 9); VALUETYPE *force_ = &force[0]; VALUETYPE *virial_ = &virial[0]; + std::vector fparam_, aparam_; validate_fparam_aparam(nframes, natoms - nghost, fparam, aparam); tile_fparam_aparam(fparam_, nframes, dfparam, fparam); tile_fparam_aparam(aparam_, nframes, (natoms - nghost) * daparam, aparam); + const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; + const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; _DP_DeepPotComputeNList( dp, nframes, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, - fparam_, aparam_, ener_, force_, virial_, nullptr, nullptr); + fparam__, aparam__, ener_, force_, virial_, nullptr, nullptr); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; /** @@ -823,13 +832,17 @@ class DeepPot { VALUETYPE *virial_ = &virial[0]; VALUETYPE *atomic_ener_ = &atom_energy[0]; VALUETYPE *atomic_virial_ = &atom_virial[0]; + std::vector fparam_, aparam_; validate_fparam_aparam(nframes, natoms - nghost, fparam, aparam); tile_fparam_aparam(fparam_, nframes, dfparam, fparam); tile_fparam_aparam(aparam_, nframes, (natoms - nghost) * daparam, aparam); + const VALUETYPE *fparam__ = !fparam_.empty() ? &fparam_[0] : nullptr; + const VALUETYPE *aparam__ = !aparam_.empty() ? &aparam_[0] : nullptr; - _DP_DeepPotComputeNList( - dp, nframes, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, - fparam_, aparam_, ener_, force_, virial_, atomic_ener_, atomic_virial_); + _DP_DeepPotComputeNList(dp, nframes, natoms, coord_, atype_, + box_, nghost, lmp_list.nl, ago, fparam__, + aparam__, ener_, force_, virial_, + atomic_ener_, atomic_virial_); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; /** @@ -877,12 +890,15 @@ class DeepPot { virial.resize(nframes * 9); VALUETYPE *force_ = &force[0]; VALUETYPE *virial_ = &virial[0]; + std::vector 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_DeepPotComputeMixedType(dp, nframes, natoms, coord_, atype_, - box_, fparam_, aparam_, ener_, + box_, fparam__, aparam__, ener_, force_, virial_, nullptr, nullptr); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; @@ -940,12 +956,15 @@ class DeepPot { VALUETYPE *virial_ = &virial[0]; VALUETYPE *atomic_ener_ = &atom_energy[0]; VALUETYPE *atomic_virial_ = &atom_virial[0]; + std::vector 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_DeepPotComputeMixedType( - dp, nframes, natoms, coord_, atype_, box_, fparam_, aparam_, ener_, + dp, nframes, natoms, coord_, atype_, box_, fparam__, aparam__, ener_, force_, virial_, atomic_ener_, atomic_virial_); DP_CHECK_OK(DP_DeepPotCheckOK, dp); }; diff --git a/source/api_c/src/c_api.cc b/source/api_c/src/c_api.cc index f04f485ccb..f407ca68e3 100644 --- a/source/api_c/src/c_api.cc +++ b/source/api_c/src/c_api.cc @@ -124,9 +124,14 @@ inline void DP_DeepPotCompute_variant(DP_DeepPot* dp, // pbc cell_.assign(cell, cell + nframes * 9); } - std::vector fparam_(fparam, fparam + nframes * dp->dfparam); - std::vector aparam_(aparam, - aparam + nframes * natoms * dp->daparam); + std::vector fparam_; + if (fparam) { + fparam_.assign(fparam, fparam + nframes * dp->dfparam); + } + std::vector aparam_; + if (aparam) { + aparam_.assign(aparam, aparam + nframes * dp->daparam); + } std::vector e; std::vector f, v, ae, av; @@ -193,9 +198,14 @@ inline void DP_DeepPotComputeNList_variant(DP_DeepPot* dp, // pbc cell_.assign(cell, cell + nframes * 9); } - std::vector fparam_(fparam, fparam + nframes * dp->dfparam); - std::vector aparam_(aparam, - aparam + nframes * natoms * dp->daparam); + std::vector fparam_; + if (fparam) { + fparam_.assign(fparam, fparam + nframes * dp->dfparam); + } + std::vector aparam_; + if (aparam) { + aparam_.assign(aparam, aparam + nframes * dp->daparam); + } std::vector e; std::vector f, v, ae, av; @@ -265,9 +275,14 @@ inline void DP_DeepPotComputeMixedType_variant(DP_DeepPot* dp, // pbc cell_.assign(cell, cell + nframes * 9); } - std::vector fparam_(fparam, fparam + nframes * dp->dfparam); - std::vector aparam_(aparam, - aparam + nframes * natoms * dp->daparam); + std::vector fparam_; + if (fparam) { + fparam_.assign(fparam, fparam + nframes * dp->dfparam); + } + std::vector aparam_; + if (aparam) { + aparam_.assign(aparam, aparam + nframes * dp->daparam); + } std::vector e; std::vector f, v, ae, av; From 860e796481919b2dfdacca7aca45b263ddbcd2dd Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 20 Mar 2023 04:25:43 -0400 Subject: [PATCH 3/4] fix error Signed-off-by: Jinzhe Zeng --- source/api_c/src/c_api.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/api_c/src/c_api.cc b/source/api_c/src/c_api.cc index f407ca68e3..4ce7dba1ca 100644 --- a/source/api_c/src/c_api.cc +++ b/source/api_c/src/c_api.cc @@ -130,7 +130,7 @@ inline void DP_DeepPotCompute_variant(DP_DeepPot* dp, } std::vector aparam_; if (aparam) { - aparam_.assign(aparam, aparam + nframes * dp->daparam); + aparam_.assign(aparam, aparam + nframes * natoms * dp->daparam); } std::vector e; std::vector f, v, ae, av; @@ -204,7 +204,7 @@ inline void DP_DeepPotComputeNList_variant(DP_DeepPot* dp, } std::vector aparam_; if (aparam) { - aparam_.assign(aparam, aparam + nframes * dp->daparam); + aparam_.assign(aparam, aparam + nframes * natoms * dp->daparam); } std::vector e; std::vector f, v, ae, av; @@ -281,7 +281,7 @@ inline void DP_DeepPotComputeMixedType_variant(DP_DeepPot* dp, } std::vector aparam_; if (aparam) { - aparam_.assign(aparam, aparam + nframes * dp->daparam); + aparam_.assign(aparam, aparam + nframes * natoms * dp->daparam); } std::vector e; std::vector f, v, ae, av; From 0e425fed561f6b6e06794fefe89bb9273dc9711e Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 20 Mar 2023 17:32:01 -0400 Subject: [PATCH 4/4] -nghost Signed-off-by: Jinzhe Zeng --- source/api_c/src/c_api.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/api_c/src/c_api.cc b/source/api_c/src/c_api.cc index 4ce7dba1ca..253790008c 100644 --- a/source/api_c/src/c_api.cc +++ b/source/api_c/src/c_api.cc @@ -204,7 +204,7 @@ inline void DP_DeepPotComputeNList_variant(DP_DeepPot* dp, } std::vector aparam_; if (aparam) { - aparam_.assign(aparam, aparam + nframes * natoms * dp->daparam); + aparam_.assign(aparam, aparam + nframes * (natoms - nghost) * dp->daparam); } std::vector e; std::vector f, v, ae, av;