source: XIOS3/dev/XIOS_ATTACHED/src/node/context.hpp @ 2504

Last change on this file since 2504 was 2504, checked in by jderouillat, 18 months ago

Add a comparison operator to the filesToWrite_ std::set to force the file creation ordering + Backporting of 2462, 2494 and test suite environment for RedHat8

  • 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.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#include "file.hpp"
18
19
20namespace xios
21{
22   class CContextClient;
23   class CContextServer;
24
25
26   /// ////////////////////// Déclarations ////////////////////// ///
27   class CContextGroup;
28   class CContextAttributes;
29   class CContext;
30   class CFile;
31   class CCouplerIn ;
32   class CCouplerOut ;
33   ///--------------------------------------------------------------
34
35   // Declare/Define CFileAttribute
36   BEGIN_DECLARE_ATTRIBUTE_MAP(CContext)
37#  include "context_attribute.conf"
38   END_DECLARE_ATTRIBUTE_MAP(CContext)
39
40   ///--------------------------------------------------------------
41  /*!
42  \class CContext
43   This class corresponds to the concrete presentation of context in xml file and in play an essential role in XIOS
44   Each object of this class contains all root definition of elements: files, fiels, domains, axis, etc, ... from which
45   we can have access to each element.
46   In fact, every thing must a be inside a particuliar context. After the xml file (iodef.xml) is parsed,
47   object of the class is created and its contains all information of other elements in the xml file.
48  */
49   class CContext
50      : public CObjectTemplate<CContext>
51      , public CContextAttributes
52   {
53         public :
54         enum EEventId
55         {
56           EVENT_ID_COLLECTIVE=100,
57           EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR,
58           EVENT_ID_CONTEXT_FINALIZE,
59           EVENT_ID_CONTEXT_FINALIZE_CLIENT,
60           EVENT_ID_COUPLER_IN_READY,
61           EVENT_ID_COUPLER_IN_CLOSE_DEFINITION,
62           EVENT_ID_COUPLER_IN_CONTEXT_FINALIZED,
63           EVENT_ID_NO_COLLECTIVE=1000,
64         };
65
66         /// typedef ///
67         typedef CObjectTemplate<CContext>   SuperClass;
68         typedef CContextAttributes SuperClassAttribute;
69
70      public :
71
72         typedef CContextAttributes RelAttributes;
73         typedef CContext           RelGroup;
74
75         //---------------------------------------------------------
76
77      public :
78
79         /// Constructeurs ///
80         CContext(void);
81         explicit CContext(const StdString & id);
82         CContext(const CContext & context);       // Not implemented yet.
83         CContext(const CContext * const context); // Not implemented yet.
84
85         /// Destructeur ///
86         virtual ~CContext(void);
87
88         static void releaseStaticAllocation(void) ;
89
90         //---------------------------------------------------------
91
92      public :
93
94         /// Mutateurs ///
95         void setCalendar(std::shared_ptr<CCalendar> newCalendar);
96
97         /// Accesseurs ///
98         std::shared_ptr<CCalendar>      getCalendar(void) const;
99
100      public :
101         // Initialize server or client
102         void init(CServerContext* parentServerContext, MPI_Comm intraComm, int serviceType);
103         void initClient(MPI_Comm intraComm, int serviceType);
104         
105         void initServer(MPI_Comm intraComm, int serviceType );
106         
107         bool isInitialized(void);
108
109         StdString dumpClassAttributes(void);
110
111         // Put sever or client into loop state
112         bool eventLoop(bool enableEventsProcessing=true);
113         bool scheduledEventLoop(bool enableEventsProcessing=true) ; 
114         void globalEventLoop(void);
115
116         // Finalize a context
117         void finalize(void);
118
119         bool isFinalized(void);
120         void closeDefinition(void);
121
122         // to be removed     
123         std::vector<CField*> findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
124         // Some functions to process context
125         std::vector<CField*> findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles);
126         std::vector<CField*> findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles);
127         std::vector<CField*> findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut);
128         std::vector<CField*> findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn);
129         // void findAllEnabledFields(void);
130         // void findAllEnabledFieldsInReadModeFiles(void);
131         void readAttributesOfEnabledFieldsInReadModeFiles();
132         void solveAllInheritance(bool apply=true);
133         void findEnabledFiles(void);
134         void findEnabledCouplerIn(void);
135         void findEnabledCouplerOut(void);
136         void createCouplerInterCommunicator(void) ;
137         void findEnabledWriteModeFiles(void);
138         void findEnabledReadModeFiles(void);
139         void closeAllFile(void);
140         void updateCalendar(int step);
141         void createFileHeader(void);
142         void initReadFiles(void);
143         void prepareTimeseries(void);
144         void startPrefetchingOfEnabledReadModeFiles();
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
152         // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
153         void distributeFiles(const vector<CFile*>& files) ;
154         void distributeFilesOnSameService(const vector<CFile*>& files, const string& poolId, const string& serviceId) ;
155         void distributeFileOverOne(const vector<CFile*>& files, const string& poolId, const string& serviceId) ; //!< Distribute files over one single server (no distribution)
156         void distributeFileOverBandwith(const std::vector<CFile*>& files, const string& poolId, const string& serviceId) ; //!< Distribute files overs servers to balance the I/O bandwith
157         void distributeFileOverMemoryBandwith(const std::vector<CFile*>& files, const string& poolId, const string& serviceId) ; //!< Distribute files overs servers to minimize the memory consumption
158         
159       public:
160         // Send context close definition
161         void sendCloseDefinition(CContextClient* client) ;
162       private:
163         set<CContextClient*> sendCloseDefinition_done_ ;
164       public:
165         // There are something to send on closing context defintion
166         void sendUpdateCalendar(int step);
167         void sendEnabledFiles(const std::vector<CFile*>& activeFiles);
168         void sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
169         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles);
170         //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers
171         void sendFinalizeClient(CContextClient* contextClient, const string& contextClientId);
172         
173         public:
174         void sendContextToFileServer(CContextClient* client) ;
175         private:
176         std::set<CContextClient*> sendToFileServer_done_ ;
177         
178         public: 
179         std::string getContextId() {return contextId_;}
180
181         // Client side: Receive and process messages
182         static void recvUpdateCalendar(CEventServer& event);
183         void recvUpdateCalendar(CBufferIn& buffer);
184         static void recvCloseDefinition(CEventServer& event);
185         static void recvSolveInheritanceContext(CEventServer& event);
186         void recvSolveInheritanceContext(CBufferIn& buffer);
187         static void recvFinalizeClient(CEventServer& event) ;
188         void recvFinalizeClient(CBufferIn& buffer);
189       
190       public:
191         void sendCouplerInReady(CContextClient* client);
192       private:
193         set<CContextClient*> sendCouplerInReady_done_;
194       public:
195         static void recvCouplerInReady(CEventServer& event) ;
196         void recvCouplerInReady(CBufferIn& buffer) ; //!< coupler is ready to receive grid definition.
197         set<CContextClient*> couplerInReady_;
198         bool isCouplerInReady(CContextClient* client) { return couplerInReady_.count(client)!=0 ;}
199
200       public:
201        void sendCouplerInCloseDefinition(CContextClient* client) ;
202        set<CContextClient*> sendCouplerInCloseDefinition_done_;
203        static void recvCouplerInCloseDefinition(CEventServer& event) ;
204        void recvCouplerInCloseDefinition(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
205        set<CContextClient*> couplerInCloseDefinition_ ;
206        bool isCouplerInCloseDefinition(CContextClient* client) { return couplerInCloseDefinition_.count(client)!=0 ;}
207
208       public:
209        void sendCouplerInContextFinalized(CContextClient* client) ;
210        set<CContextClient*> sendCouplerInContextFinalized_done_;
211        static void recvCouplerInContextFinalized(CEventServer& event) ;
212        void recvCouplerInContextFinalized(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent     
213        set<CContextClient*> couplerInContextFinalized_ ;
214        bool isCouplerInContextFinalized(CContextClient* client) { return couplerInContextFinalized_.count(client)!=0 ;}
215
216       public: 
217        void freeComms(void);                  //!< Free internally allcoated communicators
218
219         // dispatch event
220         static bool dispatchEvent(CEventServer& event);
221
222      public:
223        // Get current context
224        static CContext* getCurrent(void);
225
226        // Get context root
227        static CContextGroup* getRoot(void);
228       
229        // Set current context
230        static void setCurrent(const string& id);
231
232        // Create new context
233        static CContext* create(const string& id = "");
234
235        /// Accesseurs statiques ///
236        static StdString GetName(void);
237        static StdString GetDefName(void);
238        static ENodeType GetType(void);
239
240        static CContextGroup* GetContextGroup(void);
241
242        // Some functions to visualize structure of current context
243        static void ShowTree(StdOStream & out = std::clog);
244        static void CleanTree(void);
245        static void removeContext(const std::string& contextId);
246        static void removeAllContexts(void) ;
247        int getServiceType(void) {return serviceType_;}
248
249      public :
250         // Parse xml node and write all info into context
251         virtual void parse(xml::CXMLNode & node);
252
253         // Visualize a context
254         virtual StdString toString(void) const;
255
256
257         // Solve all inheritance relation in current context
258         virtual void solveDescInheritance(bool apply, const CAttributeMap * const parent = 0);
259
260         // Verify if all root definition in a context have children
261         virtual bool hasChild(void) const;
262
263         bool isProcessingEvent(void) {return isProcessingEvent_;}
264         bool setProcessingEvent(void) {isProcessingEvent_=true ;}
265         bool unsetProcessingEvent(void) {isProcessingEvent_=false ;}
266         
267         void addCouplingChanel(const std::string& contextId, bool out) ;
268
269      public :
270         // Calendar of context
271         std::shared_ptr<CCalendar>   calendar;
272
273         // List of all enabled files (files on which fields are written or read)
274         std::vector<CFile*> enabledFiles;
275         // List of all enabled files in read mode (files on which fields are read)
276         std::vector<CFile*> enabledReadModeFiles;
277         // List of all enabled files in write mode
278         std::vector<CFile*> enabledWriteModeFiles;
279
280         std::vector<CCouplerIn*> enabledCouplerIn;
281         std::vector<CCouplerOut*> enabledCouplerOut;
282
283
284         // List of all enabled fields whose instant data is accessible from the public API
285         // but which are not part of a file
286         std::vector<CField*> fieldsWithReadAccess_;
287         std::vector<CField*> couplerInFields_;
288         std::vector<CField*> fileInFields_;
289
290
291         // Context root
292         static std::shared_ptr<CContextGroup> root;
293
294         // Determine context on client or not
295         bool hasClient;
296
297         // Determine context on server or not
298         bool hasServer;
299      public:
300        void registerFileToWrite(CFile* file) { filesToWrite_.insert(file); } // Add a file that need to be write for example to create headers
301      private: 
302        std::set<CFile*,FilePtrCompare> filesToWrite_ ; 
303
304      private:
305        CContextClient* onlineContextClient_=nullptr ;
306       
307        std::string defaultPoolWriterId_ ;
308        std::string defaultPoolReaderId_ ;
309        std::string defaultPoolGathererId_ ;
310        std::string defaultWriterId_ ;
311        std::string defaultReaderId_ ;
312        std::string defaultGathererId_ ;
313        bool defaultUsingServer2_ ;
314        void setDefaultServices(void) ;
315
316
317        std::map<std::pair<string,string>,std::vector<pair<CContextClient*,CContextServer*>>> serversMap_ ;
318
319        std::vector<CContextClient*> writerClientOut_ ;
320        std::vector<CContextServer*> writerServerOut_ ;
321        std::vector<CContextClient*> writerClientIn_ ;
322        std::vector<CContextServer*> writerServerIn_ ;
323
324        std::vector<CContextClient*> readerClientOut_ ;
325        std::vector<CContextServer*> readerServerOut_ ;
326        std::vector<CContextClient*> readerClientIn_ ;
327        std::vector<CContextServer*> readerServerIn_ ;
328
329
330        std::map<std::string, CContextClient*> clients_ ;
331        std::map<std::string, CContextClient*> servers_ ;
332        std::map<CContextClient*, std::string> clientsId_ ;
333        std::map<CContextServer*, std::string> serversId_ ;
334
335        // list of slave servers (IO server or others)
336        std::vector<CContextClient*> slaveServers_ ;
337
338        // the map containing context client associated to it string id for coupling out ;
339        std::map<std::string, CContextClient*> couplerOutClient_ ;
340        // the map containing context server associated to it string id for coupling out ;
341        std::map<std::string, CContextServer*> couplerOutServer_ ;
342        // the map containing context client associated to it string id for coupling in ;
343        std::map<std::string, CContextClient*> couplerInClient_ ;
344        // the map containing context server associated to it string id for coupling in ;
345        std::map<std::string, CContextServer*> couplerInServer_ ;
346      public:
347         void createClientInterComm(MPI_Comm interCommClient, MPI_Comm interCommServer)  ;
348         void createServerInterComm(void)  ; // obsolete
349         void createServerInterComm_old(void)  ;
350         void createServerInterComm(const string& poolId, const string& serverId, vector<pair<string, pair<CContextClient*,CContextServer*>>>& clientServers ) ;
351         void getServerInterComm(const string& poolId, const string& serviceId,  vector<pair<CContextClient*,CContextServer*>>& clientServers) ;
352         vector<CContextClient*> getContextClient(const string& poolId, const string& serviceId) ;
353         CContextClient* getCouplerInClient(const string& contextId) { return couplerInClient_[contextId] ;}
354         CContextServer* getCouplerInServer(const string& contextId) { return couplerInServer_[contextId] ;}
355         CContextClient* getCouplerOutClient(const string& contextId) { return couplerOutClient_[contextId] ;}
356         CContextServer* getCouplerOutServer(const string& contextId) { return couplerOutServer_[contextId] ;}
357       
358       public: // must be privatize using accessors
359       
360        CRegistry* registryIn=nullptr ;    //!< input registry which is read from file
361        CRegistry* registryOut=nullptr ;   //!< output registry which will be written into file at the finalize
362
363
364        MPI_Comm intraComm_ ; //! context intra communicator
365        int intraCommRank_ ; //! context intra communicator rank
366        int intraCommSize_ ; //! context intra communicator size
367       public: 
368        MPI_Comm getIntraComm(void) {return intraComm_ ;}
369        int getIntraCommRank(void) {return intraCommRank_;}
370        int getIntraCommSize(void) {return intraCommSize_;}
371      private:
372         shared_ptr<CEventScheduler> eventScheduler_ ; //! The local event scheduler for context
373         size_t hashId_ ; //! the local hashId for scheduler
374         size_t timeLine_=0 ;
375         void initEventScheduler(void) ;
376
377         bool isPostProcessed;
378         bool allProcessed;
379         bool finalized;
380         int countChildContextFinalized_;        //!< Counter of child contexts (for now it is the number of secondary server pools)
381         CGarbageCollector garbageCollector;
382         std::list<MPI_Comm> comms; //!< Communicators allocated internally
383
384         int serviceType_;  //!< service associated to the context
385         string contextId_ ; //!< context client id for the servers. For clients this is same as getId()
386         bool isProcessingEvent_ ;
387    private:     
388         CServerContext* parentServerContext_ ;
389    public:
390         CServerContext* getParentServerContext(void) { return parentServerContext_; }
391    private: 
392      bool lockedContext_=false;
393    public: 
394        void lockContext(void) {lockedContext_=true; }
395        void unlockContext(void) {lockedContext_=false; }
396        bool isLockedContext(void) { return lockedContext_;}
397      public: // Some function maybe removed in the near future
398        // virtual void toBinary  (StdOStream & os) const;
399        // virtual void fromBinary(StdIStream & is);
400   }; // class CContext
401
402   ///--------------------------------------------------------------
403
404   // Declare/Define CContextGroup and CContextDefinition
405   DECLARE_GROUP(CContext);
406
407   ///--------------------------------------------------------------
408
409} // namespace xios
410
411#endif // __XIOS_CContext__
Note: See TracBrowser for help on using the repository browser.