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

Last change on this file since 2547 was 2547, checked in by ymipsl, 10 months ago

Major update :

  • New method to lock and unlock one-sided windows (window_dynamic) to avoid network overhead
  • Introducing multithreading on server sided to manage more efficiently dead-lock occuring (similar to co-routine which will be available and implemented in futur c++ standard), based on c++ threads
  • Suprression of old "attached mode" which is replaced by online writer and reder filters

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: 17.7 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#include "file.hpp"
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         
106         bool isInitialized(void);
107
108         StdString dumpClassAttributes(void);
109
110         // Put sever or client into loop state
111         bool eventLoop(bool enableEventsProcessing=true);
112         bool scheduledEventLoop(bool enableEventsProcessing=true) ; 
113         void globalEventLoop(void);
114         void yield(void) ;
115         void synchronize(void) ;
116
117         // Finalize a context
118         void finalize(void);
119
120         bool isFinalized(void);
121         void closeDefinition(void);
122
123         // to be removed     
124         std::vector<CField*> findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
125         // Some functions to process context
126         std::vector<CField*> findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles);
127         std::vector<CField*> findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles);
128         std::vector<CField*> findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut);
129         std::vector<CField*> findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn);
130         // void findAllEnabledFields(void);
131         // void findAllEnabledFieldsInReadModeFiles(void);
132         void readAttributesOfEnabledFieldsInReadModeFiles();
133         void solveAllInheritance(bool apply=true);
134         void findEnabledFiles(void);
135         void findEnabledCouplerIn(void);
136         void findEnabledCouplerOut(void);
137         void createCouplerInterCommunicator(void) ;
138         void findEnabledWriteModeFiles(void);
139         void findEnabledReadModeFiles(void);
140         void closeAllFile(void);
141         void updateCalendar(int step);
142         void createFileHeader(void);
143         void initReadFiles(void);
144         void prepareTimeseries(void);
145         void startPrefetchingOfEnabledReadModeFiles();
146         void doPostTimestepOperationsForEnabledReadModeFiles();
147         void findFieldsWithReadAccess(void);
148         void triggerLateFields(void) ;
149         
150         std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
151         std::map<int, StdSize> getDataBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
152
153         // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
154         void distributeFiles(const vector<CFile*>& files) ;
155         void distributeFilesOnSameService(const vector<CFile*>& files, const string& poolId, const string& serviceId) ;
156         void distributeFileOverOne(const vector<CFile*>& files, const string& poolId, const string& serviceId) ; //!< Distribute files over one single server (no distribution)
157         void distributeFileOverBandwith(const std::vector<CFile*>& files, const string& poolId, const string& serviceId) ; //!< Distribute files overs servers to balance the I/O bandwith
158         void distributeFileOverMemoryBandwith(const std::vector<CFile*>& files, const string& poolId, const string& serviceId) ; //!< Distribute files overs servers to minimize the memory consumption
159         
160       public:
161         // Send context close definition
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 sendEnabledFiles(const std::vector<CFile*>& activeFiles);
169         void sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
170         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles);
171         //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers
172         void sendFinalizeClient(CContextClient* contextClient, const string& contextClientId);
173         
174         public:
175         void sendContextToFileServer(CContextClient* client) ;
176         private:
177         std::set<CContextClient*> sendToFileServer_done_ ;
178         
179         public: 
180         std::string getContextId() {return contextId_;}
181
182         // Client side: Receive and process messages
183         static void recvUpdateCalendar(CEventServer& event);
184         void recvUpdateCalendar(CBufferIn& buffer);
185         static void recvCloseDefinition(CEventServer& event);
186         static void recvSolveInheritanceContext(CEventServer& event);
187         void recvSolveInheritanceContext(CBufferIn& buffer);
188         static void recvFinalizeClient(CEventServer& event) ;
189         void recvFinalizeClient(CBufferIn& buffer);
190       
191       public:
192         void sendCouplerInReady(CContextClient* client);
193       private:
194         set<CContextClient*> sendCouplerInReady_done_;
195       public:
196         static void recvCouplerInReady(CEventServer& event) ;
197         void recvCouplerInReady(CBufferIn& buffer) ; //!< coupler is ready to receive grid definition.
198         set<CContextClient*> couplerInReady_;
199         bool isCouplerInReady(CContextClient* client) { return couplerInReady_.count(client)!=0 ;}
200
201       public:
202        void sendCouplerInCloseDefinition(CContextClient* client) ;
203        set<CContextClient*> sendCouplerInCloseDefinition_done_;
204        static void recvCouplerInCloseDefinition(CEventServer& event) ;
205        void recvCouplerInCloseDefinition(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
206        set<CContextClient*> couplerInCloseDefinition_ ;
207        bool isCouplerInCloseDefinition(CContextClient* client) { return couplerInCloseDefinition_.count(client)!=0 ;}
208
209       public:
210        void sendCouplerInContextFinalized(CContextClient* client) ;
211        set<CContextClient*> sendCouplerInContextFinalized_done_;
212        static void recvCouplerInContextFinalized(CEventServer& event) ;
213        void recvCouplerInContextFinalized(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
214        set<CContextClient*> couplerInContextFinalized_ ;
215        bool isCouplerInContextFinalized(CContextClient* client) { return couplerInContextFinalized_.count(client)!=0 ;}
216
217       public: 
218        void freeComms(void);                  //!< Free internally allcoated communicators
219
220         // dispatch event
221         static bool dispatchEvent(CEventServer& event);
222
223      public:
224        // Get current context
225        static CContext* getCurrent(void);
226
227        // Get context root
228        static CContextGroup* getRoot(void);
229       
230        // Set current context
231        static void setCurrent(const string& id);
232
233        // Create new context
234        static CContext* create(const string& id = "");
235
236        /// Accesseurs statiques ///
237        static StdString GetName(void);
238        static StdString GetDefName(void);
239        static ENodeType GetType(void);
240
241        static CContextGroup* GetContextGroup(void);
242
243        // Some functions to visualize structure of current context
244        static void ShowTree(StdOStream & out = std::clog);
245        static void CleanTree(void);
246        static void removeContext(const std::string& contextId);
247        static void removeAllContexts(void) ;
248        int getServiceType(void) {return serviceType_;}
249
250      public :
251         // Parse xml node and write all info into context
252         virtual void parse(xml::CXMLNode & node);
253
254         // Visualize a context
255         virtual StdString toString(void) const;
256
257
258         // Solve all inheritance relation in current context
259         virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0);
260
261         // Verify if all root definition in a context have children
262         virtual bool hasChild(void) const;
263
264         bool isProcessingEvent(void) {return isProcessingEvent_;}
265         bool setProcessingEvent(void) {isProcessingEvent_=true ;}
266         bool unsetProcessingEvent(void) {isProcessingEvent_=false ;}
267         
268         void addCouplingChanel(const std::string& contextId, bool out) ;
269
270      public :
271         // Calendar of context
272         std::shared_ptr<CCalendar>   calendar;
273
274         // List of all enabled files (files on which fields are written or read)
275         std::vector<CFile*> enabledFiles;
276         // List of all enabled files in read mode (files on which fields are read)
277         std::vector<CFile*> enabledReadModeFiles;
278         // List of all enabled files in write mode
279         std::vector<CFile*> enabledWriteModeFiles;
280
281         std::vector<CCouplerIn*> enabledCouplerIn;
282         std::vector<CCouplerOut*> enabledCouplerOut;
283
284
285         // List of all enabled fields whose instant data is accessible from the public API
286         // but which are not part of a file
287         std::vector<CField*> fieldsWithReadAccess_;
288         std::vector<CField*> couplerInFields_;
289         std::vector<CField*> fileInFields_;
290
291
292         // Context root
293         static std::shared_ptr<CContextGroup> root;
294
295         // Determine context on client or not
296         bool hasClient;
297
298         // Determine context on server or not
299         bool hasServer;
300      public:
301        void registerFileToWrite(CFile* file) { filesToWrite_.insert(file); } // Add a file that need to be write for example to create headers
302      private: 
303        std::set<CFile*,FilePtrCompare> filesToWrite_ ; 
304
305      private:
306        CContextClient* onlineContextClient_=nullptr ;
307       
308        std::string defaultPoolWriterId_ ;
309        std::string defaultPoolReaderId_ ;
310        std::string defaultPoolGathererId_ ;
311        std::string defaultWriterId_ ;
312        std::string defaultReaderId_ ;
313        std::string defaultGathererId_ ;
314        bool defaultUsingServer2_ ;
315        void setDefaultServices(void) ;
316
317
318        std::map<std::pair<string,string>,std::vector<pair<CContextClient*,CContextServer*>>> serversMap_ ;
319
320        std::vector<CContextClient*> writerClientOut_ ;
321        std::vector<CContextServer*> writerServerOut_ ;
322        std::vector<CContextClient*> writerClientIn_ ;
323        std::vector<CContextServer*> writerServerIn_ ;
324
325        std::vector<CContextClient*> readerClientOut_ ;
326        std::vector<CContextServer*> readerServerOut_ ;
327        std::vector<CContextClient*> readerClientIn_ ;
328        std::vector<CContextServer*> readerServerIn_ ;
329
330
331        std::map<std::string, CContextClient*> clients_ ;
332        std::map<std::string, CContextClient*> servers_ ;
333        std::map<CContextClient*, std::string> clientsId_ ;
334        std::map<CContextServer*, std::string> serversId_ ;
335
336        // list of slave servers (IO server or others)
337        std::vector<CContextClient*> slaveServers_ ;
338
339        // the map containing context client associated to it string id for coupling out ;
340        std::map<std::string, CContextClient*> couplerOutClient_ ;
341        // the map containing context server associated to it string id for coupling out ;
342        std::map<std::string, CContextServer*> couplerOutServer_ ;
343        // the map containing context client associated to it string id for coupling in ;
344        std::map<std::string, CContextClient*> couplerInClient_ ;
345        // the map containing context server associated to it string id for coupling in ;
346        std::map<std::string, CContextServer*> couplerInServer_ ;
347      public:
348         void createClientInterComm(MPI_Comm interCommClient, MPI_Comm interCommServer)  ;
349         void createServerInterComm(void)  ; // obsolete
350         void createServerInterComm_old(void)  ;
351         void createServerInterComm(const string& poolId, const string& serverId, vector<pair<string, pair<CContextClient*,CContextServer*>>>& clientServers ) ;
352         void getServerInterComm(const string& poolId, const string& serviceId,  vector<pair<CContextClient*,CContextServer*>>& clientServers) ;
353         vector<CContextClient*> getContextClient(const string& poolId, const string& serviceId) ;
354         CContextClient* getCouplerInClient(const string& contextId) { return couplerInClient_[contextId] ;}
355         CContextServer* getCouplerInServer(const string& contextId) { return couplerInServer_[contextId] ;}
356         CContextClient* getCouplerOutClient(const string& contextId) { return couplerOutClient_[contextId] ;}
357         CContextServer* getCouplerOutServer(const string& contextId) { return couplerOutServer_[contextId] ;}
358       
359       public: // must be privatize using accessors
360       
361        CRegistry* registryIn=nullptr ;    //!< input registry which is read from file
362        CRegistry* registryOut=nullptr ;   //!< output registry which will be written into file at the finalize
363
364
365        MPI_Comm intraComm_ ; //! context intra communicator
366        int intraCommRank_ ; //! context intra communicator rank
367        int intraCommSize_ ; //! context intra communicator size
368       public: 
369        MPI_Comm getIntraComm(void) {return intraComm_ ;}
370        int getIntraCommRank(void) {return intraCommRank_;}
371        int getIntraCommSize(void) {return intraCommSize_;}
372     
373      public:
374        shared_ptr<CEventScheduler> getEventScheduler(void) {return eventScheduler_ ;}
375      private:
376         shared_ptr<CEventScheduler> eventScheduler_ ; //! The local event scheduler for context
377         size_t hashId_ ; //! the local hashId for scheduler
378         size_t timeLine_=0 ;
379         void initEventScheduler(void) ;
380
381         bool isPostProcessed;
382         bool allProcessed;
383         bool finalized;
384         int countChildContextFinalized_;        //!< Counter of child contexts (for now it is the number of secondary server pools)
385         CGarbageCollector garbageCollector;
386         std::list<MPI_Comm> comms; //!< Communicators allocated internally
387
388         int serviceType_;  //!< service associated to the context
389         string contextId_ ; //!< context client id for the servers. For clients this is same as getId()
390         bool isProcessingEvent_ ;
391    private:     
392         CServerContext* parentServerContext_ ;
393    public:
394         CServerContext* getParentServerContext(void) { return parentServerContext_; }
395    private: 
396      bool lockedContext_=false;
397    public: 
398        void lockContext(void) {lockedContext_=true; }
399        void unlockContext(void) {lockedContext_=false; }
400        bool isLockedContext(void) { return lockedContext_;}
401      public: // Some function maybe removed in the near future
402        // virtual void toBinary  (StdOStream & os) const;
403        // virtual void fromBinary(StdIStream & is);
404   }; // class CContext
405
406   ///--------------------------------------------------------------
407
408   // Declare/Define CContextGroup and CContextDefinition
409   DECLARE_GROUP(CContext);
410
411   ///--------------------------------------------------------------
412
413} // namespace xios
414
415#endif // __XIOS_CContext__
Note: See TracBrowser for help on using the repository browser.