4 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_base, smpi,
5 "Logging specific to SMPI (base)");
6 XBT_LOG_EXTERNAL_CATEGORY(smpi_base);
7 XBT_LOG_EXTERNAL_CATEGORY(smpi_bench);
8 XBT_LOG_EXTERNAL_CATEGORY(smpi_kernel);
9 XBT_LOG_EXTERNAL_CATEGORY(smpi_mpi);
10 XBT_LOG_EXTERNAL_CATEGORY(smpi_mpi_dt);
11 XBT_LOG_EXTERNAL_CATEGORY(smpi_coll);
12 XBT_LOG_EXTERNAL_CATEGORY(smpi_receiver);
13 XBT_LOG_EXTERNAL_CATEGORY(smpi_sender);
14 XBT_LOG_EXTERNAL_CATEGORY(smpi_util);
16 smpi_mpi_global_t smpi_mpi_global = NULL;
20 * Operations of MPI_OP : implemented=land,sum,min,max
22 void smpi_mpi_land_func(void *a, void *b, int *length,
23 MPI_Datatype * datatype);
25 void smpi_mpi_land_func(void *a, void *b, int *length,
26 MPI_Datatype * datatype)
29 if (*datatype == smpi_mpi_global->mpi_int) {
31 for (i = 0; i < *length; i++) {
38 * sum two vectors element-wise
40 * @param a the first vectors
41 * @param b the second vectors
42 * @return the second vector is modified and contains the element-wise sums
44 void smpi_mpi_sum_func(void *a, void *b, int *length,
45 MPI_Datatype * datatype);
47 void smpi_mpi_sum_func(void *a, void *b, int *length, MPI_Datatype * datatype)
50 if ((*datatype == smpi_mpi_global->mpi_byte) || (*datatype == smpi_mpi_global->mpi_char)) {
52 for (i = 0; i < *length; i++) {
55 } else if (*datatype == smpi_mpi_global->mpi_int) {
57 for (i = 0; i < *length; i++) {
60 } else if (*datatype == smpi_mpi_global->mpi_float) {
62 for (i = 0; i < *length; i++) {
65 } else if (*datatype == smpi_mpi_global->mpi_double) {
66 double *x = a, *y = b;
67 for (i = 0; i < *length; i++) {
73 *i multiply two vectors element-wise
75 * @param a the first vectors
76 * @param b the second vectors
77 * @return the second vector is modified and contains the element-wise products
79 void smpi_mpi_prod_func(void *a, void *b, int *length,
80 MPI_Datatype * datatype);
82 void smpi_mpi_prod_func(void *a, void *b, int *length, MPI_Datatype * datatype)
85 if ((*datatype == smpi_mpi_global->mpi_byte) || (*datatype == smpi_mpi_global->mpi_char)) {
87 for (i = 0; i < *length; i++) {
90 } else if (*datatype == smpi_mpi_global->mpi_int) {
92 for (i = 0; i < *length; i++) {
95 } else if (*datatype == smpi_mpi_global->mpi_float) {
97 for (i = 0; i < *length; i++) {
100 } else if (*datatype == smpi_mpi_global->mpi_double) {
101 double *x = a, *y = b;
102 for (i = 0; i < *length; i++) {
108 * compute the min of two vectors element-wise
110 void smpi_mpi_min_func(void *a, void *b, int *length,
111 MPI_Datatype * datatype);
113 void smpi_mpi_min_func(void *a, void *b, int *length, MPI_Datatype * datatype)
116 if ((*datatype == smpi_mpi_global->mpi_byte) || (*datatype == smpi_mpi_global->mpi_char)) {
118 for (i = 0; i < *length; i++) {
119 y[i] = x[i] < y[i] ? x[i] : y[i];
122 if (*datatype == smpi_mpi_global->mpi_int) {
124 for (i = 0; i < *length; i++) {
125 y[i] = x[i] < y[i] ? x[i] : y[i];
128 if (*datatype == smpi_mpi_global->mpi_float) {
129 float *x = a, *y = b;
130 for (i = 0; i < *length; i++) {
131 y[i] = x[i] < y[i] ? x[i] : y[i];
134 if (*datatype == smpi_mpi_global->mpi_double) {
135 double *x = a, *y = b;
136 for (i = 0; i < *length; i++) {
137 y[i] = x[i] < y[i] ? x[i] : y[i];
147 * compute the max of two vectors element-wise
149 void smpi_mpi_max_func(void *a, void *b, int *length,
150 MPI_Datatype * datatype);
152 void smpi_mpi_max_func(void *a, void *b, int *length, MPI_Datatype * datatype)
155 if ((*datatype == smpi_mpi_global->mpi_byte) || (*datatype == smpi_mpi_global->mpi_char)) {
157 for (i = 0; i < *length; i++) {
158 y[i] = x[i] > y[i] ? x[i] : y[i];
160 } else if (*datatype == smpi_mpi_global->mpi_int) {
162 for (i = 0; i < *length; i++) {
163 y[i] = x[i] > y[i] ? x[i] : y[i];
165 } else if (*datatype == smpi_mpi_global->mpi_float) {
166 float *x = a, *y = b;
167 for (i = 0; i < *length; i++) {
168 y[i] = x[i] > y[i] ? x[i] : y[i];
170 } else if (*datatype == smpi_mpi_global->mpi_double) {
171 double *x = a, *y = b;
172 for (i = 0; i < *length; i++) {
173 y[i] = x[i] > y[i] ? x[i] : y[i];
183 * tell the MPI rank of the calling process (from its SIMIX process id)
185 int smpi_mpi_comm_rank(smpi_mpi_communicator_t comm)
187 return comm->index_to_rank_map[smpi_process_index()];
190 void smpi_process_init(int *argc, char ***argv)
192 smpi_process_data_t pdata;
194 // initialize some local variables
196 pdata = xbt_new(s_smpi_process_data_t, 1);
197 SIMIX_process_set_data(SIMIX_process_self(), pdata);
199 /* get rank from command line, and remove it from argv */
200 pdata->index = atoi((*argv)[1]);
201 DEBUG1("I'm rank <%d>", pdata->index);
203 memmove((*argv)[1], (*argv)[2], sizeof(char *) * (*argc - 2));
204 (*argv)[(*argc) - 1] = NULL;
208 pdata->mutex = SIMIX_mutex_init();
209 pdata->cond = SIMIX_cond_init();
212 pdata->pending_recv_request_queue = xbt_fifo_new();
213 pdata->pending_send_request_queue = xbt_fifo_new();
214 pdata->received_message_queue = xbt_fifo_new();
216 pdata->main = SIMIX_process_self();
217 pdata->sender = SIMIX_process_create("smpi_sender",
219 SIMIX_host_get_name(SIMIX_host_self()),
222 pdata->receiver = SIMIX_process_create("smpi_receiver",
223 smpi_receiver, pdata,
224 SIMIX_host_get_name(SIMIX_host_self
228 smpi_global->main_processes[pdata->index] = SIMIX_process_self();
232 void smpi_process_finalize()
234 smpi_process_data_t pdata = SIMIX_process_get_data(SIMIX_process_self());
236 pdata->finalize = 2; /* Tell sender and receiver to quit */
237 SIMIX_process_resume(pdata->sender);
238 SIMIX_process_resume(pdata->receiver);
239 while (pdata->finalize > 0) { /* wait until it's done */
240 SIMIX_cond_wait(pdata->cond, pdata->mutex);
243 SIMIX_mutex_destroy(pdata->mutex);
244 SIMIX_cond_destroy(pdata->cond);
245 xbt_fifo_free(pdata->pending_recv_request_queue);
246 xbt_fifo_free(pdata->pending_send_request_queue);
247 xbt_fifo_free(pdata->received_message_queue);
252 /*int smpi_mpi_barrier(smpi_mpi_communicator_t comm)
255 SIMIX_mutex_lock(comm->barrier_mutex);
256 ++comm->barrier_count;
257 if (comm->barrier_count > comm->size) { // only happens on second barrier...
258 comm->barrier_count = 0;
259 } else if (comm->barrier_count == comm->size) {
260 SIMIX_cond_broadcast(comm->barrier_cond);
262 while (comm->barrier_count < comm->size) {
263 SIMIX_cond_wait(comm->barrier_cond, comm->barrier_mutex);
265 SIMIX_mutex_unlock(comm->barrier_mutex);
271 int smpi_mpi_isend(smpi_mpi_request_t request)
273 smpi_process_data_t pdata = SIMIX_process_get_data(SIMIX_process_self());
274 int retval = MPI_SUCCESS;
276 if (NULL == request) {
277 retval = MPI_ERR_INTERN;
279 xbt_fifo_push(pdata->pending_send_request_queue, request);
280 SIMIX_process_resume(pdata->sender);
286 int smpi_mpi_irecv(smpi_mpi_request_t request)
288 int retval = MPI_SUCCESS;
289 smpi_process_data_t pdata = SIMIX_process_get_data(SIMIX_process_self());
291 if (NULL == request) {
292 retval = MPI_ERR_INTERN;
294 xbt_fifo_push(pdata->pending_recv_request_queue, request);
296 if (SIMIX_process_is_suspended(pdata->receiver)) {
297 SIMIX_process_resume(pdata->receiver);
304 void print_req( smpi_mpi_request_t r );
305 void print_req( smpi_mpi_request_t r ) {
306 fprintf(stderr,"***req %p-> src=%d dst=%d tag=%d completed=0x%x consumed=0x%x\n",r,r->src,r->dst,r->tag,r->completed,r->consumed);
311 * wait and friends ...
313 int smpi_mpi_wait(smpi_mpi_request_t request, smpi_mpi_status_t * status)
315 int retval = MPI_SUCCESS;
317 if (NULL == request) {
318 retval = MPI_ERR_INTERN;
321 DEBUG3("entered smpi_mpi_wait() for req_src=%d,req_dst=%d,req_tag=%d",
322 request->src,request->dst,request->tag);
323 SIMIX_mutex_lock(request->mutex);
324 //#define DEBUG_STEPH
326 print_req( request ); //@@
328 while (!request->completed) {
329 SIMIX_cond_wait(request->cond, request->mutex);
331 if (NULL != status) {
332 status->MPI_SOURCE = request->src;
333 status->MPI_TAG = request->tag;
334 status->MPI_ERROR = MPI_SUCCESS;
336 SIMIX_mutex_unlock(request->mutex);
345 int smpi_mpi_waitall(int count, smpi_mpi_request_t requests[],
346 smpi_mpi_status_t status[])
351 smpi_mpi_status_t stat;
353 for (cpt = 0; cpt < count; cpt++) {
354 retval = smpi_mpi_waitany(count, requests, &index, &stat);
355 if (retval != MPI_SUCCESS)
357 if (MPI_STATUS_IGNORE != status)
358 memcpy(&(status[index]), &stat, sizeof(stat));
366 int smpi_mpi_waitany(int count, smpi_mpi_request_t * requests, int *index,
367 smpi_mpi_status_t * status)
371 DEBUG0("entering smpi_wait_any() ...");
372 *index = MPI_UNDEFINED;
373 if (NULL == requests) {
374 return MPI_ERR_INTERN;
376 /* First check if one of them is already done */
377 for (cpt = 0; cpt < count; cpt++) {
378 DEBUG2(" exam req[%d] of msg from <%d>",cpt,requests[cpt]->src);
379 if (requests[cpt]->completed && !requests[cpt]->consumed) { /* got ya */
380 DEBUG2("smpi_wait_any() found match req[%d] of msg from <%d>",cpt,requests[cpt]->src);
385 /* If none found, block */
386 /* FIXME: should use a SIMIX_cond_waitany, when implemented. For now, block on the first one */
388 for (cpt = 0; cpt < count; cpt++) {
391 print_req( requests[cpt] );
393 if (!requests[cpt]->completed) { /* this one is not done, wait on it */
394 DEBUG3("smpi_waitany() blocked waiting a msg <%d> -> <%d>, tag=%d",requests[cpt]->src,requests[cpt]->dst,requests[cpt]->tag);
395 while (!requests[cpt]->completed)
396 SIMIX_cond_wait(requests[cpt]->cond, requests[cpt]->mutex);
402 if (cpt == count) /* they are all done. Damn user */
403 return MPI_ERR_REQUEST;
408 print_req( requests[cpt] );
410 requests[*index]->consumed = 1;
412 print_req( requests[cpt] );
414 DEBUG2("smpi_waitany() request %p unblocked ... mark *req[%d]->consumed",requests[*index],cpt);
415 if (NULL != status) {
416 status->MPI_SOURCE = requests[*index]->src;
417 status->MPI_TAG = requests[*index]->tag;
418 status->MPI_ERROR = MPI_SUCCESS;