1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 #include "trace_impl.h"
7 #include "rlog.h"
8 #ifdef HAVE_STDLIB_H
9 #include <stdlib.h>
10 #endif
11 #ifdef HAVE_CTYPE_H
12 #include <ctype.h>
13 #endif
14 #ifdef HAVE_STRING_H
15 #include <string.h>
16 #endif
17 #include "trace_API.h"
18 #include "mpir_mem.h"
19
20 #define TRACEINPUT_SUCCESS 0
21 #define TRACEINPUT_FAIL -1
22
23 #define INVALID_EVENT -1
24
25 typedef struct _trace_file {
26 RLOG_IOStruct *pInput;
27 RLOG_STATE state;
28 RLOG_ARROW arrow;
29 RLOG_BOOL bArrowAvail;
30 RLOG_EVENT **ppEvent;
31 RLOG_BOOL **ppEventAvail;
32 } _trace_file;
33
PackQuadChar(char * str,int * length,char * base,int * pos,const int max)34 RLOG_BOOL PackQuadChar(char *str, int *length, char *base, int *pos, const int max)
35 {
36 /* Am I supposed to include the terminating NULL character? */
37 /* This function does not. */
38 if (*pos + (int) strlen(str) > max)
39 return FALSE;
40 *length = strlen(str);
41 memcpy(&base[*pos], str, *length);
42 *pos += *length;
43 return TRUE;
44 }
45
PackQuadInt(int n1,int n2,int * length,int * base,int * pos,const int max)46 RLOG_BOOL PackQuadInt(int n1, int n2, int *length, int *base, int *pos, const int max)
47 {
48 if (*pos + 2 > max)
49 return FALSE;
50 *length = 2;
51 base[*pos] = n1;
52 base[*pos + 1] = n2;
53 *pos += 2;
54 return TRUE;
55 }
56
PackQuadDouble(double d1,double d2,int * length,double * base,int * pos,const int max)57 RLOG_BOOL PackQuadDouble(double d1, double d2, int *length, double *base, int *pos, const int max)
58 {
59 if (*pos + 2 > max)
60 return FALSE;
61 *length = 2;
62 base[*pos] = d1;
63 base[*pos + 1] = d2;
64 *pos += 2;
65 return TRUE;
66 }
67
TRACE_Open(const char filespec[],TRACE_file * fp)68 TRACE_EXPORT int TRACE_Open(const char filespec[], TRACE_file * fp)
69 {
70 int i, j;
71 RLOG_IOStruct *pInput;
72
73 if (filespec == NULL || fp == NULL)
74 return TRACEINPUT_FAIL;
75
76 if (strcmp(filespec, "-h") == 0) {
77 *fp = NULL;
78 return TRACEINPUT_SUCCESS;
79 }
80
81 *fp = (_trace_file *) MPL_malloc(sizeof(_trace_file), MPL_MEM_DEBUG);
82 if (*fp == NULL)
83 return TRACEINPUT_FAIL;
84
85 (*fp)->pInput = pInput = RLOG_CreateInputStruct(filespec);
86 if (pInput == NULL) {
87 MPL_free(*fp);
88 *fp = NULL;
89 return TRACEINPUT_FAIL;
90 }
91
92 (*fp)->bArrowAvail = (RLOG_GetNextArrow(pInput, &(*fp)->arrow) == 0);
93 if (pInput->nNumRanks > 0) {
94 (*fp)->ppEvent =
95 (RLOG_EVENT **) MPL_malloc(sizeof(RLOG_EVENT *) * pInput->nNumRanks, MPL_MEM_DEBUG);
96 (*fp)->ppEventAvail = (int **) MPL_malloc(sizeof(int *) * pInput->nNumRanks, MPL_MEM_DEBUG);
97
98 for (i = 0; i < pInput->nNumRanks; i++) {
99 if (pInput->pNumEventRecursions[i] > 0) {
100 (*fp)->ppEvent[i] =
101 (RLOG_EVENT *) MPL_malloc(sizeof(RLOG_EVENT) * pInput->pNumEventRecursions[i],
102 MPL_MEM_DEBUG);
103 (*fp)->ppEventAvail[i] =
104 (int *) MPL_malloc(sizeof(int) * pInput->pNumEventRecursions[i], MPL_MEM_DEBUG);
105 } else {
106 (*fp)->ppEvent[i] = NULL;
107 (*fp)->ppEventAvail[i] = NULL;
108 }
109 }
110 } else {
111 (*fp)->ppEvent = NULL;
112 (*fp)->ppEventAvail = NULL;
113 }
114 for (j = 0; j < pInput->nNumRanks; j++) {
115 for (i = 0; i < pInput->pNumEventRecursions[j]; i++) {
116 (*fp)->ppEventAvail[j][i] =
117 (RLOG_GetNextEvent(pInput, j + pInput->header.nMinRank, i, &(*fp)->ppEvent[j][i]) ==
118 0);
119 }
120 }
121 return TRACEINPUT_SUCCESS;
122 }
123
TRACE_Close(TRACE_file * fp)124 TRACE_EXPORT int TRACE_Close(TRACE_file * fp)
125 {
126 int i;
127
128 if (*fp == NULL)
129 return TRACEINPUT_SUCCESS;
130
131 if ((*fp)->pInput) {
132 for (i = 0; i < (*fp)->pInput->nNumRanks; i++) {
133 MPL_free((*fp)->ppEvent[i]);
134 MPL_free((*fp)->ppEventAvail[i]);
135 }
136 RLOG_CloseInputStruct(&(*fp)->pInput);
137 }
138 MPL_free((*fp)->ppEvent);
139 MPL_free((*fp)->ppEventAvail);
140 MPL_free((*fp));
141 *fp = NULL;
142
143 return TRACEINPUT_SUCCESS;
144 }
145
TRACE_Peek_next_kind(const TRACE_file fp,TRACE_Rec_Kind_t * next_kind)146 TRACE_EXPORT int TRACE_Peek_next_kind(const TRACE_file fp, TRACE_Rec_Kind_t * next_kind)
147 {
148 int i, j;
149
150 *next_kind = TRACE_EOF;
151 if (fp->pInput->nCurState < fp->pInput->nNumStates) {
152 *next_kind = TRACE_CATEGORY;
153 return TRACEINPUT_SUCCESS;
154 }
155
156 for (j = 0; j < fp->pInput->nNumRanks; j++) {
157 for (i = 0; i < fp->pInput->pNumEventRecursions[j]; i++) {
158 if (fp->ppEventAvail[j][i]) {
159 *next_kind = TRACE_PRIMITIVE_DRAWABLE;
160 return TRACEINPUT_SUCCESS;
161 }
162 }
163 }
164 if (fp->bArrowAvail) {
165 *next_kind = TRACE_PRIMITIVE_DRAWABLE;
166 return TRACEINPUT_SUCCESS;
167 }
168
169 return TRACEINPUT_SUCCESS;
170 }
171
TRACE_Get_next_method(const TRACE_file fp,char method_name[],char method_extra[],int * methodID)172 TRACE_EXPORT int TRACE_Get_next_method(const TRACE_file fp,
173 char method_name[], char method_extra[], int *methodID)
174 {
175 return TRACEINPUT_FAIL;
176 }
177
TRACE_Peek_next_category(const TRACE_file fp,int * n_legend,int * n_label,int * n_methodIDs)178 TRACE_EXPORT int TRACE_Peek_next_category(const TRACE_file fp,
179 int *n_legend, int *n_label, int *n_methodIDs)
180 {
181 if (fp->pInput->nCurState >= fp->pInput->nNumStates)
182 return TRACEINPUT_FAIL;
183
184 if (RLOG_GetNextState(fp->pInput, &fp->state) != 0)
185 return TRACEINPUT_FAIL;
186 *n_legend = strlen(fp->state.description) + 1;
187 *n_label = 0;
188 *n_methodIDs = 0;
189
190 return TRACEINPUT_SUCCESS;
191 }
192
TRACE_Get_next_category(const TRACE_file fp,TRACE_Category_head_t * head,int * n_legend,char legend_base[],int * legend_pos,const int legend_max,int * n_label,char label_base[],int * label_pos,const int label_max,int * n_methodIDs,int methodID_base[],int * methodID_pos,const int methodID_max)193 TRACE_EXPORT int TRACE_Get_next_category(const TRACE_file fp,
194 TRACE_Category_head_t * head,
195 int *n_legend, char legend_base[],
196 int *legend_pos, const int legend_max,
197 int *n_label, char label_base[],
198 int *label_pos, const int label_max,
199 int *n_methodIDs, int methodID_base[],
200 int *methodID_pos, const int methodID_max)
201 {
202 char *pColorStr = fp->state.color;
203
204 head->index = fp->state.event;
205 while (isspace(*pColorStr))
206 pColorStr++;
207 head->red = atoi(pColorStr);
208 while (!isspace(*pColorStr))
209 pColorStr++;
210 while (isspace(*pColorStr))
211 pColorStr++;
212 head->green = atoi(pColorStr);
213 while (!isspace(*pColorStr))
214 pColorStr++;
215 while (isspace(*pColorStr))
216 pColorStr++;
217 head->blue = atoi(pColorStr);
218 head->alpha = 255;
219 if (fp->state.event == RLOG_ARROW_EVENT_ID)
220 head->shape = TRACE_SHAPE_ARROW;
221 else
222 head->shape = TRACE_SHAPE_STATE;
223 head->width = 1;
224
225 if (!PackQuadChar(fp->state.description, n_legend, legend_base, legend_pos, legend_max))
226 return TRACEINPUT_FAIL;
227
228 *n_label = 0;
229 *n_methodIDs = 0;
230
231 return TRACEINPUT_SUCCESS;
232 }
233
TRACE_Peek_next_ycoordmap(TRACE_file fp,int * n_rows,int * n_columns,int * max_column_name,int * max_title_name,int * n_methodIDs)234 TRACE_EXPORT int TRACE_Peek_next_ycoordmap(TRACE_file fp,
235 int *n_rows, int *n_columns,
236 int *max_column_name,
237 int *max_title_name, int *n_methodIDs)
238 {
239 return TRACEINPUT_FAIL;
240 }
241
TRACE_Get_next_ycoordmap(TRACE_file fp,char * title_name,char ** column_names,int * coordmap_sz,int coordmap_base[],int * coordmap_pos,const int coordmap_max,int * n_methodIDs,int methodID_base[],int * methodID_pos,const int methodID_max)242 TRACE_EXPORT int TRACE_Get_next_ycoordmap(TRACE_file fp,
243 char *title_name,
244 char **column_names,
245 int *coordmap_sz, int coordmap_base[],
246 int *coordmap_pos, const int coordmap_max,
247 int *n_methodIDs, int methodID_base[],
248 int *methodID_pos, const int methodID_max)
249 {
250 return TRACEINPUT_FAIL;
251 }
252
TRACE_Peek_next_primitive(const TRACE_file fp,double * starttime,double * endtime,int * n_tcoords,int * n_ycoords,int * n_bytes)253 TRACE_EXPORT int TRACE_Peek_next_primitive(const TRACE_file fp,
254 double *starttime, double *endtime,
255 int *n_tcoords, int *n_ycoords, int *n_bytes)
256 {
257 int i, j, rank = -1, level = -1;
258 double dmin;
259 RLOG_BOOL done = FALSE;
260
261 *n_tcoords = 2;
262 *n_ycoords = 2;
263 *n_bytes = 0;
264
265 for (j = 0; j < fp->pInput->nNumRanks && !done; j++) {
266 for (i = 0; i < fp->pInput->pNumEventRecursions[j] && !done; i++) {
267 if (fp->ppEventAvail[j][i]) {
268 level = i;
269 rank = j;
270 dmin = fp->ppEvent[j][i].end_time;
271 done = TRUE;
272 }
273 }
274 }
275 if (level == -1) {
276 if (!fp->bArrowAvail)
277 return TRACEINPUT_FAIL;
278 *starttime = fp->arrow.start_time;
279 *endtime = fp->arrow.end_time;
280 return TRACEINPUT_SUCCESS;
281 }
282 for (j = 0; j < fp->pInput->nNumRanks; j++) {
283 for (i = 0; i < fp->pInput->pNumEventRecursions[j]; i++) {
284 if (fp->ppEventAvail[j][i]) {
285 if (fp->ppEvent[j][i].end_time < dmin) {
286 level = i;
287 rank = j;
288 dmin = fp->ppEvent[j][i].end_time;
289 }
290 }
291 }
292 }
293 if (fp->bArrowAvail) {
294 if (fp->arrow.end_time < dmin) {
295 *starttime = fp->arrow.start_time;
296 *endtime = fp->arrow.end_time;
297 return TRACEINPUT_SUCCESS;
298 }
299 }
300 *starttime = fp->ppEvent[rank][level].start_time;
301 *endtime = fp->ppEvent[rank][level].end_time;
302
303 return TRACEINPUT_SUCCESS;
304 }
305
TRACE_Get_next_primitive(const TRACE_file fp,int * category_index,int * n_tcoords,double tcoord_base[],int * tcoord_pos,const int tcoord_max,int * n_ycoords,int ycoord_base[],int * ycoord_pos,const int ycoord_max,int * n_bytes,char byte_base[],int * byte_pos,const int byte_max)306 TRACE_EXPORT int TRACE_Get_next_primitive(const TRACE_file fp,
307 int *category_index,
308 int *n_tcoords, double tcoord_base[],
309 int *tcoord_pos, const int tcoord_max,
310 int *n_ycoords, int ycoord_base[],
311 int *ycoord_pos, const int ycoord_max,
312 int *n_bytes, char byte_base[],
313 int *byte_pos, const int byte_max)
314 {
315 int i, j, rank = 1, level = -1;
316 double dmin;
317 RLOG_BOOL done = FALSE;
318
319 *n_bytes = 0;
320
321 for (j = 0; j < fp->pInput->nNumRanks; j++) {
322 for (i = 0; i < fp->pInput->pNumEventRecursions[j]; i++) {
323 if (fp->ppEventAvail[j][i]) {
324 level = i;
325 rank = j;
326 dmin = fp->ppEvent[j][i].end_time;
327 break;
328 }
329 }
330 }
331 if (level == -1) {
332 if (!fp->bArrowAvail)
333 return TRACEINPUT_FAIL;
334 *category_index = RLOG_ARROW_EVENT_ID;
335 if (fp->arrow.leftright == RLOG_ARROW_RIGHT) {
336 PackQuadDouble(fp->arrow.start_time,
337 fp->arrow.end_time, n_tcoords, tcoord_base, tcoord_pos, tcoord_max);
338 } else {
339 PackQuadDouble(fp->arrow.end_time,
340 fp->arrow.start_time, n_tcoords, tcoord_base, tcoord_pos, tcoord_max);
341 }
342 PackQuadInt(fp->arrow.src, fp->arrow.dest, n_ycoords, ycoord_base, ycoord_pos, ycoord_max);
343 fp->bArrowAvail = (RLOG_GetNextArrow(fp->pInput, &fp->arrow) == 0);
344 return TRACEINPUT_SUCCESS;
345 }
346 for (j = 0; j < fp->pInput->nNumRanks; j++) {
347 for (i = 0; i < fp->pInput->pNumEventRecursions[j]; i++) {
348 if (fp->ppEventAvail[j][i]) {
349 if (fp->ppEvent[j][i].end_time < dmin) {
350 level = i;
351 rank = j;
352 dmin = fp->ppEvent[j][i].end_time;
353 }
354 }
355 }
356 }
357 if (fp->bArrowAvail) {
358 if (fp->arrow.end_time < dmin) {
359 *category_index = RLOG_ARROW_EVENT_ID;
360 if (fp->arrow.leftright == RLOG_ARROW_RIGHT) {
361 PackQuadDouble(fp->arrow.start_time,
362 fp->arrow.end_time, n_tcoords, tcoord_base, tcoord_pos, tcoord_max);
363 } else {
364 PackQuadDouble(fp->arrow.end_time,
365 fp->arrow.start_time,
366 n_tcoords, tcoord_base, tcoord_pos, tcoord_max);
367 }
368 PackQuadInt(fp->arrow.src,
369 fp->arrow.dest, n_ycoords, ycoord_base, ycoord_pos, ycoord_max);
370 fp->bArrowAvail = (RLOG_GetNextArrow(fp->pInput, &fp->arrow) == 0);
371 return TRACEINPUT_SUCCESS;
372 }
373 }
374 *category_index = fp->ppEvent[rank][level].event;
375 PackQuadDouble(fp->ppEvent[rank][level].start_time,
376 fp->ppEvent[rank][level].end_time,
377 n_tcoords, tcoord_base, tcoord_pos, tcoord_max);
378 PackQuadInt(fp->ppEvent[rank][level].rank,
379 fp->ppEvent[rank][level].rank, n_ycoords, ycoord_base, ycoord_pos, ycoord_max);
380 fp->ppEventAvail[rank][level] =
381 (RLOG_GetNextEvent(fp->pInput,
382 rank + fp->pInput->header.nMinRank,
383 level, &fp->ppEvent[rank][level]) == 0);
384
385 return TRACEINPUT_SUCCESS;
386 }
387
TRACE_Peek_next_composite(const TRACE_file fp,double * starttime,double * endtime,int * n_primitives,int * n_bytes)388 TRACE_EXPORT int TRACE_Peek_next_composite(const TRACE_file fp,
389 double *starttime, double *endtime,
390 int *n_primitives, int *n_bytes)
391 {
392 return TRACEINPUT_FAIL;
393 }
394
TRACE_Get_next_composite(const TRACE_file fp,int * category_index,int * n_bytes,char byte_base[],int * byte_pos,const int byte_max)395 TRACE_EXPORT int TRACE_Get_next_composite(const TRACE_file fp,
396 int *category_index,
397 int *n_bytes, char byte_base[],
398 int *byte_pos, const int byte_max)
399 {
400 return TRACEINPUT_FAIL;
401 }
402
403
TRACE_Get_position(TRACE_file fp,TRACE_int64_t * offset)404 TRACE_EXPORT int TRACE_Get_position(TRACE_file fp, TRACE_int64_t * offset)
405 {
406 return TRACEINPUT_FAIL;
407 }
408
TRACE_Set_position(TRACE_file fp,TRACE_int64_t offset)409 TRACE_EXPORT int TRACE_Set_position(TRACE_file fp, TRACE_int64_t offset)
410 {
411 return TRACEINPUT_FAIL;
412 }
413
414 /* FIXME: Improve failure reporting */
TRACE_Get_err_string(int ierr)415 TRACE_EXPORT char *TRACE_Get_err_string(int ierr)
416 {
417 /* ierr == 0 returns the help string (see the documentation on this
418 * routine) */
419 switch (ierr) {
420 case 0:
421 return "Usage: executable_name ASCII_drawable_filename";
422 default:
423 return "failure";
424 }
425 }
426