HPCToolkit
TraceDataByRank.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL: https://hpctoolkit.googlecode.com/svn/branches/hpctoolkit-hpcserver/src/tool/hpcserver/TraceDataByRank.cpp $
6 // $Id: TraceDataByRank.cpp 4307 2013-07-18 17:04:52Z felipet1326@gmail.com $
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL: https://hpctoolkit.googlecode.com/svn/branches/hpctoolkit-hpcserver/src/tool/hpcserver/TraceDataByRank.cpp $
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 #include "TraceDataByRank.hpp"
61 #include <algorithm>
62 #include <cstdlib> // previously: cmath but it causes ambuguity in abs function for gcc 4.4.6
63 #include "Constants.hpp"
64 #include <iostream>
65 
66 namespace TraceviewerServer
67 {
68 
70  int _numPixelH, int _headerSize)
71  {
72  data = _data;
73  rank = _rank;
74  //OffsetPair* offsets = data->getOffsets();
77  numPixelsH = _numPixelH;
78 
79 
80  listCPID = new vector<TimeCPID>();
81 
82  }
83  void TraceDataByRank::getData(Time timeStart, Time timeRange,
84  double pixelLength)
85  {
86  // get the start location
87  FileOffset startLoc = findTimeInInterval(timeStart, minloc, maxloc);
88 
89  // get the end location
90  Time endTime = timeStart + timeRange;
91  FileOffset endLoc = min(
93 
94  // get the number of records data to display
95  Long numRec = 1 + getNumberOfRecords(startLoc, endLoc);
96 
97  // --------------------------------------------------------------------------------------------------
98  // if the data-to-display is fit in the display zone, we don't need to use recursive binary search
99  // we just simply display everything from the file
100  // --------------------------------------------------------------------------------------------------
101  if (numRec <= numPixelsH)
102  {
103  // display all the records
104  for (FileOffset i = startLoc; i <= endLoc;)
105  {
106  listCPID->push_back(getData(i));
107  // one record of data contains of an integer (cpid) and a long (time)
108  i = i + SIZE_OF_TRACE_RECORD;
109  }
110  }
111  else
112  {
113  // the data is too big: try to fit the "big" data into the display
114 
115  //fills in the rest of the data for this process timeline
116  sampleTimeLine(startLoc, endLoc, 0, numPixelsH, 0, pixelLength, timeStart);
117  }
118  // --------------------------------------------------------------------------------------------------
119  // get the last data if necessary: the rightmost time is still less then the upper limit
120  // I think we can add the rightmost data into the list of samples
121  // --------------------------------------------------------------------------------------------------
122  if (endLoc < maxloc)
123  {
124  TimeCPID dataLast = getData(endLoc);
125  addSample(listCPID->size(), dataLast);
126  }
127 
128  // --------------------------------------------------------------------------------------------------
129  // get the first data if necessary: the leftmost time is still bigger than the lower limit
130  // similarly, we add to the list
131  // --------------------------------------------------------------------------------------------------
132  if (startLoc > minloc)
133  {
134  TimeCPID dataFirst = getData(startLoc - SIZE_OF_TRACE_RECORD);
135  addSample(0, dataFirst);
136  }
137  postProcess();
138  }
139  /*******************************************************************************************
140  * Recursive method that fills in times and timeLine with the correct data from the file.
141  * Takes in two pixel locations as endpoints and finds the timestamp that owns the pixel
142  * in between these two. It then recursively calls itself twice - once with the beginning
143  * location and the newfound location as endpoints and once with the newfound location
144  * and the end location as endpoints. Effectively updates times and timeLine by calculating
145  * the index in which to insert the next data. This way, it keeps times and timeLine sorted.
146  * @author Reed Landrum and Michael Franco
147  * @param minLoc The beginning location in the file to bound the search.
148  * @param maxLoc The end location in the file to bound the search.
149  * @param startPixel The beginning pixel in the image that corresponds to minLoc.
150  * @param endPixel The end pixel in the image that corresponds to maxLoc.
151  * @param minIndex An index used for calculating the index in which the data is to be inserted.
152  * @return Returns the index that shows the size of the recursive subtree that has been read.
153  * Used for calculating the index in which the data is to be inserted.
154  ******************************************************************************************/
155  int TraceDataByRank::sampleTimeLine(FileOffset minLoc, FileOffset maxLoc, int startPixel,
156  int endPixel, int minIndex, double pixelLength, Time startingTime)
157  {
158  int midPixel = (startPixel + endPixel) / 2;
159  if (midPixel == startPixel)
160  return 0;
161 
162  Long loc = findTimeInInterval((long)(midPixel * pixelLength + startingTime), minLoc,
163  maxLoc);
164  TimeCPID nextData = getData(loc);
165  addSample(minIndex, nextData);
166  int addedLeft = sampleTimeLine(minLoc, loc, startPixel, midPixel, minIndex,
167  pixelLength, startingTime);
168  int addedRight = sampleTimeLine(loc, maxLoc, midPixel, endPixel,
169  minIndex + addedLeft + 1, pixelLength, startingTime);
170 
171  return (addedLeft + addedRight + 1);
172  }
173 
174 
175  /*********************************************************************************
176  * Returns the location in the traceFile of the trace data (time stamp and cpid)
177  * Precondition: the location of the trace data is between minLoc and maxLoc.
178  * @param time: the time to be found
179  * @param left_boundary_offset: the start location. 0 means the beginning of the data in a process
180  * @param right_boundary_offset: the end location.
181  ********************************************************************************/
183  FileOffset r_boundOffset)
184  {
185  if (l_boundOffset == r_boundOffset)
186  return l_boundOffset;
187 
188 
189 
190  FileOffset l_index = getRelativeLocation(l_boundOffset);
191  FileOffset r_index = getRelativeLocation(r_boundOffset);
192 
193  Time l_time = data->getLong(l_boundOffset);
194  Time r_time = data->getLong(r_boundOffset);
195 
196  // apply "Newton's method" to find target time
197  while (r_index - l_index > 1)
198  {
199  FileOffset predicted_index;
200  //pat2 7/1/13: We only ever divide by rate, and double multiplication
201  //is faster than division (confirmed with a benchmark) so compute inverse
202  //rate instead. This line of code and the one in the else block account for
203  //about 40% of the computation once the data is in memory
204  //double rate = (r_time - l_time) / (r_index - l_index);
205  double invrate = (r_index - l_index) / (r_time - l_time);
206  Time mtime = (r_time - l_time) / 2;
207  if (time <= mtime)
208  {
209  predicted_index = max((Long) ((time - l_time) * invrate) + l_index, l_index);
210  }
211  else
212  {
213  predicted_index = min((r_index - (long) ((r_time - time) * invrate)), r_index);
214  }
215  // adjust so that the predicted index differs from both ends
216  // except in the case where the interval is of length only 1
217  // this helps us achieve the convergence condition
218  if (predicted_index <= l_index)
219  predicted_index = l_index + 1;
220  if (predicted_index >= r_index)
221  predicted_index = r_index - 1;
222 
223  Time temp = data->getLong(getAbsoluteLocation(predicted_index));
224  if (time >= temp)
225  {
226  l_index = predicted_index;
227  l_time = temp;
228  }
229  else
230  {
231  r_index = predicted_index;
232  r_time = temp;
233  }
234  }
235  FileOffset l_offset = getAbsoluteLocation(l_index);
236  FileOffset r_offset = getAbsoluteLocation(r_index);
237 
238  l_time = data->getLong(l_offset);
239  r_time = data->getLong(r_offset);
240 
241  int leftDiff = time - l_time;
242  int rightDiff = r_time - time;
243  bool is_left_closer = abs(leftDiff) < abs(rightDiff);
244  if (is_left_closer)
245  return l_offset;
246  else if (r_offset < maxloc)
247  return r_offset;
248  else
249  return maxloc;
250  }
252  {
253  return minloc + (relativePosition * SIZE_OF_TRACE_RECORD);
254  }
255 
257  {
258  return (absolutePosition - minloc) / SIZE_OF_TRACE_RECORD;
259  }
260  void TraceDataByRank::addSample(unsigned int index, TimeCPID dataCpid)
261  {
262  if (index == listCPID->size())
263  {
264  listCPID->push_back(dataCpid);
265  }
266  else
267  {
268  vector<TimeCPID>::iterator it = listCPID->begin();
269  it += index;
270  listCPID->insert(it, dataCpid);
271  }
272  }
273 
275  {
276 
277  Time time = data->getLong(location);
278  int CPID = data->getInt(location + SIZEOF_LONG);
279  TimeCPID ToReturn(time, CPID);
280  return ToReturn;
281  }
282 
284  {
285  return (end - start) / SIZE_OF_TRACE_RECORD;
286  }
287 
288  /*********************************************************************************************
289  * Removes unnecessary samples:
290  ********************************************************************************************/
291 
293  {
294  int len = listCPID->size();
295  for (int i = 0; i < len - 2; i++)
296  {
297 
298  while (i < len - 1 && (*listCPID)[i].timestamp == (*listCPID)[i + 1].timestamp)
299  {
300  vector<TimeCPID>::iterator it = listCPID->begin();
301  it += (i + 1);
302  listCPID->erase(it);
303  len--;
304  }
305 
306  }
307  }
308 
310  {
311  listCPID->clear();
312  delete listCPID;
313  }
314 
315 } /* namespace TraceviewerServer */
#define SIZEOF_LONG
Definition: Constants.hpp:66
int64_t getLong(FileOffset position)
FileOffset getRelativeLocation(FileOffset)
FileOffset getAbsoluteLocation(FileOffset)
void addSample(unsigned int, TimeCPID)
void getData(Time timeStart, Time timeRange, double pixelLength)
FileOffset getMaxLoc(int pseudoRank)
#define SIZE_OF_TRACE_RECORD
Definition: Constants.hpp:74
int sampleTimeLine(FileOffset minLoc, FileOffset maxLoc, int startPixel, int endPixel, int minIndex, double pixelLength, Time startingTime)
uint64_t FileOffset
Definition: FileUtils.hpp:78
Long getNumberOfRecords(FileOffset, FileOffset)
FileOffset getMinLoc(int pseudoRank)
FileOffset findTimeInInterval(Time time, FileOffset l_boundOffset, FileOffset r_boundOffset)
TraceDataByRank(FilteredBaseData *, int, int, int)