Logo AND Algorithmique Numérique Distribuée

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