42 return [
pot = std::move(
pot)](
long nAtoms,
const double *positions,
43 const int *atomicNrs,
double *forces,
44 double *energy,
const double *box) {
45 double variance = 0.0;
46 pot->force(nAtoms, positions, atomicNrs, forces, energy, &variance, box);
60 std::string(magic_enum::enum_name(pot_type)));
65 std::string(magic_enum::enum_name(pot_type)));
69 auto callback = makeForceCallback(std::move(eon_pot));
81 if (endpoints.empty()) {
87 if (endpoints.size() == 1) {
88 auto params = base_params;
90 serveMode(params, endpoints[0].host, endpoints[0].port);
95 EONC_LOG_INFO(
"Starting {} concurrent RPC servers", endpoints.size());
97 std::vector<std::thread> threads;
98 threads.reserve(endpoints.size());
100 for (
const auto &ep : endpoints) {
101 threads.emplace_back([&base_params, ep]() {
102 auto params = base_params;
104 auto pot_name = std::string(magic_enum::enum_name(ep.potential));
106 EONC_LOG_INFO(
"[{}:{}] Creating potential: {}", ep.host, ep.port,
116 auto callback = makeForceCallback(std::move(eon_pot));
122 for (
auto &t : threads) {
134 uint16_t base_port,
size_t replicas) {
144 EONC_LOG_INFO(
"Starting {} replicated servers on ports {}-{}", replicas,
145 base_port, base_port + replicas - 1);
147 std::vector<std::thread> threads;
148 threads.reserve(replicas);
150 for (
size_t i = 0; i < replicas; ++i) {
151 uint16_t port =
static_cast<uint16_t
>(base_port + i);
152 threads.emplace_back(
153 [¶ms, &host, port]() {
serveMode(params, host, port); });
156 for (
auto &t : threads) {
168 uint16_t port,
size_t pool_size) {
169 if (pool_size == 0) {
175 EONC_LOG_INFO(
"Creating pool of {} {} instances for gateway on {}:{}",
176 pool_size, std::string(magic_enum::enum_name(pot_type)), host,
179 std::vector<ForceCallback> pool;
180 pool.reserve(pool_size);
182 for (
size_t i = 0; i < pool_size; ++i) {
185 EONC_LOG_ERROR(
"Failed to create potential instance {}/{}", i + 1,
189 pool.push_back(makeForceCallback(std::move(eon_pot)));
204 if (!opts.endpoints.empty()) {
206 if (endpoints.empty()) {
215 if (opts.gateway_port > 0) {
216 size_t pool = (opts.replicas > 0) ? opts.replicas : 1;
217 serveGateway(params, opts.host, opts.gateway_port, pool);
230 std::vector<ServeEndpoint> endpoints;
231 std::istringstream stream(spec);
234 while (std::getline(stream, token,
',')) {
236 token.erase(0, token.find_first_not_of(
" \t"));
237 token.erase(token.find_last_not_of(
" \t") + 1);
242 size_t first_colon = token.find(
':');
243 if (first_colon == std::string::npos) {
244 EONC_LOG_ERROR(
"Invalid serve spec '{}': expected 'potential:port'",
249 std::string pot_str = token.substr(0, first_colon);
250 std::string rest = token.substr(first_colon + 1);
253 pot_str.erase(0, pot_str.find_first_not_of(
" \t"));
254 pot_str.erase(pot_str.find_last_not_of(
" \t") + 1);
255 rest.erase(0, rest.find_first_not_of(
" \t"));
256 rest.erase(rest.find_last_not_of(
" \t") + 1);
259 std::transform(pot_str.begin(), pot_str.end(), pot_str.begin(), ::tolower);
263 magic_enum::enum_cast<PotType>(pot_str, magic_enum::case_insensitive)
271 size_t second_colon = rest.find(
':');
272 if (second_colon != std::string::npos) {
274 ep.
host = rest.substr(0, second_colon);
275 ep.
host.erase(0, ep.
host.find_first_not_of(
" \t"));
276 ep.
host.erase(ep.
host.find_last_not_of(
" \t") + 1);
277 std::string port_str = rest.substr(second_colon + 1);
278 port_str.erase(0, port_str.find_first_not_of(
" \t"));
279 port_str.erase(port_str.find_last_not_of(
" \t") + 1);
280 ep.
port =
static_cast<uint16_t
>(std::stoi(port_str));
283 ep.
host =
"localhost";
284 ep.
port =
static_cast<uint16_t
>(std::stoi(rest));
290 endpoints.push_back(ep);
#define EONC_LOG_ERROR(...)
#define EONC_LOG_INFO(...)
struct eonc::Parameters::potential_options_t potential_options
struct eonc::Parameters::serve_options_t serve_options
std::shared_ptr< Potential > makePotential(const Parameters ¶ms)
quill::Logger * get() noexcept
Get or create the default "combi" logger.
RAII resource manager for the ARTn C library with global synchronization.
std::vector< ServeEndpoint > parseServeSpec(const std::string &spec)
Parse a serve configuration string into endpoints.
void serveGateway(const Parameters ¶ms, const std::string &host, uint16_t port, size_t pool_size)
Start a gateway server backed by a pool of potential instances.
void serveMode(const Parameters ¶ms, const std::string &host, uint16_t port)
Start a single rgpot-compatible Cap'n Proto RPC server.
void serveFromConfig(const Parameters ¶ms)
Start serve mode from config-file parameters.
std::function< void(long nAtoms, const double *positions, const int *atomicNrs, double *forces, double *energy, const double *box)> ForceCallback
Callback type for potential energy/force evaluation.
void startPooledRpcServer(std::vector< ForceCallback > pool, const std::string &host, uint16_t port)
Start a blocking Cap'n Proto RPC server backed by a pool of force callbacks dispatched round-robin.
void serveMultiple(const std::vector< ServeEndpoint > &endpoints, const Parameters &base_params)
Serve multiple potentials concurrently on different ports.
void serveReplicated(const Parameters ¶ms, const std::string &host, uint16_t base_port, size_t replicas)
Serve N replicas of the same potential across sequential ports.
void startRpcServer(ForceCallback callback, const std::string &host, uint16_t port)
Start a blocking Cap'n Proto RPC server using a force callback.
Configuration for a single serve endpoint.