Loading...
Searching...
No Matches
RgpotAdapter< RPot > Class Template Referencefinal

Wraps one rgpot kernel as an eOn Potential. More...

#include <RgpotAdapter.h>

Inheritance diagram for RgpotAdapter< RPot >:

Public Member Functions

template<class Cfg>
requires (!std::is_base_of_v<eonc::IPluginLoader, std::remove_cvref_t<Cfg>>)
 RgpotAdapter (eonc::PotType ptype, const eonc::Parameters &params, const Cfg &cfg)
 Kernels construct in place from their config: several hold mutexes or other immovable state, so the adapter never copies or moves them.
template<class Cfg>
requires (!std::is_base_of_v<eonc::IPluginLoader, std::remove_cvref_t<Cfg>>)
 RgpotAdapter (eonc::PotType ptype, const eonc::Parameters &params, const Cfg &cfg, eonc::IPluginLoader &loader)
 Test seam: injected loader, no process-default search-path mutation.
 RgpotAdapter (eonc::PotType ptype, const eonc::Parameters &params)
 Kernels with no configuration surface default-construct in place.
 RgpotAdapter (eonc::PotType ptype, const eonc::Parameters &params, eonc::IPluginLoader &loader)
 Test seam: injected loader, no process-default search-path mutation.
 RgpotAdapter (eonc::PotType ptype, const eonc::Parameters &params, RPot &&kernel)
 Take a pre-built kernel (ExprPot and other move-only constructors).
 RgpotAdapter (eonc::PotType ptype, const eonc::Parameters &params, RPot &&kernel, eonc::IPluginLoader &loader)
 Test seam: injected loader, no process-default search-path mutation.
void force (long N, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override
bool computesStress () const noexcept override
 True when force() leaves a Cauchy stress that cauchyStress() can read until the next force() on this instance.
Matrix3d cauchyStress () const override
 Cauchy stress from the last force() that reported one.
bool supportsBatchEvaluation () const noexcept override
 Reports whether the kernel serves a batch natively.
void forceBatch (long nSystems, long nAtoms, const double *const *positions, const int *const *atomicNrs, double *const *forces, double *energies, double *variances, const double *const *boxes) override
 Hands eOn's batch straight to the kernel.
bool isThreadSafe () const noexcept override
 Whether this potential's force() can be called from multiple threads on the SAME instance.
bool requiresIsolatedMoleculeLayout () const noexcept override
 Kernels that do not implement periodic boundaries must not have their coordinates wrapped.
bool needsPerImageInstance () const noexcept override
 Whether NEB should create separate Potential instances per image for true parallel force evaluation.
const RPot & kernel () const noexcept
double finiteCutoff () const noexcept override
 Classical kernels expose config().cutoff.
Public Member Functions inherited from eonc::Potential
 Potential (PotType a_ptype)
 Production default: construction-scope registry, else PotRegistry::get().
 Potential (PotType a_ptype, IPotRegistry &registry)
 Test seam: injected registry, no process-default get() counters.
 Potential (PotType a_ptype, const Parameters &p)
 Potential (const Parameters &a_params)
virtual ~Potential ()
void force (std::span< const double > positions, std::span< const int > atomicNrs, std::span< double > forces, double *energy, double *variance, std::span< const double > box)
 C++ call site: size-checked view over the raw FFI force().
virtual void setFixedMask (long nAtoms, const double *isFixed)
 Optional frozen-atom mask (nAtoms*3, 1.0 = fixed).
std::tuple< double, AtomMatrix > get_ef (const AtomMatrix &pos, const VectorXi &atmnrs, const Matrix3d &box)
PotType getType () const
virtual bool isSurrogate () const noexcept
 Whether this is a surrogate (GP) potential.
virtual unsigned layoutFlags () const noexcept
virtual bool isSharedInstanceThreadSafe () const noexcept
 Conservative gate for sharing one Potential instance across threads.
virtual std::shared_ptr< Potential > clonePotential () const
 Independent instance that does not reload from disk.
virtual void forceBatchOwned (long nSystems, long nAtoms, const double *const *positions, const int *const *atomicNrs, double *const *forces, double *energies, double *variances, const double *const *boxes, const long *owners)
 Evaluate forces for N systems in a single call.

Private Member Functions

void finishConstruct (const eonc::Parameters &params)
void validateCaps () const
void storeStress (const rgpot::ForceOut &out)

Private Attributes

RPot pot_
eonc::IPluginLoader & loader_
Matrix3d stress_ {Matrix3d::Zero()}
bool haveStress_ {false}

Additional Inherited Members

Public Types inherited from eonc::Potential
enum class  PotLayout : unsigned { InProcess = 1u << 0 , NeedsWorkingDirectory = 1u << 1 , Subprocess = 1u << 2 }
 How the pot is executed. Combine with bitwise or. More...
Public Attributes inherited from eonc::Potential
std::atomic< size_t > forceCallCounter
Protected Attributes inherited from eonc::Potential
PotType ptype

Detailed Description

template<class RPot>
class RgpotAdapter< RPot >

Wraps one rgpot kernel as an eOn Potential.

force() passes eOn's flat arrays straight into the kernel's forceImpl — the layouts match field for field, including the row-major 3x3 box — bypassing rgpot's AtomMatrix wrapper and its optional result cache. Thread-sharing policy derives from the kernel's capability descriptor instead of per-type lists.

Definition at line 31 of file RgpotAdapter.h.

Constructor & Destructor Documentation

◆ RgpotAdapter() [1/6]

template<class RPot>
template<class Cfg>
requires (!std::is_base_of_v<eonc::IPluginLoader, std::remove_cvref_t<Cfg>>)
RgpotAdapter< RPot >::RgpotAdapter ( eonc::PotType ptype,
const eonc::Parameters & params,
const Cfg & cfg )
inline

Kernels construct in place from their config: several hold mutexes or other immovable state, so the adapter never copies or moves them.

Production: process-default PluginLoader.

Definition at line 38 of file RgpotAdapter.h.

Wraps one rgpot kernel as an eOn Potential.
RgpotAdapter(eonc::PotType ptype, const eonc::Parameters &params, const Cfg &cfg)
Kernels construct in place from their config: several hold mutexes or other immovable state,...
PotType ptype
Definition Potential.h:44

◆ RgpotAdapter() [2/6]

template<class RPot>
template<class Cfg>
requires (!std::is_base_of_v<eonc::IPluginLoader, std::remove_cvref_t<Cfg>>)
RgpotAdapter< RPot >::RgpotAdapter ( eonc::PotType ptype,
const eonc::Parameters & params,
const Cfg & cfg,
eonc::IPluginLoader & loader )
inline

Test seam: injected loader, no process-default search-path mutation.

Definition at line 44 of file RgpotAdapter.h.

48 }
eonc::IPluginLoader & loader_
void finishConstruct(const eonc::Parameters &params)

◆ RgpotAdapter() [3/6]

template<class RPot>
RgpotAdapter< RPot >::RgpotAdapter ( eonc::PotType ptype,
const eonc::Parameters & params )
inline

Kernels with no configuration surface default-construct in place.

Definition at line 51 of file RgpotAdapter.h.

◆ RgpotAdapter() [4/6]

template<class RPot>
RgpotAdapter< RPot >::RgpotAdapter ( eonc::PotType ptype,
const eonc::Parameters & params,
eonc::IPluginLoader & loader )
inline

Test seam: injected loader, no process-default search-path mutation.

Definition at line 57 of file RgpotAdapter.h.

◆ RgpotAdapter() [5/6]

template<class RPot>
RgpotAdapter< RPot >::RgpotAdapter ( eonc::PotType ptype,
const eonc::Parameters & params,
RPot && kernel )
inline

Take a pre-built kernel (ExprPot and other move-only constructors).

Definition at line 64 of file RgpotAdapter.h.

const RPot & kernel() const noexcept

◆ RgpotAdapter() [6/6]

template<class RPot>
RgpotAdapter< RPot >::RgpotAdapter ( eonc::PotType ptype,
const eonc::Parameters & params,
RPot && kernel,
eonc::IPluginLoader & loader )
inline

Test seam: injected loader, no process-default search-path mutation.

Definition at line 69 of file RgpotAdapter.h.

Member Function Documentation

◆ cauchyStress()

template<class RPot>
Matrix3d RgpotAdapter< RPot >::cauchyStress ( ) const
inlinenodiscardoverridevirtual

Cauchy stress from the last force() that reported one.

sigma = (1/V) dE/dε, eV/Angstrom^3.

Reimplemented from eonc::Potential.

Definition at line 94 of file RgpotAdapter.h.

94 {
95 if (!haveStress_) {
96 throw std::logic_error("rgpot kernel did not return a stress tensor");
97 }
98 return stress_;
99 }
Matrix3d stress_

◆ computesStress()

template<class RPot>
bool RgpotAdapter< RPot >::computesStress ( ) const
inlinenodiscardoverridevirtualnoexcept

True when force() leaves a Cauchy stress that cauchyStress() can read until the next force() on this instance.

Reimplemented from eonc::Potential.

Definition at line 88 of file RgpotAdapter.h.

88 {
89 return haveStress_;
90 }

◆ finishConstruct()

template<class RPot>
void RgpotAdapter< RPot >::finishConstruct ( const eonc::Parameters & params)
inlineprivate

Definition at line 179 of file RgpotAdapter.h.

179 {
180 loader_.add_config_paths(params.potential_options().potentialsPath);
181 validateCaps();
182 }
void validateCaps() const

◆ finiteCutoff()

template<class RPot>
double RgpotAdapter< RPot >::finiteCutoff ( ) const
inlinenodiscardoverridevirtualnoexcept

Classical kernels expose config().cutoff.

Anything else is not treated as finite-range.

Reimplemented from eonc::Potential.

Definition at line 170 of file RgpotAdapter.h.

170 {
171 if constexpr (requires(const RPot &k) { k.config().cutoff; }) {
172 return pot_.config().cutoff;
173 } else {
174 return 0.0;
175 }
176 }

◆ force()

template<class RPot>
void RgpotAdapter< RPot >::force ( long N,
const double * R,
const int * atomicNrs,
double * F,
double * U,
double * variance,
const double * box )
inlineoverridevirtual

Implements eonc::Potential.

Definition at line 76 of file RgpotAdapter.h.

77 {
78 rgpot::ForceInput in{static_cast<size_t>(N), R, atomicNrs, box};
79 rgpot::ForceOut out{F, 0.0, 0.0};
80 pot_.forceImpl(in, &out);
81 *U = out.energy;
82 if (variance != nullptr) {
83 *variance = out.variance;
84 }
86 }
void storeStress(const rgpot::ForceOut &out)

◆ forceBatch()

template<class RPot>
void RgpotAdapter< RPot >::forceBatch ( long nSystems,
long nAtoms,
const double *const * positions,
const int *const * atomicNrs,
double *const * forces,
double * energies,
double * variances,
const double *const * boxes )
inlineoverridevirtual

Hands eOn's batch straight to the kernel.

eOn batches images of one system, so every system shares an atom count; rgpot allows them to differ, and filling nAtoms per system costs nothing and keeps the two contracts independent.

Calls forceBatchImpl rather than forceBatch for the same reason force() calls forceImpl: eOn owns caching, and routing through rgpot's cache would key the same geometry twice.

Reimplemented from eonc::Potential.

Definition at line 117 of file RgpotAdapter.h.

120 {
121 const auto n = static_cast<size_t>(nSystems);
124 in.reserve(n);
125 out.reserve(n);
126 for (size_t i = 0; i < n; ++i) {
127 in.push_back(rgpot::ForceInput{static_cast<size_t>(nAtoms), positions[i],
128 atomicNrs[i], boxes[i]});
129 out.push_back(rgpot::ForceOut{forces[i], 0.0, 0.0});
130 }
131
132 pot_.forceBatchImpl(
133 rgpot::ForceBatch{.nSystems = n, .in = in.data(), .out = out.data()});
134
135 haveStress_ = false;
136 for (size_t i = 0; i < n; ++i) {
137 energies[i] = out[i].energy;
138 if (variances != nullptr) {
139 variances[i] = out[i].variance;
140 }
141 if (out[i].has_stress) {
142 storeStress(out[i]);
143 }
146 }
147 }
void on_force_call(PotType t) noexcept override
static PotRegistry & get() noexcept
Process-lifetime singleton.
std::atomic< size_t > forceCallCounter
Definition Potential.h:53

◆ isThreadSafe()

template<class RPot>
bool RgpotAdapter< RPot >::isThreadSafe ( ) const
inlinenodiscardoverridevirtualnoexcept

Whether this potential's force() can be called from multiple threads on the SAME instance.

Python-based potentials return false. Potentials with internal mutex (MetatomicPotential) return true but serialize internally – use needsPerImageInstance() to check if separate instances would enable true parallelism.

Reimplemented from eonc::Potential.

Definition at line 149 of file RgpotAdapter.h.

149 {
150 return pot_.caps().reentrancy == rgpot::Reentrancy::SharedInstance;
151 }

◆ kernel()

template<class RPot>
const RPot & RgpotAdapter< RPot >::kernel ( ) const
inlinenodiscardnoexcept

Definition at line 166 of file RgpotAdapter.h.

166{ return pot_; }

◆ needsPerImageInstance()

template<class RPot>
bool RgpotAdapter< RPot >::needsPerImageInstance ( ) const
inlinenodiscardoverridevirtualnoexcept

Whether NEB should create separate Potential instances per image for true parallel force evaluation.

When true, NEB calls makePotential() once per image instead of sharing one instance. Override in potentials that use internal mutexes (e.g. MetatomicPotential).

Reimplemented from eonc::Potential.

Definition at line 160 of file RgpotAdapter.h.

160 {
161 const auto caps = pot_.caps();
162 return caps.perImageInstances ||
164 }

◆ requiresIsolatedMoleculeLayout()

template<class RPot>
bool RgpotAdapter< RPot >::requiresIsolatedMoleculeLayout ( ) const
inlinenodiscardoverridevirtualnoexcept

Kernels that do not implement periodic boundaries must not have their coordinates wrapped.

A free cluster with an atom on the cell face is torn by that wrap on the first optimizer step.

Reimplemented from eonc::Potential.

Definition at line 156 of file RgpotAdapter.h.

156 {
157 return !pot_.caps().periodic;
158 }

◆ storeStress()

template<class RPot>
void RgpotAdapter< RPot >::storeStress ( const rgpot::ForceOut & out)
inlineprivate

Definition at line 194 of file RgpotAdapter.h.

194 {
195 haveStress_ = out.has_stress != 0;
196 if (!haveStress_) {
197 return;
198 }
199 for (int row = 0; row < 3; ++row) {
200 for (int col = 0; col < 3; ++col) {
201 stress_(row, col) = out.stress[row * 3 + col];
202 }
203 }
204 }

◆ supportsBatchEvaluation()

template<class RPot>
bool RgpotAdapter< RPot >::supportsBatchEvaluation ( ) const
inlinenodiscardoverridevirtualnoexcept

Reports whether the kernel serves a batch natively.

rgpot answers every batch call, falling back to a per-system loop, so this asks the narrower question the eOn callers care about: is one batched call cheaper than N single ones? Only a native kernel makes it so.

Reimplemented from eonc::Potential.

Definition at line 105 of file RgpotAdapter.h.

105 {
106 return pot_.caps().batched;
107 }

◆ validateCaps()

template<class RPot>
void RgpotAdapter< RPot >::validateCaps ( ) const
inlineprivate

Definition at line 184 of file RgpotAdapter.h.

184 {
185 const auto caps = pot_.caps();
186 using R = rgpot::Reentrancy;
187 if (caps.reentrancy != R::SharedInstance &&
188 caps.reentrancy != R::PerInstance &&
189 caps.reentrancy != R::ProcessSerial) {
190 throw std::runtime_error("rgpot kernel advertised an unknown reentrancy");
191 }
192 }

Member Data Documentation

◆ haveStress_

template<class RPot>
bool RgpotAdapter< RPot >::haveStress_ {false}
private

Definition at line 209 of file RgpotAdapter.h.

209{false};

◆ loader_

template<class RPot>
eonc::IPluginLoader& RgpotAdapter< RPot >::loader_
private

Definition at line 207 of file RgpotAdapter.h.

◆ pot_

template<class RPot>
RPot RgpotAdapter< RPot >::pot_
private

Definition at line 206 of file RgpotAdapter.h.

◆ stress_

template<class RPot>
Matrix3d RgpotAdapter< RPot >::stress_ {Matrix3d::Zero()}
private

Definition at line 208 of file RgpotAdapter.h.


The documentation for this class was generated from the following file:
  • /home/runner/work/eOn/eOn/include/eon/potentials/RgpotAdapter/RgpotAdapter.h