-XBT_LOG_EXTERNAL_CATEGORY(smpi_base);
-XBT_LOG_EXTERNAL_CATEGORY(smpi_bench);
-XBT_LOG_EXTERNAL_CATEGORY(smpi_kernel);
-XBT_LOG_EXTERNAL_CATEGORY(smpi_mpi);
-XBT_LOG_EXTERNAL_CATEGORY(smpi_receiver);
-XBT_LOG_EXTERNAL_CATEGORY(smpi_sender);
-XBT_LOG_EXTERNAL_CATEGORY(smpi_util);
-
-smpi_mpi_global_t smpi_mpi_global = NULL;
-
-/**
- * Operations of MPI_OP : implemented=land,sum,min,max
- **/
-void smpi_mpi_land_func(void *a, void *b, int *length,
- MPI_Datatype * datatype);
-
-void smpi_mpi_land_func(void *a, void *b, int *length,
- MPI_Datatype * datatype)
-{
- int i;
- if (*datatype == smpi_mpi_global->mpi_int) {
- int *x = a, *y = b;
- for (i = 0; i < *length; i++) {
- y[i] = x[i] && y[i];
+
+static int match_recv(void* a, void* b, smx_action_t ignored) {
+ MPI_Request ref = (MPI_Request)a;
+ MPI_Request req = (MPI_Request)b;
+
+ xbt_assert(ref, "Cannot match recv against null reference");
+ xbt_assert(req, "Cannot match recv against null request");
+ return (ref->src == MPI_ANY_SOURCE || req->src == ref->src)
+ && (ref->tag == MPI_ANY_TAG || req->tag == ref->tag);
+}
+
+static int match_send(void* a, void* b,smx_action_t ignored) {
+ MPI_Request ref = (MPI_Request)a;
+ MPI_Request req = (MPI_Request)b;
+
+ xbt_assert(ref, "Cannot match send against null reference");
+ xbt_assert(req, "Cannot match send against null request");
+ return (req->src == MPI_ANY_SOURCE || req->src == ref->src)
+ && (req->tag == MPI_ANY_TAG || req->tag == ref->tag);
+}
+
+static MPI_Request build_request(void *buf, int count,
+ MPI_Datatype datatype, int src, int dst,
+ int tag, MPI_Comm comm, unsigned flags)
+{
+ MPI_Request request;
+
+ request = xbt_new(s_smpi_mpi_request_t, 1);
+ request->buf = buf;
+ // FIXME: this will have to be changed to support non-contiguous datatypes
+ request->size = smpi_datatype_size(datatype) * count;
+ request->src = src;
+ request->dst = dst;
+ request->tag = tag;
+ request->comm = comm;
+ request->action = NULL;
+ request->flags = flags;
+#ifdef HAVE_TRACING
+ request->send = 0;
+ request->recv = 0;
+#endif
+ return request;
+}
+
+static void smpi_mpi_request_free_voidp(void* request)
+{
+ MPI_Request req = request;
+ smpi_mpi_request_free(&req);
+}
+
+/* MPI Low level calls */
+MPI_Request smpi_mpi_send_init(void *buf, int count, MPI_Datatype datatype,
+ int dst, int tag, MPI_Comm comm)
+{
+ MPI_Request request =
+ build_request(buf, count, datatype, smpi_comm_rank(comm), dst, tag,
+ comm, PERSISTENT | SEND);
+
+ return request;
+}
+
+MPI_Request smpi_mpi_recv_init(void *buf, int count, MPI_Datatype datatype,
+ int src, int tag, MPI_Comm comm)
+{
+ MPI_Request request =
+ build_request(buf, count, datatype, src, smpi_comm_rank(comm), tag,
+ comm, PERSISTENT | RECV);
+
+ return request;
+}
+
+void smpi_mpi_start(MPI_Request request)
+{
+ smx_rdv_t mailbox;
+ int detached = 0;
+
+ xbt_assert(!request->action,
+ "Cannot (re)start a non-finished communication");
+ if(request->flags & RECV) {
+ print_request("New recv", request);
+ mailbox = smpi_process_mailbox();
+ // FIXME: SIMIX does not yet support non-contiguous datatypes
+ request->action = simcall_comm_irecv(mailbox, request->buf, &request->size, &match_recv, request);
+ } else {
+ print_request("New send", request);
+ mailbox = smpi_process_remote_mailbox(
+ smpi_group_index(smpi_comm_group(request->comm), request->dst));
+ // FIXME: SIMIX does not yet support non-contiguous datatypes
+
+ if (request->size < 64*1024 ) { // eager mode => detached send (FIXME: this limit should be configurable)
+ void *oldbuf = request->buf;
+ detached = 1;
+ request->buf = malloc(request->size);
+ memcpy(request->buf,oldbuf,request->size);
+ XBT_DEBUG("Send request %p is detached; buf %p copied into %p",request,oldbuf,request->buf);
+ } else {
+ XBT_DEBUG("Send request %p is not detached (buf: %p)",request,request->buf);