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, xbt_free);
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), xbt_free);
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();
141 process_category = xbt_dict_new();
144 void TRACE_smpi_start(void)
149 void TRACE_smpi_release(void)
151 if (!TRACE_smpi_is_enabled()) return;
153 TRACE_surf_release();
157 void TRACE_smpi_init(int rank)
159 if (!TRACE_smpi_is_enabled()) return;
161 char str[INSTR_DEFAULT_STR_SIZE];
162 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
165 if (TRACE_smpi_is_grouped()){
166 father = getContainer (SIMIX_host_self_get_name());
168 father = getRootContainer ();
170 xbt_assert(father!=NULL,
171 "Could not find a parent for mpi rank %s at function %s", str, __FUNCTION__);
172 newContainer(str, INSTR_SMPI, father);
175 void TRACE_smpi_finalize(int rank)
177 if (!TRACE_smpi_is_enabled()) return;
179 char str[INSTR_DEFAULT_STR_SIZE];
180 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
181 destroyContainer(getContainer (str));
184 void TRACE_smpi_collective_in(int rank, int root, const char *operation)
186 if (!TRACE_smpi_is_enabled()) return;
188 char str[INSTR_DEFAULT_STR_SIZE];
189 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
190 container_t container = getContainer (str);
191 type_t type = getType ("MPI_STATE", container->type);
192 const char *color = instr_find_color (operation);
193 val_t value = getValue (operation, color, type);
195 new_pajePushState (SIMIX_get_clock(), container, type, value);
198 void TRACE_smpi_collective_out(int rank, int root, const char *operation)
200 if (!TRACE_smpi_is_enabled()) return;
202 char str[INSTR_DEFAULT_STR_SIZE];
203 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
204 container_t container = getContainer (str);
205 type_t type = getType ("MPI_STATE", container->type);
207 new_pajePopState (SIMIX_get_clock(), container, type);
210 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation)
212 if (!TRACE_smpi_is_enabled()) return;
215 char str[INSTR_DEFAULT_STR_SIZE];
216 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
217 container_t container = getContainer (str);
218 type_t type = getType ("MPI_STATE", container->type);
219 const char *color = instr_find_color (operation);
220 val_t value = getValue (operation, color, type);
222 new_pajePushState (SIMIX_get_clock(), container, type, value);
225 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation)
227 if (!TRACE_smpi_is_enabled()) return;
229 char str[INSTR_DEFAULT_STR_SIZE];
230 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
231 container_t container = getContainer (str);
232 type_t type = getType ("MPI_STATE", container->type);
234 new_pajePopState (SIMIX_get_clock(), container, type);
237 void TRACE_smpi_send(int rank, int src, int dst)
239 if (!TRACE_smpi_is_enabled()) return;
241 char key[INSTR_DEFAULT_STR_SIZE];
242 TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
244 char str[INSTR_DEFAULT_STR_SIZE];
245 smpi_container(src, str, INSTR_DEFAULT_STR_SIZE);
246 container_t container = getContainer (str);
247 type_t type = getType ("MPI_LINK", getRootType());
249 new_pajeStartLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
252 void TRACE_smpi_recv(int rank, int src, int dst)
254 if (!TRACE_smpi_is_enabled()) return;
256 char key[INSTR_DEFAULT_STR_SIZE];
257 TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
259 char str[INSTR_DEFAULT_STR_SIZE];
260 smpi_container(dst, str, INSTR_DEFAULT_STR_SIZE);
261 container_t container = getContainer (str);
262 type_t type = getType ("MPI_LINK", getRootType());
264 new_pajeEndLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
266 #endif /* HAVE_TRACING */