Skip to content

Commit

Permalink
Merge pull request #741 from GMLC-TDC/max_time_consistency
Browse files Browse the repository at this point in the history
set the maxTime in C++ and C to be consistent with eachother,   meani…
  • Loading branch information
phlptp committed Jul 15, 2019
2 parents 4abe15e + dfecb39 commit 0538db7
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 46 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,21 @@ This is a minor release that adds some JSON related input and output functions,
- move concurrency related structures to a standalone library
- System-tests is now based on google test instead of boost test
= the deserializer for ActionMessage now uses memcpy to avoid possible undefined behavior
- The value of helics_time_maxtime has been changed for consistency with the C++ equivalent

### Fixed
- a few possible race conditions found by thread-sanitizer
- cleared up a couple scenarios that were triggering occasional test failure in the system tests
- a small memory leak when a JSON stream builder was created and not destroyed properly
- an inconsistency between the helics_time_maxtime in the C shared library and the maxTime value used in C++, this could in some cases result in failing termination conditions

### Added
- queries for getting all current inputs in JSON format.
- query for getting all updated inputs in JSON format
- publication function that accepts a JSON structure for multiple publications

### Removed
- libguarded and several concurrency related structures as they are now in a standalone repository
- libguarded and several concurrency related structures as they are now in a standalone repository that is included through submodules


## \[2.1.0\] - 2019-06-27
Expand Down
17 changes: 10 additions & 7 deletions src/helics/common/timeRepresentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ class integer_time
auto divBase = static_cast<base> (div);
double frac = div - static_cast<double> (divBase);
baseType nseconds = (divBase << N) + static_cast<base> (frac * multiplier);
return (t < -1e12) ? ((t > 1e12) ? nseconds : maxVal ()) : minVal ();
return (t < toDouble (minVal () + 10000)) ? ((t > toDouble (maxVal () - 10000)) ? nseconds : maxVal ()) :
minVal ();
}
static CHRONO_CONSTEXPR baseType convert (std::chrono::nanoseconds nsTime) noexcept
{
Expand Down Expand Up @@ -188,10 +189,7 @@ class count_time
static constexpr baseType minVal () noexcept { return (std::numeric_limits<baseType>::min) () + 1; }
static constexpr baseType zeroVal () noexcept { return baseType (0); }
static constexpr baseType epsilon () noexcept { return baseType (1); }
static constexpr baseType convert (double t) noexcept
{
return (t > -1e12) ? ((t < 1e12) ? (quick_round<baseType> (t * dFactor)) : maxVal ()) : minVal ();
}

static CHRONO_CONSTEXPR baseType convert (std::chrono::nanoseconds nsTime) noexcept
{
return (N >= 9) ? static_cast<baseType> (nsTime.count () * fac10[N - 9]) :
Expand All @@ -201,7 +199,12 @@ class count_time
{
return (static_cast<double> (val / iFactor) + static_cast<double> (val % iFactor) * ddivFactor); // NOLINT
}

static constexpr baseType convert (double t) noexcept
{
return (t > toDouble (minVal () + 10000)) ?
((t < toDouble (maxVal () - 10000)) ? (quick_round<baseType> (t * dFactor)) : maxVal ()) :
minVal ();
}
static std::int64_t toCount (baseType val, time_units units) noexcept
{
switch (units)
Expand Down Expand Up @@ -267,7 +270,7 @@ class count_time

/** class representing time as a floating point value*/
template <typename base = double>
class double_time
class float_time
{
static_assert (std::is_floating_point<base>::value, "base type must be floating point");

Expand Down
65 changes: 35 additions & 30 deletions src/helics/shared_api_library/FederateExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,8 @@ helics_time helicsFederateRequestTime (helics_federate fed, helics_time requestT
}
try
{
return static_cast<double> (fedObj->requestTime (requestTime));
auto timeret = fedObj->requestTime (requestTime);
return (timeret < helics::Time::maxVal ()) ? static_cast<double> (timeret) : helics_time_maxtime;
}
catch (...)
{
Expand All @@ -652,7 +653,8 @@ helics_time helicsFederateRequestNextStep (helics_federate fed, helics_error *er
}
try
{
return static_cast<helics_time> (fedObj->requestNextStep ());
auto timeret = fedObj->requestNextStep ();
return (timeret < helics::Time::maxVal ()) ? static_cast<double> (timeret) : helics_time_maxtime;
}
catch (...)
{
Expand Down Expand Up @@ -683,7 +685,7 @@ helics_time helicsFederateRequestTimeIterative (helics_federate fed,
{
*outIterate = getIterationStatus (val.state);
}
return static_cast<double> (val.grantedTime);
return (val.grantedTime < helics::Time::maxVal ()) ? static_cast<double> (val.grantedTime) : helics_time_maxtime;
}
catch (...)
{
Expand Down Expand Up @@ -713,6 +715,25 @@ void helicsFederateRequestTimeAsync (helics_federate fed, helics_time requestTim
}
}

helics_time helicsFederateRequestTimeComplete (helics_federate fed, helics_error *err)
{
auto fedObj = getFed (fed, err);
if (fedObj == nullptr)
{
return helics_time_invalid;
}
try
{
auto timeret = fedObj->requestTimeComplete ();
return (timeret < helics::Time::maxVal ()) ? static_cast<double> (timeret) : helics_time_maxtime;
}
catch (...)
{
helicsErrorHandler (err);
return helics_time_invalid;
}
}

void helicsFederateRequestTimeIterativeAsync (helics_federate fed,
helics_time requestTime,
helics_iteration_request iterate,
Expand All @@ -733,7 +754,7 @@ void helicsFederateRequestTimeIterativeAsync (helics_federate fed,
}
}

helics_time helicsFederateRequestTimeComplete (helics_federate fed, helics_error *err)
helics_time helicsFederateRequestTimeIterativeComplete (helics_federate fed, helics_iteration_result *outIteration, helics_error *err)
{
auto fedObj = getFed (fed, err);
if (fedObj == nullptr)
Expand All @@ -742,7 +763,12 @@ helics_time helicsFederateRequestTimeComplete (helics_federate fed, helics_error
}
try
{
return static_cast<double> (fedObj->requestTimeComplete ());
auto val = fedObj->requestTimeIterativeComplete ();
if (outIteration != nullptr)
{
*outIteration = getIterationStatus (val.state);
}
return (val.grantedTime < helics::Time::maxVal ()) ? static_cast<double> (val.grantedTime) : helics_time_maxtime;
}
catch (...)
{
Expand Down Expand Up @@ -854,7 +880,8 @@ helics_time helicsFederateGetTimeProperty (helics_federate fed, int timeProperty
try
{
auto T = fedObj->getTimeProperty (timeProperty);
return static_cast<double> (T);

return (T < helics::Time::maxVal ()) ? static_cast<double> (T) : helics_time_maxtime;
}
catch (...)
{
Expand Down Expand Up @@ -926,30 +953,8 @@ helics_time helicsFederateGetCurrentTime (helics_federate fed, helics_error *err
}
try
{
return static_cast<double> (fedObj->getCurrentTime ());
}
catch (...)
{
helicsErrorHandler (err);
return helics_time_invalid;
}
}

helics_time helicsFederateRequestTimeIterativeComplete (helics_federate fed, helics_iteration_result *outIteration, helics_error *err)
{
auto fedObj = getFed (fed, err);
if (fedObj == nullptr)
{
return helics_time_invalid;
}
try
{
auto val = fedObj->requestTimeIterativeComplete ();
if (outIteration != nullptr)
{
*outIteration = getIterationStatus (val.state);
}
return static_cast<double> (val.grantedTime);
auto T = fedObj->getCurrentTime ();
return (T < helics::Time::maxVal ()) ? static_cast<double> (T) : helics_time_maxtime;
}
catch (...)
{
Expand Down
4 changes: 2 additions & 2 deletions src/helics/shared_api_library/api-data.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ extern "C"
const helics_time helics_time_zero = 0.0; /*!< definition of time zero-the beginning of simulation*/
const helics_time helics_time_epsilon = 1.0e-9; /*!< definition of the minimum time resolution*/
const helics_time helics_time_invalid = -1.785e39; /*!< definition of an invalid time that has no meaning*/
const helics_time helics_time_maxtime =
1e53; /*!< definition of time signifying the federate has terminated or to run until the end of the simulation*/
const helics_time helics_time_maxtime = 9223372036.854774;
/*!< definition of time signifying the federate has terminated or to run until the end of the simulation*/

/** defining a boolean type for use in the helics interface*/
typedef int helics_bool;
Expand Down
13 changes: 7 additions & 6 deletions src/helics/shared_api_library/helics.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ extern "C"
HELICS_EXPORT void helicsFederateEnterExecutingModeComplete (helics_federate fed, helics_error *err);

/** request an iterative time
@details this call allows for finer grain control of the iterative process then /ref helicsFederateRequestTime it takes a time and and
@details this call allows for finer grain control of the iterative process then /ref helicsFederateRequestTime it takes a time and
iteration request and return a time and iteration status
@param fed the federate to make the request of
@param iterate the requested iteration mode
Expand Down Expand Up @@ -543,7 +543,7 @@ extern "C"
@param fed the federate to make the request of
@param requestTime the next requested time
@param[in,out] err an error object that will contain an error code and string if any error occurred during the execution of the function
@return the time granted to the federate
@return the time granted to the federate, will return helics_time_maxtime if the simulation has terminated
invalid*/
HELICS_EXPORT helics_time helicsFederateRequestTime (helics_federate fed, helics_time requestTime, helics_error *err);

Expand All @@ -552,7 +552,7 @@ extern "C"
time plus the minimum time step
@param fed the federate to make the request of
@param[in,out] err an error object that will contain an error code and string if any error occurred during the execution of the function
@return the time granted to the federate
@return the time granted to the federate, will return helics_time_maxtime if the simulation has terminated
invalid*/
HELICS_EXPORT helics_time helicsFederateRequestNextStep (helics_federate fed, helics_error *err);

Expand All @@ -564,7 +564,8 @@ extern "C"
@param iterate the requested iteration mode
@param[out] outIterate the iteration specification of the result
@param[in,out] err an error object that will contain an error code and string if any error occurred during the execution of the function
@return the granted time
@return the granted time, will return helics_time_maxtime if the simulation has terminated along with the appropriate iteration result
value
*/
HELICS_EXPORT helics_time helicsFederateRequestTimeIterative (helics_federate fed,
helics_time requestTime,
Expand All @@ -583,7 +584,7 @@ extern "C"
/** complete an asynchronous requestTime call
@param fed the federate to make the request of
@param[in,out] err an error object that will contain an error code and string if any error occurred during the execution of the function
@return the time granted to the federate*/
@return the time granted to the federate, will return helics_time_maxtime if the simulation has terminated*/
HELICS_EXPORT helics_time helicsFederateRequestTimeComplete (helics_federate fed, helics_error *err);

/** request an iterative time through an asynchronous call
Expand All @@ -603,7 +604,7 @@ extern "C"
@param fed the federate to make the request of
@param[out] outIterate the iteration specification of the result
@param[in,out] err an error object that will contain an error code and string if any error occurred during the execution of the function
@return the granted time
@return the granted time, will return helics_time_maxtime if the simulation has terminated
*/
HELICS_EXPORT helics_time helicsFederateRequestTimeIterativeComplete (helics_federate fed,
helics_iteration_result *outIterate,
Expand Down
11 changes: 11 additions & 0 deletions tests/helics/common/TimeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ SPDX-License-Identifier: BSD-3-Clause
*/

#include "helics/core/helics-time.hpp"
#include "helics/shared_api_library/api-data.h"

using namespace helics;

Expand Down Expand Up @@ -195,3 +196,13 @@ TEST (time_tests, chrono_tests)

EXPECT_TRUE (b2.to_ns () == tmns);
}

TEST (time_tests, max_tests)
{
auto tm = Time (helics_time_maxtime);
auto tmax = Time::maxVal ();
EXPECT_EQ (tm, tmax);
EXPECT_EQ (Time (-helics_time_maxtime), Time::minVal ());

EXPECT_GE (static_cast<double> (Time::maxVal ()), helics_time_maxtime);
}
12 changes: 12 additions & 0 deletions tests/helics/shared_library/TimingTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,16 @@ BOOST_AUTO_TEST_CASE (timing_with_period_change)
CE (helicsFederateFinalize (vFed, &err));
}

BOOST_AUTO_TEST_CASE (max_time_consistency)
{
SetupTest (helicsCreateValueFederate, "test", 1);
auto vFed = GetFederateAt (0);
CE (helicsFederateEnterExecutingMode (vFed, &err));
helics_time gtime;
CE (gtime = helicsFederateRequestTime (vFed, helics_time_maxtime, &err));
BOOST_CHECK_GE (gtime, helics_time_maxtime);
CE (helicsFederateFinalize (vFed, &err));
CE (gtime = helicsFederateGetCurrentTime (vFed, &err));
BOOST_CHECK_GE (gtime, helics_time_maxtime);
}
BOOST_AUTO_TEST_SUITE_END ()

0 comments on commit 0538db7

Please sign in to comment.