Commit fa6f91af authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Add support for timing oscillators app.

parent 05bc16a3
......@@ -24,7 +24,7 @@ target_link_libraries(oscillator PRIVATE mpi diy grid opts)
# Threads
find_package(Threads)
target_link_libraries(oscillator PRIVATE util ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(oscillator PRIVATE timer)
if(ENABLE_SENSEI)
target_link_libraries(oscillator PRIVATE sensei)
endif()
......@@ -4,6 +4,7 @@
#include <vector>
#include <sensei/ConfigurableAnalysis.h>
#include <timer/Timer.h>
#include <vtkDataObject.h>
#include <vtkNew.h>
#include <vtkSmartPointer.h>
......@@ -24,6 +25,7 @@ void initialize(MPI_Comm world,
int* to_x, int* to_y, int* to_z,
const std::string& config_file)
{
timer::MarkEvent mark("oscillators::bridge::initialize");
GlobalDataAdaptor = vtkSmartPointer<oscillators::DataAdaptor>::New();
GlobalDataAdaptor->Initialize(nblocks);
GlobalDataAdaptor->SetDataTimeStep(-1);
......@@ -50,15 +52,29 @@ void analyze(float time)
{
GlobalDataAdaptor->SetDataTime(time);
GlobalDataAdaptor->SetDataTimeStep(GlobalDataAdaptor->GetDataTimeStep() + 1);
timer::MarkStartTimeStep(GlobalDataAdaptor->GetDataTimeStep(), time);
timer::MarkStartEvent("oscillators::bridge::analyze");
GlobalAnalysisAdaptor->Execute(GlobalDataAdaptor.GetPointer());
timer::MarkEndEvent("oscillators::bridge::analyze");
timer::MarkStartEvent("oscillators::bridge::release-data");
GlobalDataAdaptor->ReleaseData();
timer::MarkEndEvent("oscillators::bridge::release-data");
timer::MarkEndTimeStep();
}
//-----------------------------------------------------------------------------
void finalize(size_t k_max, size_t nblocks)
{
timer::MarkStartEvent("oscillators::bridge::finalize");
GlobalAnalysisAdaptor = NULL;
GlobalDataAdaptor = NULL;
timer::MarkEndEvent("oscillators::bridge::finalize");
timer::PrintLog(cout);
}
}
......@@ -18,6 +18,8 @@
#include "analysis.h"
#endif
#include <timer/Timer.h>
using Grid = grid::Grid<float,3>;
using Vertex = Grid::Vertex;
......@@ -52,13 +54,16 @@ struct Block
for (auto& o : oscillators)
gv += o.evaluate(v_global, t);
});
}
void analyze_block()
{
#ifdef ENABLE_SENSEI
bridge::set_data(gid, grid.data());
bridge::set_data(gid, grid.data());
#else
analyze(gid, grid.data());
analyze(gid, grid.data());
#endif
}
}
static void* create() { return new Block; }
static void destroy(void* b) { delete static_cast<Block*>(b); }
......@@ -117,6 +122,8 @@ int main(int argc, char** argv)
return 1;
}
timer::MarkStartEvent("oscillators::initialize");
auto oscillators = read_oscillators(infn);
//for (auto& o : oscillators)
// fmt::print("center = {}, radius = {}, omega0 = {}, zeta = {}\n", o.center, o.radius, o.omega0, o.zeta);
......@@ -136,6 +143,7 @@ int main(int argc, char** argv)
from_x, from_y, from_z,
to_x, to_y, to_z;
// decompose the domain
diy::decompose(3, world.rank(), domain, assigner,
[&](int gid, const Bounds& core, const Bounds& bounds, const Bounds& domain, const Link& link)
......@@ -154,6 +162,9 @@ int main(int argc, char** argv)
to_z.push_back(bounds.max[2]);
});
timer::MarkEndEvent("oscillators::initialize");
timer::MarkStartEvent("oscillators::analysis::initialize");
#ifdef ENABLE_SENSEI
bridge::initialize(world, window, nblocks, gids.size(),
domain.max[0] + 1, domain.max[1] + 1, domain.max[2] + 1,
......@@ -168,6 +179,8 @@ int main(int argc, char** argv)
&from_x[0], &from_y[0], &from_z[0],
&to_x[0], &to_y[0], &to_z[0]);
#endif
timer::MarkEndEvent("oscillators::analysis::initialize");
if (world.rank() == 0)
fmt::print("Started\n");
......@@ -175,32 +188,50 @@ int main(int argc, char** argv)
using ms = std::chrono::milliseconds;
auto start = Time::now();
int t_count = 0;
float t = 0.;
while (t < t_end)
{
timer::MarkStartTimeStep(t_count, t);
timer::MarkStartEvent("oscillators::advance");
master.foreach<Block>([=](Block* b, const Proxy&, void*)
{
b->advance(t);
});
timer::MarkEndEvent("oscillators::advance");
timer::MarkStartEvent("oscillators::analysis");
master.foreach<Block>([=](Block* b, const Proxy&, void*)
{
b->analyze_block();
});
#ifdef ENABLE_SENSEI
bridge::analyze(t);
#else
analysis_round(); // let analysis do any kind of global operations it would like
#endif
timer::MarkEndEvent("oscillators::analysis");
if (sync)
world.barrier();
timer::MarkEndTimeStep();
t += dt;
t_count++;
}
world.barrier();
timer::MarkStartEvent("oscillators::finalize");
#ifdef ENABLE_SENSEI
bridge::finalize(k_max, nblocks);
#else
analysis_final(k_max, nblocks);
#endif
timer::MarkEndEvent("oscillators::finalize");
auto duration = std::chrono::duration_cast<ms>(Time::now() - start);
if (world.rank() == 0)
fmt::print("Total run time: {}.{} s\n", duration.count() / 1000, duration.count() % 1000);
{
fmt::print("Total run time: {}.{} s\n", duration.count() / 1000, duration.count() % 1000);
timer::PrintLog(std::cout);
}
}
......@@ -22,6 +22,7 @@
#include <grid/grid.h>
#include <grid/vertices.h>
#include <timer/Timer.h>
// http://stackoverflow.com/a/12580468
template<typename T, typename ...Args>
......@@ -193,6 +194,7 @@ void Autocorrelation::Initialize(MPI_Comm world,
size_t window,
int association, const char* arrayname, size_t kmax)
{
timer::MarkEvent mark("autocorrelation::initialize");
AInternals& internals = (*this->Internals);
internals.Master = make_unique<diy::Master>(world, -1, -1,
&AutocorrelationImpl::create,
......@@ -206,6 +208,7 @@ void Autocorrelation::Initialize(MPI_Comm world,
//-----------------------------------------------------------------------------
bool Autocorrelation::Execute(DataAdaptor* data)
{
timer::MarkEvent mark("autocorrelation::execute");
AInternals& internals = (*this->Internals);
const int association = internals.Association;
const char* arrayname = internals.ArrayName.c_str();
......@@ -269,6 +272,7 @@ bool Autocorrelation::Execute(DataAdaptor* data)
//-----------------------------------------------------------------------------
void Autocorrelation::PrintResults(size_t k_max)
{
timer::MarkEvent mark("autocorrelation::collect results");
AInternals& internals = (*this->Internals);
size_t nblocks = internals.NumberOfBlocks;
......
......@@ -72,6 +72,7 @@ target_link_libraries(sensei
PRIVATE diy
grid
pugixml
timer
)
#------------------------------------------------------------------------------
......
......@@ -12,6 +12,8 @@
#include "DataAdaptor.h"
#include <timer/Timer.h>
#include <algorithm>
#include <vector>
namespace
......@@ -156,6 +158,8 @@ void Histogram::Initialize(
//-----------------------------------------------------------------------------
bool Histogram::Execute(sensei::DataAdaptor* data)
{
timer::MarkEvent mark("histogram::execute");
vtkHistogram histogram;
vtkDataObject* mesh = data->GetMesh(/*structure_only*/true);
if (mesh == NULL || !data->AddArray(mesh, this->Association, this->ArrayName.c_str()))
......
#include "AnalysisAdaptor.h"
#include <sensei/DataAdaptor.h>
#include <timer/Timer.h>
#include <vtkCellData.h>
#include <vtkCompositeDataIterator.h>
......@@ -220,6 +221,8 @@ void AnalysisAdaptor::InitializeADIOS(DataAdaptor* data)
return;
}
timer::MarkEvent mark("adios::intialize");
adios_init_noxml(MPI_COMM_WORLD);
adios_allocate_buffer(ADIOS_BUFFER_ALLOC_NOW, 500);
......@@ -273,6 +276,7 @@ void AnalysisAdaptor::InitializeADIOS(DataAdaptor* data)
//----------------------------------------------------------------------------
void AnalysisAdaptor::WriteTimestep(DataAdaptor* data)
{
timer::MarkEvent mark("adios::execute");
vtkDataObject* mesh = data->GetCompleteMesh();
int nprocs = 1, rank = 0;
......
#include "AnalysisAdaptor.h"
#include <sensei/DataAdaptor.h>
#include <timer/Timer.h>
#include <vtkCPAdaptorAPI.h>
#include <vtkCPDataDescription.h>
......@@ -22,6 +23,7 @@ AnalysisAdaptor::AnalysisAdaptor()
{
if (vtkCPAdaptorAPIInitializationCounter == 0)
{
timer::MarkEvent mark("catalyst::initialize");
vtkCPAdaptorAPI::CoProcessorInitialize();
}
vtkCPAdaptorAPIInitializationCounter++;
......@@ -33,6 +35,7 @@ AnalysisAdaptor::~AnalysisAdaptor()
vtkCPAdaptorAPIInitializationCounter--;
if (vtkCPAdaptorAPIInitializationCounter == 0)
{
timer::MarkEvent mark("catalyst::finalize");
vtkCPAdaptorAPI::CoProcessorFinalize();
}
}
......@@ -49,6 +52,7 @@ void AnalysisAdaptor::AddPipeline(vtkCPPipeline* pipeline)
//-----------------------------------------------------------------------------
bool AnalysisAdaptor::Execute(DataAdaptor* dataAdaptor)
{
timer::MarkEvent mark("catalyst::execute");
double time = dataAdaptor->GetDataTime();
int timeStep = dataAdaptor->GetDataTimeStep();
int coprocessThisTimeStep;
......
#include "Slice.h"
#include "Utilities.h"
#include <timer/Timer.h>
#include <vtkCPDataDescription.h>
#include <vtkCPInputDataDescription.h>
#include <vtkObjectFactory.h>
......@@ -178,6 +180,7 @@ int Slice::RequestDataDescription(vtkCPDataDescription* dataDesc)
//----------------------------------------------------------------------------
int Slice::CoProcess(vtkCPDataDescription* dataDesc)
{
timer::MarkEvent mark("catalyst::slice");
vtkInternals& internals = (*this->Internals);
internals.UpdatePipeline(dataDesc->GetInputDescription(0)->GetGrid(), dataDesc->GetTime());
return 1;
......
......@@ -16,3 +16,10 @@ add_library(pugixml STATIC
pugixml/src/pugiconfig.hpp)
target_include_directories(pugixml
SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/pugixml/src)
add_library(timer STATIC
timer/Timer.cxx
timer/Timer.h
timer/TimerC.h)
target_include_directories(timer
SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
#include "Timer.h"
#include "TimerC.h"
#include <sys/time.h>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <map>
#include <list>
using std::endl;
using std::cerr;
namespace timer
{
namespace impl
{
static double get_mark()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec/1.0e6;
}
struct Indent
{
int Count;
Indent(int indent=0) : Count(indent) {}
Indent GetNextIndent() const
{ return Indent(this->Count+1); }
};
std::ostream &operator<<(std::ostream &os, const Indent &i)
{
for (int cc=0; cc < i.Count; ++cc) { os << " "; }
return os;
}
struct Event
{
std::string Name;
double Duration;
Event() : Duration(-1.0) {}
bool IsValid() const
{ return this->Duration > -1.0; }
void PrintLog(std::ostream& stream, Indent indent) const
{
stream << indent << this->Name.c_str() << " = " << this->Duration << endl;
for (std::list<Event>::const_iterator iter = this->SubEvents.begin();
iter != this->SubEvents.end(); ++iter)
{
iter->PrintLog(stream, indent.GetNextIndent());
}
}
std::list<Event> SubEvents;
};
static std::list<Event> GlobalEvents;
static std::list<Event> Mark;
static bool LoggingEnabled = true;
void PrintLog(std::ostream& stream, Indent indent)
{
for (std::list<Event>::iterator iter = GlobalEvents.begin();
iter != GlobalEvents.end(); ++iter)
{
iter->PrintLog(stream, indent);
}
}
}
//-----------------------------------------------------------------------------
void SetLogging(bool val)
{
impl::LoggingEnabled = val;
}
//-----------------------------------------------------------------------------
bool GetLogging()
{
return impl::LoggingEnabled;
}
//-----------------------------------------------------------------------------
void MarkStartEvent(const char* eventname)
{
if (impl::LoggingEnabled)
{
impl::Event evt;
evt.Name = eventname? eventname : "(none)";
evt.Duration = impl::get_mark();
impl::Mark.push_back(evt);
}
}
//-----------------------------------------------------------------------------
void MarkEndEvent(const char* eventname)
{
if (impl::LoggingEnabled)
{
eventname = eventname? eventname : "(none)";
impl::Event evt = impl::Mark.back();
if (strcmp(eventname, evt.Name.c_str()) != 0)
{
cerr << "Mismatched MarkStartEvent/MarkEndEvent.\n"
<< " Expecting: '" << evt.Name.c_str() << "'\n"
<< " Got: '" << eventname << "'\n"
<< "Aborting for debugging purposes.";
abort();
}
evt.Duration = impl::get_mark() - evt.Duration;
impl::Mark.pop_back();
if (impl::Mark.empty())
{
impl::GlobalEvents.push_back(evt);
}
else
{
impl::Mark.back().SubEvents.push_back(evt);
}
}
}
//-----------------------------------------------------------------------------
void MarkStartTimeStep(int timestep, double Duration)
{
}
//-----------------------------------------------------------------------------
void MarkEndTimeStep()
{
}
//-----------------------------------------------------------------------------
void PrintLog(std::ostream& stream)
{
impl::PrintLog(stream, impl::Indent());
}
}
void TIMER_SetLogging(bool val)
{
timer::SetLogging(val);
}
void TIMER_MarkStartEvent(const char* val)
{
timer::MarkStartEvent(val);
}
void TIMER_MarkEndEvent(const char* val)
{
timer::MarkEndEvent(val);
}
void TIMER_MarkStartTimeStep(int timestep, double time)
{
timer::MarkStartTimeStep(timestep, time);
}
void TIMER_MarkEndTimeStep()
{
timer::MarkEndTimeStep();
}
void TIMER_Print()
{
timer::PrintLog(std::cout);
}
#ifndef timer_Timer_h
#define timer_Timer_h
#include <iostream>
namespace timer
{
/// @brief Enable/Disable logging (default is enabled).
void SetLogging(bool val);
/// @brief Get whether logging is enabled.
bool GetLogging();
/// @brief Log start of a log-able event.
///
/// This marks the beginning of a event that must be logged.
/// The @arg eventname must match when calling MarkEndEvent() to
/// mark the end of the event.
void MarkStartEvent(const char* eventname);
/// @brief Log end of a log-able event.
///
/// This marks the end of a event that must be logged.
/// The @arg eventname must match when calling MarkEndEvent() to
/// mark the end of the event.
void MarkStartEvent(const char* eventname);
void MarkEndEvent(const char* eventname);
/// @brief Mark the beginning of a timestep.
///
/// This marks the beginning of a timestep. All MarkStartEvent and
/// MarkEndEvent after this until MarkEndTimeStep are assumed to be
/// happening for a specific timestep and will be combined with subsequent
/// timesteps.
void MarkStartTimeStep(int timestep, double time);
/// @brief Marks the end of the current timestep.
void MarkEndTimeStep();
/// @brief Print log to the output stream.
void PrintLog(std::ostream& stream);
class MarkEvent
{
const char* EventName;
public:
MarkEvent(const char* name) : EventName(name) { MarkStartEvent(name); }
~MarkEvent() { MarkEndEvent(this->EventName); }
};
}
#endif
#ifndef timerc_h
#define timerc_h
#ifdef __cplusplus
extern "C" {
#endif
void TIMER_SetLogging(bool val);
void TIMER_MarkStartEvent(const char* val);
void TIMER_MarkEndEvent(const char* val);
void TIMER_MarkStartTimeStep(int timestep, double time);
void TIMER_MarkEndTimeStep();
void TIMER_Print();
#ifdef __cplusplus
}
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment