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

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

Implementing a grid formed by only one axis or group of axis

+) Add several new attributes to axis. From now on, each axis can be distributed on client side
+) Modify mask of grid to make it more flexible to different dimension
+) Fix some bugs relating to calculation of local data index on client
+) Clean some redundant codes

Test
+) On Curie, only test_new_features.f90
+) Test cases:

  • Grid composed of: 1 domain and 1 axis, 3 axis, 1 axis
  • Mode: Attached and connected
  • No of client-server: 6-2(Connected), 2 (Attached)

+) All tests passed and results are correct

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