5 #include "xbt/xbt_portability.h"
6 #include "simix/simix.h"
7 #include "simix/private.h"
10 xbt_fifo_t *smpi_pending_send_requests = NULL;
11 xbt_fifo_t *smpi_pending_recv_requests = NULL;
12 xbt_fifo_t *smpi_received_messages = NULL;
14 int smpi_running_hosts = 0;
16 smpi_mpi_communicator_t smpi_mpi_comm_world;
18 smpi_mpi_status_t smpi_mpi_status_ignore;
20 smpi_mpi_datatype_t smpi_mpi_byte;
21 smpi_mpi_datatype_t smpi_mpi_int;
22 smpi_mpi_datatype_t smpi_mpi_double;
24 smpi_mpi_op_t smpi_mpi_land;
25 smpi_mpi_op_t smpi_mpi_sum;
27 static xbt_os_timer_t smpi_timer;
28 static int smpi_benchmarking;
29 static double smpi_reference_speed;
32 smx_mutex_t smpi_running_hosts_mutex = NULL;
33 smx_mutex_t init_mutex = NULL;
34 smx_cond_t init_cond = NULL;
39 XBT_LOG_NEW_DEFAULT_CATEGORY(smpi, "SMPI");
41 int smpi_sender(int argc, char **argv)
46 int smpi_receiver(int argc, char **argv)
51 int smpi_run_simulation(int argc, char **argv)
53 smx_cond_t cond = NULL;
54 smx_action_t action = NULL;
56 xbt_fifo_t actions_failed = xbt_fifo_new();
57 xbt_fifo_t actions_done = xbt_fifo_new();
59 srand(SMPI_RAND_SEED);
61 SIMIX_global_init(&argc, argv);
63 init_mutex = SIMIX_mutex_init();
64 init_cond = SIMIX_cond_init();
66 SIMIX_function_register("smpi_simulated_main", smpi_simulated_main);
67 SIMIX_create_environment(argv[1]);
68 SIMIX_launch_application(argv[2]);
70 /* Prepare to display some more info when dying on Ctrl-C pressing */
71 //signal(SIGINT, inthandler);
73 /* Clean IO before the run */
77 while (SIMIX_solve(actions_done, actions_failed) != -1.0) {
78 while (action = xbt_fifo_pop(actions_failed)) {
79 DEBUG1("** %s failed **", action->name);
80 while (cond = xbt_fifo_pop(action->cond_list)) {
81 SIMIX_cond_broadcast(cond);
83 SIMIX_action_destroy(action);
85 while (action = xbt_fifo_pop(actions_done)) {
86 DEBUG1("** %s done **",action->name);
87 while (cond = xbt_fifo_pop(action->cond_list)) {
88 SIMIX_cond_broadcast(cond);
90 SIMIX_action_destroy(action);
93 xbt_fifo_free(actions_failed);
94 xbt_fifo_free(actions_done);
95 INFO1("simulation time %g", SIMIX_get_clock());
100 void smpi_mpi_land_func(void *x, void *y, void *z)
102 *(int *)z = *(int *)x && *(int *)y;
105 void smpi_mpi_sum_func(void *x, void *y, void *z)
107 *(int *)z = *(int *)x + *(int *)y;
110 int smpi_mpi_rank(smpi_mpi_communicator_t *comm, smx_host_t host)
114 for(i = comm->size - 1; i > 0 && host != comm->hosts[i]; i--);
119 int inline smpi_mpi_rank_self(smpi_mpi_communicator_t *comm)
121 return smpi_mpi_rank(comm, SIMIX_host_self());
128 smx_process_t process;
133 // initialize some local variables
134 host = SIMIX_host_self();
135 hosts = SIMIX_host_get_table();
136 size = SIMIX_host_get_number();
138 // node 0 sets the globals
139 if (host == hosts[0]) {
142 smpi_running_hosts_mutex = SIMIX_mutex_init();
143 smpi_running_hosts = size;
145 // global communicator
146 smpi_mpi_comm_world.size = size;
147 smpi_mpi_comm_world.barrier = 0;
148 smpi_mpi_comm_world.barrier_mutex = SIMIX_mutex_init();
149 smpi_mpi_comm_world.barrier_cond = SIMIX_cond_init();
150 smpi_mpi_comm_world.hosts = hosts;
151 smpi_mpi_comm_world.processes = xbt_new0(smx_process_t, size);
152 smpi_mpi_comm_world.processes[0] = SIMIX_process_self();
155 smpi_mpi_byte.size = (size_t)1;
156 smpi_mpi_int.size = sizeof(int);
157 smpi_mpi_double.size = sizeof(double);
160 smpi_mpi_land.func = &smpi_mpi_land_func;
161 smpi_mpi_sum.func = &smpi_mpi_sum_func;
164 smpi_pending_send_requests = xbt_new0(xbt_fifo_t, size);
165 smpi_pending_recv_requests = xbt_new0(xbt_fifo_t, size);
166 smpi_received_messages = xbt_new0(xbt_fifo_t, size);
168 for(i = 0; i < size; i++) {
169 smpi_pending_send_requests[i] = xbt_fifo_new();
170 smpi_pending_recv_requests[i] = xbt_fifo_new();
171 smpi_received_messages[i] = xbt_fifo_new();
174 smpi_timer = xbt_os_timer_new();
175 smpi_reference_speed = SMPI_DEFAULT_SPEED;
176 smpi_benchmarking = 0;
178 // signal all nodes to perform initialization
179 SIMIX_mutex_lock(init_mutex);
181 SIMIX_cond_broadcast(init_cond);
182 SIMIX_mutex_unlock(init_mutex);
186 // make sure root is done before own initialization
187 SIMIX_mutex_lock(init_mutex);
189 SIMIX_cond_wait(init_cond, init_mutex);
191 SIMIX_mutex_unlock(init_mutex);
193 smpi_mpi_comm_world.processes[smpi_mpi_rank_self(&smpi_mpi_comm_world)] = SIMIX_process_self();
197 // wait for all nodes to signal initializatin complete
198 SIMIX_mutex_lock(init_mutex);
200 if (readycount < size) {
201 SIMIX_cond_wait(init_cond, init_mutex);
203 SIMIX_cond_broadcast(init_cond);
205 SIMIX_mutex_unlock(init_mutex);
209 void smpi_mpi_finalize()
213 SIMIX_mutex_lock(smpi_running_hosts_mutex);
214 i = --smpi_running_hosts;
215 SIMIX_mutex_unlock(smpi_running_hosts_mutex);
219 SIMIX_mutex_destroy(smpi_running_hosts_mutex);
221 for (i = 0 ; i < smpi_mpi_comm_world.size; i++) {
222 xbt_fifo_free(smpi_pending_send_requests[i]);
223 xbt_fifo_free(smpi_pending_recv_requests[i]);
224 xbt_fifo_free(smpi_received_messages[i]);
227 xbt_free(smpi_pending_send_requests);
228 xbt_free(smpi_pending_recv_requests);
229 xbt_free(smpi_received_messages);
231 SIMIX_mutex_destroy(smpi_mpi_comm_world.barrier_mutex);
232 SIMIX_cond_destroy(smpi_mpi_comm_world.barrier_cond);
233 xbt_free(smpi_mpi_comm_world.processes);
235 xbt_os_timer_free(smpi_timer);
240 void smpi_bench_begin()
242 xbt_assert0(!smpi_benchmarking, "Already benchmarking");
243 smpi_benchmarking = 1;
244 xbt_os_timer_start(smpi_timer);
248 void smpi_bench_end()
251 xbt_assert0(smpi_benchmarking, "Not benchmarking yet");
252 smpi_benchmarking = 0;
253 xbt_os_timer_stop(smpi_timer);
254 duration = xbt_os_timer_elapsed(smpi_timer);
255 // FIXME: add simix call to perform computation
259 void smpi_barrier(smpi_mpi_communicator_t *comm) {
261 SIMIX_mutex_lock(comm->barrier_mutex);
264 SIMIX_cond_wait(comm->barrier_cond, comm->barrier_mutex);
267 SIMIX_cond_broadcast(comm->barrier_cond);
269 SIMIX_mutex_unlock(comm->barrier_mutex);
272 int smpi_comm_rank(smpi_mpi_communicator_t *comm, smx_host_t host)
275 for(i = 0; i < comm->size && host != comm->hosts[i]; i++);
276 if (i >= comm->size) i = -1;
280 // FIXME: move into own file
281 int smpi_gettimeofday(struct timeval *tv, struct timezone *tz)
289 now = SIMIX_get_clock();
291 tv->tv_usec = ((now - (double)tv->tv_sec) * 1000000.0);
297 unsigned int smpi_sleep(unsigned int seconds)
302 smx_action_t sleep_action;
305 host = SIMIX_host_self();
306 sleep_action = SIMIX_action_sleep(host, seconds);
307 mutex = SIMIX_mutex_init();
308 cond = SIMIX_cond_init();
309 SIMIX_mutex_lock(mutex);
310 SIMIX_register_condition_to_action(sleep_action, cond);
311 SIMIX_register_action_to_condition(sleep_action, cond);
312 SIMIX_cond_wait(cond, mutex);
313 SIMIX_mutex_unlock(mutex);
314 SIMIX_mutex_destroy(mutex);
315 SIMIX_cond_destroy(cond);
316 // FIXME: check for success/failure?
321 void smpi_exit(int status)
324 SIMIX_mutex_lock(smpi_running_hosts_mutex);
325 smpi_running_hosts--;
326 SIMIX_mutex_unlock(smpi_running_hosts_mutex);
327 SIMIX_process_kill(SIMIX_process_self());