Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gmxapi-62 Stop condition hook task 1 #15

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/api/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ configure_file(gmxapi/session.h gmxapi)
configure_file(gmxapi/status.h gmxapi)
configure_file(gmxapi/system.h gmxapi)
configure_file(gmxapi/version.in.h gmxapi/version.h)

# headers for API development and extension

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)

file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gmxapi/context)
configure_file(gmxapi/context/outputstream.h gmxapi/context)

# Add to install target: copy the public API headers from the source directory
# into the gmxapi header subdirectory.
Expand Down Expand Up @@ -64,11 +70,14 @@ target_include_directories(gmxapi PRIVATE
# but listing all source files helps some code introspection tools work better.
target_sources(
gmxapi PRIVATE
boolean.cpp
context.cpp
gmxapi.cpp
md-impl.h
md.cpp
mdmodule.cpp
mdsignals.cpp
outputstream.cpp
session-impl.h
session.cpp
status.cpp
Expand Down
5 changes: 5 additions & 0 deletions src/api/cpp/boolean.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//
// Created by Eric Irrgang on 5/21/18.
//

#include "gmxapi/workflow/boolean.h"
52 changes: 52 additions & 0 deletions src/api/cpp/gmxapi/context/outputstream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Created by Eric Irrgang on 5/21/18.
//

#ifndef GROMACS_OUTPUTSTREAM_H
#define GROMACS_OUTPUTSTREAM_H

#include <memory>
#include <string>

namespace gmxapi {
namespace context {

class OutputStream
{
public:
~OutputStream();

/*!
* \brief Set data for a registered output stream.
*
* \param outputName Registered name of the output port
* \param data data to set with the registered output handler.
*
* We should not use a template here to handle the different data types because the template might be expressed
* with different munged symbol names by different compilers. But we want this interface to be extensible, so
* we need to consider how to allow flexible types. We could wrap all data in a gmxapi::Data wrapper or something,
* but that makes calling the set() method more cumbersome in the client code.
*
* What we could do, though, is to provide a template function as a helper that is compiled in the client code
* and just makes it easier to make the correct call here. Then a gmxapi::Data wrapper wouldn't be cumbersome.
*/
void set(std::string outputName, bool data);
//void set(std::string outputName, someOtherType

void set(const char* outputName, bool data)
{
this->set(std::string(outputName), data);
}

private:
// Private implementation class
class Impl;
// opaque pointer to implementation.
std::unique_ptr<Impl> impl_;
};

} // end namespace gmxapi::context
} //end namespace gmxapi


#endif //GROMACS_OUTPUTSTREAM_H
59 changes: 59 additions & 0 deletions src/api/cpp/gmxapi/md/mdsignals.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// 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 GMXAPI_MDSIGNALS_H
#define GMXAPI_MDSIGNALS_H

#include <memory>

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<SignalImpl>&& signal);
Signal(Signal&& signal);
Signal& operator=(Signal&& signal);
~Signal();

void operator()();

private:
std::unique_ptr<SignalImpl> 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 //GMXAPI_MDSIGNALS_H
11 changes: 11 additions & 0 deletions src/api/cpp/gmxapi/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions src/api/cpp/gmxapi/workflow/boolean.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Created by Eric Irrgang on 5/21/18.
//

#ifndef GROMACS_BOOLEAN_H
#define GROMACS_BOOLEAN_H

/*!
* \brief Workflow element for Boolean operations.
*
* Produce Boolean (true or false) output for logical operations performed on Boolean inputs.
*/
class Boolean
{

};


#endif //GROMACS_BOOLEAN_H
104 changes: 104 additions & 0 deletions src/api/cpp/mdsignals.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//
// Created by Eric Irrgang on 5/18/18.
//

#include "gmxapi/md/mdsignals.h"

#include <atomic>

#include "gromacs/compat/make_unique.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<gmxapi::Signal::SignalImpl>&& impl) :
impl_{std::move(impl)}
{
}

Signal::~Signal() = default;

void Signal::operator()()
{
impl_->call();
}

Signal::Signal(Signal &&signal) = default;

Signal &Signal::operator=(Signal &&signal) = default;

class StopSignal : public Signal::SignalImpl
{
public:
explicit StopSignal(gmx::Mdrunner* runner) : runner_{runner} {};

StopSignal(gmx::Mdrunner* runner, unsigned int numParticipants) : StopSignal(runner)
{
StopSignal::numParticipants_.store(numParticipants);
}

void call() override
{
unsigned int n{++StopSignal::numCalls_};
if (n >= StopSignal::numParticipants_.load())
{
auto signals = runner_->signals();
// sig > 0 stops at next NS step. sig < 0 stops at next step.
signals->at(eglsSTOPCOND).sig = -1;
}
}

private:
gmx::Mdrunner* runner_;

// Number of participants in this signal
static std::atomic<unsigned int> numParticipants_;

// Number of times the signal has been called.
static std::atomic<unsigned int> numCalls_;
};

std::atomic<unsigned int> StopSignal::numParticipants_{0};
std::atomic<unsigned int> StopSignal::numCalls_{0};

Signal getMdrunnerSignal(Session* session, md::signals signal)
{
//// while there is only one choice...
// if (signal == md::signals::STOP)
// {
assert(signal == md::signals::STOP);
assert(session);

auto impl = session->getRaw();
assert(impl);

auto runner = impl->getRunner();
assert(runner);

// std::unique_ptr<Signal::SignalImpl> signalImpl = gmx::compat::make_unique<StopSignal>(runner);
std::unique_ptr<Signal::SignalImpl> signalImpl = gmx::compat::make_unique<StopSignal>(runner, impl->numRestraints);

Signal functor{std::move(signalImpl)};

return functor;
// }
// else
// {
// }
}

} // end namespace gmxapi
20 changes: 20 additions & 0 deletions src/api/cpp/outputstream.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Created by Eric Irrgang on 5/21/18.
//

#include "gmxapi/context/outputstream.h"

namespace gmxapi {
namespace context {

class OutputStream::Impl {
};

void OutputStream::set(std::string outputName,
bool data)
{}

OutputStream::~OutputStream() = default;

} // end namespace gmxapi::context
} // end namespace gmxapi
10 changes: 10 additions & 0 deletions src/api/cpp/session-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -71,6 +72,15 @@ class SessionImpl
std::unique_ptr<gmx::Mdrunner> runner);

Status setRestraint(std::shared_ptr<gmxapi::MDModule> module);

/*! \internal
* \brief API implementation function to retrieve the current runner.
*
* \return non-owning pointer to the current runner or nullptr if none.
*/
gmx::Mdrunner* getRunner();

int numRestraints{0};
private:
/*!
* \brief Private constructor for use by create()
Expand Down
30 changes: 29 additions & 1 deletion src/api/cpp/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "gromacs/utility/init.h"
#include "gmxapi/md/mdmodule.h"
#include "gromacs/compat/make_unique.h"
#include "gromacs/restraint/restraintpotential.h"

#include "gmxapi/context.h"
#include "gmxapi/status.h"
Expand Down Expand Up @@ -139,6 +140,16 @@ Status SessionImpl::setRestraint(std::shared_ptr<gmxapi::MDModule> module)
return status;
}

gmx::Mdrunner *SessionImpl::getRunner()
{
gmx::Mdrunner * runner{nullptr};
if (runner_)
{
runner = runner_.get();
}
return runner;
}

Session::Session(std::unique_ptr<SessionImpl>&& impl) noexcept :
impl_{std::move(impl)}
{
Expand Down Expand Up @@ -201,11 +212,28 @@ bool Session::isOpen() const noexcept
Status setSessionRestraint(Session *session,
std::shared_ptr<gmxapi::MDModule> module)
{
auto status = gmxapi::Status(false);

auto status = session->impl_->setRestraint(std::move(module));
if (session != nullptr && module != nullptr)
{
auto restraint = module->getRestraint();
if (restraint != nullptr)
{
restraint->bindSession(session);
session->impl_->numRestraints += 1;
}

assert(session->impl_);
auto status = session->impl_->setRestraint(std::move(module));
}
return status;
}

SessionImpl *Session::getRaw() const noexcept
{
return impl_.get();
}

std::shared_ptr<Session> launchSession(Context* context, const Workflow& work) noexcept
{
auto session = context->launch(work);
Expand Down
Loading