Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fb7375a77e5a79de5f7cf26d7d5017ea108564f3
[simgrid.git] / src / smpi / smpi_deployment.cpp
1 /* Copyright (c) 2004-2017. 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 "private.h"
8 #include "simgrid/msg.h" /* barrier */
9 #include "src/smpi/SmpiHost.hpp"
10 #include "xbt/dict.h"
11 #include "xbt/log.h"
12 #include "xbt/sysdep.h"
13
14 static xbt_dict_t smpi_instances = nullptr;
15 extern int process_count;
16 extern int* index_to_process_data;
17
18 typedef struct s_smpi_mpi_instance{
19   const char* name;
20   int size;
21   int present_processes;
22   int index;
23   MPI_Comm comm_world;
24   msg_bar_t finalization_barrier;
25 } s_smpi_mpi_instance_t;
26
27 /** \ingroup smpi_simulation
28  * \brief Registers a running instance of a MPI program.
29  *
30  * FIXME : remove MSG from the loop at some point.
31  * \param name the reference name of the function.
32  * \param code the main mpi function (must have a int ..(int argc, char *argv[])) prototype
33  * \param num_processes the size of the instance we want to deploy
34  */
35 void SMPI_app_instance_register(const char *name, xbt_main_func_t code, int num_processes)
36 {
37   SIMIX_function_register(name, code);
38
39   s_smpi_mpi_instance_t* instance = (s_smpi_mpi_instance_t*)xbt_malloc(sizeof(s_smpi_mpi_instance_t));
40
41   static int already_called = 0;
42   if (!already_called) {
43     already_called = 1;
44     xbt_dynar_t hosts = MSG_hosts_as_dynar();
45     unsigned int cursor;
46     void* h;
47     xbt_dynar_foreach(hosts, cursor, h) {
48       simgrid::s4u::Host* host = static_cast<simgrid::s4u::Host*>(h);
49       host->extension_set(new simgrid::smpi::SmpiHost(host));
50     }
51     xbt_dynar_free(&hosts);
52   }
53
54   instance->name                 = name;
55   instance->size                 = num_processes;
56   instance->present_processes    = 0;
57   instance->index                = process_count;
58   instance->comm_world           = MPI_COMM_NULL;
59   instance->finalization_barrier = MSG_barrier_init(num_processes);
60
61   process_count+=num_processes;
62
63   if(smpi_instances==nullptr){
64     smpi_instances = xbt_dict_new_homogeneous(xbt_free_f);
65   }
66
67
68   xbt_dict_set(smpi_instances, name, (void*)instance, nullptr);
69 }
70
71 //get the index of the process in the process_data array
72 void smpi_deployment_register_process(const char* instance_id, int rank, int index)
73 {
74
75   if(smpi_instances==nullptr){//no instance registered, we probably used smpirun.
76     index_to_process_data[index]=index;
77     return;
78   }
79
80   s_smpi_mpi_instance_t* instance =
81      static_cast<s_smpi_mpi_instance_t*>(xbt_dict_get_or_null(smpi_instances, instance_id));
82   xbt_assert(instance, "Error, unknown instance %s", instance_id);
83
84   if(instance->comm_world == MPI_COMM_NULL){
85     MPI_Group group = new  simgrid::smpi::Group(instance->size);
86     instance->comm_world = new  simgrid::smpi::Comm(group, nullptr);
87   }
88   instance->present_processes++;
89   index_to_process_data[index]=instance->index+rank;
90   instance->comm_world->group()->set_mapping(index, rank);
91 }
92
93 //get the index of the process in the process_data array
94 MPI_Comm* smpi_deployment_comm_world(const char* instance_id)
95 {
96   if(smpi_instances==nullptr){//no instance registered, we probably used smpirun.
97     return nullptr;
98   }
99   s_smpi_mpi_instance_t* instance =
100      static_cast<s_smpi_mpi_instance_t*>(xbt_dict_get_or_null(smpi_instances, instance_id));
101   xbt_assert(instance, "Error, unknown instance %s", instance_id);
102   return &instance->comm_world;
103 }
104
105 msg_bar_t smpi_deployment_finalization_barrier(const char* instance_id)
106 {
107   if(smpi_instances==nullptr){//no instance registered, we probably used smpirun.
108     return nullptr;
109   }
110   s_smpi_mpi_instance_t* instance =
111      static_cast<s_smpi_mpi_instance_t*>(xbt_dict_get_or_null(smpi_instances, instance_id));
112   xbt_assert(instance, "Error, unknown instance %s", instance_id);
113   return instance->finalization_barrier;
114 }
115
116 void smpi_deployment_cleanup_instances(){
117   xbt_dict_cursor_t cursor = nullptr;
118   s_smpi_mpi_instance_t* instance = nullptr;
119   char *name = nullptr;
120   xbt_dict_foreach(smpi_instances, cursor, name, instance) {
121     if(instance->comm_world!=MPI_COMM_NULL)
122       delete instance->comm_world->group();
123     delete instance->comm_world;
124     MSG_barrier_destroy(instance->finalization_barrier);
125   }
126   xbt_dict_free(&smpi_instances);
127 }