Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
merge conflicts resolved
[simgrid.git] / src / instr / instr_smpi.c
1 /* Copyright (c) 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #include "instr/instr_private.h"
8 #include <ctype.h>
9 #include <wchar.h>
10
11
12 #ifdef HAVE_TRACING
13
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_smpi, instr, "Tracing SMPI");
15
16 static xbt_dict_t keys;
17
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",
27
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",
42
43     NULL, NULL,
44 };
45
46 static char *str_tolower (const char *str)
47 {
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]);
52   return ret;
53 }
54
55 static const char *instr_find_color (const char *state)
56 {
57   char *target = str_tolower (state);
58   const char *ret = NULL;
59   const char *current;
60   unsigned int i = 0;
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
64     i+=2;
65   }
66   free (target);
67   return ret;
68 }
69
70
71 static char *smpi_container(int rank, char *container, int n)
72 {
73   snprintf(container, n, "rank-%d", rank);
74   return container;
75 }
76
77 static char *TRACE_smpi_put_key(int src, int dst, char *key, int n)
78 {
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);
83   if (d == NULL) {
84     d = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
85     xbt_dict_set(keys, aux, d, NULL);
86   }
87   //generate the key
88   static unsigned long long counter = 0;
89   snprintf(key, n, "%d%d%lld", src, dst, counter++);
90
91   //push it
92   char *a = (char*)xbt_strdup(key);
93   xbt_dynar_push_as(d, char *, a);
94
95   return key;
96 }
97
98 static char *TRACE_smpi_get_key(int src, int dst, char *key, int n)
99 {
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);
103
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);
109   return key;
110 }
111
112 static xbt_dict_t process_category;
113
114 void TRACE_internal_smpi_set_category (const char *category)
115 {
116   if (!TRACE_smpi_is_enabled()) return;
117
118   //declare category
119   TRACE_category (category);
120
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);
127 }
128
129 const char *TRACE_internal_smpi_get_category (void)
130 {
131   if (!TRACE_smpi_is_enabled()) return NULL;
132
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);
136 }
137
138 void TRACE_smpi_alloc()
139 {
140   keys = xbt_dict_new_homogeneous(xbt_free);
141   process_category = xbt_dict_new_homogeneous(xbt_free);
142 }
143
144 void TRACE_smpi_start(void)
145 {
146   TRACE_start();
147 }
148
149 void TRACE_smpi_release(void)
150 {
151   xbt_dict_free(&keys);
152   xbt_dict_free(&process_category);
153   if (!TRACE_smpi_is_enabled()) return;
154
155   TRACE_surf_release();
156   TRACE_end();
157 }
158
159 void TRACE_smpi_init(int rank)
160 {
161   if (!TRACE_smpi_is_enabled()) return;
162
163   char str[INSTR_DEFAULT_STR_SIZE];
164   smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
165
166   container_t father;
167   if (TRACE_smpi_is_grouped()){
168     father = getContainer (SIMIX_host_self_get_name());
169   }else{
170     father = getRootContainer ();
171   }
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);
175 }
176
177 void TRACE_smpi_finalize(int rank)
178 {
179   if (!TRACE_smpi_is_enabled()) return;
180
181   char str[INSTR_DEFAULT_STR_SIZE];
182   smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
183   destroyContainer(getContainer (str));
184 }
185
186 void TRACE_smpi_collective_in(int rank, int root, const char *operation)
187 {
188   if (!TRACE_smpi_is_enabled()) return;
189
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);
196
197   new_pajePushState (SIMIX_get_clock(), container, type, value);
198 }
199
200 void TRACE_smpi_collective_out(int rank, int root, const char *operation)
201 {
202   if (!TRACE_smpi_is_enabled()) return;
203
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);
208
209   new_pajePopState (SIMIX_get_clock(), container, type);
210 }
211
212 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation)
213 {
214   if (!TRACE_smpi_is_enabled()) return;
215
216
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);
223
224   new_pajePushState (SIMIX_get_clock(), container, type, value);
225 }
226
227 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation)
228 {
229   if (!TRACE_smpi_is_enabled()) return;
230
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);
235
236   new_pajePopState (SIMIX_get_clock(), container, type);
237 }
238
239 void TRACE_smpi_send(int rank, int src, int dst)
240 {
241   if (!TRACE_smpi_is_enabled()) return;
242
243   char key[INSTR_DEFAULT_STR_SIZE];
244   TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
245
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());
250
251   new_pajeStartLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
252 }
253
254 void TRACE_smpi_recv(int rank, int src, int dst)
255 {
256   if (!TRACE_smpi_is_enabled()) return;
257
258   char key[INSTR_DEFAULT_STR_SIZE];
259   TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
260
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());
265
266   new_pajeEndLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
267 }
268 #endif /* HAVE_TRACING */