5 #include "xbt/xbt_portability.h"
6 #include "simix/simix.h"
9 xbt_fifo_t *smpi_pending_send_requests = NULL;
10 xbt_fifo_t *smpi_pending_recv_requests = NULL;
11 xbt_fifo_t *smpi_received_messages = NULL;
13 int smpi_running_hosts = 0;
15 smpi_mpi_communicator_t smpi_mpi_comm_world;
17 smpi_mpi_status_t smpi_mpi_status_ignore;
19 smpi_mpi_datatype_t smpi_mpi_byte;
20 smpi_mpi_datatype_t smpi_mpi_int;
21 smpi_mpi_datatype_t smpi_mpi_double;
23 smpi_mpi_op_t smpi_mpi_land;
24 smpi_mpi_op_t smpi_mpi_sum;
26 static xbt_os_timer_t smpi_timer;
27 static int smpi_benchmarking;
28 static double smpi_reference_speed;
30 XBT_LOG_NEW_DEFAULT_CATEGORY(smpi, "SMPI");
33 smx_mutex_t smpi_running_hosts_mutex;
35 int smpi_sender(int argc, char **argv)
40 int smpi_receiver(int argc, char **argv)
45 int smpi_run_simulation(int argc, char **argv)
47 smx_cond_t cond = NULL;
48 smx_action_t action = NULL;
50 xbt_fifo_t actions_failed = xbt_fifo_new();
51 xbt_fifo_t actions_done = xbt_fifo_new();
53 srand(SMPI_RAND_SEED);
55 SIMIX_global_init(&argc, argv);
56 SIMIX_function_register("smpi_simulated_main", smpi_simulated_main);
57 SIMIX_create_environment(argv[1]);
58 SIMIX_launch_application(argv[2]);
60 /* Prepare to display some more info when dying on Ctrl-C pressing */
61 //signal(SIGINT, inthandler);
63 /* Clean IO before the run */
67 while (SIMIX_solve(actions_done, actions_failed) != -1.0) {
68 while (action = xbt_fifo_pop(actions_failed)) {
69 DEBUG1("** %s failed **", action->name);
70 while (cond = xbt_fifo_pop(action->cond_list)) {
71 SIMIX_cond_broadcast(cond);
73 SIMIX_action_destroy(action);
75 while (action = xbt_fifo_pop(actions_done)) {
76 DEBUG1("** %s done **",action->name);
77 while (cond = xbt_fifo_pop(action->cond_list)) {
78 SIMIX_cond_broadcast(cond);
80 SIMIX_action_destroy(action);
83 xbt_fifo_free(actions_failed);
84 xbt_fifo_free(actions_done);
85 INFO1("simulation time %g", SIMIX_get_clock());
90 void smpi_mpi_land_func(void *x, void *y, void *z)
92 *(int *)z = *(int *)x && *(int *)y;
95 void smpi_mpi_sum_func(void *x, void *y, void *z)
97 *(int *)z = *(int *)x + *(int *)y;
100 int smpi_mpi_rank(smpi_mpi_communicator_t *comm, smx_host_t host)
104 for(i = comm->size - 1; i > 0 && host != comm->hosts[i]; i--);
109 int inline smpi_mpi_rank_self(smpi_mpi_communicator_t *comm)
111 return smpi_mpi_rank(comm, SIMIX_host_self());
122 // initialize some local variables
123 host = SIMIX_host_self();
124 hosts = SIMIX_host_get_table();
125 size = SIMIX_host_get_number();
127 // node 0 sets the globals
128 if (host == hosts[0]) {
131 smpi_running_hosts_mutex = SIMIX_mutex_init();
133 // global communicator
134 smpi_mpi_comm_world.size = size;
135 smpi_mpi_comm_world.barrier = 0;
136 smpi_mpi_comm_world.barrier_mutex = SIMIX_mutex_init();
137 smpi_mpi_comm_world.barrier_cond = SIMIX_cond_init();
138 smpi_mpi_comm_world.hosts = hosts;
139 smpi_mpi_comm_world.processes = xbt_new0(smx_process_t, size);
140 smpi_mpi_comm_world.processes[0] = SIMIX_process_self();
143 smpi_mpi_byte.size = (size_t)1;
144 smpi_mpi_int.size = sizeof(int);
145 smpi_mpi_double.size = sizeof(double);
148 smpi_mpi_land.func = &smpi_mpi_land_func;
149 smpi_mpi_sum.func = &smpi_mpi_sum_func;
152 smpi_pending_send_requests = xbt_new0(xbt_fifo_t, size);
153 smpi_pending_recv_requests = xbt_new0(xbt_fifo_t, size);
154 smpi_received_messages = xbt_new0(xbt_fifo_t, size);
156 for(i = 0; i < size; i++) {
157 smpi_pending_send_requests[i] = xbt_fifo_new();
158 smpi_pending_recv_requests[i] = xbt_fifo_new();
159 smpi_received_messages[i] = xbt_fifo_new();
162 smpi_timer = xbt_os_timer_new();
163 smpi_reference_speed = SMPI_DEFAULT_SPEED;
164 smpi_benchmarking = 0;
166 // FIXME: tell other nodes to initialize, and wait for all clear
168 // FIXME: send everyone okay to begin
171 // FIMXE: wait for node 0
172 smpi_mpi_comm_world.processes[smpi_mpi_rank_self(&smpi_mpi_comm_world)] = SIMIX_process_self();
173 // FIXME: signal node 0
174 // FIXME: wait for node 0
177 SIMIX_mutex_lock(smpi_running_hosts_mutex);
178 smpi_running_hosts++;
179 SIMIX_mutex_lock(smpi_running_hosts_mutex);
182 void smpi_mpi_finalize()
186 SIMIX_mutex_lock(smpi_running_hosts_mutex);
187 i = --smpi_running_hosts;
188 SIMIX_mutex_unlock(smpi_running_hosts_mutex);
192 SIMIX_mutex_destroy(smpi_running_hosts_mutex);
194 for (i = 0 ; i < smpi_mpi_comm_world.size; i++) {
195 xbt_fifo_free(smpi_pending_send_requests[i]);
196 xbt_fifo_free(smpi_pending_recv_requests[i]);
197 xbt_fifo_free(smpi_received_messages[i]);
200 xbt_free(smpi_pending_send_requests);
201 xbt_free(smpi_pending_recv_requests);
202 xbt_free(smpi_received_messages);
203 xbt_free(smpi_mpi_comm_world.processes);
204 xbt_os_timer_free(smpi_timer);
209 void smpi_bench_begin()
211 xbt_assert0(!smpi_benchmarking, "Already benchmarking");
212 smpi_benchmarking = 1;
213 xbt_os_timer_start(smpi_timer);
217 void smpi_bench_end()
220 xbt_assert0(smpi_benchmarking, "Not benchmarking yet");
221 smpi_benchmarking = 0;
222 xbt_os_timer_stop(smpi_timer);
223 duration = xbt_os_timer_elapsed(smpi_timer);
224 // FIXME: add simix call to perform computation
228 void smpi_barrier(smpi_mpi_communicator_t *comm) {
230 SIMIX_mutex_lock(comm->barrier_mutex);
233 SIMIX_cond_wait(comm->barrier_cond, comm->barrier_mutex);
236 SIMIX_cond_broadcast(comm->barrier_cond);
238 SIMIX_mutex_unlock(comm->barrier_mutex);
241 int smpi_comm_rank(smpi_mpi_communicator_t *comm, smx_host_t host)
244 for(i = 0; i < comm->size && host != comm->hosts[i]; i++);
245 if (i >= comm->size) i = -1;
249 // FIXME: move into own file
250 int smpi_gettimeofday(struct timeval *tv, struct timezone *tz)
258 now = SIMIX_get_clock();
260 tv->tv_usec = ((now - (double)tv->tv_sec) * 1000000.0);
266 unsigned int smpi_sleep(unsigned int seconds)
269 smx_action_t sleep_action;
272 // FIXME: simix sleep
273 self = SIMIX_host_self();
274 sleep_action = SIMIX_action_sleep(self, seconds);
280 void smpi_exit(int status)
283 SIMIX_mutex_lock(smpi_running_hosts_mutex);
284 smpi_running_hosts--;
285 SIMIX_mutex_unlock(smpi_running_hosts_mutex);
286 SIMIX_process_kill(SIMIX_process_self());