PULSAR  1.0.0
Parallel Ultra Light Systolic Array Runtime
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
svg_trace.c
Go to the documentation of this file.
1 
11 #include "svg_trace.h"
12 
13 static int eventNumCore [SVG_TRACE_MAX_CORES];
14 static double eventStartCore[SVG_TRACE_MAX_CORES][SVG_TRACE_MAX_EVENTS];
15 static double eventStopCore [SVG_TRACE_MAX_CORES][SVG_TRACE_MAX_EVENTS];
16 static int eventColorCore[SVG_TRACE_MAX_CORES][SVG_TRACE_MAX_EVENTS];
17 
19 
24 static double get_time_of_day()
25 {
26  struct timeval time_val;
27  struct timezone time_zone;
28  gettimeofday(&time_val, &time_zone);
29  return (double)(time_val.tv_sec) + (double)(time_val.tv_usec) / 1000000.0;
30 }
31 
33 
38 void svg_trace_init(int num_cores)
39 {
40  assert(num_cores <= SVG_TRACE_MAX_CORES);
41  assert(__builtin_popcount(SVG_TRACE_MAX_EVENTS) == 0x01);
42 }
43 
45 
50 void svg_trace_start(int thread_rank)
51 {
52  assert(thread_rank < SVG_TRACE_MAX_CORES);
53  eventStartCore[thread_rank][eventNumCore[thread_rank]] = get_time_of_day();
54 }
55 
57 
63 void svg_trace_stop(int thread_rank, int color)
64 {
65  assert(thread_rank < SVG_TRACE_MAX_CORES);
66  eventStopCore [thread_rank][eventNumCore[thread_rank]] = get_time_of_day();
67  eventColorCore[thread_rank][eventNumCore[thread_rank]] = color;
68  eventNumCore[thread_rank]++;
69  eventNumCore[thread_rank] &= (SVG_TRACE_MAX_EVENTS-1);
70 }
71 
73 
79 {
80  int mpi_rank;
81  int mpi_size;
82  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
83  MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
84 
85  int proc;
86  int core;
87  int event;
88  double max_time = 0.0;
89  for (core = 0; core < SVG_TRACE_MAX_CORES; core++) {
90  double time =
91  eventStopCore [core][eventNumCore[core]-1] -
92  eventStopCore[0][0];
93  if (time > max_time)
94  max_time = time;
95  }
96  double max_time_out;
97  MPI_Reduce(
98  &max_time, &max_time_out, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
99  double hscale = 2000.0 / max_time_out;
100 
101  int max_core_in = 0;
102  for (core = 0; core < SVG_TRACE_MAX_CORES; core++)
103  if (eventNumCore[core] > 1)
104  max_core_in = core;
105  int max_core;
106  MPI_Reduce(
107  &max_core_in, &max_core, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
108  double vscale = 1000.0 / ((max_core+1)*mpi_size);
109 
110  if (mpi_rank == 0) {
111  char trace_file_name[SVG_TRACE_FILE_NAME_SIZE];
112  sprintf(trace_file_name, "trace_%d.svg", (int)(time(NULL)));
113  FILE *trace_file = fopen(trace_file_name, "w");
114  assert(trace_file != NULL);
115  fprintf(trace_file,
116  "<svg width=\"200mm\" height=\"100mm\" viewBox=\"0 0 2000 1000\">\n"
117  " <g>\n");
118 
119  for (proc = 0; proc < mpi_size; proc++) {
120  if (proc > 0) {
121  MPI_Recv(
122  &eventNumCore[0],
123  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS, MPI_INT,
124  proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
125  MPI_Recv(
126  &eventStartCore[0][0],
127  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS, MPI_DOUBLE,
128  proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
129  MPI_Recv(
130  &eventStopCore[0][0],
131  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS, MPI_DOUBLE,
132  proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
133  MPI_Recv(
134  &eventColorCore[0][0],
135  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS, MPI_INT,
136  proc, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
137  }
138  for (core = 0; core < SVG_TRACE_MAX_CORES; core++) {
139  for (event = 0; event < eventNumCore[core]; event++) {
140  double start = eventStartCore[core][event] - eventStopCore[0][0];
141  double stop = eventStopCore [core][event] - eventStopCore[0][0];
142  double width = (stop-start) * hscale;
143  int color = eventColorCore[core][event];
144  int thread = proc*(max_core+1)+core;
145  fprintf(trace_file,
146  " "
147  "<rect x=\"%.2lf\" y=\"%.0lf\" width=\"%.2lf\" height=\"%.0lf\" "
148  "fill=\"#%06x\" stroke=\"#%06x\" stroke-width=\"1\"/>\n",
149  start * hscale,
150  thread * vscale,
151  width < 2.0 ? 2.0 : width,
152  vscale * 0.9,
153  abs(color),
154  color < 0 ? color : 0);
155  }
156  }
157  }
158  fprintf(trace_file,
159  " </g>\n"
160  "</svg>\n");
161  fclose(trace_file);
162  }
163  else {
164  MPI_Send(
165  &eventNumCore[0],
166  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS,
167  MPI_INT, 0, 0, MPI_COMM_WORLD);
168  MPI_Send(
169  &eventStartCore[0][0],
170  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS,
171  MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
172  MPI_Send(
173  &eventStopCore[0][0],
174  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS,
175  MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
176  MPI_Send(
177  &eventColorCore[0][0],
178  SVG_TRACE_MAX_CORES*SVG_TRACE_MAX_EVENTS,
179  MPI_INT, 0, 0, MPI_COMM_WORLD);
180  }
181 }
void svg_trace_init(int num_cores)
Initialize tracing.
Definition: svg_trace.c:38
#define SVG_TRACE_MAX_CORES
maximum values cores per node, events per core, maximum size of trace file name
Definition: svg_trace.h:29
#define SVG_TRACE_FILE_NAME_SIZE
Definition: svg_trace.h:31
void svg_trace_start(int thread_rank)
Start tracing an event.
Definition: svg_trace.c:50
SVG tracing.
void svg_trace_finish()
Finish tracing. Collect traces from all nodes. Write the combined trace to an SVG file...
Definition: svg_trace.c:78
void svg_trace_stop(int thread_rank, int color)
Stop tracing an event.
Definition: svg_trace.c:63
#define SVG_TRACE_MAX_EVENTS
Definition: svg_trace.h:30