ExaFMM 1
Fast-multipole Method for exascale systems
|
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