source: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp @ 2022

Last change on this file since 2022 was 2022, checked in by ymipsl, 3 years ago

Reimplement coupling in the new infrastructure.
Tested for 2-way coupling toy model.

YM

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 15.5 KB
Line 
1#ifndef __XIOS_CContext__
2#define __XIOS_CContext__
3
4/// XIOS headers ///
5#include "xios_spl.hpp"
6//#include "node_type.hpp"
7#include "calendar_wrapper.hpp"
8
9#include "declare_group.hpp"
10#include "data_output.hpp"
11#include "garbage_collector.hpp"
12#include "registry.hpp"
13#include "mpi.hpp"
14#include "services_manager.hpp"
15#include "server_context.hpp"
16#include "event_scheduler.hpp"
17
18
19namespace xios
20{
21   class CContextClient;
22   class CContextServer;
23
24
25   /// ////////////////////// Déclarations ////////////////////// ///
26   class CContextGroup;
27   class CContextAttributes;
28   class CContext;
29   class CFile;
30   class CCouplerIn ;
31   class CCouplerOut ;
32   ///--------------------------------------------------------------
33
34   // Declare/Define CFileAttribute
35   BEGIN_DECLARE_ATTRIBUTE_MAP(CContext)
36#  include "context_attribute.conf"
37   END_DECLARE_ATTRIBUTE_MAP(CContext)
38
39   ///--------------------------------------------------------------
40  /*!
41  \class CContext
42   This class corresponds to the concrete presentation of context in xml file and in play an essential role in XIOS
43   Each object of this class contains all root definition of elements: files, fiels, domains, axis, etc, ... from which
44   we can have access to each element.
45   In fact, every thing must a be inside a particuliar context. After the xml file (iodef.xml) is parsed,
46   object of the class is created and its contains all information of other elements in the xml file.
47  */
48   class CContext
49      : public CObjectTemplate<CContext>
50      , public CContextAttributes
51   {
52         public :
53         enum EEventId
54         {
55           EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR,
56           EVENT_ID_CREATE_FILE_HEADER,EVENT_ID_CONTEXT_FINALIZE,
57           EVENT_ID_SEND_REGISTRY,
58           EVENT_ID_CONTEXT_FINALIZE_CLIENT,
59           EVENT_ID_COUPLER_IN_READY,
60           EVENT_ID_COUPLER_IN_CLOSE_DEFINITION,
61           EVENT_ID_COUPLER_IN_CONTEXT_FINALIZED,
62         };
63
64         /// typedef ///
65         typedef CObjectTemplate<CContext>   SuperClass;
66         typedef CContextAttributes SuperClassAttribute;
67
68      public :
69
70         typedef CContextAttributes RelAttributes;
71         typedef CContext           RelGroup;
72
73         //---------------------------------------------------------
74
75      public :
76
77         /// Constructeurs ///
78         CContext(void);
79         explicit CContext(const StdString & id);
80         CContext(const CContext & context);       // Not implemented yet.
81         CContext(const CContext * const context); // Not implemented yet.
82
83         /// Destructeur ///
84         virtual ~CContext(void);
85
86         //---------------------------------------------------------
87
88      public :
89
90         /// Mutateurs ///
91         void setCalendar(std::shared_ptr<CCalendar> newCalendar);
92
93         /// Accesseurs ///
94         std::shared_ptr<CCalendar>      getCalendar(void) const;
95
96      public :
97         // Initialize server or client
98         void init(CServerContext* parentServerContext, MPI_Comm intraComm, int serviceType);
99         void initClient(MPI_Comm intraComm, int serviceType);
100         
101         void initServer(MPI_Comm intraComm, int serviceType );
102         void createClientInterComm(MPI_Comm interCommClient, MPI_Comm interCommServer)  ;
103         void createServerInterComm(void)  ;
104
105         bool isInitialized(void);
106
107         StdString dumpClassAttributes(void);
108
109         // Put sever or client into loop state
110         bool eventLoop(bool enableEventsProcessing=true);
111         void globalEventLoop(void);
112
113         // Finalize a context
114         void finalize(void);
115
116         bool isFinalized(void);
117
118         void closeDefinition(void);
119
120         // to be removed     
121         std::vector<CField*> findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
122         // Some functions to process context
123         std::vector<CField*> findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles);
124         std::vector<CField*> findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles);
125         std::vector<CField*> findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut);
126         std::vector<CField*> findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn);
127         // void findAllEnabledFields(void);
128         // void findAllEnabledFieldsInReadModeFiles(void);
129         void readAttributesOfEnabledFieldsInReadModeFiles();
130         void solveAllInheritance(bool apply=true);
131         void findEnabledFiles(void);
132         void findEnabledCouplerIn(void);
133         void findEnabledCouplerOut(void);
134         void createCouplerInterCommunicator(void) ;
135         void findEnabledWriteModeFiles(void);
136         void findEnabledReadModeFiles(void);
137         void closeAllFile(void);
138         void updateCalendar(int step);
139         void createFileHeader(void);
140         void initReadFiles(void);
141         void prepareTimeseries(void);
142         void postProcessFilterGraph();
143         void startPrefetchingOfEnabledReadModeFiles();
144         void doPreTimestepOperationsForEnabledReadModeFiles();
145         void doPostTimestepOperationsForEnabledReadModeFiles();
146         void findFieldsWithReadAccess(void);
147         void triggerLateFields(void) ;
148         
149         std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
150         std::map<int, StdSize> getDataBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
151         void setClientServerBuffer(CContextClient* contextClient, bool bufferForWriting = false); // old interface to be removed
152         void setClientServerBuffer(vector<CField*>& fields, bool bufferForWriting) ; 
153
154         // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
155         void distributeFiles(const std::vector<CFile*>& files);
156         void distributeFileOverBandwith(const std::vector<CFile*>& files) ;
157         void distributeFileOverMemoryBandwith(const std::vector<CFile*>& files) ;
158         
159         // Send context close definition
160         void sendCloseDefinition(void);
161       public:
162         void sendCloseDefinition(CContextClient* client) ;
163       private:
164         set<CContextClient*> sendCloseDefinition_done_ ;
165       public:
166         // There are something to send on closing context defintion
167         void sendUpdateCalendar(int step);
168         void sendCreateFileHeader(void);
169         void sendEnabledFiles(const std::vector<CFile*>& activeFiles);
170         void sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
171         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles);
172         //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers
173         void sendRegistry(void) ;
174         void sendFinalizeClient(CContextClient* contextClient, const string& contextClientId);
175         
176         public:
177         void sendContextToFileServer(CContextClient* client) ;
178         private:
179         std::set<CContextClient*> sendToFileServer_done_ ;
180         
181         public: 
182         std::string getContextId() {return contextId_;}
183
184         // Client side: Receive and process messages
185         static void recvUpdateCalendar(CEventServer& event);
186         void recvUpdateCalendar(CBufferIn& buffer);
187         static void recvCloseDefinition(CEventServer& event);
188         static void recvCreateFileHeader(CEventServer& event);
189         void recvCreateFileHeader(CBufferIn& buffer);
190         static void recvSolveInheritanceContext(CEventServer& event);
191         void recvSolveInheritanceContext(CBufferIn& buffer);
192         static void recvRegistry(CEventServer& event) ;
193         void recvRegistry(CBufferIn& buffer) ; //!< registry is received by the servers
194         static void recvFinalizeClient(CEventServer& event) ;
195         void recvFinalizeClient(CBufferIn& buffer);
196       
197       public:
198         void sendCouplerInReady(CContextClient* client);
199       private:
200         set<CContextClient*> sendCouplerInReady_done_;
201       public:
202         static void recvCouplerInReady(CEventServer& event) ;
203         void recvCouplerInReady(CBufferIn& buffer) ; //!< coupler is ready to receive grid definition.
204         set<CContextClient*> couplerInReady_;
205         bool isCouplerInReady(CContextClient* client) { return couplerInReady_.count(client)!=0 ;}
206
207       public:
208        void sendCouplerInCloseDefinition(CContextClient* client) ;
209        set<CContextClient*> sendCouplerInCloseDefinition_done_;
210        static void recvCouplerInCloseDefinition(CEventServer& event) ;
211        void recvCouplerInCloseDefinition(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
212        set<CContextClient*> couplerInCloseDefinition_ ;
213        bool isCouplerInCloseDefinition(CContextClient* client) { return couplerInCloseDefinition_.count(client)!=0 ;}
214
215       public:
216        void sendCouplerInContextFinalized(CContextClient* client) ;
217        set<CContextClient*> sendCouplerInContextFinalized_done_;
218        static void recvCouplerInContextFinalized(CEventServer& event) ;
219        void recvCouplerInContextFinalized(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
220        set<CContextClient*> couplerInContextFinalized_ ;
221        bool isCouplerInContextFinalized(CContextClient* client) { return couplerInContextFinalized_.count(client)!=0 ;}
222
223       public: 
224        void freeComms(void);                  //!< Free internally allcoated communicators
225        void releaseClientBuffers(void);       //! Deallocate buffers allocated by clientContexts
226
227         // dispatch event
228         static bool dispatchEvent(CEventServer& event);
229
230      public:
231        // Get current context
232        static CContext* getCurrent(void);
233
234        // Get context root
235        static CContextGroup* getRoot(void);
236
237        // Set current context
238        static void setCurrent(const string& id);
239
240        // Create new context
241        static CContext* create(const string& id = "");
242
243        /// Accesseurs statiques ///
244        static StdString GetName(void);
245        static StdString GetDefName(void);
246        static ENodeType GetType(void);
247
248        static CContextGroup* GetContextGroup(void);
249
250        // Some functions to visualize structure of current context
251        static void ShowTree(StdOStream & out = std::clog);
252        static void CleanTree(void);
253        int getServiceType(void) {return serviceType_;}
254
255      public :
256         // Parse xml node and write all info into context
257         virtual void parse(xml::CXMLNode & node);
258
259         // Visualize a context
260         virtual StdString toString(void) const;
261
262
263         // Solve all inheritance relation in current context
264         virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0);
265
266         // Verify if all root definition in a context have children
267         virtual bool hasChild(void) const;
268
269         bool isProcessingEvent(void) {return isProcessingEvent_;}
270         bool setProcessingEvent(void) {isProcessingEvent_=true ;}
271         bool unsetProcessingEvent(void) {isProcessingEvent_=false ;}
272         MPI_Comm getIntraComm(void) {return intraComm_ ;}
273         int getIntraCommRank(void) {return intraCommRank_;}
274         int getIntraCommSize(void) {return intraCommSize_;}
275
276         void addCouplingChanel(const std::string& contextId, bool out) ;
277
278      public :
279         // Calendar of context
280         std::shared_ptr<CCalendar>   calendar;
281
282         // List of all enabled files (files on which fields are written or read)
283         std::vector<CFile*> enabledFiles;
284         // List of all enabled files in read mode (files on which fields are read)
285         std::vector<CFile*> enabledReadModeFiles;
286         // List of all enabled files in write mode
287         std::vector<CFile*> enabledWriteModeFiles;
288
289         std::vector<CCouplerIn*> enabledCouplerIn;
290         std::vector<CCouplerOut*> enabledCouplerOut;
291
292
293         // List of all enabled fields whose instant data is accessible from the public API
294         // but which are not part of a file
295         std::vector<CField*> fieldsWithReadAccess_;
296         std::vector<CField*> couplerInFields_;
297         std::vector<CField*> fileInFields_;
298
299
300         // Context root
301         static std::shared_ptr<CContextGroup> root;
302
303         // Determine context on client or not
304         bool hasClient;
305
306         // Determine context on server or not
307         bool hasServer;
308
309         CContextServer* server;    //!< Concrete context server
310         CContextClient* client;    //!< Concrete contex client
311         std::vector<CContextServer*> serverPrimServer;
312         std::vector<CContextClient*> clientPrimServer;
313
314         // list of slave servers (IO server or others)
315         set<CContextClient*> slaveServers_ ;
316      private:
317         // the map containing context client associated to it string id for coupling out ;
318         std::map<std::string, CContextClient*> couplerOutClient_ ;
319         // the map containing context server associated to it string id for coupling out ;
320         std::map<std::string, CContextServer*> couplerOutServer_ ;
321         // the map containing context client associated to it string id for coupling in ;
322         std::map<std::string, CContextClient*> couplerInClient_ ;
323         // the map containing context server associated to it string id for coupling in ;
324         std::map<std::string, CContextServer*> couplerInServer_ ;
325      public:
326         CContextClient* getCouplerInClient(const string& contextId) { return couplerInClient_[contextId] ;}
327         CContextServer* getCouplerInServer(const string& contextId) { return couplerInServer_[contextId] ;}
328         CContextClient* getCouplerOutClient(const string& contextId) { return couplerOutClient_[contextId] ;}
329         CContextServer* getCouplerOutServer(const string& contextId) { return couplerOutServer_[contextId] ;}
330     
331 
332         std::vector<std::string> primServerId_;
333
334         CRegistry* registryIn ;    //!< input registry which is read from file
335         CRegistry* registryOut ;   //!< output registry which will be written into file at the finalize
336
337
338        MPI_Comm intraComm_ ; //! context intra communicator
339        int intraCommRank_ ; //! context intra communicator rank
340        int intraCommSize_ ; //! context intra communicator size
341       
342      private:
343         CEventScheduler* eventScheduler_ ; //! The local event scheduler for context
344         size_t hashId_ ; //! the local hashId for scheduler
345         size_t timeLine_=0 ;
346         void initEventScheduler(void) ;
347
348         bool isPostProcessed;
349         bool allProcessed;
350         bool finalized;
351         int countChildContextFinalized_;        //!< Counter of child contexts (for now it is the number of secondary server pools)
352         CGarbageCollector garbageCollector;
353         std::list<MPI_Comm> comms; //!< Communicators allocated internally
354
355         int serviceType_;  //!< service associated to the context
356         string contextId_ ; //!< context client id for the servers. For clients this is same as getId()
357         bool isProcessingEvent_ ;
358         CServerContext* parentServerContext_ ;
359
360      public: // Some function maybe removed in the near future
361        // virtual void toBinary  (StdOStream & os) const;
362        // virtual void fromBinary(StdIStream & is);
363   }; // class CContext
364
365   ///--------------------------------------------------------------
366
367   // Declare/Define CContextGroup and CContextDefinition
368   DECLARE_GROUP(CContext);
369
370   ///--------------------------------------------------------------
371
372} // namespace xios
373
374#endif // __XIOS_CContext__
Note: See TracBrowser for help on using the repository browser.