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

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

Changing interface of tests to make sure global index begins at zero (0)

+) In all tests, ibegin, jbegin starts at zero (0), so there are some minor changes in field_glo
+) Improve a littel bit class design

Test
+) On Curie,
+) All test passed and results are the same as before

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