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

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

Seperating global index computation on client and server side

+) Create a class which do mapping in general manner, between client and server index global
+) Remove some redundant functions and variables
+) Add some comments to code

Test
+) On Curie. Only test_new_features.f90
+) Test passes and results are correct.
+) Need to change index from 1 to 0

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