Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7cdf66f0f104f50a2f13f618a14b9d82e8c05928
[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, xbt_free);
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_length(d)!=0,
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), xbt_free);
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();
141   process_category = xbt_dict_new();
142 }
143
144 void TRACE_smpi_start(void)
145 {
146   TRACE_start();
147 }
148
149 void TRACE_smpi_release(void)
150 {
151   if (!TRACE_smpi_is_enabled()) return;
152
153   TRACE_surf_release();
154   TRACE_end();
155 }
156
157 void TRACE_smpi_init(int rank)
158 {
159   if (!TRACE_smpi_is_enabled()) return;
160
161   char str[INSTR_DEFAULT_STR_SIZE];
162   smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
163
164   container_t father;
165   if (TRACE_smpi_is_grouped()){
166     father = getContainer (SIMIX_host_self_get_name());
167   }else{
168     father = getRootContainer ();
169   }
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);
173 }
174
175 void TRACE_smpi_finalize(int rank)
176 {
177   if (!TRACE_smpi_is_enabled()) return;
178
179   char str[INSTR_DEFAULT_STR_SIZE];
180   smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
181   destroyContainer(getContainer (str));
182 }
183
184 void TRACE_smpi_collective_in(int rank, int root, const char *operation)
185 {
186   if (!TRACE_smpi_is_enabled()) return;
187
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);
194
195   new_pajePushState (SIMIX_get_clock(), container, type, value);
196 }
197
198 void TRACE_smpi_collective_out(int rank, int root, const char *operation)
199 {
200   if (!TRACE_smpi_is_enabled()) return;
201
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);
206
207   new_pajePopState (SIMIX_get_clock(), container, type);
208 }
209
210 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation)
211 {
212   if (!TRACE_smpi_is_enabled()) return;
213
214
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);
221
222   new_pajePushState (SIMIX_get_clock(), container, type, value);
223 }
224
225 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation)
226 {
227   if (!TRACE_smpi_is_enabled()) return;
228
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);
233
234   new_pajePopState (SIMIX_get_clock(), container, type);
235 }
236
237 void TRACE_smpi_send(int rank, int src, int dst)
238 {
239   if (!TRACE_smpi_is_enabled()) return;
240
241   char key[INSTR_DEFAULT_STR_SIZE];
242   TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
243
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());
248
249   new_pajeStartLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
250 }
251
252 void TRACE_smpi_recv(int rank, int src, int dst)
253 {
254   if (!TRACE_smpi_is_enabled()) return;
255
256   char key[INSTR_DEFAULT_STR_SIZE];
257   TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
258
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());
263
264   new_pajeEndLink (SIMIX_get_clock(), getRootContainer(), type, container, "PTP", key);
265 }
266 #endif /* HAVE_TRACING */