Loading...
Searching...
No Matches
RgpotPot Class Referencefinal

Potential backed by rgpot NWChemPot / CPMDPot (in-process dlopen of libnwchemc / libcpmdc). More...

#include <RgpotPot.h>

Inheritance diagram for RgpotPot:

Public Member Functions

 RgpotPot (const eonc::Parameters &p)
 ~RgpotPot () override
 RgpotPot (const RgpotPot &)=delete
RgpotPot & operator= (const RgpotPot &)=delete
void force (long N, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override
bool isThreadSafe () const noexcept override
 Whether this potential's force() can be called from multiple threads on the SAME instance.
bool supportsBatchEvaluation () const noexcept override
 With cpmdc calculator groups ([RgpotPot] ranks_per_image), a batch is spread over the groups: system j runs on group j mod G, then every rank receives every result, so all ranks keep the same band.
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
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) override
 System j runs on group owners[j] mod G when owners is given (an owner below zero falls back to j), so a NEB image keeps its group across partial band updates.
bool requiresIsolatedMoleculeLayout () const noexcept override
 NWChem molecular SCF does not support PBC; CPMD may be periodic.
const std::string & backend () const noexcept
bool engineAvailable () const
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 double finiteCutoff () const noexcept
 Finite interaction range in position length units.
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 bool needsPerImageInstance () const noexcept
 Whether NEB should create separate Potential instances per image for true parallel force evaluation.
virtual std::shared_ptr< Potential > clonePotential () const
 Independent instance that does not reload from disk.
virtual bool computesStress () const noexcept
 True when force() leaves a Cauchy stress that cauchyStress() can read until the next force() on this instance.
virtual Matrix3d cauchyStress () const
 Cauchy stress in eV/Angstrom^3.

Private Member Functions

void serveWorker ()
void computeSingle (long N, const double *R, const int *atomicNrs, double *F, double *U, const double *box)
void computeBatch (long nSystems, long nAtoms, const double *const *positions, const int *const *atomicNrs, double *const *forces, double *energies, const double *const *boxes, const std::int64_t *owners)
void sendStop ()
void stopAndDrop ()
void releaseWorkersAtExit ()

Private Attributes

std::unique_ptr< RGPotEngine > impl_
std::string backend_
bool driver_ {true}
bool stopped_ {false}
bool dropped_ {false}
bool acked_ {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

Potential backed by rgpot NWChemPot / CPMDPot (in-process dlopen of libnwchemc / libcpmdc).

Not potserv RPC. Configure via [RgpotPot] INI; energy eV, forces eV/Angstrom.

Definition at line 25 of file RgpotPot.h.

Constructor & Destructor Documentation

◆ RgpotPot() [1/2]

RgpotPot::RgpotPot ( const eonc::Parameters & p)
explicit

Definition at line 18 of file RgpotPot.cpp.

19 : eonc::Potential(eonc::PotType::RGPOT, p) {
20 RGPotEngineOptions opt;
21 const auto &o = p.rgpot_options();
22 opt.backend = o.backend;
23 opt.basis = o.basis;
24 opt.theory = o.theory;
25 opt.scf_type = o.scf_type;
26 opt.functional = o.functional;
27 opt.cutoff_ry = o.cutoff_ry;
28 opt.charge = o.charge;
29 opt.multiplicity = o.multiplicity;
30 opt.engine_path = o.engine_path;
31 opt.engine_library = o.engine_library;
32 opt.engine_root = o.engine_root;
33 opt.title = o.title;
34 opt.memory_mb = o.memory_mb;
35 opt.scratch_dir = o.scratch_dir;
36 opt.input_block = o.input_block;
37 opt.permanent_dir = o.permanent_dir;
38 opt.params_path = o.params_path;
39 opt.ranks_per_image = o.ranks_per_image;
40 opt.model_path = o.model_path;
41 opt.device = o.device;
42 opt.length_unit = o.length_unit;
43 opt.extensions_directory = o.extensions_directory;
44 opt.check_consistency = o.check_consistency;
45 opt.uncertainty_threshold = o.uncertainty_threshold;
46 opt.torch_determinism_strict = o.torch_determinism_strict;
47 opt.xtb_paramset = o.xtb_paramset;
48 opt.xtb_accuracy = o.xtb_accuracy;
49 opt.xtb_electronic_temperature = o.xtb_electronic_temperature;
50 opt.xtb_max_iterations = o.xtb_max_iterations;
51 opt.xtb_charge = o.xtb_charge;
52 opt.xtb_uhf = o.xtb_uhf;
53
54 // Env overrides (CI / benchmarks)
55 if (const char *e = std::getenv("RGPOT_BACKEND"))
56 opt.backend = e;
57 if (const char *e = std::getenv("RGPOT_NWCHEM_BASIS"))
58 opt.basis = e;
59 if (const char *e = std::getenv("RGPOT_NWCHEM_THEORY"))
60 opt.theory = e;
61 if (const char *e = std::getenv("RGPOT_NWCHEM_SCF_TYPE"))
62 opt.scf_type = e;
63 if (const char *e = std::getenv("RGPOT_PARAMS_PATH"))
64 opt.params_path = e;
65 // Engine-path env overrides are backend-scoped: NWCHEMC_LIBRARY must not
66 // leak into a cpmdc configure (CPMDPot resolves CPMDC_LIBRARY itself).
67 std::string backend_lc = opt.backend;
68 std::ranges::transform(backend_lc, backend_lc.begin(),
69 [](unsigned char c) { return std::tolower(c); });
70 if (backend_lc.rfind("nwchem", 0) == 0) {
71 if (const char *e = std::getenv("NWCHEMC_LIBRARY"))
72 opt.engine_path = e;
73 else if (const char *e = std::getenv("RGPOT_NWCHEMC_ENGINE"))
74 opt.engine_path = e;
75 else if (const char *e = std::getenv("RGPOT_NWCHEM_ENGINE"))
76 opt.engine_path = e;
77 } else if (backend_lc.rfind("cpmd", 0) == 0) {
78 if (const char *e = std::getenv("CPMDC_LIBRARY"))
79 opt.engine_path = e;
80 else if (const char *e = std::getenv("RGPOT_CPMDC_ENGINE"))
81 opt.engine_path = e;
82 } else if (backend_lc.rfind("meta", 0) == 0 || backend_lc == "mta") {
83 if (const char *e = std::getenv("RGPOT_METATOMIC_ENGINE"))
84 opt.engine_path = e;
85 else if (const char *e = std::getenv("METATOMIC_ENGINE"))
86 opt.engine_path = e;
87 if (const char *e = std::getenv("RGPOT_METATOMIC_MODEL"))
88 opt.model_path = e;
89 } else if (backend_lc == "xtb" || backend_lc == "xtbpot" ||
90 backend_lc == "gfn" || backend_lc == "gfnxtb") {
91 if (const char *e = std::getenv("RGPOT_XTB_ENGINE"))
92 opt.engine_path = e;
93 else if (const char *e = std::getenv("XTB_ENGINE"))
94 opt.engine_path = e;
95 if (opt.xtb_paramset.empty() || opt.xtb_paramset == "GFN2xTB") {
96 if (!p.xtb_options().paramset.empty())
98 }
99 }
100
101 // Dual-read [Metatomic] when RGPOT backend is metatomic
102 if ((backend_lc.rfind("meta", 0) == 0 || backend_lc == "mta") &&
103 opt.model_path.empty())
105 if ((backend_lc.rfind("meta", 0) == 0 || backend_lc == "mta") &&
106 opt.device == "cpu" && !p.metatomic_options().device.empty())
108
109 impl_ = std::make_unique<RGPotEngine>(opt);
110 backend_ = impl_->backend();
111 driver_ = impl_->worldRank() == 0;
112 std::cout
113 << "RgpotPot: in-process rgpot backend=" << backend_
114 << " (dlopen: libnwchemc/libcpmdc/libmetatomic_engine/libxtb_engine)"
115 << std::endl;
116 // Finalize is registered first. The grouped-exit handler is next, and
117 // the stop handler is last, so exit runs stop, then Finalize, then _Exit.
118 impl_->finalizeMpiAtExit();
119 impl_->armGroupedExit();
121 if (!driver_)
122 serveWorker();
123}
std::string backend_
Definition RgpotPot.h:77
std::unique_ptr< RGPotEngine > impl_
Definition RgpotPot.h:76
bool driver_
Definition RgpotPot.h:78
void serveWorker()
Definition RgpotPot.cpp:264
void releaseWorkersAtExit()
Definition RgpotPot.cpp:175
const metatomic_options_t & metatomic_options() const
const xtb_options_t & xtb_options() const
const rgpot_options_t & rgpot_options() const
std::string scf_type
Definition RGPotEngine.h:11
std::string title
Definition RGPotEngine.h:19
std::string xtb_paramset
Definition RGPotEngine.h:37
std::string basis
Definition RGPotEngine.h:9
std::string scratch_dir
Definition RGPotEngine.h:21
std::string engine_path
Definition RGPotEngine.h:16
std::string params_path
Definition RGPotEngine.h:26
std::string backend
Definition RGPotEngine.h:8
std::string extensions_directory
Definition RGPotEngine.h:32
std::string engine_library
Definition RGPotEngine.h:17
double xtb_electronic_temperature
Definition RGPotEngine.h:39
std::string permanent_dir
Definition RGPotEngine.h:24
std::string functional
Definition RGPotEngine.h:12
std::string length_unit
Definition RGPotEngine.h:31
bool torch_determinism_strict
Definition RGPotEngine.h:35
std::string device
Definition RGPotEngine.h:30
std::string model_path
Definition RGPotEngine.h:29
std::string engine_root
Definition RGPotEngine.h:18
double uncertainty_threshold
Definition RGPotEngine.h:34
std::string theory
Definition RGPotEngine.h:10
std::string input_block
Definition RGPotEngine.h:23

◆ ~RgpotPot()

RgpotPot::~RgpotPot ( )
override

Definition at line 125 of file RgpotPot.cpp.

125 {
126 const bool grouped = impl_ && impl_->calculatorWorld() > 1;
127 stopAndDrop();
128 // ~CPMDPot dlcloses libcpmdc. On several ranks that runs Fortran
129 // destructors while another rank may already be in MPI_Finalize.
130 // The process reclaims the engine at _Exit.
131 if (grouped)
132 (void)impl_.release();
133}
void stopAndDrop()
Definition RgpotPot.cpp:158

◆ RgpotPot() [2/2]

RgpotPot::RgpotPot ( const RgpotPot & )
delete

Member Function Documentation

◆ backend()

const std::string & RgpotPot::backend ( ) const
inlinenodiscardnoexcept

Definition at line 58 of file RgpotPot.h.

58{ return backend_; }

◆ computeBatch()

void RgpotPot::computeBatch ( long nSystems,
long nAtoms,
const double *const * positions,
const int *const * atomicNrs,
double *const * forces,
double * energies,
const double *const * boxes,
const std::int64_t * owners )
private

Definition at line 225 of file RgpotPot.cpp.

229 {
230 const int groups = impl_->calculatorGroups();
231 const int mine = impl_->calculatorIndex();
232 auto ownerOf = [&](long j) {
233 const std::int64_t id = owners && owners[j] >= 0 ? owners[j] : j;
234 return static_cast<int>(id % groups);
235 };
236 if (impl_->calculatorWorld() <= 1) {
237 for (long j = 0; j < nSystems; j++)
238 impl_->force(nAtoms, positions[j], atomicNrs[j], forces[j], &energies[j],
239 boxes[j]);
240 return;
241 }
242 std::vector<char> ok(static_cast<size_t>(nSystems), 1);
243 std::vector<std::string> errors(static_cast<size_t>(nSystems));
244 for (long j = 0; j < nSystems; j++) {
245 if (ownerOf(j) == mine)
246 ok[static_cast<size_t>(j)] =
247 try_force(*impl_, nAtoms, positions[j], atomicNrs[j], forces[j],
248 &energies[j], boxes[j], errors[static_cast<size_t>(j)]);
249 }
250 // Every share runs before any rank raises, so all ranks leave together.
251 long failed = -1;
252 for (long j = 0; j < nSystems; j++) {
253 const int owner = ownerOf(j);
254 if (!impl_->shareResult(owner, nAtoms, forces[j], &energies[j],
255 ok[static_cast<size_t>(j)] != 0,
256 errors[static_cast<size_t>(j)]) &&
257 failed < 0)
258 failed = j;
259 }
260 if (failed >= 0)
261 raise_failure(failed, ownerOf(failed), errors[static_cast<size_t>(failed)]);
262}

◆ computeSingle()

void RgpotPot::computeSingle ( long N,
const double * R,
const int * atomicNrs,
double * F,
double * U,
const double * box )
private

Definition at line 214 of file RgpotPot.cpp.

215 {
216 // Group 0 computes; its first rank's result reaches every rank.
217 std::string error;
218 bool ok = true;
219 if (impl_->calculatorIndex() == 0)
220 ok = try_force(*impl_, N, R, atomicNrs, F, U, box, error);
221 if (!impl_->shareResult(0, N, F, U, ok, error))
222 raise_failure(0, 0, error);
223}
std::string error()
Definition DynLib.h:82

◆ engineAvailable()

bool RgpotPot::engineAvailable ( ) const
nodiscard

Definition at line 135 of file RgpotPot.cpp.

135{ return impl_ && impl_->available(); }

◆ force()

void RgpotPot::force ( long N,
const double * R,
const int * atomicNrs,
double * F,
double * U,
double * variance,
const double * box )
overridevirtual

Implements eonc::Potential.

Definition at line 317 of file RgpotPot.cpp.

318 {
319 if (variance)
320 *variance = 0.0;
321 if (impl_->calculatorWorld() <= 1) {
322 impl_->force(N, R, atomicNrs, F, U, box);
323 return;
324 }
325 std::int64_t hdr[3] = {kSingle, N, 1};
326 impl_->broadcastFromDriver(hdr, sizeof(hdr));
327 impl_->broadcastFromDriver(const_cast<double *>(R), 3 * N * sizeof(double));
328 impl_->broadcastFromDriver(const_cast<int *>(atomicNrs), N * sizeof(int));
329 impl_->broadcastFromDriver(const_cast<double *>(box), 9 * sizeof(double));
330 // Before the evaluation, so a failure that ends the job still stops
331 // the workers.
333 computeSingle(N, R, atomicNrs, F, U, box);
334}
void computeSingle(long N, const double *R, const int *atomicNrs, double *F, double *U, const double *box)
Definition RgpotPot.cpp:214

◆ forceBatch()

void RgpotPot::forceBatch ( long nSystems,
long nAtoms,
const double *const * positions,
const int *const * atomicNrs,
double *const * forces,
double * energies,
double * variances,
const double *const * boxes )
overridevirtual

Reimplemented from eonc::Potential.

Definition at line 340 of file RgpotPot.cpp.

344 {
345 forceBatchOwned(nSystems, nAtoms, positions, atomicNrs, forces, energies,
346 variances, boxes, nullptr);
347}
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) override
System j runs on group owners[j] mod G when owners is given (an owner below zero falls back to j),...
Definition RgpotPot.cpp:349

◆ forceBatchOwned()

void RgpotPot::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 )
overridevirtual

System j runs on group owners[j] mod G when owners is given (an owner below zero falls back to j), so a NEB image keeps its group across partial band updates.

Reimplemented from eonc::Potential.

Definition at line 349 of file RgpotPot.cpp.

354 {
355 std::vector<std::int64_t> ids(static_cast<size_t>(nSystems), -1);
356 if (owners) {
357 for (long j = 0; j < nSystems; j++)
358 ids[static_cast<size_t>(j)] = owners[j];
359 }
360 if (impl_->calculatorWorld() > 1) {
361 std::int64_t hdr[3] = {kBatch, nAtoms, nSystems};
362 impl_->broadcastFromDriver(hdr, sizeof(hdr));
363 std::vector<double> R(static_cast<size_t>(3 * nAtoms * nSystems));
364 std::vector<int> Z(static_cast<size_t>(nAtoms * nSystems));
365 std::vector<double> box(static_cast<size_t>(9 * nSystems));
366 for (long j = 0; j < nSystems; j++) {
367 std::copy(positions[j], positions[j] + 3 * nAtoms,
368 R.begin() + 3 * nAtoms * j);
369 std::copy(atomicNrs[j], atomicNrs[j] + nAtoms, Z.begin() + nAtoms * j);
370 std::copy(boxes[j], boxes[j] + 9, box.begin() + 9 * j);
371 }
372 impl_->broadcastFromDriver(R.data(), R.size() * sizeof(double));
373 impl_->broadcastFromDriver(Z.data(), Z.size() * sizeof(int));
374 impl_->broadcastFromDriver(box.data(), box.size() * sizeof(double));
375 impl_->broadcastFromDriver(ids.data(), ids.size() * sizeof(std::int64_t));
376 }
378 computeBatch(nSystems, nAtoms, positions, atomicNrs, forces, energies, boxes,
379 ids.data());
380 for (long j = 0; j < nSystems; j++) {
381 if (variances)
382 variances[j] = 0.0;
385 }
386}
void computeBatch(long nSystems, long nAtoms, const double *const *positions, const int *const *atomicNrs, double *const *forces, double *energies, const double *const *boxes, const std::int64_t *owners)
Definition RgpotPot.cpp:225
void on_force_call(PotType t) noexcept override
static PotRegistry & get() noexcept
Process-lifetime singleton.
std::atomic< size_t > forceCallCounter
Definition Potential.h:53
PotType ptype
Definition Potential.h:44

◆ isThreadSafe()

bool RgpotPot::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 36 of file RgpotPot.h.

36{ return false; }

◆ operator=()

RgpotPot & RgpotPot::operator= ( const RgpotPot & )
delete

◆ releaseWorkersAtExit()

void RgpotPot::releaseWorkersAtExit ( )
private

Definition at line 175 of file RgpotPot.cpp.

175 {
176 if (g_driver || !impl_ || impl_->calculatorWorld() <= 1)
177 return;
178 // Runs before the MPI_Finalize handler registered in the constructor.
179 // After a failed engine call the workers can sit in a collective that
180 // the stop broadcast never meets; the grouped exit handler aborts the
181 // world instead.
182 g_driver = this;
183 std::atexit([] {
184 if (g_driver && !RGPotEngine::mpiAbortRequested())
185 g_driver->stopAndDrop();
186 });
187}
static bool mpiAbortRequested() noexcept
True once rgpot asked for MPI_Abort at exit in this process.

◆ requiresIsolatedMoleculeLayout()

bool RgpotPot::requiresIsolatedMoleculeLayout ( ) const
inlinenodiscardoverridevirtualnoexcept

NWChem molecular SCF does not support PBC; CPMD may be periodic.

Reimplemented from eonc::Potential.

Definition at line 55 of file RgpotPot.h.

55 {
56 return backend_ == "nwchemc";
57 }

◆ sendStop()

void RgpotPot::sendStop ( )
private

Definition at line 148 of file RgpotPot.cpp.

148 {
149 if (!impl_ || !driver_ || stopped_ || impl_->calculatorWorld() <= 1)
150 return;
151 std::int64_t hdr[3] = {kStop, 0, 0};
152 impl_->broadcastFromDriver(hdr, sizeof(hdr));
153 stopped_ = true;
154 if (g_driver == this)
155 g_driver = nullptr;
156}
bool stopped_
Definition RgpotPot.h:79

◆ serveWorker()

void RgpotPot::serveWorker ( )
private

Definition at line 264 of file RgpotPot.cpp.

264 {
265 for (;;) {
266 std::int64_t hdr[3] = {kStop, 0, 0};
267 impl_->broadcastFromDriver(hdr, sizeof(hdr));
268 if (hdr[0] == kStop) {
269 // Drop CPMD, wait until the driver has dropped it too, then exit 0.
270 // MPI_Finalize is collective and runs from the exit handler.
271 if (!dropped_) {
272 impl_->shutdownModule();
273 dropped_ = true;
274 }
275 std::int64_t ack[3] = {kDown, 0, 0};
276 impl_->broadcastFromDriver(ack, sizeof(ack));
277 std::exit(0);
278 }
279 const long n = static_cast<long>(hdr[1]);
280 const long m = hdr[0] == kBatch ? static_cast<long>(hdr[2]) : 1;
281 std::vector<double> R(static_cast<size_t>(3 * n * m));
282 std::vector<int> Z(static_cast<size_t>(n * m));
283 std::vector<double> box(static_cast<size_t>(9 * m));
284 impl_->broadcastFromDriver(R.data(), R.size() * sizeof(double));
285 impl_->broadcastFromDriver(Z.data(), Z.size() * sizeof(int));
286 impl_->broadcastFromDriver(box.data(), box.size() * sizeof(double));
287 std::vector<std::int64_t> ids(static_cast<size_t>(m), -1);
288 if (hdr[0] == kBatch)
289 impl_->broadcastFromDriver(ids.data(), ids.size() * sizeof(std::int64_t));
290 std::vector<double> F(R.size()), U(static_cast<size_t>(m));
291 // A failed request raised on the driver too; the driver decides
292 // whether the job goes on, so a worker keeps serving.
293 if (hdr[0] == kSingle) {
294 try {
295 computeSingle(n, R.data(), Z.data(), F.data(), U.data(), box.data());
296 } catch (const std::runtime_error &) {
297 }
298 continue;
299 }
300 std::vector<const double *> pos(static_cast<size_t>(m)), bx(pos.size());
301 std::vector<const int *> nrs(pos.size());
302 std::vector<double *> frc(pos.size());
303 for (long j = 0; j < m; j++) {
304 pos[static_cast<size_t>(j)] = R.data() + 3 * n * j;
305 nrs[static_cast<size_t>(j)] = Z.data() + n * j;
306 frc[static_cast<size_t>(j)] = F.data() + 3 * n * j;
307 bx[static_cast<size_t>(j)] = box.data() + 9 * j;
308 }
309 try {
310 computeBatch(m, n, pos.data(), nrs.data(), frc.data(), U.data(),
311 bx.data(), ids.data());
312 } catch (const std::runtime_error &) {
313 }
314 }
315}
bool dropped_
Definition RgpotPot.h:80

◆ stopAndDrop()

void RgpotPot::stopAndDrop ( )
private

Definition at line 158 of file RgpotPot.cpp.

158 {
159 if (!impl_)
160 return;
161 const bool grouped = driver_ && impl_->calculatorWorld() > 1;
162 if (grouped && !stopped_)
163 sendStop();
164 if (!dropped_) {
165 impl_->shutdownModule();
166 dropped_ = true;
167 }
168 if (grouped && !acked_) {
169 std::int64_t hdr[3] = {kDown, 0, 0};
170 impl_->broadcastFromDriver(hdr, sizeof(hdr));
171 acked_ = true;
172 }
173}
bool acked_
Definition RgpotPot.h:81
void sendStop()
Definition RgpotPot.cpp:148

◆ supportsBatchEvaluation()

bool RgpotPot::supportsBatchEvaluation ( ) const
nodiscardoverridevirtualnoexcept

With cpmdc calculator groups ([RgpotPot] ranks_per_image), a batch is spread over the groups: system j runs on group j mod G, then every rank receives every result, so all ranks keep the same band.

Reimplemented from eonc::Potential.

Definition at line 336 of file RgpotPot.cpp.

336 {
337 return impl_ && impl_->calculatorGroups() > 1;
338}

Member Data Documentation

◆ acked_

bool RgpotPot::acked_ {false}
private

Definition at line 81 of file RgpotPot.h.

81{false};

◆ backend_

std::string RgpotPot::backend_
private

Definition at line 77 of file RgpotPot.h.

◆ driver_

bool RgpotPot::driver_ {true}
private

Definition at line 78 of file RgpotPot.h.

78{true};

◆ dropped_

bool RgpotPot::dropped_ {false}
private

Definition at line 80 of file RgpotPot.h.

80{false};

◆ impl_

std::unique_ptr<RGPotEngine> RgpotPot::impl_
private

Definition at line 76 of file RgpotPot.h.

◆ stopped_

bool RgpotPot::stopped_ {false}
private

Definition at line 79 of file RgpotPot.h.

79{false};

The documentation for this class was generated from the following files:
  • /home/runner/work/eOn/eOn/include/eon/potentials/Rgpot/RgpotPot.h
  • /home/runner/work/eOn/eOn/client/potentials/Rgpot/RgpotPot.cpp