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%llu", 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_release(void)
146 xbt_dict_free(&keys);
147 xbt_dict_free(&process_category);
150 void TRACE_smpi_init(int rank)
152 if (!TRACE_smpi_is_enabled()) return;
154 char str[INSTR_DEFAULT_STR_SIZE];
155 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
158 if (TRACE_smpi_is_grouped()){
159 father = PJ_container_get (SIMIX_host_self_get_name());
161 father = PJ_container_get_root ();
163 xbt_assert(father!=NULL,
164 "Could not find a parent for mpi rank %s at function %s", str, __FUNCTION__);
165 PJ_container_new(str, INSTR_SMPI, father);
168 void TRACE_smpi_finalize(int rank)
170 if (!TRACE_smpi_is_enabled()) return;
172 char str[INSTR_DEFAULT_STR_SIZE];
173 container_t container = PJ_container_get(smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE));
174 PJ_container_remove_from_parent (container);
175 PJ_container_free (container);
178 void TRACE_smpi_collective_in(int rank, int root, const char *operation)
180 if (!TRACE_smpi_is_enabled()) return;
182 char str[INSTR_DEFAULT_STR_SIZE];
183 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
184 container_t container = PJ_container_get (str);
185 type_t type = PJ_type_get ("MPI_STATE", container->type);
186 const char *color = instr_find_color (operation);
187 val_t value = PJ_value_get (operation, type);
189 value = PJ_value_new (operation, color, type);
191 new_pajePushState (SIMIX_get_clock(), container, type, value);
194 void TRACE_smpi_collective_out(int rank, int root, const char *operation)
196 if (!TRACE_smpi_is_enabled()) return;
198 char str[INSTR_DEFAULT_STR_SIZE];
199 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
200 container_t container = PJ_container_get (str);
201 type_t type = PJ_type_get ("MPI_STATE", container->type);
203 new_pajePopState (SIMIX_get_clock(), container, type);
206 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation)
208 if (!TRACE_smpi_is_enabled()) return;
211 char str[INSTR_DEFAULT_STR_SIZE];
212 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
213 container_t container = PJ_container_get (str);
214 type_t type = PJ_type_get ("MPI_STATE", container->type);
215 const char *color = instr_find_color (operation);
216 val_t value = PJ_value_get (operation, type);
218 value = PJ_value_new (operation, color, type);
220 new_pajePushState (SIMIX_get_clock(), container, type, value);
223 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation)
225 if (!TRACE_smpi_is_enabled()) return;
227 char str[INSTR_DEFAULT_STR_SIZE];
228 smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
229 container_t container = PJ_container_get (str);
230 type_t type = PJ_type_get ("MPI_STATE", container->type);
232 new_pajePopState (SIMIX_get_clock(), container, type);
235 void TRACE_smpi_send(int rank, int src, int dst)
237 if (!TRACE_smpi_is_enabled()) return;
239 char key[INSTR_DEFAULT_STR_SIZE];
240 TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
242 char str[INSTR_DEFAULT_STR_SIZE];
243 smpi_container(src, str, INSTR_DEFAULT_STR_SIZE);
244 container_t container = PJ_container_get (str);
245 type_t type = PJ_type_get ("MPI_LINK", PJ_type_get_root());
247 new_pajeStartLink (SIMIX_get_clock(), PJ_container_get_root(), type, container, "PTP", key);
250 void TRACE_smpi_recv(int rank, int src, int dst)
252 if (!TRACE_smpi_is_enabled()) return;
254 char key[INSTR_DEFAULT_STR_SIZE];
255 TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
257 char str[INSTR_DEFAULT_STR_SIZE];
258 smpi_container(dst, str, INSTR_DEFAULT_STR_SIZE);
259 container_t container = PJ_container_get (str);
260 type_t type = PJ_type_get ("MPI_LINK", PJ_type_get_root());
262 new_pajeEndLink (SIMIX_get_clock(), PJ_container_get_root(), type, container, "PTP", key);
264 #endif /* HAVE_TRACING */