Skip to content

Commit 87e6a54

Browse files
authored
support exceptions in C/hpp APIs (#2344)
Signed-off-by: Jinzhe Zeng <jinzhe.zeng@rutgers.edu>
1 parent 1303740 commit 87e6a54

File tree

6 files changed

+221
-41
lines changed

6 files changed

+221
-41
lines changed

source/api_c/include/c_api.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ extern DP_Nlist* DP_NewNlist(int inum_,
2121
int* numneigh_,
2222
int** firstneigh_);
2323

24+
/**
25+
* @brief Check if there is any exceptions throw.
26+
*
27+
* @param dp The neighbor list to use.
28+
* @return const char* error message.
29+
*/
30+
const char* DP_NlistCheckOK(DP_Nlist* dp);
31+
2432
/**
2533
* @brief The deep potential.
2634
**/
@@ -446,6 +454,14 @@ double DP_DeepPotModelDeviGetCutoff(DP_DeepPotModelDevi* dp);
446454
*/
447455
int DP_DeepPotModelDeviGetNumbTypes(DP_DeepPotModelDevi* dp);
448456

457+
/**
458+
* @brief Check if there is any exceptions throw.
459+
*
460+
* @param dp The DP model deviation to use.
461+
* @return const char* error message.
462+
*/
463+
const char* DP_DeepPotModelDeviCheckOK(DP_DeepPotModelDevi* dp);
464+
449465
/**
450466
* @brief Get the type map of a DP.
451467
* @param[in] dp The DP to use.
@@ -472,6 +488,14 @@ const char* DP_DeepPotGetTypeMap(DP_DeepPot* dp);
472488
**/
473489
typedef struct DP_DeepTensor DP_DeepTensor;
474490

491+
/**
492+
* @brief Check if there is any exceptions throw.
493+
*
494+
* @param dp The DP to use.
495+
* @return const char* error message.
496+
*/
497+
const char* DP_DeepPotCheckOK(DP_DeepPot* dp);
498+
475499
/**
476500
* @brief Deep Tensor constructor with initialization.
477501
* @param[in] c_model The name of the frozen model file.
@@ -755,6 +779,14 @@ int* DP_DeepTensorGetSelTypes(DP_DeepTensor* dt);
755779
*/
756780
int DP_DeepTensorGetNumbSelTypes(DP_DeepTensor* dt);
757781

782+
/**
783+
* @brief Check if there is any exceptions throw.
784+
*
785+
* @param dt The Deep Tensor to use.
786+
* @return const char* error message.
787+
*/
788+
const char* DP_DeepTensorCheckOK(DP_DeepTensor* dt);
789+
758790
/**
759791
* @brief The dipole charge modifier.
760792
**/
@@ -878,6 +910,14 @@ int* DP_DipoleChargeModifierGetSelTypes(DP_DipoleChargeModifier* dt);
878910
*/
879911
int DP_DipoleChargeModifierGetNumbSelTypes(DP_DipoleChargeModifier* dt);
880912

913+
/**
914+
* @brief Check if there is any exceptions throw.
915+
*
916+
* @param dcm The DipoleChargeModifier to use.
917+
* @return const char* error message.
918+
*/
919+
const char* DP_DipoleChargeModifierCheckOK(DP_DipoleChargeModifier* dcm);
920+
881921
/**
882922
* @brief Convert PBtxt to PB.
883923
* @param[in] c_pbtxt The name of the PBtxt file.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,65 @@
1+
#include <string>
2+
13
#include "DataModifier.h"
24
#include "DeepPot.h"
35
#include "DeepTensor.h"
46
#include "neighbor_list.h"
57

8+
// catch deepmd::deepmd_exception and store it in dp->exception
9+
// return nothing
10+
#define DP_REQUIRES_OK(dp, xx) \
11+
try { \
12+
xx; \
13+
} catch (deepmd::deepmd_exception & ex) { \
14+
dp->exception = std::string(ex.what()); \
15+
return; \
16+
}
17+
18+
#define DP_NEW_OK(dpcls, xx) \
19+
try { \
20+
xx; \
21+
} catch (deepmd::deepmd_exception & ex) { \
22+
dpcls* _new_dp = new dpcls; \
23+
_new_dp->exception = std::string(ex.what()); \
24+
return _new_dp; \
25+
}
26+
627
struct DP_Nlist {
28+
DP_Nlist();
729
DP_Nlist(deepmd::InputNlist& nl);
830

931
deepmd::InputNlist nl;
32+
std::string exception;
1033
};
1134

1235
struct DP_DeepPot {
36+
DP_DeepPot();
1337
DP_DeepPot(deepmd::DeepPot& dp);
1438

1539
deepmd::DeepPot dp;
40+
std::string exception;
1641
};
1742

1843
struct DP_DeepPotModelDevi {
44+
DP_DeepPotModelDevi();
1945
DP_DeepPotModelDevi(deepmd::DeepPotModelDevi& dp);
2046

2147
deepmd::DeepPotModelDevi dp;
48+
std::string exception;
2249
};
2350

2451
struct DP_DeepTensor {
52+
DP_DeepTensor();
2553
DP_DeepTensor(deepmd::DeepTensor& dt);
2654

2755
deepmd::DeepTensor dt;
56+
std::string exception;
2857
};
2958

3059
struct DP_DipoleChargeModifier {
60+
DP_DipoleChargeModifier();
3161
DP_DipoleChargeModifier(deepmd::DipoleChargeModifier& dcm);
3262

3363
deepmd::DipoleChargeModifier dcm;
64+
std::string exception;
3465
};

source/api_c/include/deepmd.hpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,35 @@ This header-only library provides a C++ 11 interface to the DeePMD-kit C API.
88

99
#include <algorithm>
1010
#include <cassert>
11+
#include <exception>
1112
#include <iostream>
1213
#include <string>
1314
#include <vector>
1415

1516
#include "c_api.h"
1617

18+
namespace deepmd {
19+
namespace hpp {
20+
/**
21+
* @brief General DeePMD-kit exception. Throw if anything doesn't work.
22+
**/
23+
struct deepmd_exception : public std::runtime_error {
24+
public:
25+
deepmd_exception() : runtime_error("DeePMD-kit C API Error!"){};
26+
deepmd_exception(const std::string &msg)
27+
: runtime_error(std::string("DeePMD-kit C API Error: ") + msg){};
28+
};
29+
} // namespace hpp
30+
} // namespace deepmd
31+
32+
/**
33+
* @brief Check if any exceptions throw in the C++ API. Throw if possible.
34+
*/
35+
#define DP_CHECK_OK(check_func, dp) \
36+
const char *err_msg = check_func(dp); \
37+
if (strlen(err_msg)) \
38+
throw deepmd::hpp::deepmd_exception(std::string(err_msg));
39+
1740
template <typename FPTYPE>
1841
inline void _DP_DeepPotCompute(DP_DeepPot *dp,
1942
const int nframes,
@@ -422,13 +445,17 @@ struct InputNlist {
422445
ilist(nullptr),
423446
numneigh(nullptr),
424447
firstneigh(nullptr),
425-
nl(DP_NewNlist(0, nullptr, nullptr, nullptr)){};
448+
nl(DP_NewNlist(0, nullptr, nullptr, nullptr)) {
449+
DP_CHECK_OK(DP_NlistCheckOK, nl);
450+
};
426451
InputNlist(int inum_, int *ilist_, int *numneigh_, int **firstneigh_)
427452
: inum(inum_),
428453
ilist(ilist_),
429454
numneigh(numneigh_),
430455
firstneigh(firstneigh_),
431-
nl(DP_NewNlist(inum_, ilist_, numneigh_, firstneigh_)){};
456+
nl(DP_NewNlist(inum_, ilist_, numneigh_, firstneigh_)) {
457+
DP_CHECK_OK(DP_NlistCheckOK, nl);
458+
};
432459
/// @brief C API neighbor list.
433460
DP_Nlist *nl;
434461
/// @brief Number of core region atoms
@@ -504,6 +531,7 @@ class DeepPot {
504531
return;
505532
}
506533
dp = DP_NewDeepPotWithParam(model.c_str(), gpu_rank, file_content.c_str());
534+
DP_CHECK_OK(DP_DeepPotCheckOK, dp);
507535
};
508536

509537
/**
@@ -542,6 +570,7 @@ class DeepPot {
542570
_DP_DeepPotCompute<VALUETYPE>(dp, nframes, natoms, coord_, atype_, box_,
543571
nullptr, nullptr, ener_, force_, virial_,
544572
nullptr, nullptr);
573+
DP_CHECK_OK(DP_DeepPotCheckOK, dp);
545574
};
546575
/**
547576
* @brief Evaluate the energy, force, virial, atomic energy, and atomic virial
@@ -589,6 +618,7 @@ class DeepPot {
589618
_DP_DeepPotCompute<VALUETYPE>(dp, nframes, natoms, coord_, atype_, box_,
590619
nullptr, nullptr, ener_, force_, virial_,
591620
atomic_ener_, atomic_virial_);
621+
DP_CHECK_OK(DP_DeepPotCheckOK, dp);
592622
};
593623

594624
/**
@@ -634,6 +664,7 @@ class DeepPot {
634664
_DP_DeepPotComputeNList<VALUETYPE>(
635665
dp, nframes, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago,
636666
nullptr, nullptr, ener_, force_, virial_, nullptr, nullptr);
667+
DP_CHECK_OK(DP_DeepPotCheckOK, dp);
637668
};
638669
/**
639670
* @brief Evaluate the energy, force, virial, atomic energy, and atomic virial
@@ -687,6 +718,7 @@ class DeepPot {
687718
_DP_DeepPotComputeNList<VALUETYPE>(
688719
dp, nframes, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago,
689720
nullptr, nullptr, ener_, force_, virial_, atomic_ener_, atomic_virial_);
721+
DP_CHECK_OK(DP_DeepPotCheckOK, dp);
690722
};
691723
/**
692724
* @brief Get the cutoff radius.
@@ -759,6 +791,7 @@ class DeepPotModelDevi {
759791
for (std::string const &str : models) cstrings.push_back(str.data());
760792

761793
dp = DP_NewDeepPotModelDevi(cstrings.data(), cstrings.size());
794+
DP_CHECK_OK(DP_DeepPotModelDeviCheckOK, dp);
762795
numb_models = models.size();
763796
};
764797

@@ -804,6 +837,7 @@ class DeepPotModelDevi {
804837
_DP_DeepPotModelDeviComputeNList<VALUETYPE>(
805838
dp, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, ener_,
806839
force_, virial_, nullptr, nullptr);
840+
DP_CHECK_OK(DP_DeepPotModelDeviCheckOK, dp);
807841

808842
// reshape
809843
ener.resize(numb_models);
@@ -867,6 +901,7 @@ class DeepPotModelDevi {
867901
_DP_DeepPotModelDeviComputeNList<VALUETYPE>(
868902
dp, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, ener_,
869903
force_, virial_, atomic_ener_, atomic_virial_);
904+
DP_CHECK_OK(DP_DeepPotModelDeviCheckOK, dp);
870905

871906
// reshape
872907
ener.resize(numb_models);
@@ -945,6 +980,7 @@ class DeepTensor {
945980
return;
946981
}
947982
dt = DP_NewDeepTensorWithParam(model.c_str(), gpu_rank, name_scope.c_str());
983+
DP_CHECK_OK(DP_DeepTensorCheckOK, dt);
948984
odim = output_dim();
949985
nsel_types = DP_DeepTensorGetNumbSelTypes(dt);
950986
};
@@ -979,6 +1015,7 @@ class DeepTensor {
9791015

9801016
_DP_DeepTensorComputeTensor<VALUETYPE>(dt, natoms, coord_, atype_, box_,
9811017
p_tensor, p_size);
1018+
DP_CHECK_OK(DP_DeepTensorCheckOK, dt);
9821019

9831020
tensor.resize(size);
9841021
std::copy(tensor_, tensor_ + size, tensor.begin());
@@ -1021,6 +1058,7 @@ class DeepTensor {
10211058
_DP_DeepTensorComputeTensorNList<VALUETYPE>(dt, natoms, coord_, atype_,
10221059
box_, nghost, lmp_list.nl,
10231060
p_tensor, p_size);
1061+
DP_CHECK_OK(DP_DeepTensorCheckOK, dt);
10241062

10251063
tensor.resize(size);
10261064
std::copy(tensor_, tensor_ + size, tensor.begin());
@@ -1064,6 +1102,7 @@ class DeepTensor {
10641102
_DP_DeepTensorCompute<VALUETYPE>(dt, natoms, coord_, atype_, box_,
10651103
global_tensor_, force_, virial_, nullptr,
10661104
nullptr, nullptr);
1105+
DP_CHECK_OK(DP_DeepTensorCheckOK, dt);
10671106
};
10681107
/**
10691108
* @brief Evaluate the global tensor, force, virial, atomic tensor, and atomic
@@ -1114,6 +1153,7 @@ class DeepTensor {
11141153
_DP_DeepTensorCompute<VALUETYPE>(
11151154
dt, natoms, coord_, atype_, box_, global_tensor_, force_, virial_,
11161155
p_atomic_tensor, atomic_virial_, p_size_at);
1156+
DP_CHECK_OK(DP_DeepTensorCheckOK, dt);
11171157

11181158
atom_tensor.resize(size_at);
11191159
std::copy(atomic_tensor_, atomic_tensor_ + size_at, atom_tensor.begin());
@@ -1161,6 +1201,7 @@ class DeepTensor {
11611201
_DP_DeepTensorComputeNList<VALUETYPE>(
11621202
dt, natoms, coord_, atype_, box_, nghost, lmp_list.nl, global_tensor_,
11631203
force_, virial_, nullptr, nullptr, nullptr);
1204+
DP_CHECK_OK(DP_DeepTensorCheckOK, dt);
11641205
};
11651206
/**
11661207
* @brief Evaluate the global tensor, force, virial, atomic tensor, and atomic
@@ -1215,6 +1256,7 @@ class DeepTensor {
12151256
_DP_DeepTensorComputeNList<VALUETYPE>(
12161257
dt, natoms, coord_, atype_, box_, nghost, lmp_list.nl, global_tensor_,
12171258
force_, virial_, p_atomic_tensor, atomic_virial_, p_size_at);
1259+
DP_CHECK_OK(DP_DeepTensorCheckOK, dt);
12181260

12191261
atom_tensor.resize(size_at);
12201262
std::copy(atomic_tensor_, atomic_tensor_ + size_at, atom_tensor.begin());
@@ -1302,6 +1344,7 @@ class DipoleChargeModifier {
13021344
}
13031345
dcm = DP_NewDipoleChargeModifierWithParam(model.c_str(), gpu_rank,
13041346
name_scope.c_str());
1347+
DP_CHECK_OK(DP_DipoleChargeModifierCheckOK, dcm);
13051348
nsel_types = DP_DipoleChargeModifierGetNumbSelTypes(dcm);
13061349
};
13071350
/**
@@ -1350,6 +1393,7 @@ class DipoleChargeModifier {
13501393
_DP_DipoleChargeModifierComputeNList<VALUETYPE>(
13511394
dcm, natoms, dcoord, datype, dbox_, dpairs, npairs, delef, nghost,
13521395
lmp_list.nl, dfcorr, dvcorr);
1396+
DP_CHECK_OK(DP_DipoleChargeModifierCheckOK, dcm);
13531397
};
13541398
/**
13551399
* @brief Get the cutoff radius.

0 commit comments

Comments
 (0)