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

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

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