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 */