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

Last change on this file since 568 was 568, checked in by mhnguyen, 9 years ago

Implementing discovering algorithm of server index

+) Implement the algorithm with only one level
+) Remove some redundant functions, corrects some interface

Test
+) On Curie
+) Test passed and results are correct

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