Skip to content
Snippets Groups Projects
JikanDepths.cpp 8.36 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "Jikan.h"
    
    数学の武士's avatar
    数学の武士 committed
    #include "JikanDepths.h"
    #include "ToJSON.h"
    
    #include <iostream>
    #include <map>
    #include <string>
    
    
    #ifdef INCLUDE_OPEN_MP
    #include <omp.h>
    #endif
    
    using namespace std;
    
    数学の武士's avatar
    数学の武士 committed
    
    Jikan::Jikan()
    {
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp master
        {
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
            this->EventType["Synchronous events"] = set<string>();
            this->EventType["Asynchronous events"] = set<string>();
    
            this->JSONname = OUTPUT_NAME + string(".json");
            this->JSONdata = "";
            this->Error = "";
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
    数学の武士's avatar
    数学の武士 committed
    };
    
    #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()
    {
        return true;
    }
    
    
    数学の武士's avatar
    数学の武士 committed
    Jikan::~Jikan()
    {
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp master
        {
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
            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();
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
    数学の武士's avatar
    数学の武士 committed
    }
    
    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::JikanStart(const string& name, const int& mode)
    
        bool ExistFlag, ifMPI, ifOpenMP;
    
    数学の武士's avatar
    数学の武士 committed
        ExistFlag = this->ifContains(name);
    
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp master
        {
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
            (this->Events)[name].ifStart = true;
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
    数学の武士's avatar
    数学の武士 committed
            #ifdef INCLUDE_OPEN_MP
    
            #pragma omp master
            {
    
    数学の武士's avatar
    数学の武士 committed
            #endif
    
                (this->Events)[name] = EventData(name);
                (this->Events)[name].GetModeVals(mode);
    
    数学の武士's avatar
    数学の武士 committed
            #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
            #endif
    
    数学の武士's avatar
    数学の武士 committed
        // else
        // {
        //     bool ifStart = (this->Events)[name].ifStart;
    
    数学の武士's avatar
    数学の武士 committed
        //     if(!ifStart)
        //         return;
        // }
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp barrier
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
    
        ifMPI = (this->Events)[name].mode[0], ifOpenMP = (this->Events)[name].mode[1];
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp master
        {
    
    数学の武士's avatar
    数学の武士 committed
        #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();
            //---------------------------------------------------------------------------------------
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
        //--------------------------- OpenMP synchronization --------------------------------
        if(ifOpenMP)
    
    数学の武士's avatar
    数学の武士 committed
            #ifdef INCLUDE_OPEN_MP
            #pragma omp barrier
            #endif
    
        //-----------------------------------------------------------------------------------
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp master
        {
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
    数学の武士's avatar
    数学の武士 committed
            this->StartEvent(name);
    
    数学の武士's avatar
    数学の武士 committed
         #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
    void Jikan::JikanEnd(const string& name)
    
    数学の武士's avatar
    数学の武士 committed
        bool ExistFlag, ifStart;
    
        bool ifMPI, ifOpenMP, ifCUDA;
    
    
    数学の武士's avatar
    数学の武士 committed
        ExistFlag = this->ifContains(name);
        ifStart = (this->Events)[name].ifStart;
    
        if((!ExistFlag) || (!ifStart))
            return;
    
    
        ifMPI = (this->Events)[name].mode[0], ifOpenMP = (this->Events)[name].mode[1], ifCUDA = (this->Events)[name].mode[2];
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp master
        {
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
            if((ifCUDA) && (!ifMPI) && (!ifOpenMP))
            {    
                #ifdef INCLUDE_GPU_TIMER
    
                    this->EndCUDASync(name);
                    this->CUDAGetTime(name);
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
        //--------------------------- OpenMP synchronization --------------------------------
        if(ifOpenMP)
        {
    
    数学の武士's avatar
    数学の武士 committed
            #ifdef INCLUDE_OPEN_MP
            #pragma omp barrier
            #endif
    
        }
        //-----------------------------------------------------------------------------------
    
        //--------------------------- MPI synchronization ---------------------------------------
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
        #pragma omp master
        {
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
            if(ifMPI)
                this->BarrierMPI();
    
            (this->Events)[name].ifStart = false;
    
    
    数学の武士's avatar
    数学の武士 committed
            this->EndEvent(name);
    
    数学の武士's avatar
    数学の武士 committed
        #ifdef INCLUDE_OPEN_MP
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
        //---------------------------------------------------------------------------------------
    
    数学の武士's avatar
    数学の武士 committed
    }
    
    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;
        }
    
    void Jikan::SetDumpFilename(const string& name)
    {
        this->JSONname = name;
    }
    
    
    数学の武士's avatar
    数学の武士 committed
    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
    
                this->StartCUDASync(name);
    
            #endif
        }
    
        #ifdef INCLUDE_OPEN_MP
            else if( (!ifMPI) && (ifOpenMP) )
                (this->Events)[name].double_start = omp_get_wtime();
    
    数学の武士's avatar
    数学の武士 committed
        #endif
    
    
        else
            (this->Events)[name].start = chrono::steady_clock::now();
    
    数学の武士's avatar
    数学の武士 committed
    void Jikan::EndEvent(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
    
                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].count ++;
    
                #ifdef SAVE_TIME_SERIES
                    (this->Events)[name].time_series.push_back(main_elapsed);
                #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;
    
            (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
        }
    }
    
    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;