Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
made some changes to allow more than one DO_ONCE block. also fixed bug in
[simgrid.git] / src / smpi / smpi_global.c
1 #include <stdio.h>
2
3 #include "private.h"
4
5 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi, XBT_LOG_ROOT_CAT, "All SMPI categories");
6
7 smpi_global_t     smpi_global     = NULL;
8
9 void *smpi_request_new(void);
10
11 void *smpi_request_new()
12 {
13         smpi_mpi_request_t request = xbt_new(s_smpi_mpi_request_t, 1);
14
15         request->buf       = NULL;
16         request->completed = 0;
17         request->mutex     = SIMIX_mutex_init();
18         request->cond      = SIMIX_cond_init();
19         request->data      = NULL;
20         request->forward   = 0;
21
22         return request;
23 }
24
25 void smpi_request_free(void *pointer);
26
27 void smpi_request_free(void *pointer)
28 {
29
30         smpi_mpi_request_t request = pointer;
31
32         SIMIX_cond_destroy(request->cond);
33         SIMIX_mutex_destroy(request->mutex);
34         xbt_free(request);
35
36         return;
37 }
38
39 void smpi_request_reset(void *pointer);
40
41 void smpi_request_reset(void *pointer)
42 {
43         smpi_mpi_request_t request = pointer;
44
45         request->buf       = NULL;
46         request->completed = 0;
47         request->data      = NULL;
48         request->forward   = 0;
49
50         return;
51 }
52
53
54 void *smpi_message_new(void);
55
56 void *smpi_message_new()
57 {
58         smpi_received_message_t message = xbt_new(s_smpi_received_message_t, 1);
59         message->buf = NULL;
60         return message;
61 }
62
63 void smpi_message_free(void *pointer);
64
65 void smpi_message_free(void *pointer)
66 {
67         xbt_free(pointer);
68         return;
69 }
70
71 void smpi_message_reset(void *pointer);
72
73 void smpi_message_reset(void *pointer)
74 {
75         smpi_received_message_t message = pointer;
76         message->buf = NULL;
77         return;
78 }
79
80 int smpi_create_request(void *buf, int count, smpi_mpi_datatype_t datatype,
81         int src, int dst, int tag, smpi_mpi_communicator_t comm, smpi_mpi_request_t *requestptr)
82 {
83         int retval = MPI_SUCCESS;
84
85         smpi_mpi_request_t request = NULL;
86
87         // parameter checking prob belongs in smpi_mpi, but this is less repeat code
88         if (NULL == buf) {
89                 retval = MPI_ERR_INTERN;
90         } else if (0 > count) {
91                 retval = MPI_ERR_COUNT;
92         } else if (NULL == datatype) {
93                 retval = MPI_ERR_TYPE;
94         } else if (MPI_ANY_SOURCE != src && (0 > src || comm->size <= src)) {
95                 retval = MPI_ERR_RANK;
96         } else if (0 > dst || comm->size <= dst) {
97                 retval = MPI_ERR_RANK;
98         } else if (MPI_ANY_TAG != tag && 0 > tag) {
99                 retval = MPI_ERR_TAG;
100         } else if (NULL == comm) {
101                 retval = MPI_ERR_COMM;
102         } else if (NULL == requestptr) {
103                 retval = MPI_ERR_ARG;
104         } else {
105                 request           = xbt_mallocator_get(smpi_global->request_mallocator);
106                 request->comm     = comm;
107                 request->src      = src;
108                 request->dst      = dst;
109                 request->tag      = tag;
110                 request->buf      = buf;
111                 request->datatype = datatype;
112                 request->count    = count;
113
114                 *requestptr       = request;
115         }
116         return retval;
117 }
118
119 void smpi_global_init()
120 {
121         int i;
122
123         int size = SIMIX_host_get_number();
124
125         smpi_global                                      = xbt_new(s_smpi_global_t, 1);
126
127         // config variable
128         smpi_global->reference_speed                     = SMPI_DEFAULT_SPEED;
129
130         smpi_global->root_ready                          = 0;
131         smpi_global->ready_process_count                 = 0;
132
133         // start/stop
134         smpi_global->start_stop_mutex                    = SIMIX_mutex_init();
135         smpi_global->start_stop_cond                     = SIMIX_cond_init();
136
137         // host info blank until sim starts
138         // FIXME: is this okay?
139         smpi_global->hosts                               = NULL;
140         smpi_global->host_count                          = 0;
141
142         // running hosts
143         smpi_global->running_hosts_count_mutex           = SIMIX_mutex_init();
144         smpi_global->running_hosts_count                 = 0;
145
146         // mallocators
147         smpi_global->request_mallocator                  = xbt_mallocator_new(SMPI_REQUEST_MALLOCATOR_SIZE,
148                                                              smpi_request_new, smpi_request_free, smpi_request_reset);
149         smpi_global->message_mallocator                  = xbt_mallocator_new(SMPI_MESSAGE_MALLOCATOR_SIZE,
150                                                              smpi_message_new, smpi_message_free, smpi_message_reset);
151
152         // queues
153         smpi_global->pending_send_request_queues         = xbt_new(xbt_fifo_t,  size);
154         smpi_global->pending_send_request_queues_mutexes = xbt_new(smx_mutex_t, size);
155         smpi_global->pending_recv_request_queues         = xbt_new(xbt_fifo_t,  size);
156         smpi_global->pending_recv_request_queues_mutexes = xbt_new(smx_mutex_t, size);
157         smpi_global->received_message_queues             = xbt_new(xbt_fifo_t,  size);
158         smpi_global->received_message_queues_mutexes     = xbt_new(smx_mutex_t, size);
159
160         // sender/receiver processes
161         smpi_global->sender_processes                    = xbt_new(smx_process_t, size);
162         smpi_global->receiver_processes                  = xbt_new(smx_process_t, size);
163
164         // timers
165         smpi_global->timer                               = xbt_os_timer_new();
166         smpi_global->timer_mutex                         = SIMIX_mutex_init();
167         smpi_global->timer_cond                          = SIMIX_cond_init();
168
169         smpi_global->execute_mutex                       = SIMIX_mutex_init();
170         smpi_global->execute_cond                        = SIMIX_cond_init();
171         smpi_global->execute_count                       = 0;
172
173         smpi_global->do_once_duration_nodes              = NULL;
174         smpi_global->do_once_duration                    = NULL;
175         smpi_global->do_once_mutex                       = SIMIX_mutex_init();
176
177         for (i = 0; i < size; i++) {
178                 smpi_global->pending_send_request_queues[i]         = xbt_fifo_new();
179                 smpi_global->pending_send_request_queues_mutexes[i] = SIMIX_mutex_init();
180                 smpi_global->pending_recv_request_queues[i]         = xbt_fifo_new();
181                 smpi_global->pending_recv_request_queues_mutexes[i] = SIMIX_mutex_init();
182                 smpi_global->received_message_queues[i]             = xbt_fifo_new();
183                 smpi_global->received_message_queues_mutexes[i]     = SIMIX_mutex_init();
184         }
185
186 }
187
188 void smpi_global_destroy()
189 {
190         int i;
191
192         int size = SIMIX_host_get_number();
193
194         smpi_do_once_duration_node_t curr, next;
195
196         // start/stop
197         SIMIX_mutex_destroy(smpi_global->start_stop_mutex);
198         SIMIX_cond_destroy(smpi_global->start_stop_cond);
199
200         // processes
201         xbt_free(smpi_global->sender_processes);
202         xbt_free(smpi_global->receiver_processes);
203
204         // running hosts
205         SIMIX_mutex_destroy(smpi_global->running_hosts_count_mutex);
206
207         // mallocators
208         xbt_mallocator_free(smpi_global->request_mallocator);
209         xbt_mallocator_free(smpi_global->message_mallocator);
210
211         xbt_os_timer_free(smpi_global->timer);
212         SIMIX_mutex_destroy(smpi_global->timer_mutex);
213         SIMIX_cond_destroy(smpi_global->timer_cond);
214         SIMIX_mutex_destroy(smpi_global->execute_mutex);
215         SIMIX_cond_destroy(smpi_global->execute_cond);
216
217         for(curr = smpi_global->do_once_duration_nodes; NULL != curr; curr = next) {
218                 next = curr->next;
219                 xbt_free(curr->file);
220                 xbt_free(curr);
221         }
222
223         SIMIX_mutex_destroy(smpi_global->do_once_mutex);
224
225         for(i = 0; i < size; i++) {
226                 xbt_fifo_free(smpi_global->pending_send_request_queues[i]);
227                 SIMIX_mutex_destroy(smpi_global->pending_send_request_queues_mutexes[i]);
228                 xbt_fifo_free(smpi_global->pending_recv_request_queues[i]);
229                 SIMIX_mutex_destroy(smpi_global->pending_recv_request_queues_mutexes[i]);
230                 xbt_fifo_free(smpi_global->received_message_queues[i]);
231                 SIMIX_mutex_destroy(smpi_global->received_message_queues_mutexes[i]);
232         }
233
234         xbt_free(smpi_global->pending_send_request_queues);
235         xbt_free(smpi_global->pending_send_request_queues_mutexes);
236         xbt_free(smpi_global->pending_recv_request_queues);
237         xbt_free(smpi_global->pending_recv_request_queues_mutexes);
238         xbt_free(smpi_global->received_message_queues);
239         xbt_free(smpi_global->received_message_queues_mutexes);
240
241         xbt_free(smpi_global);
242
243         smpi_global = NULL;
244 }
245
246 int smpi_host_index()
247 {
248         smx_host_t host = SIMIX_host_self();
249         smpi_host_data_t hdata = (smpi_host_data_t)SIMIX_host_get_data(host);
250
251         return hdata->index;
252 }
253
254 int smpi_run_simulation(int *argc, char **argv)
255 {
256         smx_cond_t   cond           = NULL;
257         smx_action_t action         = NULL;
258
259         xbt_fifo_t   actions_failed = xbt_fifo_new();
260         xbt_fifo_t   actions_done   = xbt_fifo_new();
261
262         srand(SMPI_RAND_SEED);
263
264         SIMIX_global_init(argc, argv);
265
266         SIMIX_function_register("smpi_simulated_main", smpi_simulated_main);
267         SIMIX_function_register("smpi_sender",         smpi_sender);
268         SIMIX_function_register("smpi_receiver",       smpi_receiver);
269
270         // FIXME: ought to verify these files...
271         SIMIX_create_environment(argv[1]);
272
273         // must initialize globals between creating environment and launching app....
274         smpi_global_init();
275
276         SIMIX_launch_application(argv[2]);
277
278         /* Prepare to display some more info when dying on Ctrl-C pressing */
279         // FIXME: doesn't work
280         //signal(SIGINT, inthandler);
281
282         /* Clean IO before the run */
283         fflush(stdout);
284         fflush(stderr);
285
286         while (SIMIX_solve(actions_done, actions_failed) != -1.0) {
287                 while ((action = xbt_fifo_pop(actions_failed))) {
288                         DEBUG1("** %s failed **", action->name);
289                         while((cond = xbt_fifo_pop(action->cond_list))) {
290                                 SIMIX_cond_broadcast(cond);
291                         }
292                 }
293                 while((action = xbt_fifo_pop(actions_done))) {
294                         DEBUG1("** %s done **",action->name);
295                         while((cond = xbt_fifo_pop(action->cond_list))) {
296                                 SIMIX_cond_broadcast(cond);
297                         }
298                 }
299         }
300
301         // FIXME: cleanup incomplete
302         xbt_fifo_free(actions_failed);
303         xbt_fifo_free(actions_done);
304
305         INFO1("simulation time %g", SIMIX_get_clock());
306
307         smpi_global_destroy();
308
309         SIMIX_clean();
310
311         return 0;
312 }