Loading...
Searching...
No Matches
eonc::LammpsLoader Class Reference

#include <LammpsLoader.h>

Inheritance diagram for eonc::LammpsLoader:

Public Member Functions

bool is_loaded () const noexcept override
bool available () const override
 Filesystem probe: a candidate liblammps file is visible without dlopen, so LAMMPS static initializers (the banner) do not run.
const std::string & last_error () const noexcept override
 Why the last ensure_loaded() failed. Empty if unused or loaded.
void require_loaded () override
 Load on first use, then throw if liblammps is not available.
 LammpsLoader (const LammpsLoader &)=delete
LammpsLoader & operator= (const LammpsLoader &)=delete
Public Member Functions inherited from eonc::ILammpsLoader
virtual ~ILammpsLoader ()=default
 ILammpsLoader (const ILammpsLoader &)=delete
ILammpsLoader & operator= (const ILammpsLoader &)=delete

Static Public Member Functions

static LammpsLoader & instance ()
 Thread-safe singleton accessor (Meyer's pattern). Does not dlopen.

Private Member Functions

 LammpsLoader ()=default
 ~LammpsLoader () override
void ensure_loaded ()
template<typename Fn>
Fn load_sym (const char *name)
 Try to load a symbol; returns nullptr on failure.

Private Attributes

bool m_loaded {false}
bool m_tried {false}
dynlib::Handle m_handle {}
std::string m_last_error {}

Additional Inherited Members

Public Types inherited from eonc::ILammpsLoader
using open_no_mpi_fn = void *(*)(int, char **, void **)
using close_fn = void (*)(void *)
using command_fn = char *(*)(void *, const char *)
using file_fn = void (*)(void *, const char *)
using scatter_atoms_fn = void (*)(void *, const char *, int, int, void *)
using extract_var_fn = void *(*)(void *, const char *, const char *)
Public Attributes inherited from eonc::ILammpsLoader
open_no_mpi_fn open_no_mpi {nullptr}
close_fn close {nullptr}
command_fn command {nullptr}
file_fn file {nullptr}
scatter_atoms_fn scatter_atoms {nullptr}
extract_var_fn extract_variable {nullptr}
Protected Member Functions inherited from eonc::ILammpsLoader
 ILammpsLoader ()=default

Detailed Description

Definition at line 74 of file LammpsLoader.h.

Constructor & Destructor Documentation

◆ LammpsLoader() [1/2]

eonc::LammpsLoader::LammpsLoader ( const LammpsLoader & )
delete

◆ LammpsLoader() [2/2]

eonc::LammpsLoader::LammpsLoader ( )
privatedefault

◆ ~LammpsLoader()

eonc::LammpsLoader::~LammpsLoader ( )
overrideprivate

Definition at line 135 of file LammpsLoader.cpp.

dynlib::Handle m_handle
void close(Handle h) noexcept
Definition DynLib.h:77

Member Function Documentation

◆ available()

bool eonc::LammpsLoader::available ( ) const
nodiscardoverridevirtual

Filesystem probe: a candidate liblammps file is visible without dlopen, so LAMMPS static initializers (the banner) do not run.

Implements eonc::ILammpsLoader.

Definition at line 137 of file LammpsLoader.cpp.

137 {
138 return lib_file_visible(lammps_lib_names());
139}

◆ ensure_loaded()

void eonc::LammpsLoader::ensure_loaded ( )
private

Definition at line 84 of file LammpsLoader.cpp.

84 {
85 if (m_tried)
86 return;
87 m_tried = true;
88 m_last_error.clear();
89
90 // Always dlopen the soname. lib_file_visible only walks cwd and
91 // LD_LIBRARY_PATH; the dynamic linker also searches ld.so.cache and
92 // the default lib dirs. Gating on visibility skipped a distro so.
93 m_handle = dynlib::openFirst(lammps_lib_names());
94 if (!m_handle) {
95 const std::string dle = dynlib::error();
96 if (!lib_file_visible(lammps_lib_names())) {
97 m_last_error = "liblammps.so not visible on LD_LIBRARY_PATH / cwd "
98 "and dlopen of the soname failed "
99 "(liblammps_pot.so is the eOn plugin, not LAMMPS)";
100 } else {
101 m_last_error = "liblammps.so is visible but dlopen failed";
102 }
103 if (!dle.empty()) {
104 m_last_error += ": " + dle;
105 }
106 return;
107 }
108
110 close = dynlib::loadSym<close_fn>(m_handle, "lammps_close");
111 command = dynlib::loadSym<command_fn>(m_handle, "lammps_command");
112 file = dynlib::loadSym<file_fn>(m_handle, "lammps_file");
114 dynlib::loadSym<scatter_atoms_fn>(m_handle, "lammps_scatter_atoms");
116 dynlib::loadSym<extract_var_fn>(m_handle, "lammps_extract_variable");
117
118#ifdef EONMPI
119 open_mpi = dynlib::loadSym<open_mpi_fn>(m_handle, "lammps_open");
120#endif
121
122 if (!open_no_mpi || !close || !command || !file || !scatter_atoms ||
124 std::cerr << "[LAMMPS] Library loaded but missing required symbols\n";
125 m_last_error = "opened a liblammps* but lammps_open_no_mpi is missing "
126 "(plugin or ABI mismatch, not the LAMMPS C library)";
128 m_handle = {};
129 return;
130 }
131
132 m_loaded = true;
133}
open_no_mpi_fn open_no_mpi
extract_var_fn extract_variable
scatter_atoms_fn scatter_atoms
std::string m_last_error
std::string error()
Definition DynLib.h:82
Fn loadSym(Handle h, const char *name) noexcept
Load a symbol and cast to a function pointer type.
Definition DynLib.h:99
Handle openFirst(const char *const names[]) noexcept
Try a list of library names in order, return first successful handle.
Definition DynLib.h:89

◆ instance()

LammpsLoader & eonc::LammpsLoader::instance ( )
static

Thread-safe singleton accessor (Meyer's pattern). Does not dlopen.

Definition at line 79 of file LammpsLoader.cpp.

79 {
80 static LammpsLoader loader;
81 return loader;
82}
LammpsLoader(const LammpsLoader &)=delete

◆ is_loaded()

bool eonc::LammpsLoader::is_loaded ( ) const
inlinenodiscardoverridevirtualnoexcept

Implements eonc::ILammpsLoader.

Definition at line 79 of file LammpsLoader.h.

79{ return m_loaded; }

◆ last_error()

const std::string & eonc::LammpsLoader::last_error ( ) const
inlinenodiscardoverridevirtualnoexcept

Why the last ensure_loaded() failed. Empty if unused or loaded.

Implements eonc::ILammpsLoader.

Definition at line 86 of file LammpsLoader.h.

86 {
87 return m_last_error;
88 }

◆ load_sym()

template<typename Fn>
Fn eonc::LammpsLoader::load_sym ( const char * name)
inlineprivate

Try to load a symbol; returns nullptr on failure.

Definition at line 108 of file LammpsLoader.h.

108 {
109 return reinterpret_cast<Fn>(dynlib::sym(m_handle, name));
110 }
void * sym(Handle h, const char *name) noexcept
Definition DynLib.h:75

◆ operator=()

LammpsLoader & eonc::LammpsLoader::operator= ( const LammpsLoader & )
delete

◆ require_loaded()

void eonc::LammpsLoader::require_loaded ( )
overridevirtual

Load on first use, then throw if liblammps is not available.

Implements eonc::ILammpsLoader.

Definition at line 141 of file LammpsLoader.cpp.

141 {
143 if (!m_loaded) {
144 std::string msg =
145 "LAMMPS potential requested but liblammps is not usable.\n";
146 if (!m_last_error.empty()) {
147 msg += m_last_error;
148 msg += "\n";
149 }
150 msg += "Need a real liblammps.so with lammps_open_no_mpi, built for "
151 "this glibc. conda-forge latest may need a newer libc than "
152 "the host. liblammps_pot.so is the eOn plugin, not LAMMPS.";
153 throw std::runtime_error(msg);
154 }
155}

Member Data Documentation

◆ m_handle

dynlib::Handle eonc::LammpsLoader::m_handle {}
private

Definition at line 104 of file LammpsLoader.h.

104{};

◆ m_last_error

std::string eonc::LammpsLoader::m_last_error {}
private

Definition at line 105 of file LammpsLoader.h.

105{};

◆ m_loaded

bool eonc::LammpsLoader::m_loaded {false}
private

Definition at line 102 of file LammpsLoader.h.

102{false};

◆ m_tried

bool eonc::LammpsLoader::m_tried {false}
private

Definition at line 103 of file LammpsLoader.h.

103{false};

The documentation for this class was generated from the following files: