KMR
kmrtrace.c
Go to the documentation of this file.
1 /* kmrtrace.c (2015-12-07) */
2 /* Copyright (C) 2012-2016 RIKEN AICS */
3 
4 /** \file kmrtrace.c KMRViz tracing Support. */
5 
6 #include <mpi.h>
7 #include <stdint.h>
8 #include <assert.h>
9 #include "../config.h"
10 #include "kmr.h"
11 #include "kmrimpl.h"
12 #include "kmrtrace.h"
13 
14 typedef struct kmr_trace kmr_trace_t;
15 
16 /* Time getting function used by the tracer */
17 static inline double
18 kmr_trace_gettime()
19 {
20  return kmr_wtime() * 10E9;
21 }
22 
23 /* Initialize */
24 static void
25 kmr_trace_init(kmr_trace_t *kt, MPI_Comm comm)
26 {
27  MPI_Comm_rank(comm, &(kt->rank));
28  kt->start_t = kt->end_t = 0.0;
29  kt->n = 0;
30  kt->head = kt->tail = NULL;
31 }
32 
33 /* Finalize */
34 static void
35 kmr_trace_fini(kmr_trace_t *kt)
36 {
37  kmr_trace_entry_t * en = kt->head;
38  while (en) {
39  kmr_trace_entry_t * enn = en->next;
40  kmr_free(en, sizeof(kmr_trace_entry_t));
41  en = enn;
42  }
43 }
44 
45 /* Start tracing */
46 static void
47 kmr_trace_start(kmr_trace_t *kt)
48 {
49  kt->start_t = kmr_trace_gettime();
50 }
51 
52 /* Stop tracing */
53 static void
54 kmr_trace_stop(kmr_trace_t *kt)
55 {
56  kt->end_t = kmr_trace_gettime();
57 }
58 
59 static int
60 kmr_trace_count(kmr_trace_entry_t * e1, kmr_trace_entry_t * e2)
61 {
62  if (!e1 || !e2 || e1 == e2) return 0; // to pair with itself
63  kmr_trace_entry_t * e = e1;
64  int count = 0;
65  while (e != e2 && e != NULL) {
66  e = e->next;
67  count++;
68  }
69  if (e == e2) {
70  return count;
71  }
72  return 0;
73 }
74 
75 /* Dump the trace to a binary file */
76 static void
77 kmr_trace_dump_bin(kmr_trace_t * kt, char * filename)
78 {
79  FILE * wp = fopen(filename, "wb");
80  if (!wp) {
81  fprintf(stderr, "error: fopen: %s (%s)\n", strerror(errno), filename);
82  }
83  uint32_t endian_checker = KT_ENDIAN_CHECKER;
84  if (fwrite(&endian_checker, sizeof(endian_checker), 1, wp) != 1
85  || fwrite(&kt->rank, sizeof(kt->rank), 1, wp) != 1
86  || fwrite(&kt->start_t, sizeof(kt->start_t), 1, wp) != 1
87  || fwrite(&kt->end_t, sizeof(kt->end_t), 1, wp) != 1
88  || fwrite(&kt->n, sizeof(kt->n), 1, wp) != 1) {
89  fprintf(stderr, "error: fwrite: %s (%s)\n", strerror(errno), filename);
90  }
91  kmr_trace_entry_t * en = kt->head;
92  while (en) {
93  kmr_trace_entry_t * enn = en->next;
94  int offset = kmr_trace_count(en, en->pair);
95  if (fwrite(&en->t, sizeof(en->t), 1, wp) != 1
96  || fwrite(&en->kvi_element_count, sizeof(en->kvi_element_count), 1, wp) != 1
97  || fwrite(&en->kvo_element_count, sizeof(en->kvo_element_count), 1, wp) != 1
98  || fwrite(&en->e, sizeof(en->e), 1, wp) != 1
99  || fwrite(&offset, sizeof(offset), 1, wp) != 1) {
100  fprintf(stderr, "error: fwrite: %s (%s)\n",
101  strerror(errno), filename);
102  }
103  en = enn;
104  }
105  fclose(wp);
106  printf("rank %d's trace written to %s\n", kt->rank, filename);
107 }
108 
109 /* Dump the trace to a text file */
110 static void
111 kmr_trace_dump_txt(kmr_trace_t * kt, char * filename)
112 {
113  FILE * wp = fopen(filename, "wb");
114  if (!wp) {
115  fprintf(stderr, "error: fopen: %s (%s)\n", strerror(errno), filename);
116  }
117  double base_t = kt->start_t;
118  fprintf(wp, "rank: %d\nstart_t: %.0lf\nend_t: %.0lf\nn: %ld\n",
119  kt->rank, kt->start_t - base_t, kt->end_t - base_t, kt->n);
120  kmr_trace_entry_t * en = kt->head;
121  while (en) {
122  kmr_trace_entry_t * enn = en->next;
123  int offset = kmr_trace_count(en, en->pair);
124  fprintf(wp, "event %d at t=%.0lf, element count=(%ld,%ld), offset to pair: %d\n",
125  en->e, en->t - base_t, en->kvi_element_count,
126  en->kvo_element_count, offset);
127  en = enn;
128  }
129  fclose(wp);
130  printf("rank %d's trace written to %s\n", kt->rank, filename);
131 }
132 
133 /* Dump the trace to files */
134 static void
135 kmr_trace_dump(KMR *mr)
136 {
137  char *prefix = 0;
138  if (strlen(mr->identifying_name) > 0) {
139  prefix = mr->identifying_name;
140  } else {
141  prefix = "00kt";
142  }
143  char filename[KT_PATHLEN];
144  kmr_trace_t *kt = mr->kvt_ctx;
145  sprintf(filename, "%s_rank%d.bin", prefix, kt->rank);
146  kmr_trace_dump_bin(kt, filename);
147  sprintf(filename, "%s_rank%d.txt", prefix, kt->rank);
148  kmr_trace_dump_txt(kt, filename);
149 }
150 
151 
152 /** Initialize a trace */
154 {
155  /* inialized irrespective of mr->kmrviz_trace */
156  mr->kvt_ctx = (kmr_trace_t *)kmr_malloc(sizeof(kmr_trace_t));
157  kmr_trace_init(mr->kvt_ctx, mr->comm);
158  kmr_trace_start(mr->kvt_ctx);
159 }
160 
161 /** Finalize a trace */
163 {
164  if (mr->kmrviz_trace) {
165  kmr_trace_stop(mr->kvt_ctx);
166  kmr_trace_dump(mr);
167  kmr_trace_fini(mr->kvt_ctx);
168  }
169  kmr_free(mr->kvt_ctx, sizeof(kmr_trace_t));
170 }
171 
172 /** Add an entry to the trace */
175  KMR_KVS *kvi, KMR_KVS *kvo)
176 {
177  /* Create */
178  kmr_trace_entry_t * en =
180  en->t = kmr_trace_gettime();
181  en->e = ev;
182  if (kvi) {
183  en->kvi_element_count = kvi->c.element_count;
184  } else {
185  en->kvi_element_count = -1;
186  }
187  if (kvo) {
188  en->kvo_element_count = kvo->c.element_count;
189  } else {
190  en->kvo_element_count = -1;
191  }
192  en->pair = NULL;
193  en->next = NULL;
194  /* Append */
195  kmr_trace_t *kt = mr->kvt_ctx;
196  if (!kt->head) {
197  kt->head = kt->tail = en;
198  } else {
199  kt->tail->next = en;
200  kt->tail = en;
201  }
202  kt->n++;
203  /* Pair */
204  if (pre) {
205  pre->pair = en;
206  }
207  /* Return */
208  return en;
209 }
210 
211 
212 /*
213 Copyright (C) 2012-2016 RIKEN AICS
214 This library is distributed WITHOUT ANY WARRANTY. This library can be
215 redistributed and/or modified under the terms of the BSD 2-Clause License.
216 */
void kmr_trace_finalize(KMR *mr)
Finalize a trace.
Definition: kmrtrace.c:162
Key-Value Stream (abstract).
Definition: kmr.h:587
Utilities Private Part (do not include from applications).
#define kmr_malloc(Z)
Allocates memory, or aborts when failed.
Definition: kmrimpl.h:177
KMR Context.
Definition: kmr.h:222
Definition: kmrtrace.h:27
void kmr_trace_initialize(KMR *mr)
Initialize a trace.
Definition: kmrtrace.c:153
kmr_trace_entry_t * kmr_trace_add_entry(KMR *mr, kmr_trace_event_t ev, kmr_trace_entry_t *pre, KMR_KVS *kvi, KMR_KVS *kvo)
Add an entry to the trace.
Definition: kmrtrace.c:174
KMR Interface.
kmr_trace_event_t
Current supported trace events.
Definition: kmrtrace.h:14
KMRViz tracing Support.