#include "Jikan.h" #include "JikanDepths.h" #include "ToJSON.h" #include <iostream> // #include <map> #include <string> #ifdef INCLUDE_OPEN_MP #include <omp.h> #endif using namespace std; Jikan::Jikan() { #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif this->EventType["Synchronous events"] = set<string>(); this->EventType["Asynchronous events"] = set<string>(); this->JSONname = OUTPUT_NAME + string(".json"); this->JSONdata = ""; this->Error = ""; #ifdef INCLUDE_OPEN_MP } #endif }; #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; } #endif bool Jikan::ifWriteProc() { #ifdef INCLUDE_MPI int init_flag, fin_flag; MPI_Initialized(&init_flag); MPI_Finalized(&fin_flag); int GlobalCommRank; if((!fin_flag) && init_flag) { MPI_Comm_rank(MPI_COMM_WORLD, &GlobalCommRank); if(GlobalCommRank == 0) return true; else return false; } else return true; #endif return true; } Jikan::~Jikan() { #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif this->Events.clear(); unordered_map<string, set<string> >::iterator it; for(it = this->EventType.begin(); it!=this->EventType.end(); ++it) it->second.clear(); this->EventType.clear(); #ifdef INCLUDE_OPEN_MP } #endif } bool Jikan::ifContains(const string& Name) { unordered_map<string, EventData>::iterator it; it = this->Events.find(Name); if (it == this->Events.end()) return false; return true; } void Jikan::JikanStart(const string& name, const int& mode) { bool ExistFlag, ifMPI, ifOpenMP; ExistFlag = this->ifContains(name); if(!ExistFlag) { #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif (this->Events)[name] = EventData(name); (this->Events)[name].GetModeVals(mode); #ifdef INCLUDE_OPEN_MP } #endif } #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif (this->Events)[name].ifStart = true; // printf("(this->Events)[name].ifStart = %d\n", (this->Events)[name].ifStart); #ifdef INCLUDE_OPEN_MP } #endif // printf("118 (this->Events)[name].ifStart = %d\n", (this->Events)[name].ifStart); // else // { // bool ifStart = (this->Events)[name].ifStart; // if(!ifStart) // return; // } #ifdef INCLUDE_OPEN_MP #pragma omp barrier #endif ifMPI = (this->Events)[name].mode[0], ifOpenMP = (this->Events)[name].mode[1]; #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif if(!ExistFlag) { string EventTypeName; if(mode == TimerMode::NO_SYNC) EventTypeName = "Asynchronous events"; else EventTypeName = "Synchronous events"; this->EventType[EventTypeName].insert(name); } //--------------------------- MPI synchronization --------------------------------------- if(ifMPI) this->BarrierMPI(); //--------------------------------------------------------------------------------------- #ifdef INCLUDE_OPEN_MP } #endif //--------------------------- OpenMP synchronization -------------------------------- if(ifOpenMP) { #ifdef INCLUDE_OPEN_MP #pragma omp barrier #endif } //----------------------------------------------------------------------------------- #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif // printf("170 (this->Events)[name].ifStart = %d\n", (this->Events)[name].ifStart); this->StartEvent(name); // printf("(this->Events)[name].ifStart = %d\n", (this->Events)[name].ifStart); #ifdef INCLUDE_OPEN_MP } #endif // printf("177 (this->Events)[name].ifStart = %d\n", (this->Events)[name].ifStart); } void Jikan::JikanEnd(const string& name, const int cont_mode_t) { bool ExistFlag, ifStart; bool ifMPI, ifOpenMP, ifCUDA; ExistFlag = this->ifContains(name); ifStart = (this->Events)[name].ifStart; // printf("JikanEnd\n"); if((!ExistFlag) || (!ifStart)) { // printf("ExistFlag = %d, ifStart = %d\n", ExistFlag, ifStart); return; } ifMPI = (this->Events)[name].mode[0], ifOpenMP = (this->Events)[name].mode[1], ifCUDA = (this->Events)[name].mode[2]; // printf("JikanEnd:: ifCUDA = %d\n", ifCUDA); #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif if((ifCUDA) && (!ifMPI) && (!ifOpenMP)) { #ifdef INCLUDE_GPU_TIMER this->EndCUDASync(name); this->CUDAGetTime(name, cont_mode_t); #endif } #ifdef INCLUDE_OPEN_MP } #endif //--------------------------- OpenMP synchronization -------------------------------- if(ifOpenMP) { #ifdef INCLUDE_OPEN_MP #pragma omp barrier #endif } //----------------------------------------------------------------------------------- //--------------------------- MPI synchronization --------------------------------------- #ifdef INCLUDE_OPEN_MP #pragma omp master { #endif if(ifMPI) this->BarrierMPI(); this->EndEvent(name, cont_mode_t); #ifdef INCLUDE_OPEN_MP } #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() { unordered_map<string, set<string> >::iterator it; unordered_map<string, set<string> >::iterator end_m; // = this->EventType.end(); // end_m--; string Name; string Out = "{ "; string TypedOutput; for(it = this->EventType.begin(); it!=this->EventType.end(); ++it) { if(next(it) != this->EventType.end()) { Name = it->first; TypedOutput = ""; this->GenerateTypedOutputData(Name, TypedOutput); Out += TypedOutput + ",\n"; } else end_m = it; } 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; } } void Jikan::SetDumpFilename(const string& name) { this->JSONname = name; } void Jikan::StartEvent(const string& name) { bool ifMPI = (this->Events)[name].mode[0], ifOpenMP = (this->Events)[name].mode[1], ifCUDA = (this->Events)[name].mode[2]; if((ifCUDA)) { #ifdef INCLUDE_GPU_TIMER // printf("StartCUDASync\n"); this->StartCUDASync(name); #endif } #ifdef INCLUDE_OPEN_MP else if( (!ifMPI) && (ifOpenMP) ) (this->Events)[name].double_start = omp_get_wtime(); #endif else (this->Events)[name].start = chrono::steady_clock::now(); } #define btoa(x) ((x)?"true":"false") void Jikan::EndEvent(const string& name, const int cont_mode_t) { bool ifMPI = (this->Events)[name].mode[0], ifOpenMP = (this->Events)[name].mode[1], ifCUDA = (this->Events)[name].mode[2]; // printf("%s %s %s\n", btoa(ifMPI), btoa(ifOpenMP), btoa(ifCUDA)); if(ifCUDA) { #ifdef INCLUDE_GPU_TIMER this->EndCUDASync(name); #endif } #ifdef INCLUDE_OPEN_MP else if( (!ifMPI) && (ifOpenMP)) { double end = omp_get_wtime(); double main_elapsed = end - (this->Events)[name].double_start; (this->Events)[name].elapsed_time += main_elapsed; (this->Events)[name].ContiniousTime += main_elapsed; if(cont_mode_t == 0) { (this->Events)[name].count ++; } #ifdef SAVE_TIME_SERIES if(cont_mode_t == 0) { (this->Events)[name].time_series.push_back((this->Events)[name].ContiniousTime); (this->Events)[name].ContiniousTime = 0.0; } #endif } #endif else { 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; //printf("%e\n", main_elapsed); (this->Events)[name].elapsed_time += main_elapsed; (this->Events)[name].ContiniousTime += main_elapsed; if(cont_mode_t == 0) { (this->Events)[name].count ++; } #ifdef SAVE_TIME_SERIES if(cont_mode_t == 0) { (this->Events)[name].time_series.push_back((this->Events)[name].ContiniousTime); (this->Events)[name].ContiniousTime = 0.0; } #endif } } void Jikan::BarrierMPI() { #ifdef INCLUDE_MPI int init_flag, fin_flag; MPI_Initialized(&init_flag); MPI_Finalized(&fin_flag); if((!fin_flag) && init_flag) MPI_Barrier(MPI_COMM_WORLD); #endif } class Jikan Timer;