Loading...
Searching...
No Matches
ASE Class Reference

#include <ASE.h>

Inheritance diagram for ASE:

Public Member Functions

 ASE (const Parameters &a_params)
virtual ~ASE ()
void force (long nAtoms, 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 needsPerImageInstance () const noexcept override
 ASE calculators are independent objects.
Public Member Functions inherited from eonc::Potential
 Potential (PotType a_ptype)
 Potential (PotType a_ptype, const Parameters &)
 Potential (const Parameters &a_params)
virtual ~Potential ()
std::tuple< double, AtomMatrixget_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 bool requiresIsolatedMoleculeLayout () const noexcept
 True for molecular QM / non-PBC backends (NWChem socket, ASE ORCA/NWChem, …).
virtual bool isSharedInstanceThreadSafe () const noexcept
 Conservative gate for sharing one Potential instance across threads.
virtual bool supportsBatchEvaluation () const noexcept
 Whether this potential supports batched evaluation of N systems in a single call.
virtual 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)
 Evaluate forces for N systems in a single call.

Private Attributes

size_t counter {0}
py::module_ py_module
py::object calculator
py::object _calculate

Additional Inherited Members

Public Attributes inherited from eonc::Potential
std::atomic< size_t > forceCallCounter
Protected Attributes inherited from eonc::Potential
PotType ptype

Detailed Description

Definition at line 19 of file ASE.h.

Constructor & Destructor Documentation

◆ ASE()

ASE::ASE ( const Parameters & a_params)

Definition at line 26 of file ASE.cpp.

27 : Potential(PotType::ASE_POT, a_params) {
29 counter = 1;
30 std::string py_file = a_params.potential_options.extPotPath;
31
32 // import
33 try {
34 // must briefly disable FPE because Python packages like Numpy causes it
35 // during import
36 eonc::FPEHandler fpeh;
37 fpeh.eat_fpe();
38
39 // Create a Python script to use importlib.util to load the module
40 py::exec(R"(
41 import sys
42 import importlib.util
43
44 def load_module_from_path(module_name, file_path):
45 spec = importlib.util.spec_from_file_location(module_name, file_path)
46 module = importlib.util.module_from_spec(spec)
47 sys.modules[module_name] = module
48 spec.loader.exec_module(module)
49 return module
50 )");
51
52 // Prepare the module name and file path
53 std::string module_name = "ase_eon";
54 py::object load_module = py::globals()["load_module_from_path"];
55 py_module = load_module(module_name, py_file);
56
57 fpeh.restore_fpe();
58
59 calculator = py_module.attr("ase_calc")();
60 _calculate = py_module.attr("_calculate");
61
62 } catch (const std::exception &e) {
py::object calculator
Definition ASE.h:24
py::module_ py_module
Definition ASE.h:23
size_t counter
Definition ASE.h:22
py::object _calculate
Definition ASE.h:25
struct eonc::Parameters::potential_options_t potential_options
Potential(PotType a_ptype)
Definition Potential.h:35
void ensure_interpreter()
Definition NbGuard.h:21

◆ ~ASE()

virtual ASE::~ASE ( )
inlinevirtual

Definition at line 30 of file ASE.h.

30 {
31 QUILL_LOG_INFO(eonc::log::get(), "[ASE] called potential {} times",
32 counter);
33 }
quill::Logger * get() noexcept
Get or create the default "combi" logger.
Definition EonLogger.h:44

Member Function Documentation

◆ force()

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

Implements eonc::Potential.

Definition at line 64 of file ASE.cpp.

64 : Exception during Python module import: %s\n",
65 e.what());
66 fprintf(stderr, "%s should exist and have no errors on the Python side.\n",
67 py_file.c_str());
68 throw std::runtime_error(std::string("ASE calculator import failed: ") +
69 e.what());
70 }
71 return;
72}
73
74void ASE::force(long nAtoms, const double *R, const int *atomicNrs, double *F,
75 double *U, double *variance, const double *box) {
76 variance = nullptr;
77 try {
78 // TODO(rg): This is easier on the type system if Eigen::Map is used like in
79 // ASE_ORCA convert arrays to Numpy arrays
80 std::vector<size_t> R_shape = {static_cast<size_t>(nAtoms), 3};
81 py::array_t<double> R_np(R_shape, R);
82 py::array_t<int> atomicNrs_np(nAtoms, atomicNrs);
83 py::array_t<double> box_np({3, 3}, box);
84
85 // get energy and forces (in this order) from Python
86 std::tuple<double, py::array_t<double>> py_result =
87 _calculate(R_np, atomicNrs_np, box_np, calculator)
88 .cast<std::tuple<double, py::array_t<double>>>();
89
90 // copy the results to the output arrays
91 *U = std::get<0>(py_result);
92 py::array_t<double> forces = std::get<1>(py_result);
93 auto buffer = forces.request();
94 double *ptr = static_cast<double *>(buffer.ptr);
95 std::copy(ptr, ptr + buffer.size, F);
96
97 } catch (py::error_already_set &e) {
98 fprintf(stderr, "ASE calculator: Python error: %s\n", e.what());
99 throw std::runtime_error(std::string("ASE calculator Python error: ") +
ASE(const Parameters &a_params)
Definition ASE.cpp:26

◆ isThreadSafe()

bool ASE::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 37 of file ASE.h.

37{ return false; }

◆ needsPerImageInstance()

bool ASE::needsPerImageInstance ( ) const
inlinenodiscardoverridevirtualnoexcept

ASE calculators are independent objects.

Most production calculators (VASP, Gaussian, ORCA, etc.) spawn subprocesses that release the GIL.

Reimplemented from eonc::Potential.

Definition at line 40 of file ASE.h.

40 {
41 return true;
42 }

Member Data Documentation

◆ _calculate

py::object ASE::_calculate
private

Definition at line 25 of file ASE.h.

◆ calculator

py::object ASE::calculator
private

Definition at line 24 of file ASE.h.

◆ counter

size_t ASE::counter {0}
private

Definition at line 22 of file ASE.h.

22{0};

◆ py_module

py::module_ ASE::py_module
private

Definition at line 23 of file ASE.h.


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