1 /* Copyright (c) 2010, 2012-2014. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
11 #include <simgrid/sg_config.h>
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_smpi, instr, "Tracing SMPI");
18 static xbt_dict_t keys;
20 static const char *smpi_colors[] ={
22 "irecv", "1 0.52 0.52",
24 "isend", "0.52 0.52 1",
27 "waitall", "0.78 0.78 0",
28 "waitany", "0.78 0.78 0.58",
32 "allgatherv", "1 0.52 0.52",
34 "alltoall", "0.52 0 1",
35 "alltoallv", "0.78 0.52 1",
36 "barrier", "0 0.78 0.78",
37 "bcast", "0 0.78 0.39",
39 "gatherv", "1 1 0.52",
41 "reducescatter", "0.52 1 0.52",
42 "scan", "1 0.58 0.23",
43 "exscan", "1 0.54 0.25",
44 "scatterv", "0.52 0 0.52",
45 "scatter", "1 0.74 0.54",
52 static char *str_tolower (const char *str)
54 char *ret = xbt_strdup (str);
55 int i, n = strlen (ret);
56 for (i = 0; i < n; i++)
57 ret[i] = tolower (str[i]);
61 static const char *instr_find_color (const char *state)
63 char *target = str_tolower (state);
64 const char *ret = NULL;
67 while ((current = smpi_colors[i])){
68 if (strcmp (state, current) == 0){ ret = smpi_colors[i+1]; break; } //exact match
69 if (strstr(target, current)) { ret = smpi_colors[i+1]; break; }; //as substring
77 static char *smpi_container(int rank, char *container, int n)
79 snprintf(container, n, "rank-%d", rank);
83 static char *TRACE_smpi_get_key(int src, int dst, char *key, int n);
86 static char *TRACE_smpi_put_key(int src, int dst, char *key, int n)
88 //get the dynar for src#dst
89 char aux[INSTR_DEFAULT_STR_SIZE];
90 snprintf(aux, INSTR_DEFAULT_STR_SIZE, "%d#%d", src, dst);
91 xbt_dynar_t d = xbt_dict_get_or_null(keys, aux);
94 if(!xbt_dynar_is_empty(d)){
95 //receive was already pushed, perform a get instead
96 TRACE_smpi_get_key(src , dst, key ,n);
101 d = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
102 xbt_dict_set(keys, aux, d, NULL);
106 static unsigned long long counter = 0;
108 snprintf(key, n, "%d_%d_%llu", src, dst, counter++);
111 char *a = (char*)xbt_strdup(key);
112 xbt_dynar_push_as(d, char *, a);
117 static char *TRACE_smpi_get_key(int src, int dst, char *key, int n)
119 char aux[INSTR_DEFAULT_STR_SIZE];
120 snprintf(aux, INSTR_DEFAULT_STR_SIZE, "%d#%d", src, dst);
121 xbt_dynar_t d = xbt_dict_get_or_null(keys, aux);
123 // xbt_assert(!xbt_dynar_is_empty(d),
124 // "Trying to get a link key (for message reception) that has no corresponding send (%s).", __FUNCTION__);
126 // sometimes the receive may be posted before the send
127 if(xbt_dynar_is_empty(d)){
128 TRACE_smpi_put_key(src, dst, key, n);
132 char *s = xbt_dynar_get_as (d, 0, char *);
133 snprintf (key, n, "%s", s);
134 xbt_dynar_remove_at (d, 0, NULL);
138 static xbt_dict_t process_category;
140 static void cleanup_extra_data (instr_extra_data extra){
142 if(extra->sendcounts!=NULL)
143 xbt_free(extra->sendcounts);
144 if(extra->recvcounts!=NULL)
145 xbt_free(extra->recvcounts);
150 void TRACE_internal_smpi_set_category (const char *category)
152 if (!TRACE_smpi_is_enabled()) return;
155 TRACE_category (category);
157 char processid[INSTR_DEFAULT_STR_SIZE];
158 snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
159 if (xbt_dict_get_or_null (process_category, processid))
160 xbt_dict_remove (process_category, processid);
161 if (category != NULL)
162 xbt_dict_set (process_category, processid, xbt_strdup(category), NULL);
165 const char *TRACE_internal_smpi_get_category (void)
167 if (!TRACE_smpi_is_enabled()) return NULL;
169 char processid[INSTR_DEFAULT_STR_SIZE];
170 snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
171 return xbt_dict_get_or_null (process_category, processid);
174 void TRACE_smpi_alloc()
176 keys = xbt_dict_new_homogeneous(xbt_dynar_free_voidp);
177 process_category = xbt_dict_new_homogeneous(xbt_free);
180 void TRACE_smpi_release(void)
182 xbt_dict_free(&keys);
183 xbt_dict_free(&process_category);
186 void TRACE_smpi_init(int rank)
188 if (!TRACE_smpi_is_enabled()) return;
190 char str[INSTR_DEFAULT_STR_SIZE];
191 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
194 if (TRACE_smpi_is_grouped()){
195 father = PJ_container_get (SIMIX_host_self_get_name());
197 father = PJ_container_get_root ();
199 xbt_assert(father!=NULL,
200 "Could not find a parent for mpi rank %s at function %s", str, __FUNCTION__);
201 PJ_container_new(str, INSTR_SMPI, father);
204 void TRACE_smpi_finalize(int rank)
206 if (!TRACE_smpi_is_enabled()) return;
208 char str[INSTR_DEFAULT_STR_SIZE];
209 container_t container = PJ_container_get(smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE));
210 PJ_container_remove_from_parent (container);
211 PJ_container_free (container);
214 void TRACE_smpi_collective_in(int rank, int root, const char *operation, instr_extra_data extra)
216 if (!TRACE_smpi_is_enabled()) {
217 cleanup_extra_data(extra);
221 char str[INSTR_DEFAULT_STR_SIZE];
222 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
223 container_t container = PJ_container_get (str);
224 type_t type = PJ_type_get ("MPI_STATE", container->type);
225 const char *color = instr_find_color (operation);
226 val_t value = PJ_value_get_or_new (operation, color, type);
227 new_pajePushStateWithExtra (SIMIX_get_clock(), container, type, value, (void*)extra);
231 void TRACE_smpi_collective_out(int rank, int root, const char *operation)
233 if (!TRACE_smpi_is_enabled()) return;
235 char str[INSTR_DEFAULT_STR_SIZE];
236 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
237 container_t container = PJ_container_get (str);
238 type_t type = PJ_type_get ("MPI_STATE", container->type);
240 new_pajePopState (SIMIX_get_clock(), container, type);
243 void TRACE_smpi_computing_init(int rank)
245 //first use, initialize the color in the trace
246 //TODO : check with lucas and Pierre how to generalize this approach
247 //to avoid unnecessary access to the color array
248 if (!TRACE_smpi_is_enabled() || !TRACE_smpi_is_computing()) return;
250 char str[INSTR_DEFAULT_STR_SIZE];
251 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
252 container_t container = PJ_container_get (str);
253 type_t type = PJ_type_get ("MPI_STATE", container->type);
254 const char *color = instr_find_color ("computing");
255 val_t value = PJ_value_get_or_new ("computing", color, type);
256 new_pajePushState (SIMIX_get_clock(), container, type, value);
259 void TRACE_smpi_computing_in(int rank, instr_extra_data extra)
261 //do not forget to set the color first, otherwise this will explode
262 if (!TRACE_smpi_is_enabled()|| !TRACE_smpi_is_computing()) {
263 cleanup_extra_data(extra);
267 char str[INSTR_DEFAULT_STR_SIZE];
268 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
269 container_t container = PJ_container_get (str);
270 type_t type = PJ_type_get ("MPI_STATE", container->type);
271 val_t value = PJ_value_get_or_new ("computing", NULL, type);
272 new_pajePushStateWithExtra (SIMIX_get_clock(), container, type, value, (void*)extra);
275 void TRACE_smpi_computing_out(int rank)
277 if (!TRACE_smpi_is_enabled()|| !TRACE_smpi_is_computing()) return;
278 char str[INSTR_DEFAULT_STR_SIZE];
279 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
280 container_t container = PJ_container_get (str);
281 type_t type = PJ_type_get ("MPI_STATE", container->type);
282 new_pajePopState (SIMIX_get_clock(), container, type);
285 void TRACE_smpi_testing_in(int rank, instr_extra_data extra)
287 //do not forget to set the color first, otherwise this will explode
288 if (!TRACE_smpi_is_enabled()) {
289 cleanup_extra_data(extra);
293 char str[INSTR_DEFAULT_STR_SIZE];
294 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
295 container_t container = PJ_container_get (str);
296 type_t type = PJ_type_get ("MPI_STATE", container->type);
297 val_t value = PJ_value_get_or_new ("test", NULL, type);
298 new_pajePushStateWithExtra (SIMIX_get_clock(), container, type, value, (void*)extra);
301 void TRACE_smpi_testing_out(int rank)
303 if (!TRACE_smpi_is_enabled()) return;
304 char str[INSTR_DEFAULT_STR_SIZE];
305 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
306 container_t container = PJ_container_get (str);
307 type_t type = PJ_type_get ("MPI_STATE", container->type);
308 new_pajePopState (SIMIX_get_clock(), container, type);
311 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation, instr_extra_data extra)
313 if (!TRACE_smpi_is_enabled()) {
314 cleanup_extra_data(extra);
318 char str[INSTR_DEFAULT_STR_SIZE];
319 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
320 container_t container = PJ_container_get (str);
321 type_t type = PJ_type_get ("MPI_STATE", container->type);
322 const char *color = instr_find_color (operation);
323 val_t value = PJ_value_get_or_new (operation, color, type);
324 new_pajePushStateWithExtra (SIMIX_get_clock(), container, type, value, (void*)extra);
327 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation)
329 if (!TRACE_smpi_is_enabled()) return;
331 char str[INSTR_DEFAULT_STR_SIZE];
332 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
333 container_t container = PJ_container_get (str);
334 type_t type = PJ_type_get ("MPI_STATE", container->type);
336 new_pajePopState (SIMIX_get_clock(), container, type);
339 void TRACE_smpi_send(int rank, int src, int dst, int size)
341 if (!TRACE_smpi_is_enabled()) return;
343 char key[INSTR_DEFAULT_STR_SIZE] = {0};
344 TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
346 char str[INSTR_DEFAULT_STR_SIZE];
347 smpi_container(src, str, INSTR_DEFAULT_STR_SIZE);
348 container_t container = PJ_container_get (str);
349 type_t type = PJ_type_get ("MPI_LINK", PJ_type_get_root());
351 new_pajeStartLinkWithSize (SIMIX_get_clock(), PJ_container_get_root(), type, container, "PTP", key, size);
354 void TRACE_smpi_recv(int rank, int src, int dst)
356 if (!TRACE_smpi_is_enabled()) return;
358 char key[INSTR_DEFAULT_STR_SIZE] = {0};
359 TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
361 char str[INSTR_DEFAULT_STR_SIZE];
362 smpi_container(dst, str, INSTR_DEFAULT_STR_SIZE);
363 container_t container = PJ_container_get (str);
364 type_t type = PJ_type_get ("MPI_LINK", PJ_type_get_root());
366 new_pajeEndLink (SIMIX_get_clock(), PJ_container_get_root(), type, container, "PTP", key);
368 #endif /* HAVE_TRACING */