Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Clearly state that we don't care about the return code of actors
[simgrid.git] / teshsuite / smpi / gh-139 / gh-139.c
1 /* Copyright (c) 2019-2020. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <mpi.h>
8 #include <simgrid/msg.h>
9 #include <simgrid/simix.h>
10 #include <stdio.h>
11
12 XBT_LOG_NEW_DEFAULT_CATEGORY(smpi_test, "Messages specific for this SMPI example");
13
14 struct param {
15   MPI_Request* req;
16   int rank;
17 };
18
19 struct threadwrap {
20   void* father_data;
21   void* (*f)(void*);
22   void* param;
23 };
24
25 static int global_rank;
26 void* req_wait(void* bar);
27
28 // Thread creation helper
29
30 static void thread_create_wrapper(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
31 {
32   int the_global_rank  = global_rank;
33   struct threadwrap* t = (struct threadwrap*)sg_actor_self_data();
34   XBT_INFO("new thread has parameter rank %d and global variable rank %d", ((struct param*)(t->param))->rank,
35            the_global_rank);
36   sg_actor_self_data_set(t->father_data);
37   t->f(t->param);
38   sg_actor_self_data_set(NULL);
39   free(t);
40 }
41
42 static void mpi_thread_create(const char* name, void* (*f)(void*), void* param)
43 {
44   struct threadwrap* threadwrap = (struct threadwrap*)malloc(sizeof(*threadwrap));
45   threadwrap->father_data       = sg_actor_self_data();
46   threadwrap->f                 = f;
47   threadwrap->param             = param;
48   sg_actor_t actor              = sg_actor_init(name, sg_host_self());
49   sg_actor_data_set(actor, threadwrap);
50   sg_actor_start(actor, thread_create_wrapper, 0, NULL);
51 }
52
53 static void mythread_create(const char* name, MPI_Request* req, int rank)
54 {
55   struct param* param = (struct param*)malloc(sizeof(*param));
56   param->req          = req;
57   param->rank         = rank;
58   mpi_thread_create(name, req_wait, param);
59 }
60
61 // Actual application
62
63 void* req_wait(void* bar)
64 {
65   struct param* param = (struct param*)bar;
66   int rank;
67   MPI_Status status;
68
69   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
70
71   XBT_INFO("%d has MPI rank %d and global variable rank %d", param->rank, rank, global_rank);
72   XBT_INFO("%d waiting request", rank);
73   MPI_Wait(param->req, &status);
74   XBT_INFO("%d request done", rank);
75   XBT_INFO("%d still has MPI rank %d and global variable %d", param->rank, rank, global_rank);
76   free(param);
77   return NULL;
78 }
79
80 int main(int argc, char* argv[])
81 {
82   int rank;
83   int size;
84   char c = 0;
85   MPI_Request req;
86   MPI_Init(&argc, &argv);
87   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
88   MPI_Comm_size(MPI_COMM_WORLD, &size);
89   XBT_INFO("I'm %d/%d", rank, size);
90   global_rank = rank;
91
92   if (rank == 0) {
93     c = 42;
94     MPI_Isend(&c, 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD, &req);
95     mythread_create("wait send", &req, rank);
96   } else if (rank == 1) {
97     MPI_Irecv(&c, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &req);
98     mythread_create("wait recv", &req, rank);
99   }
100
101   sg_actor_sleep_for(1 + rank);
102   MPI_Finalize();
103   XBT_INFO("finally %d", c);
104   return 0;
105 }