ExaFMM 1
Fast-multipole Method for exascale systems
include/logger.h
Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2011 by Rio Yokota, Simon Layton, Lorena Barba
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020 THE SOFTWARE.
00021 */
00022 #ifndef logger_h
00023 #define logger_h
00024 #include <sys/time.h>
00025 #include "types.h"
00026 
00027 //! Timer and Trace logger
00028 class Logger {
00029 private:
00030   std::ofstream   timerFile;                                    //!< File ID to store log
00031   Timer           beginTimer;                                   //!< Timer base value
00032   Timer           timer;                                        //!< Stores timings for all events
00033   Traces          traces;                                       //!< Stores traces for all events
00034   pthread_mutex_t mutex;                                        //!< Pthread communicator
00035 
00036 //! Timer function
00037   double get_time() const {
00038     struct timeval tv;                                          // Time value
00039     gettimeofday(&tv, NULL);                                    // Get time of day in seconds and microseconds
00040     return double(tv.tv_sec+tv.tv_usec*1e-6);                   // Combine seconds and microseconds and return
00041   }
00042 
00043 public:
00044   bool printNow;                                                //!< Switch to print timings
00045 
00046 //! Constructor
00047   Logger() {
00048     timerFile.open("time.dat");                                 // Open timer log file
00049     printNow = false;                                           // Don't print by default
00050     pthread_mutex_init(&mutex,NULL);                            // Initialize pthread communicator
00051   }
00052 //! Destructor
00053   ~Logger() {
00054     timerFile.close();                                          // Close timer log file
00055   }
00056 
00057 //! Start timer for given event
00058   inline void startTimer(std::string event) {
00059     beginTimer[event] = get_time();                             // Get time of day and store in beginTimer
00060   }
00061 
00062 //! Stop timer for given event
00063   inline double stopTimer(std::string event, bool print=false) {
00064     double endTimer = get_time();                               // Get time of day and store in endTimer
00065     timer[event] += endTimer - beginTimer[event];               // Accumulate event time to timer
00066     if(print) std::cout << event << " : " << timer[event] << std::endl;// Print event and timer to screen
00067     return endTimer - beginTimer[event];                        // Return the event time
00068   }
00069 
00070 //! Erase entry in timer
00071   inline void eraseTimer(std::string event) {
00072     timer.erase(event);                                         // Erase event from timer
00073   }
00074 
00075 //! Erase all events in timer
00076   inline void resetTimer() {
00077     timer.clear();                                              // Clear timer
00078   }
00079 
00080 //! Print timings of a specific event
00081   inline void printTime(std::string event) {
00082     std::cout << event << " : " << timer[event] << std::endl;   // Print event and timer
00083   }
00084 
00085 //! Print timings of all events
00086   inline void printAllTime() {
00087     for( TI_iter E=timer.begin(); E!=timer.end(); ++E ) {       // Loop over all events
00088       std::cout << E->first << " : " << E->second << std::endl; //  Print event and timer
00089     }                                                           // End loop over all events
00090   }
00091 
00092 //! Write timings of all events
00093   inline void writeTime() {
00094     for( TI_iter E=timer.begin(); E!=timer.end(); ++E ) {       // Loop over all events
00095       timerFile << E->first << " " << E->second << std::endl;   //  Print event and timer
00096     }                                                           // End loop over all events
00097   }
00098 
00099 //! Start tracer for given event
00100   inline void startTracer(ThreadTrace &beginTrace) {
00101     pthread_mutex_lock(&mutex);                                 // Lock shared variable access
00102     beginTrace[pthread_self()] = get_time();                    // Get time of day and store in beginTrace
00103     pthread_mutex_unlock(&mutex);                               // Unlock shared variable access
00104   }
00105 
00106 //! Stop tracer for given event
00107   inline void stopTracer(ThreadTrace &beginTrace, int color) {
00108     pthread_mutex_lock(&mutex);                                 // Lock shared variable access
00109     Trace trace;                                                // Define trace structure
00110     trace.thread = pthread_self();                              // Store pthread id
00111     trace.begin  = beginTrace[pthread_self()];                  // Store tic
00112     trace.end    = get_time();                                  // Store toc
00113     trace.color  = color;                                       // Store color of event
00114     traces.push(trace);                                         // Push trace to queue of traces
00115     pthread_mutex_unlock(&mutex);                               // Unlock shared variable access
00116   }
00117 
00118 //! Write traces of all events
00119   inline void writeTrace() {
00120     std::ofstream traceFile("trace.svg");                       // Open trace log file
00121     traceFile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" // Header statements for trace log file
00122         << "<!DOCTYPE svg PUBLIC \"-_W3C_DTD SVG 1.0_EN\" \"http://www.w3.org/TR/SVG/DTD/svg10.dtd\">\n"
00123         << "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
00124         << "  width=\"200mm\" height=\"40mm\" viewBox=\"0 0 20000 4000\">\n"
00125         << "  <g>\n";
00126     int num_thread = 0;                                         // Counter for number of threads to trace
00127     ThreadMap threadMap;                                        // Map pthread ID to thread ID
00128     double base = traces.front().begin;                         // Base time
00129     double scale = 30000.0;                                     // Scale the length of bar plots
00130     while( !traces.empty() ) {                                  // While queue of traces is not empty
00131       Trace trace = traces.front();                             //  Get trace at front of the queue
00132       traces.pop();                                             //  Pop trace at front
00133       pthread_t thread = trace.thread;                          //  Get pthread ID of trace
00134       double begin  = trace.begin;                              //  Get begin time of trace
00135       double end    = trace.end;                                //  Get end time of trace
00136       int    color  = trace.color;                              //  Get color of trace
00137       if( threadMap[thread] == 0 ) {                            //  If it's a new pthread ID
00138         threadMap[thread] = ++num_thread;                       //   Map it to an incremented thread ID
00139       }                                                         //  End if for new pthread ID
00140       begin -= base;                                            //  Subtract base time from begin time
00141       end   -= base;                                            //  Subtract base time from end time
00142       traceFile << "    <rect x=\"" << begin * scale            //  x position of bar plot
00143           << "\" y=\"" << (threadMap[thread] - 1) * 100.0       //  y position of bar plot
00144           << "\" width=\"" << (end - begin) * scale             //  width of bar
00145           << "\" height=\"90.0\" fill=\"#"<< std::setfill('0') << std::setw(6) << std::hex << color// height of bar
00146           << "\" stroke=\"#000000\" stroke-width=\"1\"/>\n";    //  stroke color and width
00147     }                                                           // End while loop for queue of traces
00148     traceFile << "  </g>\n" "</svg>\n";                         // Footer for trace log file 
00149     traceFile.close();                                          // Close trace log file
00150   }
00151 };
00152 
00153 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines