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

Reduce time-tracking overhead #1988

Merged
merged 8 commits into from
Feb 14, 2023
Merged
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: 6 additions & 3 deletions include/amici/solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ class Solver {

/**
* @brief Set the maximum CPU time allowed for integration
* @param maxtime Time in seconds
* @param maxtime Time in seconds. Zero means infinite time.
*/
void setMaxTime(double maxtime);

Expand All @@ -500,10 +500,13 @@ class Solver {

/**
* @brief Check whether maximum integration time was exceeded
* @param interval Only check the time every ``interval`` ths call to avoid
* potentially relatively expensive syscalls

* @return True if the maximum integration time was exceeded,
* false otherwise.
*/
bool timeExceeded() const;
bool timeExceeded(int interval = 1) const;

/**
* @brief returns the maximum number of solver steps for the backward
Expand Down Expand Up @@ -1609,7 +1612,7 @@ class Solver {
long int maxsteps_ {10000};

/** Maximum CPU-time for integration in seconds */
std::chrono::duration<double, std::ratio<1>> maxtime_ {std::chrono::duration<double>::max()};
std::chrono::duration<double, std::ratio<1>> maxtime_ {0};

/** Time at which solver timer was started */
mutable std::clock_t starttime_;
Expand Down
15 changes: 13 additions & 2 deletions src/solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,9 +862,20 @@ void Solver::startTimer() const
starttime_ = std::clock();
}

bool Solver::timeExceeded() const
bool Solver::timeExceeded(int interval) const
{
auto cputime_exceed = static_cast<double>(std::clock() - starttime_) / CLOCKS_PER_SEC;
static int eval_counter = 0;

// 0 means infinite time
if(maxtime_.count() == 0)
return false;

if (++eval_counter % interval)
return false;

eval_counter = 0;
auto cputime_exceed = static_cast<double>(std::clock() - starttime_)
/ CLOCKS_PER_SEC;
return std::chrono::duration<double>(cputime_exceed) > maxtime_;
}

Expand Down
4 changes: 2 additions & 2 deletions src/solver_cvodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ static int fxdot(realtype t, N_Vector x, N_Vector xdot, void *user_data) {
auto solver = dynamic_cast<CVodeSolver const *>(typed_udata->second);
Expects(model);

if(solver->timeExceeded()) {
if (solver->timeExceeded(500)) {
return AMICI_MAX_TIME_EXCEEDED;
}

Expand Down Expand Up @@ -1072,7 +1072,7 @@ static int fxBdot(realtype t, N_Vector x, N_Vector xB, N_Vector xBdot,
auto solver = dynamic_cast<CVodeSolver const*>(typed_udata->second);
Expects(model);

if(solver->timeExceeded()) {
if (solver->timeExceeded(500)) {
return AMICI_MAX_TIME_EXCEEDED;
}

Expand Down
5 changes: 2 additions & 3 deletions src/solver_idas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ int fxdot(realtype t, N_Vector x, N_Vector dx, N_Vector xdot,
auto solver = dynamic_cast<IDASolver const*>(typed_udata->second);
Expects(model);

if(solver->timeExceeded()) {
if (solver->timeExceeded(500)) {
return AMICI_MAX_TIME_EXCEEDED;
}

Expand Down Expand Up @@ -1082,7 +1082,7 @@ int fxBdot(realtype t, N_Vector x, N_Vector dx, N_Vector xB,
auto solver = dynamic_cast<IDASolver const*>(typed_udata->second);
Expects(model);

if(solver->timeExceeded()) {
if (solver->timeExceeded(500)) {
return AMICI_MAX_TIME_EXCEEDED;
}

Expand Down Expand Up @@ -1111,7 +1111,6 @@ int fqBdot(realtype t, N_Vector x, N_Vector dx, N_Vector xB,

model->fqBdot(t, x, dx, xB, dxB, qBdot);
return model->checkFinite(gsl::make_span(qBdot), ModelQuantity::qBdot);

}


Expand Down
4 changes: 4 additions & 0 deletions tests/cpp/steadystate/tests1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ TEST(ExampleSteadystate, Maxtime)
amici::hdf5::readSolverSettingsFromHDF5(
NEW_OPTION_FILE, *solver, "/model_steadystate/nosensi/options");

// Ensure the solver needs sufficiently many steps that time is checked
// at least once during integration
solver->setRelativeTolerance(1e-14);

auto rdata = runAmiciSimulation(*solver, nullptr, *model);
ASSERT_EQ(amici::AMICI_SUCCESS, rdata->status);

Expand Down