Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/vis15/src/logging/lib/load-log.cxx
ViewVC logotype

Annotation of /branches/vis15/src/logging/lib/load-log.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4868 - (view) (download) (as text)

1 : jhr 4848 /*! \file load-log.cxx
2 :     *
3 :     * \author John Reppy
4 :     */
5 :    
6 :     /*
7 :     * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
8 :     *
9 :     * COPYRIGHT (c) 2016 The University of Chicago
10 :     * All rights reserved.
11 :     */
12 :    
13 :     #include "diderot/log-file.hxx"
14 :     #include "load-log.hxx"
15 :     #include <algorithm>
16 :     #include <cstdlib>
17 :     #include <fstream>
18 :     #include <iostream>
19 :     #include <sys/stat.h>
20 :    
21 :     // comparison fucntion for events. Returns true if ev1 < ev2 when ordered
22 :     // first by time stamps and then by worker ID.
23 :     //
24 :     static bool compare_events (event const &ev1, event const &ev2)
25 :     {
26 :     return (ev1._ts < ev2._ts) || ((ev1._ts == ev2._ts) && (ev1._worker < ev2._worker));
27 :     }
28 :    
29 :     // convert a timestamp to nanoseconds
30 :     //
31 :     inline uint64_t get_timestamp (int kind, diderot::log::time_stamp *ts)
32 :     {
33 :     if (kind == diderot::log::TS_MACH_ABSOLUTE)
34 :     return ts->_mach;
35 :     else if (kind == diderot::log::TS_TIMESPEC)
36 :     return ts->_tv._sec * 1000000000 + ts->_tv._frac;
37 :     else /* kind == diderot::log::TS_TIMEVAL */
38 :     return ts->_tv._sec * 1000000000 + ts->_tv._frac * 1000;
39 :     }
40 :    
41 :     // load a log file
42 :     //
43 :     log_file *load_log_file (std::string const &name)
44 :     {
45 :     // get the file size and compute the expected number
46 :     // of buffers.
47 :     int numBufs;
48 :     {
49 :     struct stat st;
50 :     if (stat(name.c_str(), &st) < 0) {
51 :     perror ("stat");
52 :     exit (1);
53 :     }
54 : jhr 4855 numBufs = (st.st_size - sizeof(diderot::log::file_hdr)) / sizeof(diderot::log::buffer);
55 :     if (st.st_size != sizeof(diderot::log::file_hdr) + numBufs * sizeof(diderot::log::buffer)) {
56 : jhr 4848 std::cerr << "Warning: log file size is not a whole number of buffers\n";
57 :     }
58 :     }
59 :    
60 :     // open the file
61 :     std::ifstream ins(name, std::ifstream::in | std::ifstream::binary);
62 : jhr 4855 if (ins.fail()) {
63 : jhr 4848 std::cerr << "Error: unable to open \"" << name << "\"\n";
64 :     exit (1);
65 :     }
66 :    
67 :     // read the header
68 :     diderot::log::file_hdr hdr;
69 :     ins.read (reinterpret_cast<char *>(&hdr), sizeof(hdr));
70 : jhr 4855 if (ins.fail()) {
71 : jhr 4848 std::cerr << "Error attempting to read header from \"" << name << "\"\n";
72 :     exit (1);
73 :     }
74 :    
75 :     // check the header
76 :     if (hdr._magic != diderot::log::file_hdr::MAGIC) {
77 :     std::cerr << "bogus magic number\n";
78 :     exit (1);
79 :     }
80 :     if (hdr._hdrSzB != sizeof(diderot::log::file_hdr)) {
81 :     std::cerr << "bogus header size " << hdr._hdrSzB << " (expected "
82 :     << sizeof(diderot::log::file_hdr) << ")\n";
83 :     exit (1);
84 :     }
85 :     if (hdr._version[0] != DIDEROT_LOG_VERSION_MAJOR) {
86 :     std::cerr << "wrong version = " << hdr._version[0] << "." << hdr._version[1]
87 :     << "." << hdr._version[2] << " (expected " << DIDEROT_LOG_VERSION_MAJOR << ".x.y)\n";
88 :     exit (1);
89 :     }
90 :     if (hdr._version[1] != 0) {
91 :     std::cerr << "fat-event format not supported\n";
92 :     exit (1);
93 :     }
94 :     if (hdr._bufSzB != diderot::log::buffer::SIZEB) {
95 :     std::cerr << "using different block size " << hdr._bufSzB << " (expected "
96 :     << diderot::log::buffer::SIZEB << ")\n";
97 :     exit (1);
98 :     }
99 :    
100 :     // compute an upper bound on the number of events in the file
101 :     uint64_t maxNumEvents = diderot::log::buffer::NUM_EVENTS * numBufs;
102 :    
103 :     // initialize the in-memory log file
104 :     log_file *log = new log_file;
105 :     log->_date = std::string(hdr._date, 32);
106 :     log->_clockName = std::string(hdr._clockName, 32);
107 :     log->_nNodes = hdr._nNodes;
108 :     log->_nCores = hdr._nCores;
109 :     log->_nWorkers = hdr._nWorkers;
110 :     log->_events.reserve (maxNumEvents);
111 :    
112 : jhr 4868 // track last timestamp per worker to detect anomolies
113 :     uint64_t lastTS[hdr._nWorkers];
114 :     for (int i = 0; i <= hdr._nWorkers; i++) {
115 :     lastTS[i] = 0;
116 :     }
117 :    
118 : jhr 4848 // read in the events
119 :     diderot::log::buffer buf;
120 :     uint64_t numEvents = 0;
121 :     for (int i = 0; i < numBufs; i++) {
122 :     ins.read (reinterpret_cast<char *>(&buf), sizeof(buf));
123 : jhr 4855 if (ins.fail()) {
124 : jhr 4848 std::cerr << "Error attempting to read buffer from \"" << name << "\"\n";
125 :     exit (1);
126 :     }
127 :     if (buf._next > diderot::log::buffer::NUM_EVENTS)
128 :     buf._next = diderot::log::buffer::NUM_EVENTS;
129 :     uint16_t worker = buf._worker;
130 :     if (log->_nWorkers < worker) {
131 :     std::cerr << "invalid worker ID " << worker << " for buffer (expected 0.."
132 :     << log->_nWorkers << ")\n";
133 :     exit (1);
134 :     }
135 :     for (int j = 0; j < buf._next; j++, numEvents++) {
136 :     diderot::log::event *ep = &(buf._log[j]);
137 : jhr 4868 uint64_t ts = get_timestamp(hdr._tsKind, &(ep->_ts));
138 :     if (ts < lastTS[worker]) {
139 :     std::cerr << "warning: timestamp for worker " << worker
140 :     << "; event #" << j << "(=" << ep->_event << ") occurs "
141 :     << lastTS[worker]-ts << "ns too early\n";
142 :     }
143 :     lastTS[worker] = ts;
144 :     log->_events.push_back (event (ts, worker, ep->_event, ep->_strand));
145 : jhr 4848 }
146 :     }
147 :     ins.close();
148 :    
149 : jhr 4853 if (numEvents == 0) {
150 :     return log;
151 :     }
152 :    
153 : jhr 4848 // sort the events by <timestamp, worker-id>
154 :     std::sort (log->_events.begin(), log->_events.end(), compare_events);
155 :    
156 :     // Adjust the timestamps to be relative to the start of the run
157 :     uint64_t startTime = get_timestamp (hdr._tsKind, &(hdr._startTime));
158 :     if (log->_events[0]._ts < startTime) {
159 :     std::cerr << "Warning: first event occurs " << (startTime - log->_events[0]._ts)
160 :     << " ns. before start time\n";
161 :     startTime = log->_events[0]._ts;
162 :     }
163 :     for (auto it = log->_events.begin(); it != log->_events.end(); ++it) {
164 :     it->_ts -= startTime;
165 :     }
166 :    
167 :     return log;
168 :    
169 :     }

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0