2 /* Copyright (c) 2007-2014. The SimGrid Team.
3 * All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_rma, smpi, "Logging specific to SMPI (RMA operations)");
14 /* FIXME:using a global array of MPI_Win simplifies the way to exchange pointers and info,
15 * but it breaks distributed simulation
18 xbt_bar_t creation_bar = NULL;
20 typedef struct s_smpi_mpi_win{
29 MPI_Win* connected_wins;
33 MPI_Win smpi_mpi_win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm){
37 int comm_size = smpi_comm_size(comm);
38 int rank=smpi_comm_rank(comm);
39 XBT_DEBUG("Creating window");
41 win = xbt_new(s_smpi_mpi_win_t, 1);
44 win->disp_unit = disp_unit;
48 win->requests = xbt_dynar_new(sizeof(MPI_Request), NULL);
49 win->connected_wins = xbt_malloc0(comm_size*sizeof(MPI_Win));
50 win->connected_wins[rank] = win;
53 win->bar=xbt_barrier_init(comm_size);
56 mpi_coll_allgather_fun(&(win->connected_wins[rank]),
64 mpi_coll_bcast_fun( &(win->bar),
70 mpi_coll_barrier_fun(comm);
75 int smpi_mpi_win_free( MPI_Win* win){
77 //As per the standard, perform a barrier to ensure every async comm is finished
78 xbt_barrier_wait((*win)->bar);
79 xbt_dynar_free(&(*win)->requests);
80 xbt_free((*win)->connected_wins);
87 int smpi_mpi_win_fence( int assert, MPI_Win win){
89 XBT_DEBUG("Entering fence");
91 if(assert != MPI_MODE_NOPRECEDE){
92 xbt_barrier_wait(win->bar);
94 xbt_dynar_t reqs = win->requests;
95 int size = xbt_dynar_length(reqs);
98 // start all requests that have been prepared by another process
99 xbt_dynar_foreach(reqs, cpt, req){
100 if (req->flags & PREPARED) smpi_mpi_start(req);
103 MPI_Request* treqs = xbt_dynar_to_array(reqs);
104 smpi_mpi_waitall(size,treqs,MPI_STATUSES_IGNORE);
106 win->requests=xbt_dynar_new(sizeof(MPI_Request), NULL);
109 win->assert = assert;
111 xbt_barrier_wait(win->bar);
112 XBT_DEBUG("Leaving fence ");
117 int smpi_mpi_put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
118 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win)
120 //get receiver pointer
121 MPI_Win recv_win = win->connected_wins[target_rank];
123 void* recv_addr = recv_win->base + target_disp * smpi_datatype_size(target_datatype)/* recv_win->disp_unit*/;
124 smpi_datatype_use(origin_datatype);
125 smpi_datatype_use(target_datatype);
126 XBT_DEBUG("Entering MPI_Put to %d", target_rank);
128 if(target_rank != smpi_comm_rank(win->comm)){
129 //prepare send_request
130 MPI_Request sreq = smpi_rma_send_init(origin_addr, origin_count, origin_datatype,
131 smpi_process_index(), smpi_group_index(smpi_comm_group(win->comm),target_rank), RMA_TAG+1, win->comm);
133 //prepare receiver request
134 MPI_Request rreq = smpi_rma_recv_init(recv_addr, target_count, target_datatype,
135 smpi_process_index(), smpi_group_index(smpi_comm_group(win->comm),target_rank), RMA_TAG+1, recv_win->comm);
137 //push request to receiver's win
138 xbt_dynar_push_as(recv_win->requests, MPI_Request, rreq);
141 smpi_mpi_start(sreq);
143 //push request to sender's win
144 xbt_dynar_push_as(win->requests, MPI_Request, sreq);
146 //perform actual copy
147 /*smpi_datatype_copy(origin_addr, origin_count, origin_datatype,
148 recv_addr, target_count, target_datatype);*/
153 int smpi_mpi_get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
154 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win)
157 MPI_Win send_win = win->connected_wins[target_rank];
159 void* send_addr = send_win->base + target_disp * smpi_datatype_size(target_datatype)/** send_win->disp_unit*/;
160 smpi_datatype_use(origin_datatype);
161 smpi_datatype_use(target_datatype);
162 XBT_DEBUG("Entering MPI_Get from %d", target_rank);
164 if(target_rank != smpi_comm_rank(win->comm)){
165 //prepare send_request
166 MPI_Request sreq = smpi_rma_send_init(send_addr, target_count, target_datatype,
167 smpi_group_index(smpi_comm_group(win->comm),target_rank), smpi_process_index(), RMA_TAG+2, send_win->comm);
169 //prepare receiver request
170 MPI_Request rreq = smpi_rma_recv_init(origin_addr, origin_count, origin_datatype,
171 smpi_group_index(smpi_comm_group(win->comm),target_rank), smpi_process_index(), RMA_TAG+2, win->comm);
173 //push request to receiver's win
174 xbt_dynar_push_as(send_win->requests, MPI_Request, sreq);
177 smpi_mpi_start(rreq);
179 //push request to sender's win
180 xbt_dynar_push_as(win->requests, MPI_Request, rreq);
182 //perform actual copy
183 /*smpi_datatype_copy(send_addr, target_count, target_datatype,
184 origin_addr, origin_count, origin_datatype);*/
191 int smpi_mpi_accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
192 MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win)
194 //get receiver pointer
195 MPI_Win recv_win = win->connected_wins[target_rank];
197 void* recv_addr = recv_win->base + target_disp * smpi_datatype_size(target_datatype) /** recv_win->disp_unit*/;
198 XBT_DEBUG("Entering MPI_Accumulate to %d", target_rank);
200 smpi_datatype_use(origin_datatype);
201 smpi_datatype_use(target_datatype);
203 if(target_rank != smpi_comm_rank(win->comm)){
204 //prepare send_request
205 MPI_Request sreq = smpi_rma_send_init(origin_addr, origin_count, origin_datatype,
206 smpi_process_index(), smpi_group_index(smpi_comm_group(win->comm),target_rank), RMA_TAG+3, win->comm);
208 //prepare receiver request
209 MPI_Request rreq = smpi_rma_recv_init(NULL, 0, target_datatype,
210 smpi_process_index(), smpi_group_index(smpi_comm_group(win->comm),target_rank), RMA_TAG+3, recv_win->comm);
211 rreq->flags |= ACCUMULATE;
212 //push request to receiver's win
213 xbt_dynar_push_as(recv_win->requests, MPI_Request, rreq);
215 smpi_mpi_start(sreq);
216 //push request to sender's win
217 xbt_dynar_push_as(win->requests, MPI_Request, sreq);
219 //perform actual accumulation
220 smpi_op_apply(op, origin_addr, recv_addr, &origin_count, &origin_datatype);