Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
New trace replayer, as fast as hell, and as boring as hell, too
[simgrid.git] / src / replay / replay_MPI.c
1 /* Example of traces replay without context switches, running MPI actions */
2
3 /* Copyright (c) 2010. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7  * under the terms of the license (GNU LGPL) which comes with this package. */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <errno.h>
11 #include "replay.h"
12 #include "xbt/log.h"
13 #include "xbt/str.h"
14 #include "xbt/dynar.h"
15 #include "simix/smurf_private.h"
16
17 XBT_LOG_NEW_DEFAULT_CATEGORY(mpi_replay,"MPI replayer");
18
19
20 /* Helper function */
21 static double parse_double(const char *string) {
22   double value;
23   char *endptr;
24
25   value = strtod(string, &endptr);
26   if (*endptr != '\0')
27     THROW1(unknown_error, 0, "%s is not a double", string);
28   return value;
29 }
30 static int get_rank (const char *process_name){
31   return atoi(&(process_name[1]));
32 }
33
34 const char *state_name[] = {
35     "pump",
36     "compute0", "compute1", "compute2",
37     "send0","send1","send2","send3",
38     "irecv0",
39     "recv0",
40     "wait0",
41     "init0", "init1"
42 };
43 typedef enum {
44   e_mpi_pump_evt_trace=0,
45   e_mpi_compute0,e_mpi_compute1,e_mpi_compute2,
46   e_mpi_send0,e_mpi_send1,e_mpi_send2,e_mpi_send3,
47   e_mpi_irecv0,
48   e_mpi_recv0,
49   e_mpi_wait0,
50   e_mpi_init0,e_mpi_init1
51 } e_mpi_replay_state_t;
52
53 typedef struct {
54   /* Myself */
55   char *procname;
56   smx_host_t myhost;
57   e_mpi_replay_state_t state;
58   /* Parsing logic */
59   replay_trace_reader_t reader;
60   const char * const*evt;
61   /* simix interface */
62   smx_action_t act;
63
64   xbt_dynar_t isends; /* of msg_comm_t, cleaned up automatically on send event */
65 } s_mpi_replay_t, *mpi_replay_t;
66
67 static void *mpi_replay_init(int argc, char *argv[]) {
68
69   mpi_replay_t res = xbt_new0(s_mpi_replay_t,1);
70   res->procname = xbt_strdup(argv[0]);
71   res->state = e_mpi_pump_evt_trace;
72
73   res->reader = replay_trace_reader_new(argv[1]);
74   return res;
75 }
76
77 static void mpi_replay_run(void*data,void *syscall_res) {
78   mpi_replay_t g = (mpi_replay_t)data; /* my globals */
79
80   new_event:
81   INFO2("mpi_replay_run, state=%s (%d)",state_name[g->state],g->state);
82
83   switch(g->state){
84
85   case e_mpi_pump_evt_trace: { /* nothing to do, parse next event and call function again */
86
87     g->evt = replay_trace_reader_get(g->reader);
88     if (strcmp(g->procname, g->evt[0])) {
89       WARN1("Ignore trace element not for me at %s",
90           replay_trace_reader_position(g->reader));
91       goto new_event;
92     }
93
94     if (!strcmp(g->evt[1],"send")) {
95       g->state = e_mpi_send0;
96       goto new_event;
97     } else if (!strcmp(g->evt[1],"recv")) {
98       g->state = e_mpi_recv0;
99       goto new_event;
100     } else if (!strcmp(g->evt[1],"irecv")||!strcmp(g->evt[1],"Irecv")) {
101       g->state = e_mpi_irecv0;
102       goto new_event;
103     } else if (!strcmp(g->evt[1],"wait")) {
104       g->state = e_mpi_wait0;
105       goto new_event;
106     } else if (!strcmp(g->evt[1],"compute")) {
107       g->state = e_mpi_compute0;
108       goto new_event;
109     } else if (!strcmp(g->evt[1],"init")) {
110       g->state = e_mpi_init0;
111       goto new_event;
112     } else {
113       WARN2("Ignoring unrecognized trace element at %s: %s",
114           replay_trace_reader_position(g->reader),g->evt[1]);
115       goto new_event;
116     }
117   } THROW_IMPOSSIBLE;
118
119   /* *** Send *** */
120   case e_mpi_send0: {
121     char to[250];
122     sprintf(to, "%s_%s", g->procname, g->evt[2]);
123
124     DEBUG2("Entering Send at %s (size: %lg)",
125         replay_trace_reader_position(g->reader), parse_double(g->evt[3]));
126     g->state = e_mpi_send1;
127     SIMIX_req_rdv_create(to);
128   } THROW_IMPOSSIBLE;
129
130   case e_mpi_send1:
131     g->state = e_mpi_send2;
132     SIMIX_req_comm_isend(syscall_res, parse_double(g->evt[3]),-1,
133         NULL,0,//void *src_buff, size_t src_buff_size,
134         NULL,NULL);//int (*match_fun)(void *, void *), void *data)
135     THROW_IMPOSSIBLE;
136   case e_mpi_send2:
137     if (parse_double(g->evt[3])<65536) {
138       xbt_dynar_push(g->isends,&syscall_res);
139       g->state = e_mpi_pump_evt_trace;
140       goto new_event;
141     }
142     g->act = syscall_res;
143     g->state=e_mpi_send3;
144     SIMIX_req_comm_wait(g->act,-1);
145   case e_mpi_send3:
146     g->state=e_mpi_pump_evt_trace;
147     SIMIX_req_comm_destroy(g->act);
148
149   /* *** Computation *** */
150   case e_mpi_compute0:
151     g->state = e_mpi_compute1;
152     SIMIX_req_host_execute(replay_trace_reader_position(g->reader),
153         g->myhost,parse_double(g->evt[2]));
154     THROW_IMPOSSIBLE;
155   case e_mpi_compute1:
156     g->act = syscall_res;
157     g->state = e_mpi_compute2;
158     SIMIX_req_host_execution_wait(g->act);
159     THROW_IMPOSSIBLE;
160   case e_mpi_compute2:
161     g->state = e_mpi_pump_evt_trace;
162     SIMIX_req_host_execution_destroy(g->act);
163     THROW_IMPOSSIBLE;
164
165   case e_mpi_irecv0: xbt_die("irecv0 unimplemented");
166   case e_mpi_recv0: xbt_die("recv0 unimplemented");
167   case e_mpi_wait0: xbt_die("wait0 unimplemented");
168   case e_mpi_init0:
169     g->state = e_mpi_init1;
170     SIMIX_req_process_get_host(SIMIX_process_self());
171     THROW_IMPOSSIBLE;
172   case e_mpi_init1:
173     g->myhost = syscall_res;
174     g->state = e_mpi_pump_evt_trace;
175     goto new_event;
176
177   }
178   THROW_IMPOSSIBLE;
179 }
180 static void mpi_replay_fini(void *data) {
181   mpi_replay_t g = (mpi_replay_t)data;
182   replay_trace_reader_free(&g->reader);
183   free(data);
184 }
185
186 int main(int argc, char *argv[]) {
187   SG_replay_init(&argc,argv);
188   if (argc<3) {
189     fprintf(stderr,"USAGE: replay platform_file deployment_file\n");
190     exit(1);
191   }
192   SG_replay_set_functions(mpi_replay_init,mpi_replay_run,mpi_replay_fini);
193   SG_replay(argv[1],argv[2]);
194
195   return 0;
196 }