Skip to content
Snippets Groups Projects
Commit f8430c5e authored by 数学の武士's avatar 数学の武士
Browse files

Initial commit

parents
Branches
Tags
No related merge requests found
{
"files.associations": {
"typeinfo": "cpp"
}
}
\ No newline at end of file
cmake_minimum_required(VERSION 3.0)
enable_language(CXX)
enable_language(CUDA)
find_package(CUDA REQUIRED)
find_package(MPI REQUIRED)
find_package(OpenMP)
project(timer)
include_directories(${MPI_INCLUDE_PATH})
include_directories(${CUDA_INCLUDE_DIRS})
set(SOURCE_LIB Event.cpp Jikan.cpp Jikan.cu JikanWrapper.cpp ToJSON.cpp)
add_library(timer STATIC ${SOURCE_LIB})
\ No newline at end of file
#include "Event.h"
#include "Jikan-config.h"
using namespace std;
EventData::EventData(){}
EventData::~EventData()
{
this->time_series.clear();
}
EventData::EventData(const string& name)
{
this->start = chrono::steady_clock::now();
this->elapsed_time = 0.0;
this->count = 0;
this->ifCUDA = 0;
this->event_name = name;
this->ifStart = false, this->ifEnd = false;
}
EventData& EventData::operator=(const EventData& src)
{
this->start = src.start;
this->elapsed_time = 0.0;
this->count = 0;
this->ifCUDA = 0;
this->event_name = src.event_name;
this->ifStart = false, this->ifEnd = false;
return *this;
}
double EventData::GetMeanElapsedTime()
{
return this->elapsed_time / this->count;
}
Event.h 0 → 100644
#pragma once
#include <string>
#include <vector>
#include <map>
#include <chrono>
#include "Jikan-config.h"
#ifdef INCLUDE_GPU_TIMER
#include <cuda_runtime.h>
#endif
typedef std::chrono::steady_clock::time_point chrono_time_type;
class EventData{
public:
#ifdef INCLUDE_GPU_TIMER
cudaEvent_t gpu_start, gpu_end;
#endif
chrono_time_type start;
double elapsed_time; // seconds
int count, ifCUDA;
bool ifStart, ifEnd;
std::vector<double> time_series;
std::string event_name;
EventData();
~EventData();
EventData(const std::string& name);
EventData& operator=(const EventData& src);
double GetMeanElapsedTime();
};
\ No newline at end of file
#define TIMER_ON
#define INCLUDE_GPU_TIMER
#define INCLUDE_MPI
#define INCLUDE_OPEN_MP
#define SAVE_TIME_SERIES
#define OUTPUT_NAME "Jikan-output"
\ No newline at end of file
Jikan.cpp 0 → 100644
#include "Jikan.h"
#include "ToJSON.h"
#include <iostream>
#include <map>
#include <string>
using namespace std;
class Jikan Timer;
Jikan::Jikan()
{
this->EventType["Synchronous events"] = set<string>();
this->EventType["Asynchronous events"] = set<string>();
this->EventType["CUDA events"] = set<string>();
this->JSONname = OUTPUT_NAME + string(".json");
this->JSONdata = "";
this->Error = "";
};
#ifdef INCLUDE_MPI
bool Jikan::ifWriteProc(MPI_Comm comm, int id)
{
bool if_write = false;
int init_flag, fin_flag, iproc;
MPI_Initialized(&init_flag);
MPI_Finalized(&fin_flag);
bool if_MPI = (init_flag) && (!fin_flag);
if(if_MPI)
{
MPI_Comm_rank(comm, &iproc);
if( iproc == id)
if_write = true;
}
else
if_write = true;
return if_write;
}
#else
bool Jikan::ifWriteProc()
{
return true;
}
#endif
Jikan::~Jikan()
{
this->Events.clear();
map<string, set<string> >::iterator it;
for(it = this->EventType.begin(); it!=this->EventType.end(); ++it)
it->second.clear();
this->EventType.clear();
}
bool Jikan::ifContains(const string& Name)
{
map<string, EventData>::iterator it;
it = this->Events.find(Name);
if (it == this->Events.end())
return false;
return true;
}
void Jikan::Jikan_sync_start(const string& name)
{
bool ExistFlag;
ExistFlag = this->ifContains(name);
if(ExistFlag)
{
chrono_time_type start = chrono::steady_clock::now();
(this->Events)[name].start = start;
}
else
{
this->EventType["Synchronous events"].insert(name);
(this->Events)[name] = EventData(name);
chrono_time_type start = chrono::steady_clock::now();
(this->Events)[name].start = start;
}
(this->Events)[name].ifStart = true;
}
void Jikan::Jikan_sync_end(const string& name)
{
bool ExistFlag, ifStart;
ExistFlag = this->ifContains(name);
ifStart = (this->Events)[name].ifStart;
if((!ExistFlag) || (!ifStart))
return;
chrono_time_type end = chrono::steady_clock::now();
chrono_time_type start = (this->Events)[name].start;
double main_elapsed = chrono::duration_cast<chrono::nanoseconds>(end - start).count() * 1e-9;
(this->Events)[name].elapsed_time += main_elapsed;
(this->Events)[name].count ++;
#ifdef SAVE_TIME_SERIES
(this->Events)[name].time_series.push_back(main_elapsed);
#endif
(this->Events)[name].ifStart = false;
}
void Jikan::Jikan_start(const string& name)
{
bool ExistFlag;
ExistFlag = this->ifContains(name);
if(ExistFlag)
{
chrono_time_type start = chrono::steady_clock::now();
(this->Events)[name].start = start;
}
else
{
this->EventType["Asynchronous events"].insert(name);
(this->Events)[name] = EventData(name);
chrono_time_type start = chrono::steady_clock::now();
(this->Events)[name].start = start;
}
(this->Events)[name].ifStart = true;
}
void Jikan::Jikan_end(const string& name)
{
bool ExistFlag, ifStart;
ExistFlag = this->ifContains(name);
ifStart = (this->Events)[name].ifStart;
if((!ExistFlag) || (!ifStart))
return;
chrono_time_type end = chrono::steady_clock::now();
chrono_time_type start = (this->Events)[name].start;
double main_elapsed = chrono::duration_cast<chrono::nanoseconds>(end - start).count() * 1e-9;
(this->Events)[name].elapsed_time += main_elapsed;
(this->Events)[name].count ++;
#ifdef SAVE_TIME_SERIES
(this->Events)[name].time_series.push_back(main_elapsed);
#endif
(this->Events)[name].ifStart = false;
}
void Jikan::GenerateTypedOutputData(const string& EventType, string& EventTypeString)
{
const int n = this->EventType[EventType].size();
EventTypeString = JSON::StartTypedBlock(EventType);
if(n == 0)
{
EventTypeString += "\n\t}";
return;
}
string Row;
string Name;
set<string>::iterator it;
set<string>::iterator end_m = this->EventType[EventType].end();
--end_m;
for (it = this->EventType[EventType].begin(); it != end_m; ++it)
{
Name = *it;
JSON::GenerateRow(this->Events[Name], Row, JSON::SeparateRows);
EventTypeString += Row;
}
Name = *end_m;
JSON::GenerateRow(this->Events[Name], Row, JSON::FinishRows);
EventTypeString += Row;
}
void Jikan::GenerateOutputData()
{
map<string, set<string> >::iterator it;
map<string, set<string> >::iterator end_m = this->EventType.end();
--end_m;
string Name;
string Out = "{ ";
string TypedOutput;
for(it = this->EventType.begin(); it!=end_m; ++it)
{
Name = it->first;
TypedOutput = "";
this->GenerateTypedOutputData(Name, TypedOutput);
Out += TypedOutput + ",\n";
}
Name = end_m->first;
TypedOutput = "";
this->GenerateTypedOutputData(Name, TypedOutput);
Out += TypedOutput + "\n}";
this->JSONdata = Out;
bool OutputRes = JSON::WriteOutput(this->JSONname, this->JSONdata);
if(OutputRes != true)
{
this->Error = JSON::Error;
}
#ifdef INCLUDE_GPU_TIMER
this->FreeCudaEvents();
#endif
}
void Jikan::SetDumpFilename(const std::string& name)
{
this->JSONname = name;
}
\ No newline at end of file
Jikan.cu 0 → 100644
#include <sys/time.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include "Jikan.h"
#include "Jikan-config.h"
#ifdef INCLUDE_OPEN_MP
#include "omp.h"
#endif
using namespace std;
void Jikan::cuda_Jikan_start(const string& name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
bool ExistFlag;
ExistFlag = this->ifContains(name);
if(ExistFlag == false)
{
(this->Events)[name] = EventData(name);
this->EventType["CUDA events"].insert(name);
(this->Events)[name].ifCUDA = 1;
cudaEventCreate(&(((this->Events)[name]).gpu_start));
cudaEventCreate(&(((this->Events)[name]).gpu_end));
}
(this->Events)[name].ifStart = true;
cudaEventRecord ((this->Events)[name].gpu_start);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void Jikan::cuda_Jikan_end(const string& name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
bool ExistFlag, ifStart;
ExistFlag = this->ifContains(name);
ifStart = (this->Events)[name].ifStart;
if((!ExistFlag) || (!ifStart))
return;
float GPUtime = 0.0;
cudaEventRecord((this->Events)[name].gpu_end);
cudaEventSynchronize((this->Events)[name].gpu_end);
cudaEventElapsedTime(&GPUtime, (this->Events)[name].gpu_start, (this->Events)[name].gpu_end); //milliseconds
GPUtime *= 1e-3;
(this->Events)[name].elapsed_time += GPUtime;
(this->Events)[name].count ++;
#ifdef SAVE_TIME_SERIES
(this->Events)[name].time_series.push_back(GPUtime);
#endif
(this->Events)[name].ifStart = false;
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void Jikan::FreeCudaEvents()
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
map<string, EventData>::iterator it;
for (it = this->Events.begin(); it!=this->Events.end(); ++it)
{
if((it->second).ifCUDA == 1)
{
cudaEventDestroy((it->second).gpu_start);
cudaEventDestroy((it->second).gpu_end);
}
}
#ifdef INCLUDE_OPEN_MP
}
#endif
}
\ No newline at end of file
Jikan.h 0 → 100644
#pragma once
#include "JikanWrapper.h"
#include "Jikan-config.h"
#include "Event.h"
#include <iostream>
#include <string>
#include <set>
#ifdef INCLUDE_MPI
#include <mpi.h>
#endif
class Jikan
{
public:
std::map<std::string, EventData> Events;
std::map<std::string, std::set<std::string> > EventType;
std::string JSONname;
std::string JSONdata;
std::string Error;
Jikan();
~Jikan();
void Jikan_sync_start(const std::string& name);
void Jikan_sync_end( const std::string& name);
void Jikan_start(const std::string& name);
void Jikan_end( const std::string& name);
#ifdef INCLUDE_GPU_TIMER
void cuda_Jikan_start(const std::string& name);
void cuda_Jikan_end( const std::string& name);
#endif
void GenerateTypedOutputData(const std::string& EventType, std::string& EventTypeString);
void GenerateOutputData();
// private:
bool ifContains(const std::string& name);
#ifdef INCLUDE_MPI
bool ifWriteProc(MPI_Comm comm, int id);
#else
bool ifWriteProc();
#endif
void SetDumpFilename(const std::string& name);
private:
#ifdef INCLUDE_GPU_TIMER
void FreeCudaEvents();
#endif
};
\ No newline at end of file
#include "Jikan.h"
#include "JikanWrapper.h"
#ifdef INCLUDE_OPEN_MP
#include "omp.h"
#endif
#ifdef INCLUDE_MPI
#include "mpi.h"
#endif
using namespace std;
extern "C"
{
extern class Jikan Timer;
void TimerStart(const char* name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
Timer.Jikan_start(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void TimerEnd(const char* name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
Timer.Jikan_end(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
#ifdef INCLUDE_MPI
void MPI_SyncTimerStart(const char* name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
int init_flag, fin_flag;
MPI_Initialized(&init_flag);
MPI_Finalized(&fin_flag);
if((!fin_flag) && init_flag)
MPI_Barrier(MPI_COMM_WORLD);
Timer.Jikan_sync_start(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void MPI_SyncTimerEnd(const char* name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
int init_flag, fin_flag;
MPI_Initialized(&init_flag);
MPI_Finalized(&fin_flag);
if((!fin_flag) && init_flag)
MPI_Barrier(MPI_COMM_WORLD);
Timer.Jikan_sync_end(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void MPI_SyncTimerStartCustom(const char* name, MPI_Comm comm)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
int init_flag, fin_flag;
MPI_Initialized(&init_flag);
MPI_Finalized(&fin_flag);
if((!fin_flag) && init_flag)
MPI_Barrier(MPI_COMM_WORLD);
Timer.Jikan_sync_start(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void MPI_SyncTimerEndCustom(const char* name, MPI_Comm comm)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
int init_flag, fin_flag;
MPI_Initialized(&init_flag);
MPI_Finalized(&fin_flag);
if((!fin_flag) && init_flag)
MPI_Barrier(comm);
Timer.Jikan_sync_end(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void WriteOutputCustom(MPI_Comm comm, int id)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
bool ifWrite = Timer.ifWriteProc(comm, id);
if(ifWrite == true)
Timer.GenerateOutputData();
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void WriteOutput(int id)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
bool ifWrite = Timer.ifWriteProc(MPI_COMM_WORLD, id);
// cout << ifWrite << endl;
if(ifWrite == true)
Timer.GenerateOutputData();
#ifdef INCLUDE_OPEN_MP
}
#endif
}
#else
void WriteOutput()
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
bool ifWrite = Timer.ifWriteProc();
if(ifWrite == true)
Timer.GenerateOutputData();
#ifdef INCLUDE_OPEN_MP
}
#endif
}
#endif
#ifdef INCLUDE_OPEN_MP
void OpenMP_SyncTimerStart(const char* name)
{
#pragma omp barrier
#pragma omp master
{
string str_name = name;
Timer.Jikan_sync_start(str_name);
}
}
void OpenMP_SyncTimerEnd(const char* name)
{
#pragma omp barrier
#pragma omp master
{
string str_name = name;
Timer.Jikan_sync_end(str_name);
}
}
#endif
//--------
#ifdef INCLUDE_GPU_TIMER
void CudaTimerStart(const char* name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
Timer.cuda_Jikan_start(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
void CudaTimerEnd(const char* name)
{
#ifdef INCLUDE_OPEN_MP
#pragma omp master
{
#endif
string str_name = name;
Timer.cuda_Jikan_end(str_name);
#ifdef INCLUDE_OPEN_MP
}
#endif
}
#endif
}
\ No newline at end of file
#pragma once
#include "Jikan-config.h"
#ifdef INCLUDE_MPI
#include <mpi.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
void TimerStart(const char* name);
void TimerEnd(const char* name);
// SIMPLE TIMER -------------------------------------------
#ifdef TIMER_ON
#define JIKAN_TIMER_START(name) TimerStart(name);
#define JIKAN_TIMER_END(name) TimerEnd(name);
#else
#define JIKAN_TIMER_START(name)
#define JIKAN_TIMER_END(name)
#endif
//---------------------------------------------------------
// MPI TIMER ----------------------------------------------
#ifdef INCLUDE_MPI
void MPI_SyncTimerStart(const char* name);
void MPI_SyncTimerEnd(const char* name);
#define MPI_SYNC_JIKAN_TIMER_START_DEF(name) MPI_SyncTimerStart(name);
#define MPI_SYNC_JIKAN_TIMER_END_DEF(name) MPI_SyncTimerEnd(name);
void MPI_SyncTimerStartCustom(const char* name, MPI_Comm comm);
void MPI_SyncTimerEndCustom(const char* name, MPI_Comm comm);
#define MPI_SYNC_JIKAN_TIMER_START_CUSTOM(name, comm) MPI_SyncTimerStartCustom(name, comm);
#define MPI_SYNC_JIKAN_TIMER_END_CUSTOM(name, comm) MPI_SyncTimerEndCustom(name, comm);
#ifdef TIMER_ON
#define SYNC_SELECT(_1, _2, macro, ...) macro
#define MPI_SYNC_JIKAN_TIMER_START(...) SYNC_SELECT(__VA_ARGS__, MPI_SYNC_JIKAN_TIMER_START_CUSTOM, MPI_SYNC_JIKAN_TIMER_START_DEF)(__VA_ARGS__)
#define MPI_SYNC_JIKAN_TIMER_END(...) SYNC_SELECT(__VA_ARGS__, MPI_SYNC_JIKAN_TIMER_END_CUSTOM, MPI_SYNC_JIKAN_TIMER_END_DEF )(__VA_ARGS__)
#else
#define MPI_SYNC_JIKAN_TIMER_START(...)
#define MPI_SYNC_JIKAN_TIMER_END(...)
#endif
#else
#define MPI_SYNC_JIKAN_TIMER_START(...)
#define MPI_SYNC_JIKAN_TIMER_END(...)
#endif
//---------------------------------------------------------
// OpenMP TIMER -------------------------------------------
#ifdef INCLUDE_OPEN_MP
void OpenMP_SyncTimerStart(const char* name);
void OpenMP_SyncTimerEnd(const char* name);
#ifdef TIMER_ON
#define OpenMP_SYNC_JIKAN_TIMER_START(name) OpenMP_SyncTimerStart(name);
#define OpenMP_SYNC_JIKAN_TIMER_END(name) OpenMP_SyncTimerEnd(name);
#else
#define OpenMP_SYNC_JIKAN_TIMER_START(name)
#define OpenMP_SYNC_JIKAN_TIMER_END(name)
#endif
#else
#define OpenMP_SYNC_JIKAN_TIMER_START(name)
#define OpenMP_SYNC_JIKAN_TIMER_END(name)
#endif
//---------------------------------------------------------
// CUDA TIMER ---------------------------------------------
#ifdef INCLUDE_GPU_TIMER
void CudaTimerStart(const char* name);
void CudaTimerEnd(const char* name);
#ifdef TIMER_ON
#define JIKAN_CUDA_TIMER_START(name) CudaTimerStart(name);
#define JIKAN_CUDA_TIMER_END(name) CudaTimerEnd(name);
#else
#define JIKAN_CUDA_TIMER_START(name)
#define JIKAN_CUDA_TIMER_END(name)
#endif
#else
#define JIKAN_CUDA_TIMER_START(name)
#define JIKAN_CUDA_TIMER_END(name)
#endif
//---------------------------------------------------------
#ifdef INCLUDE_MPI
void WriteOutputCustom(MPI_Comm comm, int id);
void WriteOutput(int id);
#ifdef TIMER_ON
#define JIKAN_TIMER_OUTPUT_CUSTOM(comm) WriteOutputCustom(comm, 0);
#define JIKAN_TIMER_OUTPUT_DEF() WriteOutput(0);
#define OUTPUT_SELECT(_0, _1, macro, ...) macro
#define JIKAN_TIMER_OUTPUT(...) OUTPUT_SELECT(__VA_ARGS__, JIKAN_TIMER_OUTPUT_CUSTOM, JIKAN_TIMER_OUTPUT_DEF)(__VA_ARGS__)
#else
#define JIKAN_TIMER_OUTPUT(...)
#endif
#else
void WriteOutput();
#define JIKAN_TIMER_OUTPUT() WriteOutput();
#endif
#ifdef __cplusplus
}
#endif
\ No newline at end of file
#include "ToJSON.h"
#include "Event.h"
#include <fstream>
using namespace std;
string JSON::Error = "";
string JSON::SeparateRows = "}, \n";
string JSON::SeparateSubRows = ", \n";
string JSON::FinishRows = "}\n\t}";
string JSON::FinishSubRows = "}";
string JSON::Finish = "}\n";
string JSON::StartRow(const string& name)
{
string row = "\n{ \"" + name + "\" : ";
return row;
}
string JSON::StartSubRow(const string& name)
{
string row = "\t\t\"" + name + "\" : ";
return row;
}
string JSON::StartTypedBlock(const string& name)
{
string row = "\n\t\"" + name + "\" : \n\t{ \n";
return row;
}
bool JSON::GenerateRow(EventData Event, string &ResRow, const string& EndRowJSON)
{
char AccurateValue[256];
sprintf(AccurateValue, "%.10e", Event.elapsed_time);
string FullElapsedTime = JSON::StartSubRow(string("Full elapsed time")) + string(AccurateValue) + JSON::SeparateSubRows;
AccurateValue[0] = '\0';
double mean_elapsed = Event.GetMeanElapsedTime();
sprintf(AccurateValue, "%.10e", mean_elapsed);
string MeanElapsedTime = JSON::StartSubRow(string("Mean elapsed time")) + string(AccurateValue) + JSON::SeparateSubRows;
string TimeSeries = JSON::StartSubRow(string("Time series")) + "[";
int TimeSeriesLen = Event.time_series.size();
for (int i = 0; i < TimeSeriesLen - 1; i++)
{
AccurateValue[0] = '\0';
sprintf(AccurateValue, "%.10e", Event.time_series[i]);
TimeSeries += string(AccurateValue) + ", ";
}
if(TimeSeriesLen != 0)
{
AccurateValue[0] = '\0';
sprintf(AccurateValue, "%.10e", Event.time_series[TimeSeriesLen - 1]);
TimeSeries += string(AccurateValue);
}
TimeSeries += "]" ;
string JSONrow = JSON::StartSubRow(Event.event_name) + "{" + FullElapsedTime + MeanElapsedTime + TimeSeries + EndRowJSON;
ResRow = JSONrow;
return true;
}
bool JSON::WriteOutput(const string& Filename, const string& OutputData)
{
ofstream file;
file.open(Filename);
if (!file)
{
string error_definition = "Can't open file " + Filename + "\n";
JSON::Error = error_definition;
return false;
}
file << OutputData;
file.close();
return true;
}
ToJSON.h 0 → 100644
#pragma once
#include "Event.h"
class JSON
{
public:
static std::string Error;
static std::string StartTypedBlock(const std::string& name);
static std::string StartRow(const std::string& name);
static std::string StartSubRow(const std::string& name);
static std::string Finish;
static std::string FinishSubRows;
static std::string SeparateSubRows;
static std::string SeparateRows;
static std::string FinishRows;
static bool GenerateRow(EventData Event, std::string &ResRow, const std::string& name);
static bool WriteOutput(const std::string& Filename, const std::string& OutputData);
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment