1 /* Copyright (c) 2010. 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. */
7 #include "instr/instr_private.h"
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_smpi, instr, "Tracing SMPI");
16 static xbt_dict_t keys;
18 static const char *smpi_colors[] ={
19 "recv", "255 000 000",
20 "irecv", "255 135 135",
21 "send", "000 000 255",
22 "isend", "135 135 255",
23 "sendrecv", "000 255 255",
24 "wait", "255 255 000",
25 "waitall", "200 200 000",
26 "waitany", "200 200 150",
28 "allgather", "255 000 000",
29 "allgatherv", "255 135 135",
30 "allreduce", "255 000 255",
31 "alltoall", "135 000 255",
32 "alltoallv", "200 135 255",
33 "barrier", "000 200 200",
34 "bcast", "000 200 100",
35 "gather", "255 255 000",
36 "gatherv", "255 255 135",
37 "reduce", "000 255 000",
38 "reducescatter", "135 255 135",
39 "scan", "255 150 060",
40 "scatterv", "135 000 135",
41 "scatter", "255 190 140",
46 static char *str_tolower (const char *str)
48 char *ret = xbt_strdup (str);
49 int i, n = strlen (ret);
50 for (i = 0; i < n; i++)
51 ret[i] = tolower (str[i]);
55 static const char *instr_find_color (const char *state)
57 char *target = str_tolower (state);
58 const char *ret = NULL;
61 while ((current = smpi_colors[i])){
62 if (strcmp (state, current) == 0){ ret = smpi_colors[i+1]; break; } //exact match
63 if (strstr(target, current)) { ret = smpi_colors[i+1]; break; }; //as substring
71 static char *smpi_container(int rank, char *container, int n)
73 snprintf(container, n, "rank-%d", rank);
77 static char *TRACE_smpi_put_key(int src, int dst, char *key, int n)
79 //get the dynar for src#dst
80 char aux[INSTR_DEFAULT_STR_SIZE];
81 snprintf(aux, INSTR_DEFAULT_STR_SIZE, "%d#%d", src, dst);
82 xbt_dynar_t d = xbt_dict_get_or_null(keys, aux);
84 d = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
85 xbt_dict_set(keys, aux, d, NULL);
88 static unsigned long long counter = 0;
89 snprintf(key, n, "%d%d%lld", src, dst, counter++);
92 char *a = (char*)xbt_strdup(key);
93 xbt_dynar_push_as(d, char *, a);
98 static char *TRACE_smpi_get_key(int src, int dst, char *key, int n)
100 char aux[INSTR_DEFAULT_STR_SIZE];
101 snprintf(aux, INSTR_DEFAULT_STR_SIZE, "%d#%d", src, dst);
102 xbt_dynar_t d = xbt_dict_get_or_null(keys, aux);
104 xbt_assert(!xbt_dynar_is_empty(d),
105 "Trying to get a link key (for message reception) that has no corresponding send (%s).", __FUNCTION__);
106 char *s = xbt_dynar_get_as (d, 0, char *);
107 snprintf (key, n, "%s", s);
108 xbt_dynar_remove_at (d, 0, NULL);
112 static xbt_dict_t process_category;
114 void TRACE_internal_smpi_set_category (const char *category)
116 if (!TRACE_smpi_is_enabled()) return;
119 TRACE_category (category);
121 char processid[INSTR_DEFAULT_STR_SIZE];
122 snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
123 if (xbt_dict_get_or_null (process_category, processid))
124 xbt_dict_remove (process_category, processid);
125 if (category != NULL)
126 xbt_dict_set (process_category, processid, xbt_strdup(category), NULL);
129 const char *TRACE_internal_smpi_get_category (void)
131 if (!TRACE_smpi_is_enabled()) return NULL;
133 char processid[INSTR_DEFAULT_STR_SIZE];
134 snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
135 return xbt_dict_get_or_null (process_category, processid);
138 void TRACE_smpi_alloc()
140 keys = xbt_dict_new_homogeneous(xbt_free);
141 process_category = xbt_dict_new_homogeneous(xbt_free);
144 void TRACE_smpi_start(void)
149 void TRACE_smpi_release(void)
151 xbt_dict_free(&keys);
152 xbt_dict_free(&process_category);
153 if (!TRACE_smpi_is_enabled()) return;
155 TRACE_surf_release();
159 void TRACE_smpi_init(int rank)
161 if (!TRACE_smpi_is_enabled()) return;
163 char str[INSTR_DEFAULT_STR_SIZE];
164 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
167 if (TRACE_smpi_is_grouped()){
168 father = getContainer (SIMIX_host_self_get_name());
170 father = getRootContainer ();
172 xbt_assert(father!=NULL,
173 "Could not find a parent for mpi rank %s at function %s", str, __FUNCTION__);
174 newContainer(str, INSTR_SMPI, father);
177 void TRACE_smpi_finalize(int rank)
179 if (!TRACE_smpi_is_enabled()) return;
181 char str[INSTR_DEFAULT_STR_SIZE];
182 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
183 destroyContainer(getContainer (str));
186 void TRACE_smpi_collective_in(int rank, int root, const char *operation)
188 if (!TRACE_smpi_is_enabled()) return;
190 char str[INSTR_DEFAULT_STR_SIZE];
191 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
192 container_t container = getContainer (str);
193 type_t type = getType ("MPI_STATE", container->type);
194 const char *color = instr_find_color (operation);
195 val_t value = getValue (operation, color, type);
197 new_pajePushState (SIMIX_get_clock(), container, type, value);
200 void TRACE_smpi_collective_out(int rank, int root, const char *operation)
202 if (!TRACE_smpi_is_enabled()) return;
204 char str[INSTR_DEFAULT_STR_SIZE];
205 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
206 container_t container = getContainer (str);
207 type_t type = getType ("MPI_STATE", container->type);
209 new_pajePopState (SIMIX_get_clock(), container, type);
212 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation)
214 if (!TRACE_smpi_is_enabled()) return;
217 char str[INSTR_DEFAULT_STR_SIZE];
218 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
219 container_t container = getContainer (str);
220 type_t type = getType ("MPI_STATE", container->type);
221 const char *color = instr_find_color (operation);
222 val_t value = getValue (operation, color, type);
224 new_pajePushState (SIMIX_get_clock(), container, type, value);
227 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation)
229 if (!TRACE_smpi_is_enabled()) return;
231 char str[INSTR_DEFAULT_STR_SIZE];
232 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
233 container_t container = getContainer (str);
234 type_t type = getType ("MPI_STATE", container->type);
236 new_pajePopState (SIMIX_get_clock(), container, type);
239 void TRACE_smpi_send(int rank, int src, int dst)
241 if (!TRACE_smpi_is_enabled()) return;
243 char key[INSTR_DEFAULT_STR_SIZE];
244 TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
246 char str[INSTR_DEFAULT_STR_SIZE];
247 smpi_container(src, str, INSTR_DEFAULT_STR_SIZE);
248 container_t container = getContainer (str);
249 type_t type = getType ("MPI_LINK", getRootType());
251 new_pajeStartLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
254 void TRACE_smpi_recv(int rank, int src, int dst)
256 if (!TRACE_smpi_is_enabled()) return;
258 char key[INSTR_DEFAULT_STR_SIZE];
259 TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
261 char str[INSTR_DEFAULT_STR_SIZE];
262 smpi_container(dst, str, INSTR_DEFAULT_STR_SIZE);
263 container_t container = getContainer (str);
264 type_t type = getType ("MPI_LINK", getRootType());
266 new_pajeEndLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
268 #endif /* HAVE_TRACING */