source: XIOS3/trunk/src/transport/context_client.cpp @ 2633

Last change on this file since 2633 was 2629, checked in by jderouillat, 2 months ago

Delete boost dependencies, the few features used are replaced by functions stored in extern/boost_extraction

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 6.2 KB
Line 
1#include "xios_spl.hpp"
2#include "context_client.hpp"
3#include "context_server.hpp"
4#include "event_client.hpp"
5#include "buffer_out.hpp"
6#include "buffer_client.hpp"
7#include "type.hpp"
8#include "event_client.hpp"
9#include "context.hpp"
10#include "mpi.hpp"
11#include "timer.hpp"
12#include "cxios.hpp"
13#include "server.hpp"
14#include "services.hpp"
15#include <random>
16#include <chrono>
17#include "one_sided_context_client.hpp"
18#include "p2p_context_client.hpp"
19#include "legacy_context_client.hpp"
20#include "online_context_client.hpp"
21
22
23namespace xios
24{
25    /*!
26    \param [in] parent Pointer to context on client side
27    \param [in] intraComm_ communicator of group client
28    \param [in] interComm_ communicator of group server
29    \cxtSer [in] cxtSer Pointer to context of server side. (It is only used in case of attached mode).
30    */
31    CContextClient::CContextClient(CContext* parent, MPI_Comm intraComm_, MPI_Comm interComm_, CContext* cxtSer)
32     : parentServer(cxtSer),  associatedServer_(nullptr)
33    {
34     
35      context_ = parent;
36      intraComm = intraComm_;
37      interComm = interComm_;
38      MPI_Comm_rank(intraComm, &clientRank);
39      MPI_Comm_size(intraComm, &clientSize);
40
41      int flag;     
42      MPI_Comm_test_inter(interComm, &flag);
43      if (flag) MPI_Comm_remote_size(interComm, &serverSize);
44      else  MPI_Comm_size(interComm, &serverSize);
45     
46      computeLeader(clientRank, clientSize, serverSize, ranksServerLeader, ranksServerNotLeader);
47
48      auto time=chrono::system_clock::now().time_since_epoch().count() ;
49      std::default_random_engine rd(time); // not reproducible from a run to another
50      std::uniform_int_distribution<size_t> dist;
51      hashId_=dist(rd) ;
52      MPI_Bcast(&hashId_,1,MPI_SIZE_T,0,intraComm) ; // Bcast to all server of the context
53
54    }
55
56    template<>
57    CContextClient* CContextClient::getNew<CContextClient::generic>(CContext* parent, MPI_Comm intraComm, MPI_Comm interComm, CContext* parentServer)
58    { 
59      string defaultProtocol = CXios::getin<string>("transport_protocol", "default") ;
60      if (defaultProtocol=="one_sided") return getNew<CContextClient::oneSided>(parent, intraComm, interComm) ;
61      else if  (defaultProtocol=="p2p") return getNew<CContextClient::p2p>(parent, intraComm, interComm) ;
62      else if  (defaultProtocol=="legacy") return getNew<CContextClient::legacy>(parent, intraComm, interComm) ;
63      else if  (defaultProtocol=="online") return getNew<CContextClient::online>(parent, intraComm, interComm) ;
64      else if  (defaultProtocol=="default") return getNew<CContextClient::legacy>(parent, intraComm, interComm) ;
65      else ERROR("CContextClient* CContextClient::getNew<CContextClient::generic>(CContext* parent, MPI_Comm intraComm, MPI_Comm interComm, CContext* parentServer)",
66                <<"Protocol name <"<<defaultProtocol<<"> is undefined,  must be <default>, <one_sided> or <legacy>" ) ; 
67    }
68
69    template<>
70    CContextClient* CContextClient::getNew<CContextClient::oneSided>(CContext* parent, MPI_Comm intraComm, MPI_Comm interComm, CContext* parentServer)
71    { 
72      return new COneSidedContextClient(parent, intraComm, interComm, parentServer); 
73    }
74
75    template<>
76    CContextClient* CContextClient::getNew<CContextClient::p2p>(CContext* parent, MPI_Comm intraComm, MPI_Comm interComm, CContext* parentServer)
77    { 
78      return new CP2pContextClient(parent, intraComm, interComm, parentServer); 
79    }
80
81    template<>
82    CContextClient* CContextClient::getNew<CContextClient::legacy>(CContext* parent, MPI_Comm intraComm, MPI_Comm interComm, CContext* parentServer)
83    { 
84      return new CLegacyContextClient(parent, intraComm, interComm, parentServer); 
85    }
86
87    template<>
88    CContextClient* CContextClient::getNew<CContextClient::online>(CContext* parent, MPI_Comm intraComm, MPI_Comm interComm, CContext* parentServer)
89    { 
90      return new COnlineContextClient(parent, intraComm, interComm, parentServer); 
91    }
92
93    void CContextClient::computeLeader(int clientRank, int clientSize, int serverSize,
94                                       std::list<int>& rankRecvLeader,
95                                       std::list<int>& rankRecvNotLeader)
96    {
97      if ((0 == clientSize) || (0 == serverSize)) return;
98
99      if (clientSize < serverSize)
100      {
101        int serverByClient = serverSize / clientSize;
102        int remain = serverSize % clientSize;
103        int rankStart = serverByClient * clientRank;
104
105        if (clientRank < remain)
106        {
107          serverByClient++;
108          rankStart += clientRank;
109        }
110        else
111          rankStart += remain;
112
113        for (int i = 0; i < serverByClient; i++)
114          rankRecvLeader.push_back(rankStart + i);
115
116        rankRecvNotLeader.resize(0);
117      }
118      else
119      {
120        int clientByServer = clientSize / serverSize;
121        int remain = clientSize % serverSize;
122
123        if (clientRank < (clientByServer + 1) * remain)
124        {
125          if (clientRank % (clientByServer + 1) == 0)
126            rankRecvLeader.push_back(clientRank / (clientByServer + 1));
127          else
128            rankRecvNotLeader.push_back(clientRank / (clientByServer + 1));
129        }
130        else
131        {
132          int rank = clientRank - (clientByServer + 1) * remain;
133          if (rank % clientByServer == 0)
134            rankRecvLeader.push_back(remain + rank / clientByServer);
135          else
136            rankRecvNotLeader.push_back(remain + rank / clientByServer);
137        }
138      }
139    }
140
141  /*!
142  Get leading server in the group of connected server
143  \return ranks of leading servers
144  */
145  const std::list<int>& CContextClient::getRanksServerNotLeader(void) const
146  {
147    return ranksServerNotLeader;
148  }
149
150  /*!
151  Check if client connects to leading server
152  \return connected(true), not connected (false)
153  */
154  bool CContextClient::isServerNotLeader(void) const
155  {
156    return !ranksServerNotLeader.empty();
157  }
158
159  /*!
160  Get leading server in the group of connected server
161  \return ranks of leading servers
162  */
163  const std::list<int>& CContextClient::getRanksServerLeader(void) const
164  {
165    return ranksServerLeader;
166  }
167
168  /*!
169  Check if client connects to leading server
170  \return connected(true), not connected (false)
171  */
172  bool CContextClient::isServerLeader(void) const
173  {
174    return !ranksServerLeader.empty();
175  }
176
177
178
179}
Note: See TracBrowser for help on using the repository browser.