source: XIOS3/trunk/src/node/context.hpp @ 2405

Last change on this file since 2405 was 2405, checked in by ymipsl, 21 months ago

Refactor service management from context
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: 16.0 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_COLLECTIVE=100,
56           EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR,
57           EVENT_ID_CONTEXT_FINALIZE,
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           EVENT_ID_NO_COLLECTIVE=1000,
63         };
64
65         /// typedef ///
66         typedef CObjectTemplate<CContext>   SuperClass;
67         typedef CContextAttributes SuperClassAttribute;
68
69      public :
70
71         typedef CContextAttributes RelAttributes;
72         typedef CContext           RelGroup;
73
74         //---------------------------------------------------------
75
76      public :
77
78         /// Constructeurs ///
79         CContext(void);
80         explicit CContext(const StdString & id);
81         CContext(const CContext & context);       // Not implemented yet.
82         CContext(const CContext * const context); // Not implemented yet.
83
84         /// Destructeur ///
85         virtual ~CContext(void);
86
87         static void releaseStaticAllocation(void) ;
88
89         //---------------------------------------------------------
90
91      public :
92
93         /// Mutateurs ///
94         void setCalendar(std::shared_ptr<CCalendar> newCalendar);
95
96         /// Accesseurs ///
97         std::shared_ptr<CCalendar>      getCalendar(void) const;
98
99      public :
100         // Initialize server or client
101         void init(CServerContext* parentServerContext, MPI_Comm intraComm, int serviceType);
102         void initClient(MPI_Comm intraComm, int serviceType);
103         
104         void initServer(MPI_Comm intraComm, int serviceType );
105         void createClientInterComm(MPI_Comm interCommClient, MPI_Comm interCommServer)  ;
106 
107         void createServerInterComm(void)  ;
108         void createServerInterComm_old(void)  ;
109         void createServerInterComm(const string& poolId, const string& serverId, vector<pair<string, pair<CContextClient*,CContextServer*>>>& clientServers ) ;
110 
111
112         bool isInitialized(void);
113
114         StdString dumpClassAttributes(void);
115
116         // Put sever or client into loop state
117         bool eventLoop(bool enableEventsProcessing=true);
118         bool scheduledEventLoop(bool enableEventsProcessing=true) ; 
119         void globalEventLoop(void);
120
121         // Finalize a context
122         void finalize(void);
123
124         bool isFinalized(void);
125
126         void closeDefinition(void);
127
128         // to be removed     
129         std::vector<CField*> findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
130         // Some functions to process context
131         std::vector<CField*> findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles);
132         std::vector<CField*> findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles);
133         std::vector<CField*> findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut);
134         std::vector<CField*> findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn);
135         // void findAllEnabledFields(void);
136         // void findAllEnabledFieldsInReadModeFiles(void);
137         void readAttributesOfEnabledFieldsInReadModeFiles();
138         void solveAllInheritance(bool apply=true);
139         void findEnabledFiles(void);
140         void findEnabledCouplerIn(void);
141         void findEnabledCouplerOut(void);
142         void createCouplerInterCommunicator(void) ;
143         void findEnabledWriteModeFiles(void);
144         void findEnabledReadModeFiles(void);
145         void closeAllFile(void);
146         void updateCalendar(int step);
147         void createFileHeader(void);
148         void initReadFiles(void);
149         void prepareTimeseries(void);
150         void postProcessFilterGraph();
151         void startPrefetchingOfEnabledReadModeFiles();
152         void doPreTimestepOperationsForEnabledReadModeFiles();
153         void doPostTimestepOperationsForEnabledReadModeFiles();
154         void findFieldsWithReadAccess(void);
155         void triggerLateFields(void) ;
156         
157         std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
158         std::map<int, StdSize> getDataBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
159
160         // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
161         void distributeFiles(const std::vector<CFile*>& files);
162         void distributeFileOverBandwith(const std::vector<CFile*>& files) ;
163         void distributeFileOverMemoryBandwith(const std::vector<CFile*>& files) ;
164         
165         // Send context close definition
166         void sendCloseDefinition(void);
167       public:
168         void sendCloseDefinition(CContextClient* client) ;
169       private:
170         set<CContextClient*> sendCloseDefinition_done_ ;
171       public:
172         // There are something to send on closing context defintion
173         void sendUpdateCalendar(int step);
174         void sendEnabledFiles(const std::vector<CFile*>& activeFiles);
175         void sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
176         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles);
177         //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers
178         void sendFinalizeClient(CContextClient* contextClient, const string& contextClientId);
179         
180         public:
181         void sendContextToFileServer(CContextClient* client) ;
182         private:
183         std::set<CContextClient*> sendToFileServer_done_ ;
184         
185         public: 
186         std::string getContextId() {return contextId_;}
187
188         // Client side: Receive and process messages
189         static void recvUpdateCalendar(CEventServer& event);
190         void recvUpdateCalendar(CBufferIn& buffer);
191         static void recvCloseDefinition(CEventServer& event);
192         static void recvSolveInheritanceContext(CEventServer& event);
193         void recvSolveInheritanceContext(CBufferIn& buffer);
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        static void removeContext(const std::string& contextId);
254        static void removeAllContexts(void) ;
255        int getServiceType(void) {return serviceType_;}
256
257      public :
258         // Parse xml node and write all info into context
259         virtual void parse(xml::CXMLNode & node);
260
261         // Visualize a context
262         virtual StdString toString(void) const;
263
264
265         // Solve all inheritance relation in current context
266         virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0);
267
268         // Verify if all root definition in a context have children
269         virtual bool hasChild(void) const;
270
271         bool isProcessingEvent(void) {return isProcessingEvent_;}
272         bool setProcessingEvent(void) {isProcessingEvent_=true ;}
273         bool unsetProcessingEvent(void) {isProcessingEvent_=false ;}
274         MPI_Comm getIntraComm(void) {return intraComm_ ;}
275         int getIntraCommRank(void) {return intraCommRank_;}
276         int getIntraCommSize(void) {return intraCommSize_;}
277
278         void addCouplingChanel(const std::string& contextId, bool out) ;
279
280      public :
281         // Calendar of context
282         std::shared_ptr<CCalendar>   calendar;
283
284         // List of all enabled files (files on which fields are written or read)
285         std::vector<CFile*> enabledFiles;
286         // List of all enabled files in read mode (files on which fields are read)
287         std::vector<CFile*> enabledReadModeFiles;
288         // List of all enabled files in write mode
289         std::vector<CFile*> enabledWriteModeFiles;
290
291         std::vector<CCouplerIn*> enabledCouplerIn;
292         std::vector<CCouplerOut*> enabledCouplerOut;
293
294
295         // List of all enabled fields whose instant data is accessible from the public API
296         // but which are not part of a file
297         std::vector<CField*> fieldsWithReadAccess_;
298         std::vector<CField*> couplerInFields_;
299         std::vector<CField*> fileInFields_;
300
301
302         // Context root
303         static std::shared_ptr<CContextGroup> root;
304
305         // Determine context on client or not
306         bool hasClient;
307
308         // Determine context on server or not
309         bool hasServer;
310
311         CContextServer* server;    //!< Concrete context server
312         CContextClient* client;    //!< Concrete contex client
313         std::vector<CContextServer*> serverPrimServer;
314         std::vector<CContextClient*> clientPrimServer;
315
316         // list of slave servers (IO server or others)
317         set<CContextClient*> slaveServers_ ;
318
319      private:
320        std::string defaultReaderId ;
321        std::string defaultWriterId ;
322        std::string defaultGathererId ;
323
324        std::map<std::string, CContextClient*> clients_ ;
325        std::map<std::string, CContextClient*> servers_ ;
326
327      private:
328         // the map containing context client associated to it string id for coupling out ;
329         std::map<std::string, CContextClient*> couplerOutClient_ ;
330         // the map containing context server associated to it string id for coupling out ;
331         std::map<std::string, CContextServer*> couplerOutServer_ ;
332         // the map containing context client associated to it string id for coupling in ;
333         std::map<std::string, CContextClient*> couplerInClient_ ;
334         // the map containing context server associated to it string id for coupling in ;
335         std::map<std::string, CContextServer*> couplerInServer_ ;
336      public:
337         CContextClient* getCouplerInClient(const string& contextId) { return couplerInClient_[contextId] ;}
338         CContextServer* getCouplerInServer(const string& contextId) { return couplerInServer_[contextId] ;}
339         CContextClient* getCouplerOutClient(const string& contextId) { return couplerOutClient_[contextId] ;}
340         CContextServer* getCouplerOutServer(const string& contextId) { return couplerOutServer_[contextId] ;}
341     
342 
343         std::vector<std::string> primServerId_;
344
345         CRegistry* registryIn=nullptr ;    //!< input registry which is read from file
346         CRegistry* registryOut=nullptr ;   //!< output registry which will be written into file at the finalize
347
348
349        MPI_Comm intraComm_ ; //! context intra communicator
350        int intraCommRank_ ; //! context intra communicator rank
351        int intraCommSize_ ; //! context intra communicator size
352       
353      private:
354         shared_ptr<CEventScheduler> eventScheduler_ ; //! The local event scheduler for context
355         size_t hashId_ ; //! the local hashId for scheduler
356         size_t timeLine_=0 ;
357         void initEventScheduler(void) ;
358
359         bool isPostProcessed;
360         bool allProcessed;
361         bool finalized;
362         int countChildContextFinalized_;        //!< Counter of child contexts (for now it is the number of secondary server pools)
363         CGarbageCollector garbageCollector;
364         std::list<MPI_Comm> comms; //!< Communicators allocated internally
365
366         int serviceType_;  //!< service associated to the context
367         string contextId_ ; //!< context client id for the servers. For clients this is same as getId()
368         bool isProcessingEvent_ ;
369    private:     
370         CServerContext* parentServerContext_ ;
371    public:
372         CServerContext* getParentServerContext(void) { return parentServerContext_; }
373    private: 
374      bool lockedContext_=false;
375    public: 
376        void lockContext(void) {lockedContext_=true; }
377        void unlockContext(void) {lockedContext_=false; }
378        bool isLockedContext(void) { return lockedContext_;}
379      public: // Some function maybe removed in the near future
380        // virtual void toBinary  (StdOStream & os) const;
381        // virtual void fromBinary(StdIStream & is);
382   }; // class CContext
383
384   ///--------------------------------------------------------------
385
386   // Declare/Define CContextGroup and CContextDefinition
387   DECLARE_GROUP(CContext);
388
389   ///--------------------------------------------------------------
390
391} // namespace xios
392
393#endif // __XIOS_CContext__
Note: See TracBrowser for help on using the repository browser.