eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
MetatomicLoader.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
#include "
eon/potentials/Metatomic/MetatomicLoader.h
"
7
8
#include "
eon/potentials/PluginLoader.h
"
9
10
#include <iostream>
11
#include <vector>
12
13
#ifndef _WIN32
14
#include <dlfcn.h>
15
#endif
16
17
namespace
eonc
{
18
19
MetatomicLoader
&
MetatomicLoader::instance
() {
20
static
MetatomicLoader
loader;
21
return
loader;
22
}
23
24
bool
MetatomicLoader::try_load
() {
25
if
(
m_loaded
)
26
return
true
;
27
28
#ifdef _WIN32
29
const
char
*candidates[] = {
"metatomic_pot.dll"
,
"libmetatomic_pot.dll"
,
30
nullptr
};
31
#elif defined(__APPLE__)
32
const
char
*candidates[] = {
"libmetatomic_pot.dylib"
,
"libmetatomic_pot.so"
,
33
nullptr
};
34
#else
35
const
char
*candidates[] = {
"libmetatomic_pot.so"
,
nullptr
};
36
#endif
37
38
// RTLD_GLOBAL without DEEPBIND so MetatomicPotential's Potential/PotRegistry
39
// symbols bind to the already-loaded host libeonclib (single registry).
40
auto
open_mta = [](
const
char
*name) ->
dynlib::Handle
{
41
#if defined(__linux__)
42
return ::dlopen(name, RTLD_NOW | RTLD_GLOBAL);
43
#elif defined(_WIN32)
44
return
dynlib::open
(name);
45
#else
46
return ::dlopen(name, RTLD_NOW | RTLD_GLOBAL);
47
#endif
48
};
49
50
for
(
const
char
**p = candidates; *p; ++p) {
51
m_handle
= open_mta(*p);
52
if
(
m_handle
)
53
break
;
54
}
55
if
(!
m_handle
) {
56
for
(
const
auto
&dir :
PluginLoader::instance
().search_paths()) {
57
for
(
const
char
**p = candidates; *p; ++p) {
58
std::string full = dir;
59
if
(!full.empty() && full.back() !=
'/'
&& full.back() !=
'\\'
)
60
full +=
'/'
;
61
full += *p;
62
m_handle
= open_mta(full.c_str());
63
if
(
m_handle
)
64
break
;
65
}
66
if
(
m_handle
)
67
break
;
68
}
69
}
70
if
(!
m_handle
)
71
return
false
;
72
73
create
=
dynlib::loadSym<create_fn>
(
m_handle
,
"eon_mta_pot_create"
);
74
destroy
=
dynlib::loadSym<destroy_fn>
(
m_handle
,
"eon_mta_pot_destroy"
);
75
force
=
dynlib::loadSym<force_fn>
(
m_handle
,
"eon_mta_pot_force"
);
76
abi_version
=
77
dynlib::loadSym<abi_version_fn>
(
m_handle
,
"eon_mta_abi_version"
);
78
79
if
(!
create
|| !
destroy
|| !
force
|| !
abi_version
) {
80
std::cerr <<
"[Metatomic] libmetatomic_pot loaded but missing C ABI "
81
"symbols\n"
;
82
dynlib::close
(
m_handle
);
83
m_handle
= {};
84
create
=
nullptr
;
85
destroy
=
nullptr
;
86
force
=
nullptr
;
87
abi_version
=
nullptr
;
88
return
false
;
89
}
90
const
int
ver =
abi_version
();
91
if
(ver !=
EON_MTA_ABI_VERSION
) {
92
std::cerr <<
"[Metatomic] ABI version mismatch: library="
<< ver
93
<<
" host="
<<
EON_MTA_ABI_VERSION
<<
"\n"
;
94
dynlib::close
(
m_handle
);
95
m_handle
= {};
96
create
=
nullptr
;
97
destroy
=
nullptr
;
98
force
=
nullptr
;
99
abi_version
=
nullptr
;
100
return
false
;
101
}
102
m_loaded
=
true
;
103
return
true
;
104
}
105
106
MetatomicLoader::~MetatomicLoader
() {
dynlib::close
(
m_handle
); }
107
108
void
MetatomicLoader::require_loaded
() {
109
if
(!
try_load
()) {
110
throw
std::runtime_error(
111
"Metatomic potential requested but libmetatomic_pot.so not found or "
112
"ABI mismatch.\n"
113
"Build with -Dwith_metatomic=true and put the plugin on "
114
"LD_LIBRARY_PATH / EON_POTENTIALS_PATH / [Potential] potentials_path."
);
115
}
116
}
117
118
}
// namespace eonc
MetatomicLoader.h
EON_MTA_ABI_VERSION
#define EON_MTA_ABI_VERSION
Definition
metatomic_c_abi.h:79
PluginLoader.h
eonc::MetatomicLoader::try_load
bool try_load()
Attempt (re)load if not yet successful. Safe after potentials_path inject.
Definition
MetatomicLoader.cpp:24
eonc::MetatomicLoader::~MetatomicLoader
~MetatomicLoader()
Definition
MetatomicLoader.cpp:106
eonc::MetatomicLoader::instance
static MetatomicLoader & instance()
Definition
MetatomicLoader.cpp:19
eonc::MetatomicLoader::force
force_fn force
Definition
MetatomicLoader.h:36
eonc::MetatomicLoader::MetatomicLoader
MetatomicLoader(const MetatomicLoader &)=delete
eonc::MetatomicLoader::m_handle
dynlib::Handle m_handle
Definition
MetatomicLoader.h:47
eonc::MetatomicLoader::abi_version
abi_version_fn abi_version
Definition
MetatomicLoader.h:37
eonc::MetatomicLoader::require_loaded
void require_loaded()
Definition
MetatomicLoader.cpp:108
eonc::MetatomicLoader::m_loaded
bool m_loaded
Definition
MetatomicLoader.h:46
eonc::MetatomicLoader::destroy
destroy_fn destroy
Definition
MetatomicLoader.h:35
eonc::MetatomicLoader::create
create_fn create
Definition
MetatomicLoader.h:34
eonc::PluginLoader::instance
static PluginLoader & instance()
Thread-safe singleton accessor (Meyer's pattern).
Definition
PluginLoader.cpp:20
eonc::dynlib::Handle
void * Handle
Definition
DynLib.h:60
eonc::dynlib::open
Handle open(const char *name) noexcept
Definition
DynLib.h:62
eonc::dynlib::close
void close(Handle h) noexcept
Definition
DynLib.h:77
eonc::dynlib::loadSym
Fn loadSym(Handle h, const char *name) noexcept
Load a symbol and cast to a function pointer type.
Definition
DynLib.h:99
eonc
RAII resource manager for the ARTn C library with global synchronization.
Definition
ARTnSaddleSearch.cpp:19
client
potentials
Metatomic
MetatomicLoader.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf