From d363e92131a4f2f1f1049bc7f7242542761b3900 Mon Sep 17 00:00:00 2001 From: "M. Eric Irrgang" Date: Fri, 18 May 2018 18:47:01 +0300 Subject: [PATCH] gmxapi-62 Stop condition hook task 1 Work in progress. This commit will be rewritten soon. Don't merge into anything but a temporary integration branch. --- src/api/cpp/CMakeLists.txt | 2 + src/api/cpp/gmxapi/md/mdsignals.h | 56 +++++++++++++++ src/api/cpp/gmxapi/session.h | 11 +++ src/api/cpp/mdsignals.cpp | 79 ++++++++++++++++++++++ src/api/cpp/session-impl.h | 8 +++ src/api/cpp/session.cpp | 15 ++++ src/gromacs/context/CMakeLists.txt | 25 +++++++ src/gromacs/restraint/restraintpotential.h | 20 +++++- 8 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 src/api/cpp/gmxapi/md/mdsignals.h create mode 100644 src/api/cpp/mdsignals.cpp create mode 100644 src/gromacs/context/CMakeLists.txt diff --git a/src/api/cpp/CMakeLists.txt b/src/api/cpp/CMakeLists.txt index f7813f200..595027e9e 100644 --- a/src/api/cpp/CMakeLists.txt +++ b/src/api/cpp/CMakeLists.txt @@ -21,6 +21,7 @@ configure_file(gmxapi/version.in.h gmxapi/version.h) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gmxapi/md) #configure_file(gmxapi/md/runnerstate.h gmxapi/md) configure_file(gmxapi/md/mdmodule.h gmxapi/md) +configure_file(gmxapi/md/mdsignals.h gmxapi/md) # Add to install target: copy the public API headers from the source directory # into the gmxapi header subdirectory. @@ -71,6 +72,7 @@ target_sources( mdmodule.cpp session-impl.h session.cpp + mdsignals.cpp status.cpp system.cpp system-impl.h diff --git a/src/api/cpp/gmxapi/md/mdsignals.h b/src/api/cpp/gmxapi/md/mdsignals.h new file mode 100644 index 000000000..1f915b874 --- /dev/null +++ b/src/api/cpp/gmxapi/md/mdsignals.h @@ -0,0 +1,56 @@ +// +// Created by Eric Irrgang on 5/18/18. +// + +/* WARNING + * This whole file is not intended to make it into a public release and is not part of the gmxapi API. It is for + * prototyping only. Please don't let it slip into a release without serious design considerations. + */ + +#ifndef GROMACS_SIGNALS_H +#define GROMACS_SIGNALS_H + +#include + +namespace gmxapi { + +namespace md +{ + +enum class signals { + STOP +}; + +} // end namespace md + + +class Session; // defined in gmxapi/session.h + +/*! + * \brief Proxy for signalling function objects. + * + * Objects of this type are simple callables that issue a specific signal. + */ +class Signal +{ + public: + class SignalImpl; + explicit Signal(std::unique_ptr&& signal); + + void operator()(); + + private: + std::unique_ptr impl_; +}; + +/*! + * \brief Get a function object that issues a signal to the currently active MD runner. + * + * \param session pointer to the active Session. + * \return Callable function object handle + */ +Signal getMdrunnerSignal(Session* session, md::signals signal); + +} // end namespace md + +#endif //GROMACS_SIGNALS_H diff --git a/src/api/cpp/gmxapi/session.h b/src/api/cpp/gmxapi/session.h index ffc0dec15..495ad199a 100644 --- a/src/api/cpp/gmxapi/session.h +++ b/src/api/cpp/gmxapi/session.h @@ -107,6 +107,17 @@ class Session bool isOpen() const noexcept; + /*! \internal + * \brief Get a non-owning handle to the implementation object. + * + * Get a raw pointer to the implementation object. The pointer is valid only during the lifetime of the Session, + * so retain a shared pointer to this Session object or only hold the pointer for the duration of a code block + * guaranteed to exist entirely within the lifetime of a Session object. + * + * \return opaque pointer used by gmxapi implementation and extension code. + */ + SessionImpl* getRaw() const noexcept; + private: friend Status setSessionRestraint(Session* session, diff --git a/src/api/cpp/mdsignals.cpp b/src/api/cpp/mdsignals.cpp new file mode 100644 index 000000000..22443c26f --- /dev/null +++ b/src/api/cpp/mdsignals.cpp @@ -0,0 +1,79 @@ +// +// Created by Eric Irrgang on 5/18/18. +// + + + +#include +#include "gmxapi/md/mdsignals.h" + +#include "gromacs/mdlib/simulationsignal.h" +#include "programs/mdrun/runner.h" + +#include "gmxapi/session.h" + +#include "session-impl.h" + +namespace gmxapi { + +class Signal::SignalImpl +{ + public: + virtual void call() = 0; + + +}; + +Signal::Signal(std::unique_ptr&& impl) : + impl_{std::move(impl)} +{ +} + +void Signal::operator()() +{ + impl_->call(); +} + +class StopSignal : public Signal::SignalImpl +{ + public: + explicit StopSignal(gmx::Mdrunner* runner) : runner_{runner} {}; + + static Signal create(gmx::Mdrunner* runner) + { + auto impl = gmx::compat::make_unique(runner); + auto signal = gmxapi::Signal(std::move(impl)); + return signal; + } + + void call() override + { + auto signals = runner_->signals(); + signals->at(eglsSTOPCOND).sig = true; + } + + private: + gmx::Mdrunner* runner_; +}; + + +Signal getMdrunnerSignal(Session* session, md::signals signal) +{ +// if (signal == md::signals::STOP) +// { + assert(session); + + auto impl = session->getRaw(); + assert(impl); + + auto runner = impl->getRunner(); + assert(runner); + + return StopSignal::create(runner); +// } +// else +// { +// } +} + +} // end namespace gmxapi diff --git a/src/api/cpp/session-impl.h b/src/api/cpp/session-impl.h index 33b2afecd..07a8a4d01 100644 --- a/src/api/cpp/session-impl.h +++ b/src/api/cpp/session-impl.h @@ -16,6 +16,7 @@ namespace gmxapi // Forward declaration class MpiContextManager; // Locally defined in session.cpp +class ContextImpl; // locally defined in context.cpp /*! * \brief Implementation class for executing sessions. @@ -71,6 +72,13 @@ class SessionImpl std::unique_ptr runner); Status setRestraint(std::shared_ptr module); + + /*! + * \brief API implementation function to retrieve the current runner. + * + * \return non-owning pointer to the current runner or nullptr if none. + */ + gmx::Mdrunner* getRunner(); private: /*! * \brief Private constructor for use by create() diff --git a/src/api/cpp/session.cpp b/src/api/cpp/session.cpp index 1a4c8d154..858d738a3 100644 --- a/src/api/cpp/session.cpp +++ b/src/api/cpp/session.cpp @@ -139,6 +139,16 @@ Status SessionImpl::setRestraint(std::shared_ptr module) return status; } +gmx::Mdrunner *SessionImpl::getRunner() +{ + gmx::Mdrunner * runner{nullptr}; + if (runner_) + { + runner = runner_.get(); + } + return runner; +} + Session::Session(std::unique_ptr&& impl) noexcept : impl_{std::move(impl)} { @@ -206,6 +216,11 @@ Status setSessionRestraint(Session *session, return status; } +SessionImpl *Session::getRaw() const noexcept +{ + return impl_.get(); +} + std::shared_ptr launchSession(Context* context, const Workflow& work) noexcept { auto session = context->launch(work); diff --git a/src/gromacs/context/CMakeLists.txt b/src/gromacs/context/CMakeLists.txt new file mode 100644 index 000000000..e50105d62 --- /dev/null +++ b/src/gromacs/context/CMakeLists.txt @@ -0,0 +1,25 @@ +# +#add_library(restraint OBJECT +# restraintpotential.h +# restraintpotential.cpp +# vectortype.h +# manager.cpp +# manager.h +# restraintfunctor-impl.cpp +# restraintfunctor-impl.h +# restraintcalculation.h +# restraintcalculation.cpp +# restraintcalculation-impl.h +# restraintmdmodule.h +# restraintmdmodule.cpp +# restraintmdmodule-impl.h) +#set_target_properties(restraint PROPERTIES POSITION_INDEPENDENT_CODE ON) +# +#set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} $ PARENT_SCOPE) +# +#gmx_install_headers(restraintpotential.h +# vectortype.h) +# +#if (BUILD_TESTING) +# add_subdirectory(tests) +#endif() diff --git a/src/gromacs/restraint/restraintpotential.h b/src/gromacs/restraint/restraintpotential.h index 8b27b4041..82660c1cb 100644 --- a/src/gromacs/restraint/restraintpotential.h +++ b/src/gromacs/restraint/restraintpotential.h @@ -208,7 +208,25 @@ class IRestraintPotential double t) = 0; - // An update function to be called on the simulation master rank/thread periodically by the Restraint framework. + /*! + * \brief Call-back hook for restraint implementations. + * + * An update function to be called on the simulation master rank/thread periodically + * by the Restraint framework. + * Receives the same input as the evaluate() method, but is only called on the master + * rank of a simulation to allow implementation code to be thread-safe without knowing + * anything about the domain decomposition. + * + * \param v position of the first site + * \param v0 position of the second site + * \param t simulation time + * + * \internal + * We give the definition here because we don't want plugins to have to link against + * libgromacs right now (complicated header maintenance and no API stability guarantees). + * But once we've had plugin restraints wrap themselves in a Restraint template, we can set update = 0 + * \todo: Provide gmxapi facility for plugin restraints to wrap themselves with a default implementation to let this class be pure virtual. + */ virtual void update(gmx::Vector v, gmx::Vector v0, double t) { (void)v; (void)v0; (void)t; };