Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[trace] fix comment
[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%llu", 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_release(void)
145 {
146   xbt_dict_free(&keys);
147   xbt_dict_free(&process_category);
148 }
149
150 void TRACE_smpi_init(int rank)
151 {
152   if (!TRACE_smpi_is_enabled()) return;
153
154   char str[INSTR_DEFAULT_STR_SIZE];
155   smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
156
157   container_t father;
158   if (TRACE_smpi_is_grouped()){
159     father = PJ_container_get (SIMIX_host_self_get_name());
160   }else{
161     father = PJ_container_get_root ();
162   }
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);
166 }
167
168 void TRACE_smpi_finalize(int rank)
169 {
170   if (!TRACE_smpi_is_enabled()) return;
171
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);
176 }
177
178 void TRACE_smpi_collective_in(int rank, int root, const char *operation)
179 {
180   if (!TRACE_smpi_is_enabled()) return;
181
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);
188   if (value == NULL){
189     value = PJ_value_new (operation, color, type);
190   }
191   new_pajePushState (SIMIX_get_clock(), container, type, value);
192 }
193
194 void TRACE_smpi_collective_out(int rank, int root, const char *operation)
195 {
196   if (!TRACE_smpi_is_enabled()) return;
197
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);
202
203   new_pajePopState (SIMIX_get_clock(), container, type);
204 }
205
206 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation)
207 {
208   if (!TRACE_smpi_is_enabled()) return;
209
210
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);
217   if (value == NULL){
218     value = PJ_value_new (operation, color, type);
219   }
220   new_pajePushState (SIMIX_get_clock(), container, type, value);
221 }
222
223 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation)
224 {
225   if (!TRACE_smpi_is_enabled()) return;
226
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);
231
232   new_pajePopState (SIMIX_get_clock(), container, type);
233 }
234
235 void TRACE_smpi_send(int rank, int src, int dst)
236 {
237   if (!TRACE_smpi_is_enabled()) return;
238
239   char key[INSTR_DEFAULT_STR_SIZE];
240   TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
241
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());
246
247   new_pajeStartLink (SIMIX_get_clock(), PJ_container_get_root(), type, container, "PTP", key);
248 }
249
250 void TRACE_smpi_recv(int rank, int src, int dst)
251 {
252   if (!TRACE_smpi_is_enabled()) return;
253
254   char key[INSTR_DEFAULT_STR_SIZE];
255   TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
256
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());
261
262   new_pajeEndLink (SIMIX_get_clock(), PJ_container_get_root(), type, container, "PTP", key);
263 }
264 #endif /* HAVE_TRACING */