Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update copyright lines.
[simgrid.git] / teshsuite / smpi / gh-139 / gh-139.c
1 /* Copyright (c) 2019-2021. 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/actor.h>
9 #include <simgrid/host.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_get_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   SMPI_thread_create();
37   t->f(t->param);
38   free(t);
39 }
40
41 static void mpi_thread_create(const char* name, void* (*f)(void*), void* param)
42 {
43   struct threadwrap* threadwrap = (struct threadwrap*)malloc(sizeof(*threadwrap));
44   threadwrap->f                 = f;
45   threadwrap->param             = param;
46   sg_actor_t actor              = sg_actor_init(name, sg_host_self());
47   sg_actor_set_data(actor, threadwrap);
48   sg_actor_start(actor, thread_create_wrapper, 0, NULL);
49 }
50
51 static void mythread_create(const char* name, MPI_Request* req, int rank)
52 {
53   struct param* param = (struct param*)malloc(sizeof(*param));
54   param->req          = req;
55   param->rank         = rank;
56   mpi_thread_create(name, req_wait, param);
57 }
58
59 // Actual application
60
61 void* req_wait(void* bar)
62 {
63   struct param* param = (struct param*)bar;
64   int rank;
65   MPI_Status status;
66   char err_string[1024];
67   int length = 1024;
68   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
69
70   XBT_INFO("%d has MPI rank %d and global variable rank %d", param->rank, rank, global_rank);
71   XBT_INFO("%d waiting request", rank);
72   int ret = MPI_Wait(param->req, &status);
73   MPI_Error_string(ret, err_string, &length);
74   XBT_INFO("%d request done, return %s", rank, err_string);
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 }