source: XIOS/trunk/src/client_server_mapping.cpp @ 569

Last change on this file since 569 was 569, checked in by mhnguyen, 6 years ago

Correct some bugs on discovering server index and do some code cleanings

+) Add some checking functions to make sure mpi_isend and mpi_irecv work correctly
+) Add comments to code
+) Remove some redundant code and comments

Test
+) On Curie
+) The new functions are tested in test_new_features.f90. Test_client and test_complete work like before
+) Test cases:

  • 3 dimension grid with: 1 domain, 1 axis
  • 3 dimension grid with: 3 axis
  • Attached and connected

+) All pass and results are correct

TODO:
+) Fix zoom bug with grid composed of only one axis

File size: 5.3 KB
Line 
1/*!
2   \file client_server_mapping.hpp
3   \author Ha NGUYEN
4   \since 04 Feb 2015
5   \date 09 Mars 2015
6
7   \brief Mapping between index client and server.
8 */
9#include "client_server_mapping.hpp"
10
11namespace xios {
12
13CClientServerMapping::CClientServerMapping()
14  : indexGlobalOnServer_(), localIndexSend2Server_(), connectedClients_()
15{
16}
17
18CClientServerMapping::~CClientServerMapping()
19{
20}
21
22/*!
23  Compute mapping global index of server which client sends to.
24  \param [in] globalIndexOnClient global index on client
25  \param [in] globalIndexServer global index of servers
26*/
27void CClientServerMapping::computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
28                                                     const std::vector<CArray<size_t,1>* >& globalIndexServer)
29{
30  defaultComputeServerIndexMapping(globalIndexOnClient, globalIndexServer);
31}
32
33/*!
34   Compute index of data which are sent to server and index global on server side
35   \param [in] globalIndexOnClient global index of data on client
36   \param [in] globalIndexServer global index of server(s)
37   \param [in] localIndexOnClient local index of data on client which are sent to server
38*/
39void CClientServerMapping::defaultComputeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
40                                                            const std::vector<CArray<size_t,1>* >& globalIndexServer,
41                                                            const CArray<int,1>* localIndexOnClient)
42{
43  int nServer = globalIndexServer.size();
44  std::vector<CArray<size_t,1>::const_iterator> itBegin(nServer), itEnd(nServer), it(nServer);
45  for (int i = 0; i < nServer; ++i)
46  {
47    itBegin[i] = it[i] = globalIndexServer[i]->begin();
48    itEnd[i]   = globalIndexServer[i]->end();
49  }
50
51  size_t ssize = globalIndexOnClient.numElements();
52  for (int i = 0; i < ssize; ++i)
53  {
54    for (int j = 0; j < nServer; ++j)
55    {
56      // Just temporarily, it's bad.
57      if (std::binary_search(itBegin[j], itEnd[j], globalIndexOnClient(i)))
58      {
59        // Just try to calculate local index server on client side
60        (indexGlobalOnServer_[j]).push_back((globalIndexOnClient)(i));
61        if (0 != localIndexOnClient) (localIndexSend2Server_[j]).push_back((*localIndexOnClient)(i));
62        else
63          (localIndexSend2Server_[j]).push_back(i);
64        continue;
65      }
66    }
67  }
68}
69
70/*!
71  Compute how many clients each server will receive data from
72  On client can send data to several servers as well as one server can receive data originated from
73some clients. In order to write data correctly, each server must know from how many clients it receives data
74  \param [in] nbServer number of servers
75  \param [in] nClient number of clients
76  \param [in] clientIntraComm MPI communication of clients
77  \param [in] connectedServerRank Rank of servers connected to one client
78*/
79std::map<int,int> CClientServerMapping::computeConnectedClients(int nbServer, int nbClient,
80                                                                MPI_Comm& clientIntraComm,
81                                                                const std::vector<int>& connectedServerRank)
82{
83  std::map<int, int> connectedClients; // number of clients connected to a server
84
85  std::vector<int>::const_iterator itbVec, iteVec, it;
86  itbVec = it = connectedServerRank.begin();
87  iteVec = connectedServerRank.end();
88
89  std::vector<int> connectedServer;
90  std::vector<bool> isConnected(nbServer,false);
91
92  for (it = itbVec; it != iteVec; ++it)
93  {
94    for (int serverNum = 0; serverNum < nbServer; ++serverNum)
95      if (*it == serverNum) isConnected[serverNum] = true;
96  }
97
98  for(int serverNum = 0; serverNum<nbServer; ++serverNum)
99    if (isConnected[serverNum])
100      connectedServer.push_back(serverNum);
101
102
103  int nbConnectedServer=connectedServer.size();
104  int* recvCount=new int[nbClient];
105  int* displ=new int[nbClient];
106  int* sendBuff=new int[nbConnectedServer];
107  valarray<int> clientRes(0,nbServer);
108
109  for(int n=0;n<nbConnectedServer;n++) sendBuff[n]=connectedServer[n] ;
110
111  // get connected server for everybody
112  MPI_Allgather(&nbConnectedServer,1,MPI_INT,recvCount,1,MPI_INT,clientIntraComm) ;
113
114  displ[0]=0 ;
115  for(int n=1;n<nbClient;n++) displ[n]=displ[n-1]+recvCount[n-1] ;
116  int recvSize=displ[nbClient-1]+recvCount[nbClient-1] ;
117  int* recvBuff=new int[recvSize] ;
118
119
120  MPI_Allgatherv(sendBuff,nbConnectedServer,MPI_INT,recvBuff,recvCount,displ,MPI_INT,clientIntraComm) ;
121  for(int n=0;n<recvSize;n++) clientRes[recvBuff[n]]++ ;
122
123  for(int n=0;n<nbConnectedServer;n++)
124  {
125    connectedClients[connectedServer[n]] = clientRes[connectedServer[n]];
126  }
127
128  delete [] recvCount ;
129  delete [] displ ;
130  delete [] sendBuff ;
131  delete [] recvBuff ;
132
133  return connectedClients;
134}
135
136/*!
137  Return local index of data that is send to server
138  \return mapping of server rank and local index of sending data on the client
139*/
140const std::map<int, std::vector<int> >& CClientServerMapping::getLocalIndexSendToServer() const
141{
142  return localIndexSend2Server_;
143}
144
145/*!
146  Return global index of data on each connected server.
147  On receiving data sent from client(s), each server with this global index, is able to
148know where the data should be written.
149  \return mapping of server rank and its global index.
150*/
151const std::map<int, std::vector<size_t> >& CClientServerMapping::getGlobalIndexOnServer() const
152{
153  return indexGlobalOnServer_;
154}
155
156} //namespace xios
Note: See TracBrowser for help on using the repository browser.