IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 8ab149dc authored by Dominik Baack's avatar Dominik Baack Committed by Ralf Ulrich
Browse files

fixed template class stuff

added missing unit test
parent acf5664c
No related branches found
No related tags found
No related merge requests found
...@@ -13,11 +13,11 @@ set ( ...@@ -13,11 +13,11 @@ set (
corsika/process/devtools corsika/process/devtools
) )
add_library (ProcessDevTools STATIC ${MODEL_SOURCES}) add_library (DevTools_Analytic STATIC ${MODEL_SOURCES})
CORSIKA_COPY_HEADERS_TO_NAMESPACE (ProcessDevTools ${MODEL_NAMESPACE} ${MODEL_HEADERS}) CORSIKA_COPY_HEADERS_TO_NAMESPACE (DevTools_Analytic ${MODEL_NAMESPACE} ${MODEL_HEADERS})
set_target_properties ( set_target_properties (
ProcessDevTools DevTools_Analytic
PROPERTIES PROPERTIES
VERSION ${PROJECT_VERSION} VERSION ${PROJECT_VERSION}
SOVERSION 1 SOVERSION 1
...@@ -25,32 +25,39 @@ set_target_properties ( ...@@ -25,32 +25,39 @@ set_target_properties (
# target dependencies on other libraries (also the header onlys) # target dependencies on other libraries (also the header onlys)
target_link_libraries ( target_link_libraries (
ProcessDevTools DevTools_Analytic
CORSIKAsetup CORSIKAprocesssequence
CORSIKAunits
CORSIKAthirdparty
) )
target_include_directories ( target_include_directories (
ProcessDevTools DevTools_Analytic
INTERFACE INTERFACE
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include/include> $<INSTALL_INTERFACE:include/include>
) )
install ( install (
TARGETS ProcessDevTools TARGETS DevTools_Analytic
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include/${MODEL_NAMESPACE}
) )
# -------------------- # --------------------
# code unit testing # code unit testing
CORSIKA_ADD_TEST (testExecTime testExecTime.cc) CORSIKA_ADD_TEST (testExecTime
SOURCES
testExecTime.cc
${MODEL_HEADERS}
)
target_link_libraries ( target_link_libraries (
testExecTime ProcessDevTools testExecTime
CORSIKAsetup DevTools_Analytic
DevTools_Dummy DevTools_Dummy
CORSIKAtesting
CORSIKAthirdparty # for catch2 CORSIKAthirdparty # for catch2
) )
...@@ -14,51 +14,90 @@ ...@@ -14,51 +14,90 @@
namespace corsika::process { namespace corsika::process {
namespace devtools { namespace devtools {
template <class T>
void ExecTime<T>::start() {
fStart = std::chrono::steady_clock::now();
}
template <class T> } // namespace devtools
void ExecTime<T>::stop() { } // namespace corsika::process
auto end = std::chrono::steady_clock::now();
std::chrono::microseconds timeDiv =
std::chrono::duration_cast<std::chrono::microseconds>(end - start);
fElapsedSum += timeDiv;
fN++;
if (fMax < timeDiv) fMax = timeDiv;
if (timeDiv < fMin) fMin = timeDiv;
auto delta = timeDiv - fMean;
fMean += delta / fN;
auto delta2 = timeDiv - fMean;
fMean2 += delta * delta2; /*
} template <typename T, bool>
class ExecTime_BoundaryCrossing {};
template <typename T> template <typename T>
double ExecTime<T>::mean() { class ExecTime_BoundaryCrossing<T, true> : protected T {
return fMean; public:
} template <
typename Particle, typename VTNType,
typename std::enable_if_t<
std::is_base_of<BoundaryCrossingProcess<typename T::_TDerived>, T>::value,
int> = 0>
EProcessReturn DoBoundaryCrossing(Particle& p, VTNType const& from,
VTNType const& to) {
return T::DoBoundaryCrossing(p, from, to);
}
};
template <typename T, bool>
class ExecTime_Continuous {};
template <typename T> template <typename T>
double ExecTime<T>::var() { class ExecTime_Continuous<T, true> : protected T {
return fMean2 / count; public:
} template <typename Particle, typename Track>
EProcessReturn DoContinuous(Particle& p, Track const& t) const {
return T::DoContinous(p, t);
}
template <typename Particle, typename Track>
units::si::LengthType MaxStepLength(Particle const& p, Track const& track) const {
return T::MaxStepLength(p, track);
}
};
template <typename T, bool>
class ExecTime_Decay {};
template <typename T> template <typename T>
double ExecTime<T>::min() { class ExecTime_Decay<T, true> : protected T {
return fMin; public:
} template <typename Particle>
EProcessReturn DoDecay(Particle& p) {
return T::DoDecay(p);
}
template <typename Particle>
corsika::units::si::TimeType GetLifetime(Particle& p) {
return T::GetLifetime(p);
}
};
template <typename T, bool>
class ExecTime_Interaction {};
template <typename T> template <typename T>
double ExecTime<T>::max() { class ExecTime_Interaction<T, true> : protected T {
return fMax; public:
} template <typename Particle>
EProcessReturn DoInteraction(Particle& p) {
return T::DoInteraction(p);
}
template <typename Particle>
corsika::units::si::GrammageType GetInteractionLength(Particle& p) {
return T::GetInteractionLength(p);
}
};
template <typename T, bool>
class ExecTime_Secondaries {};
} // namespace devtools template <typename T>
} // namespace corsika::process class ExecTime_Secondaries<T, true> : protected T {
\ No newline at end of file public:
template <typename Secondaries>
inline EProcessReturn DoSecondaries(Secondaries& sec) {
return T::DoSecondaries(sec);
}
};
*/
\ No newline at end of file
...@@ -21,117 +21,118 @@ ...@@ -21,117 +21,118 @@
namespace corsika::process { namespace corsika::process {
namespace devtools { namespace devtools {
template <typename T, bool>
class ExecTime_BoundaryCrossing {};
template <typename T> template <typename T>
class ExecTime_BoundaryCrossing<T, true> : protected T { class ExecTime : private T {
private:
std::chrono::high_resolution_clock::time_point fStart;
std::chrono::duration<double,std::micro> fElapsedSum;
double fMean;
double fMean2;
double fMin;
double fMax;
long long fN;
protected:
public: public:
template < ExecTime() {
typename Particle, typename VTNType, fMin = std::numeric_limits<long long>::max();
typename std::enable_if_t< fMax = 0;
std::is_base_of<BoundaryCrossingProcess<typename T::_TDerived>, T>::value, fMean = 0;
int> = 0> fMean2 = 0;
fN = 0;
}
void start() { fStart = std::chrono::high_resolution_clock::now(); }
void stop() {
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double,std::micro> timeDiv =
std::chrono::duration_cast< std::chrono::duration<double,std::micro> >(end - fStart);
fElapsedSum += timeDiv;
fN = fN + 1;
if (fMax < timeDiv.count()) fMax = timeDiv.count();
if (timeDiv.count() < fMin) fMin = timeDiv.count();
double delta = timeDiv.count() - fMean;
fMean += delta / static_cast<double>(fN);
double delta2 = timeDiv.count() - fMean;
fMean2 += delta * delta2;
}
double mean() const { return fMean; }
double min() const { return fMin; }
double max() const { return fMax; }
double var() const { return fMean2 / fN; }
double sumTime() const { return fElapsedSum.count(); }
template <typename Particle, typename VTNType>
EProcessReturn DoBoundaryCrossing(Particle& p, VTNType const& from, EProcessReturn DoBoundaryCrossing(Particle& p, VTNType const& from,
VTNType const& to) { VTNType const& to) {
return T::DoBoundaryCrossing(p, from, to); this->start();
auto r = T::DoBoundaryCrossing(p, from, to);
this->stop();
return r;
} }
};
template <typename T, bool>
class ExecTime_Continuous {};
template <typename T>
class ExecTime_Continuous<T, true> : protected T {
public:
template <typename Particle, typename Track> template <typename Particle, typename Track>
EProcessReturn DoContinuous(Particle& p, Track const& t) const { EProcessReturn DoContinuous(Particle& p, Track const& t) const {
return T::DoContinous(p, t); this->start();
auto r = T::DoContinous(p, t);
this->stop();
return r;
} }
template <typename Particle, typename Track> template <typename Particle, typename Track>
units::si::LengthType MaxStepLength(Particle const& p, Track const& track) const { units::si::LengthType MaxStepLength(Particle const& p, Track const& track) const {
return T::MaxStepLength(p, track); this->start();
auto r = T::MaxStepLength(p, track);
this->stop();
return r;
} }
};
template <typename T, bool>
class ExecTime_Decay {};
template <typename T>
class ExecTime_Decay<T, true> : protected T {
public:
template <typename Particle> template <typename Particle>
EProcessReturn DoDecay(Particle& p) { EProcessReturn DoDecay(Particle& p) {
return T::DoDecay(p); this->start();
auto r = T::DoDecay(p);
this->stop();
return r;
} }
template <typename Particle> template <typename Particle>
corsika::units::si::TimeType GetLifetime(Particle& p) { corsika::units::si::TimeType GetLifetime(Particle& p) {
return T::GetLifetime(p); this->start();
auto r = T::GetLifetime(p);
this->stop();
return r;
} }
};
template <typename T, bool>
class ExecTime_Interaction {};
template <typename T>
class ExecTime_Interaction<T, true> : protected T {
public:
template <typename Particle> template <typename Particle>
EProcessReturn DoInteraction(Particle& p) { EProcessReturn DoInteraction(Particle& p) {
return T::DoInteraction(p); this->start();
auto r = T::DoInteraction(p);
this->stop();
return r;
} }
template <typename Particle> template <typename Particle>
corsika::units::si::GrammageType GetInteractionLength(Particle& p) { corsika::units::si::GrammageType GetInteractionLength(Particle& p) {
return T::GetInteractionLength(p); this->start();
auto r = T::GetInteractionLength(p);
this->stop();
return r;
} }
};
template <typename T, bool>
class ExecTime_Secondaries {};
template <typename T>
class ExecTime_Secondaries<T, true> : protected T {
public:
template <typename Secondaries> template <typename Secondaries>
inline EProcessReturn DoSecondaries(Secondaries& sec) { inline EProcessReturn DoSecondaries(Secondaries& sec) {
return T::DoSecondaries(sec); this->start();
auto r = T::DoSecondaries(sec);
this->stop();
return r;
} }
};
template <typename T>
class ExecTime
: public ExecTime_BoundaryCrossing<
T,
std::is_base_of<BoundaryCrossingProcess<typename T::_TDerived>, T>::value>,
public ExecTime_Continuous<
T, std::is_base_of<ContinuousProcess<typename T::_TDerived>, T>::value>,
public ExecTime_Decay<
T, std::is_base_of<DecayProcess<typename T::_TDerived>, T>::value>,
public ExecTime_Interaction<
T, std::is_base_of<InteractionProcess<typename T::_TDerived>, T>::value>,
public ExecTime_Secondaries<
T, std::is_base_of<SecondariesProcess<typename T::_TDerived>, T>::value> {
private:
std::chrono::microseconds fStart;
std::chrono::microseconds fElapsedSum;
std::chrono::microseconds fMean;
std::chrono::microseconds fMean2;
std::chrono::microseconds fMin;
std::chrono::microseconds fMax;
long long fN;
void start();
void stop();
protected:
public:
double mean();
double min();
double max();
double var();
/* /*
// Stack // Stack
......
...@@ -18,12 +18,14 @@ ...@@ -18,12 +18,14 @@
#include <corsika/process/devtools/DummyInteractionProcess.h> #include <corsika/process/devtools/DummyInteractionProcess.h>
#include <corsika/process/devtools/DummySecondariesProcess.h> #include <corsika/process/devtools/DummySecondariesProcess.h>
#include <random>
using namespace corsika::process; using namespace corsika::process;
using namespace corsika::process::devtools; using namespace corsika::process::devtools;
TEST_CASE("ContinuousProcess interface", "[proccesses][DevTools ExecTime]") { TEST_CASE("ContinuousProcess interface", "[proccesses][DevTools ExecTime]") {
ExecTime<DummyBoundaryCrossingProcess<100>> execTime; ExecTime<DummyBoundaryCrossingProcess<50>> execTime;
int tmp = 0; int tmp = 0;
SECTION("BoundaryCrossing") { SECTION("BoundaryCrossing") {
...@@ -31,6 +33,48 @@ TEST_CASE("ContinuousProcess interface", "[proccesses][DevTools ExecTime]") { ...@@ -31,6 +33,48 @@ TEST_CASE("ContinuousProcess interface", "[proccesses][DevTools ExecTime]") {
REQUIRE(execTime.DoBoundaryCrossing(tmp, 0, 0) == EProcessReturn::eOk); REQUIRE(execTime.DoBoundaryCrossing(tmp, 0, 0) == EProcessReturn::eOk);
auto end = std::chrono::steady_clock::now(); auto end = std::chrono::steady_clock::now();
REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() == REQUIRE(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() ==
Approx(100).margin(1)); Approx(50).margin(1));
for (int i = 0; i < 100; i++) execTime.DoBoundaryCrossing(tmp, 0, 0);
REQUIRE(execTime.mean() == Approx(50 * 1000).margin(1 * 1000));
REQUIRE(execTime.sumTime() == Approx(50 * 100 * 1000).margin(100 * 1000));
REQUIRE(execTime.var() == Approx(0).margin(20000));
}
SECTION("TestMeanAlgo") {
std::default_random_engine generator;
std::normal_distribution<double> distribution(10000.0, 200.0);
double fStart;
double fElapsedSum;
double fMean;
double fMean2;
long long fMin;
long long fMax;
long long fN;
for (int i = 0; i < 1000000; i++) {
auto timeDiv = distribution(generator);
fElapsedSum += timeDiv;
fN = fN + 1;
if (fMax < timeDiv) fMax = timeDiv;
if (timeDiv < fMin) fMin = timeDiv;
double delta = timeDiv - fMean;
fMean += delta / static_cast<double>(fN);
double delta2 = timeDiv - fMean;
fMean2 += delta * delta2;
}
REQUIRE(fMean2 / fN == Approx(200*200).margin(200)); // Varianz
REQUIRE(fMean == Approx(10000).margin(10));
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment