eOn 3.2.0
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
GenericEngineLoader.cpp
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
#include "
eon/potentials/Rgpot/GenericEngineLoader.h
"
13
#include <cstdlib>
14
#include <stdexcept>
15
#include <vector>
16
#ifndef _WIN32
17
#include <dlfcn.h>
18
#endif
19
20
namespace
{
21
void
*open_lib(
const
char
*path) {
22
#ifndef _WIN32
23
return
dlopen(path, RTLD_NOW | RTLD_GLOBAL);
24
#else
25
return
nullptr
;
26
#endif
27
}
28
void
close_lib(
void
*h) {
29
#ifndef _WIN32
30
if
(h)
31
dlclose(h);
32
#endif
33
}
34
void
*load_sym(
void
*h,
const
char
*n) {
35
#ifndef _WIN32
36
return
dlsym(h, n);
37
#else
38
return
nullptr
;
39
#endif
40
}
41
}
// namespace
42
43
GenericEngineLoader::GenericEngineLoader
(
const
GenericEngineOptions
&opt)
44
:
m_tag
(opt.tag.empty() ? opt.library : opt.tag) {
45
std::vector<std::string> paths;
46
if
(!opt.
engine_path
.empty())
47
paths.push_back(opt.
engine_path
);
48
if (!opt.
env_var
.empty())
49
if (
const
char
*e = std::getenv(opt.
env_var
.c_str()))
50
if (e && *e)
51
paths.emplace_back(e);
52
paths.push_back(opt.
library
);
53
auto
add_dirs = [&](
const
char
*env) {
54
if (!env)
55
return;
56
std::string s(env);
57
size_t i = 0;
58
while (i < s.size()) {
59
const auto j = s.find(
':'
, i);
60
const auto dir = s.substr(i, j == std::string::npos ? j : j - i);
61
if (!dir.empty())
62
paths.push_back(dir +
"/"
+ opt.library);
63
if (j == std::string::npos)
64
break;
65
i = j + 1;
66
}
67
};
68
add_dirs(std::getenv(
"EON_POTENTIALS_PATH"
));
69
70
std::string last_dlerr;
71
for
(
const
auto
&p : paths) {
72
m_lib = open_lib(p.c_str());
73
if
(m_lib)
74
break
;
75
#ifndef _WIN32
76
if
(
const
char
*e = dlerror())
77
last_dlerr = e;
78
#endif
79
}
80
if
(!m_lib) {
81
std::string msg =
82
"RGPOT("
+ m_tag +
"): "
+ opt.library +
" not found (set "
+
83
(opt.env_var.empty() ? std::string(
"engine_path"
) : opt.env_var) +
84
" or EON_POTENTIALS_PATH)"
;
85
if
(!last_dlerr.empty())
86
msg += std::string(
"; last dlerror: "
) + last_dlerr;
87
throw
std::runtime_error(msg);
88
}
89
90
auto
abi =
91
reinterpret_cast<
int
(*)()
>
(load_sym(m_lib,
"rgpot_engine_abi_version"
));
92
m_create =
93
reinterpret_cast<
create_fn
>
(load_sym(m_lib,
"rgpot_engine_create"
));
94
m_destroy =
95
reinterpret_cast<
destroy_fn
>
(load_sym(m_lib,
"rgpot_engine_destroy"
));
96
m_force =
reinterpret_cast<
force_fn
>
(load_sym(m_lib,
"rgpot_engine_force"
));
97
if
(!abi || !m_create || !m_destroy || !m_force ||
98
abi() !=
RGPOT_ENGINE_ABI_VERSION
) {
99
close_lib(m_lib);
100
m_lib =
nullptr
;
101
throw
std::runtime_error(
"RGPOT("
+ m_tag +
102
"): engine C ABI missing/mismatch"
);
103
}
104
char
err[1024]{};
105
m_pot = m_create(opt.config.data(), opt.config.size(), err,
sizeof
err);
106
if
(!m_pot) {
107
close_lib(m_lib);
108
m_lib =
nullptr
;
109
throw
std::runtime_error(
"RGPOT("
+ m_tag +
110
"): create failed: "
+ std::string(err));
111
}
112
}
113
114
GenericEngineLoader::~GenericEngineLoader
() {
115
// Destroy the pot while the engine is still mapped. Do not dlclose the
116
// engine: torch static teardown after dlclose routinely SEGV on exit.
117
if
(
m_pot
&&
m_destroy
)
118
m_destroy
(
m_pot
);
119
m_pot
=
nullptr
;
120
m_lib
=
nullptr
;
121
}
122
123
void
GenericEngineLoader::force
(
long
N,
const
double
*R,
const
int
*atomicNrs,
124
double
*F,
double
*U,
double
*variance,
125
const
double
*box)
const
{
126
if
(!
m_pot
|| !
m_force
)
127
throw
std::runtime_error(
"RGPOT("
+
m_tag
+
"): engine not available"
);
128
double
var = 0.0;
129
const
int
rc =
m_force
(
m_pot
, N, R, atomicNrs, F, U,
130
variance ? variance : &var, box,
nullptr
,
nullptr
);
131
if
(rc != 0)
132
throw
std::runtime_error(
"RGPOT("
+
m_tag
+
"): force failed"
);
133
}
GenericEngineLoader.h
GenericEngineLoader::m_tag
std::string m_tag
Definition
GenericEngineLoader.h:52
GenericEngineLoader::~GenericEngineLoader
~GenericEngineLoader()
Definition
GenericEngineLoader.cpp:114
GenericEngineLoader::m_destroy
destroy_fn m_destroy
Definition
GenericEngineLoader.h:59
GenericEngineLoader::GenericEngineLoader
GenericEngineLoader(const GenericEngineOptions &opt)
Definition
GenericEngineLoader.cpp:43
GenericEngineLoader::force
void force(long N, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) const
Definition
GenericEngineLoader.cpp:123
GenericEngineLoader::m_pot
RgpotEnginePot * m_pot
Definition
GenericEngineLoader.h:51
GenericEngineLoader::m_lib
void * m_lib
Definition
GenericEngineLoader.h:50
GenericEngineLoader::m_force
force_fn m_force
Definition
GenericEngineLoader.h:60
RGPOT_ENGINE_ABI_VERSION
#define RGPOT_ENGINE_ABI_VERSION
Definition
engine_c_abi.h:70
GenericEngineOptions
Definition
GenericEngineLoader.h:24
GenericEngineOptions::env_var
std::string env_var
Optional env var naming an explicit .so path (checked first).
Definition
GenericEngineLoader.h:28
GenericEngineOptions::engine_path
std::string engine_path
Optional explicit .so path from config.
Definition
GenericEngineLoader.h:30
GenericEngineOptions::library
std::string library
Library basename to search for, e.g. "libuma_engine.so".
Definition
GenericEngineLoader.h:26
client
potentials
Rgpot
GenericEngineLoader.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf