source: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp @ 1949

Last change on this file since 1949 was 1943, checked in by ymipsl, 4 years ago

Solve issues for grid mask on server side.

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
  • Property svn:executable set to *
File size: 36.1 KB
RevLine 
[591]1#ifndef __XIOS_CGrid__
2#define __XIOS_CGrid__
[219]3
[591]4/// XIOS headers ///
5#include "xios_spl.hpp"
[219]6#include "group_factory.hpp"
7
8#include "declare_group.hpp"
9#include "domain.hpp"
10#include "axis.hpp"
[887]11#include "scalar.hpp"
[369]12#include "array_new.hpp"
13#include "attribute_array.hpp"
[552]14#include "distribution_server.hpp"
[553]15#include "client_server_mapping.hpp"
[567]16#include "utils.hpp"
[619]17#include "transformation_enum.hpp"
[1918]18#include "grid_local_connector.hpp"
19#include "grid_elements.hpp"
[1930]20#include "grid_scatterer_connector.hpp"
21#include "grid_gatherer_connector.hpp"
[219]22
[1930]23
[335]24namespace xios {
[509]25
[1564]26   /// ////////////////////// Declarations ////////////////////// ///
[219]27
28   class CGridGroup;
29   class CGridAttributes;
[540]30   class CDomainGroup;
31   class CAxisGroup;
[887]32   class CScalarGroup;
[219]33   class CGrid;
[551]34   class CDistributionClient;
[552]35   class CDistributionServer;
[553]36   class CServerDistributionDescription;
37   class CClientServerMapping;
[620]38   class CGridTransformation;
[219]39
40   ///--------------------------------------------------------------
41
42   // Declare/Define CGridAttribute
43   BEGIN_DECLARE_ATTRIBUTE_MAP(CGrid)
44#  include "grid_attribute.conf"
45   END_DECLARE_ATTRIBUTE_MAP(CGrid)
46
47   ///--------------------------------------------------------------
48
49   class CGrid
50      : public CObjectTemplate<CGrid>
51      , public CGridAttributes
52   {
53         /// typedef ///
54         typedef CObjectTemplate<CGrid>   SuperClass;
55         typedef CGridAttributes SuperClassAttribute;
56
[1930]57      private:
58       
59        // define a structure to store elements (CDomain, CAxis, CScalar) using a void* and a type to cast the pointer
60         enum EElementType { TYPE_SCALAR, TYPE_AXIS, TYPE_DOMAIN } ;
61         struct SElement {void* ptr ; EElementType type ; CScalar* scalar ;  CAxis* axis ; CDomain* domain ; } ;
62         vector<SElement> elements_ ;
63         bool elementsComputed_ = false ; 
64         /** retrieve the vector of elements as a structure containing a void* and the type of pointer */
65         vector<SElement>& getElements(void) { if (!elementsComputed_) computeElements() ; return elements_ ; } 
66         void computeElements(void) ;
67         /** List order of axis and domain in a grid, if there is a domain, it will take value 2, axis 1, scalar 0 */
68         std::vector<int> order_;
69
[676]70      public:
[219]71
72         typedef CGridAttributes RelAttributes;
73         typedef CGridGroup      RelGroup;
74
[300]75         enum EEventId
76         {
[1943]77           EVENT_ID_INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR,
78           EVENT_ID_SEND_MASK,
79
[650]80         };
[509]81
[219]82         /// Constructeurs ///
83         CGrid(void);
[650]84         explicit CGrid(const StdString& id);
85         CGrid(const CGrid& grid);       // Not implemented yet.
86         CGrid(const CGrid* const grid); // Not implemented yet.
[219]87
88         /// Traitements ///
[509]89//         void solveReference(void);
[219]90
[676]91         void checkEligibilityForCompressedOutput();
[1930]92         
[676]93
[509]94
95         void checkMaskIndex(bool doCalculateIndex);
96
[650]97 //        virtual void toBinary  (StdOStream& os) const;
98//         virtual void fromBinary(StdIStream& is);
[219]99
[676]100         void addRelFileCompressed(const StdString& filename);
101
[219]102         /// Tests ///
[676]103         bool isCompressible(void) const;
104         bool isWrittenCompressed(const StdString& filename) const;
[219]105
[676]106      public:
[219]107
108         /// Accesseurs ///
[1158]109         StdSize getDimension(void);
[509]110
[1869]111         StdSize  getDataSize(void) ;
[219]112
[1875]113         /**
114          * Get the local data grid size, ie the size of the compressed grid (inside the workflow)
115          * \return The size od the compressed grid
116          */
117         StdSize  getLocalDataSize(void) ;
118
[1564]119         /// Entrees-sorties de champs
[369]120         template <int n>
[1869]121         void inputField(const CArray<double,n>& field, CArray<double,1>& stored) ;
[593]122         template <int n>
[1869]123         void maskField(const CArray<double,n>& field, CArray<double,1>& stored) ;
[1637]124         template <int n>
[1869]125         void outputField(const CArray<double,1>& stored, CArray<double,n>& field) ; 
[1250]126         template <int n>
[1869]127         void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) ; 
[509]128
[650]129         virtual void parse(xml::CXMLNode& node);
[540]130
[219]131         /// Destructeur ///
132         virtual ~CGrid(void);
133
[676]134      public:
[219]135
136         /// Accesseurs statiques ///
137         static StdString GetName(void);
138         static StdString GetDefName(void);
[509]139
[219]140         static ENodeType GetType(void);
141
142         /// Instanciateurs Statiques ///
[347]143         static CGrid* createGrid(CDomain* domain);
144         static CGrid* createGrid(CDomain* domain, CAxis* axis);
[745]145         static CGrid* createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
[887]146                                  const CArray<int,1>& axisDomainOrder = CArray<int,1>());
[745]147         static CGrid* createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
[887]148                                  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder = CArray<int,1>());
149         static CGrid* createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
150                                  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder);
[745]151         static StdString generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
[887]152                                     const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder = CArray<int,1>());
[823]153         static StdString generateId(const CGrid* gridSrc, const CGrid* gridDest);
154         static CGrid* cloneGrid(const StdString& idNewGrid, CGrid* gridSrc);
[219]155
[1144]156      public:           
[219]157         void computeIndexServer(void);
158         void computeIndex(void);
[586]159         void computeIndexScalarGrid();
[1129]160         void computeWrittenIndex();
[1869]161         void solveDomainAxisRef(bool areAttributesChecked);
162         void checkElementsAttributes(void) ;
[219]163
[509]164         void solveDomainRef(bool checkAtt);
165         void solveAxisRef(bool checkAtt);
[887]166         void solveScalarRef(bool checkAtt);
[1869]167         void solveElementsRefInheritance(bool apply = true);
168        // void solveTransformations();
[775]169         void solveDomainAxisBaseRef();
[509]170
[835]171         CDomain* addDomain(const std::string& id=StdString());
172         CAxis* addAxis(const std::string& id=StdString());
[887]173         CScalar* addScalar(const std::string& id=StdString());
[1870]174
175      public:
176         void sendGridToFileServer(CContextClient* client) ;
177      private:
178         std::set<CContextClient*> sendGridToFileServer_done_ ;
[1875]179     
[1870]180      public:
[1875]181         void sendGridToCouplerOut(CContextClient* client, const string& fieldId) ;
182      private:
183         std::set<CContextClient*> sendGridToCouplerOut_done_ ;
184
185      public:
186         void makeAliasForCoupling(const string& fieldId) ;
187
188      public:
[1784]189         void sendAddDomain(const std::string& id,CContextClient* contextClient);
190         void sendAddAxis(const std::string& id,CContextClient* contextClient);
191         void sendAddScalar(const std::string& id,CContextClient* contextClient);
192         void sendAllDomains(CContextClient* contextClient);
193         void sendAllAxis(CContextClient* contextClient);
194         void sendAllScalars(CContextClient* contextClient);
[540]195
[650]196         static void recvAddDomain(CEventServer& event);
197         void recvAddDomain(CBufferIn& buffer);
198         static void recvAddAxis(CEventServer& event);
199         void recvAddAxis(CBufferIn& buffer);
[887]200         static void recvAddScalar(CEventServer& event);
201         void recvAddScalar(CBufferIn& buffer);
[540]202
[650]203         static bool dispatchEvent(CEventServer& event);
204         static void recvIndex(CEventServer& event);
[1853]205         void recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server);
[1875]206       
207       public: 
208         void sendIndex(CContextClient* client, const string& gridId="");
209       private:
210          set<CContextClient*> sendIndex_done_ ;
211       
212       public:
213         void sendIndexScalarGrid(CContextClient* client, const string& gridId="");
214       private:
215          set<CContextClient*> sendIndexScalarGrid_done_ ;
216     
217       public:
[1294]218         void setContextClient(CContextClient* contextClient);
219
[509]220         void computeDomConServer();
221         std::map<int, int> getDomConServerSide();
[1330]222         std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, bool bufferForWriting = false);
223         std::map<int, StdSize> getDataBufferSize(CContextClient* client, const std::string& id = "", bool bufferForWriting = false);
[540]224         std::vector<StdString> getDomainList();
225         std::vector<StdString> getAxisList();
[887]226         std::vector<StdString> getScalarList();
[540]227         std::vector<CDomain*> getDomains();
228         std::vector<CAxis*> getAxis();
[887]229         std::vector<CScalar*> getScalars();
[943]230         CDomain* getDomain(int domainIndex);
231         CAxis* getAxis(int axisIndex);
232         CScalar* getScalar(int scalarIndex);
[551]233         std::vector<int> getAxisOrder();
[567]234         std::vector<int> getGlobalDimension();
[1236]235         bool isScalarGrid() const;         
[540]236
[567]237         bool doGridHaveDataToWrite();
[1235]238         bool doGridHaveDataDistributed(CContextClient* client = 0);
[1871]239         size_t getWrittenDataSize() ;
[676]240         int getNumberWrittenIndexes() const;
241         int getTotalNumberWrittenIndexes() const;
242         int getOffsetWrittenIndexes() const;
[567]243
[620]244         CGridTransformation* getTransformations();
[567]245
[632]246         void transformGrid(CGrid* transformGridSrc);
[1869]247         
248         void prepareTransformGrid(CGrid* transformGridSrc);
249         bool prepareTransformGrid_done_ = false ;
250
251         void makeTransformGrid(void); 
252         bool makeTransformGrid_done_ = false ;
253         
254         std::vector<std::string> getAuxInputTransformGrid(void) ; 
255
[775]256         void completeGrid(CGrid* transformGridSrc = 0);
[687]257         void doAutoDistribution(CGrid* transformGridSrc);
[619]258         bool isTransformed();
259         void setTransformed();
[890]260         bool isGenerated();
261         void setGenerated();
[823]262         void addTransGridSource(CGrid* gridSrc);
263         std::map<CGrid*, std::pair<bool,StdString> >& getTransGridSource();
[824]264         bool hasTransform();
[1215]265         size_t getGlobalWrittenSize(void) ;
[1875]266         
267         bool isCompleted(void) ;
268         void setCompleted(void) ;
269         void unsetCompleted(void) ;
[509]270
[1869]271
[1637]272         bool hasMask(void) const;
[650]273         void checkMask(void);
[821]274         void createMask(void);
[1129]275         void modifyMask(const CArray<int,1>& indexToModify, bool valueToModify = false);
276         void modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue = false);
[1918]277       
278        /** get mask pointer stored in mask_1d, or mask_2d, or..., or mask_7d */
279         CArray<bool,1> mask_ ;
280         CArray<bool,1>& getMask(void) ;
[509]281
[742]282         void computeGridGlobalDimension(const std::vector<CDomain*>& domains,
283                                         const std::vector<CAxis*>& axis,
[887]284                                         const std::vector<CScalar*>& scalars,
285                                         const CArray<int,1>& axisDomainOrder);
[742]286
[1869]287         void computeGridIndexToFileServer(CContextClient* client) ;
[1870]288 
289     private:
290        /** Client-like distribution calculated based on the knowledge of the entire grid */
291       CDistributionClient* clientDistribution_;
292     public: 
[1869]293       void computeClientDistribution(void) ;
[1870]294     private:
[1869]295       bool computeClientDistribution_done_ = false ;
[1870]296     public:
297       CDistributionClient* getClientDistribution(void); 
[1869]298
[1871]299     private:   
300       /** Server-like distribution calculated upon receiving indexes */
301       CDistributionServer* serverDistribution_;
302       void computeServerDistribution(void) ;
303       bool computeServerDistribution_done_=false ;
304     public: 
[1872]305       CDistributionServer* getServerDistribution(void) { if (!computeServerDistribution_done_) computeServerDistribution() ; return serverDistribution_ ;}
[1871]306
307
[1870]308     private:
[567]309       template<int N>
310       void checkGridMask(CArray<bool,N>& gridMask,
[664]311                          const std::vector<CArray<bool,1>* >& domainMasks,
[567]312                          const std::vector<CArray<bool,1>* >& axisMasks,
[887]313                          const CArray<int,1>& axisDomainOrder,
[821]314                          bool createMask = false);
[1918]315
[623]316        template<int N>
[1129]317        void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify);
[623]318
[1129]319        template<int N>
320        void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue);
321
[1869]322        void storeField_arr(const double* const data, CArray<double, 1>& stored) ;
323        void restoreField_arr(const CArray<double, 1>& stored, double* const data) ;
324        void uncompressField_arr(const double* const data, CArray<double, 1>& outData) ;
325        void maskField_arr(const double* const data, CArray<double, 1>& stored) ;
[1144]326
[540]327        void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
328        void setVirtualAxisGroup(CAxisGroup* newVAxisGroup);
[887]329        void setVirtualScalarGroup(CScalarGroup* newVScalarGroup);
[567]330
[887]331        void setDomainList(const std::vector<CDomain*> domains = std::vector<CDomain*>());
[540]332        void setAxisList(const std::vector<CAxis*> axis = std::vector<CAxis*>());
[887]333        void setScalarList(const std::vector<CScalar*> scalars = std::vector<CScalar*>());
[540]334
[887]335        CDomainGroup* getVirtualDomainGroup() const;
[540]336        CAxisGroup* getVirtualAxisGroup() const;
[887]337        CScalarGroup* getVirtualScalarGroup() const;
[619]338
[657]339        void checkAttributesAfterTransformation();
[619]340        void setTransformationAlgorithms();
[1542]341        void computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,
[1263]342                                   const CContextClient* client,
[865]343                                   CClientServerMapping::GlobalIndexMap& globalIndexOnServer);
[1158]344        int computeGridGlobalDimension(std::vector<int>& globalDim,
345                                       const std::vector<CDomain*> domains,
346                                       const std::vector<CAxis*> axis,
347                                       const std::vector<CScalar*> scalars,
348                                       const CArray<int,1>& axisDomainOrder);
349        int getDistributedDimension();
[619]350
[1869]351        void computeConnectedClients(CContextClient* client);
352        set<CContextClient*> computeConnectedClients_done_ ;
353
354        void computeConnectedClientsScalarGrid(CContextClient* client); 
355        set<CContextClient*> computeConnectedClientsScalarGrid_done_ ;
[1794]356
357      public:
358/** Array containing the local index of the grid
359 *  storeIndex_client[local_workflow_grid_index] -> local_model_grid_index.
360 *  Used to store field from model into the worklow, or to return field into models. 
361 *  The size of the array is the number of local index of the workflow grid */       
[1869]362        CArray<int, 1> storeIndex_client_;
363        void computeStoreIndex_client(void) ;
364        bool computeStoreIndex_client_done_ = false ;
365        CArray<int, 1>& getStoreIndex_client(void) { if (!computeStoreIndex_client_done_) computeStoreIndex_client() ; return storeIndex_client_ ;}
[1794]366
367/** Array containing the grid mask masked defined by the mask_nd grid attribute.       
368  * The corresponding masked field value provided by the model will be replaced by a NaN value
369  * in the workflow.  */
[1869]370        CArray<bool, 1> storeMask_client_;
371        void computeStoreMask_client(void) ;
372        bool computeStoreMask_client_done_ = false ;
373        CArray<bool, 1>& getStoreMask_client(void) { if (!computeStoreMask_client_done_) computeStoreMask_client() ; return storeMask_client_ ;}
[1794]374
375/** Map containing the indexes on client side that will be sent to each connected server.
376  * storeIndex_toSrv[&contextClient] -> map concerning the contextClient for which the data will be sent (client side)
377  * storeIndex_toSrv[&contextClient][rank] -> array of indexes that will be sent to each "rank" of the connected servers
378  * storeIndex_toSrv[&contextClient][rank](index_of_buffer_sent_to_server) -> local index of the field of the workflow
379  * grid that will be sent to server */
380         std::map<CContextClient*, map<int, CArray<int, 1> > > storeIndex_toSrv_;
381
382
383/** Map containing the indexes on client side that will be received from each connected server.
384  * This map is used to agreggate field data received from server (for reading) into a single array, which will be an entry
385  * point of the worklow on client side.
386  * storeIndex_toSrv[rank] -> array of indexes that will be received from each "rank" of the connected servers
387  * storeIndex_toSrv[rank](index_of_buffer_received_from_server) -> local index of the field in the "workflow grid"
388  * that has been received from server */
389         std::map<int, CArray<int, 1> > storeIndex_fromSrv_; // Support, for now, reading with level-1 server
390
391
392/** Maps storing the number of participating clients for data sent a specific server for a given contextClient, identified
393  * by the servers communicator size. In future must be direcly identified by context.
394  * nbSender_[context_server_size] -> map the number of client sender by connected rank of servers
395  * nbSender_[context_server_size] [rank_server] -> the number of client participating to a send message for a server of rank "rank_server"
396  * Usefull to indicate in a message the number of participant needed by the transfer protocol */
397         std::map<int, std::map<int,int> > nbSenders_;
398
[1881]399      private:
[1794]400/** Maps storing the number of participating servers for data sent a specific client for a given contextClient.
401  * Symetric of nbSenders_, but for server side which want to send data to client.
402  * nbReadSender_[context_client_size] -> map the number of server sender by connected rank of clients
[1881]403  * nbReadSender_[context_client_size] [rank_client] -> the number of server participating to a send message for a client of rank "rank_client"
[1794]404  * Usefull to indicate in a message the number of participant needed by the transfer protocol */
405         std::map<CContextClient*, std::map<int,int> > nbReadSenders_;
[1881]406      public:
407         std::map<int,int>& getNbReadSenders(CContextClient* client) 
408         { if (nbReadSenders_.count(client)==0) computeNbReadSenders(client) ; return nbReadSenders_[client] ;}
409      private:
410         void computeNbReadSenders(CContextClient* client) ;
411     
[1794]412
413// Manh Ha's comment: " A client receives global index from other clients (via recvIndex)
414// then does mapping these index into local index of STORE_CLIENTINDEX
415// In this way, store_clientIndex can be used as an input of a source filter
416// Maybe we need a flag to determine whether a client wants to write. TODO "
417
[1870]418      private:
419       /** Map storing received data on server side. This map is the equivalent to the storeIndex_client, but for data received from client
420        * instead that from model. This map is used to concatenate data received from several clients into a single array on server side
421        * which match the local workflow grid.
422        * outLocalIndexStoreOnClient_[client_rank] -> Array of index from client of rank "client_rank"
423        * outLocalIndexStoreOnClient_[client_rank](index of buffer from client) -> local index of the workflow grid
424        * The map is created in CGrid::computeClientIndex and filled upon receiving data in CField::recvUpdateData().
425        * Symetrically it is also used to send data from a server to several client for reading case. */
426        map<int, CArray<size_t, 1>> outLocalIndexStoreOnClient_; 
427      public:
428         void computeOutLocalIndexStoreOnClient(void) ;
429      private:
430         bool computeOutLocalIndexStoreOnClient_done_ = false ; 
431      public:   
432         map<int, CArray<size_t, 1>>& getOutLocalIndexStoreOnClient(void) 
433         { if (!computeOutLocalIndexStoreOnClient_done_) computeOutLocalIndexStoreOnClient(); return outLocalIndexStoreOnClient_ ; }
[1794]434
[1870]435      public:
[1794]436/** Indexes calculated based on server-like distribution.
437 *  They are used for writing/reading data and only calculated for server level that does the writing/reading.
[1847]438 *  Along with localIndexToWriteOnClient, these indexes are used to correctly place incoming data.
439 *  size of the array : numberWrittenIndexes_ : number of index written in a compressed way
440 *  localIndexToWriteOnServer_(compressed_written_index) : -> local uncompressed index that will be written in the file */
441         CArray<size_t,1> localIndexToWriteOnServer_;
[1794]442
443/** Indexes calculated based on client-like distribution.
444  * They are used for writing/reading data and only calculated for server level that does the writing/reading.
[1847]445  * Along with localIndexToWriteOnServer, these indexes are used to correctly place incoming data.
446  * size of the array : numberWrittenIndexes_
447  * localIndexToWriteOnClient_(compressed_written_index) -> local index of the workflow grid*/
448         CArray<size_t,1> localIndexToWriteOnClient_;
[1794]449
[1870]450      public: 
451        bool isDataDistributed(void) ; 
[540]452      private:
[1236]453
[1294]454/** Clients that have to send a grid. There can be multiple clients in case of secondary server, otherwise only one client. */
[1353]455        std::list<CContextClient*> clients;
456        std::set<CContextClient*> clientsSet;
[1294]457
[1870]458      private: 
459        /** Map storing received indexes on server side sent by clients. Key = sender rank, value = global index array.
460            Later, the global indexes received will be mapped onto local index computed with the local distribution.
461            outGlobalIndexFromClient_[rank] -> array of global index send by client of rank "rank"
462            outGlobalIndexFromClient_[rank](n) -> global index of datav n sent by client
463        */     
[1847]464        map<int, CArray<size_t, 1> > outGlobalIndexFromClient_;
[1870]465      public: 
466        map<int, CArray<size_t, 1> >& getOutGlobalIndexFromClient() { return outGlobalIndexFromClient_ ;}
[1794]467
[1870]468      private:
[1294]469        bool isChecked;
470        bool isDomainAxisChecked;
471        bool isIndexSent;
472
[540]473        CDomainGroup* vDomainGroup_;
474        CAxisGroup* vAxisGroup_;
[887]475        CScalarGroup* vScalarGroup_;
476        std::vector<std::string> axisList_, domList_, scalarList_;
477        bool isAxisListSet, isDomListSet, isScalarListSet;
[567]478
[568]479        CClientServerMapping* clientServerMap_;
[676]480        int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_;
[1243]481
[1330]482/** Map storing local ranks of connected receivers. Key = size of receiver's intracomm.
483  * It is calculated in computeConnectedClients(). */
[1263]484        std::map<int, std::vector<int> > connectedServerRank_;
[1243]485
[1330]486/** Map storing the size of data to be send. Key = size of receiver's intracomm
487  * It is calculated in computeConnectedClients(). */
[1263]488        std::map<int, std::map<int,size_t> > connectedDataSize_;
[1243]489
[1330]490/** Ranks of connected receivers in case of reading. It is calculated in recvIndex(). */
491        std::vector<int> connectedServerRankRead_;
492
493/** Size of data to be send in case of reading. It is calculated in recvIndex(). */
494        std::map<int,size_t> connectedDataSizeRead_;
[1870]495     
[676]496         //! True if and only if the data defined on the grid can be outputted in a compressed way
497        bool isCompressible_;
498        std::set<std::string> relFilesCompressed;
[619]499
[1129]500        bool isTransformed_, isGenerated_;
501        bool computedWrittenIndex_;
[1870]502       
[620]503        std::vector<int> axisPositionInGrid_;
[1870]504        void computeAxisPositionInGrid(void) ;
505        bool computeAxisPositionInGrid_done_ = false ;
506        std::vector<int>& getAxisPositionInGrid(void) { if (!computeAxisPositionInGrid_done_) computeAxisPositionInGrid() ; return axisPositionInGrid_ ;}
507
[620]508        CGridTransformation* transformations_;
[1158]509        bool hasDomainAxisBaseRef_;       
[823]510        std::map<CGrid*, std::pair<bool,StdString> > gridSrc_;
[824]511        bool hasTransform_;
[1243]512
[1847]513/** Map storing global indexes of server-like (band-wise) distribution for sending to receivers (client side).
514  * Key = size of receiver's intracomm (i.e. number of servers)
515  * ~ map<int, umap<int, std::vector<size_t> >> globalIndexOnServer_
516  * globalIndexOnServer_[servers_size] -> map for a distribution of size "servers_size" (number of servers)
517  * globalIndexOnServer_[servers_size][server_rank] -> array of global index managed by server of rank "server_rank"
518  * globalIndexOnServer_[servers_size][server_rank][n] -> global index of data to be send to the server by client based on sub element of the grid.
519  * -> grid masking is not included.
[1263]520  */
521//        std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;
[1943]522      std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;
523     
[1243]524
[1930]525     //////////////////////////////////////////////////////////////////////////////////////
526     //  this part is related to distribution, element definition, views and connectors  //
527     //////////////////////////////////////////////////////////////////////////////////////
[1943]528      private:
529       static void recvMask(CEventServer& event) ;
530       void receiveMask(CEventServer& event) ;
[1243]531
[1918]532      private: 
533        CGridLocalElements* gridLocalElements_= nullptr ;
534        void computeGridLocalElements(void) ;
535      public:
536        CGridLocalElements* getGridLocalElements(void) { if (gridLocalElements_==nullptr) computeGridLocalElements() ; return gridLocalElements_ ;}
537
538      private:
539        CGridLocalConnector* modelToWorkflowConnector_ ;
540      public:
541        void computeModelToWorkflowConnector(void) ;
542        CGridLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_;}
543
[1930]544      private:
545        CGridLocalConnector* workflowToModelConnector_ ;
546      public:
547        void computeWorkflowToModelConnector(void) ;
548        CGridLocalConnector* getWorkflowToModelConnector(void) { if (workflowToModelConnector_==nullptr) computeWorkflowToModelConnector() ; return workflowToModelConnector_;}
549
550      public: //?
551        void distributeGridToFileServer(CContextClient* client);
552     
[1934]553           
[1930]554      private:
555        CGridLocalConnector* workflowToFullConnector_ = nullptr;
556      public:
557        void computeWorkflowToFullConnector(void) ;
558        CGridLocalConnector* getWorkflowToFullConnector(void) { if (workflowToFullConnector_==nullptr) computeWorkflowToFullConnector() ; return workflowToFullConnector_;}
559
560      private:
561        CGridLocalConnector* fullToWorkflowConnector_ = nullptr;
562      public:
563        void computeFullToWorkflowConnector(void) ;
564        CGridLocalConnector* getFullToWorkflowConnector(void) { if (fullToWorkflowConnector_==nullptr) computeFullToWorkflowConnector() ; return fullToWorkflowConnector_;}
565
[1934]566   
567
[1930]568      private:
569         CGridGathererConnector* clientFromClientConnector_ = nullptr ;
570      public:
571         CGridGathererConnector* getClientFromClientConnector(void) { if (clientFromClientConnector_==nullptr) computeClientFromClientConnector() ; return clientFromClientConnector_;}
572         void computeClientFromClientConnector(void) ;
573
574      private:
575         map<CContextClient*, CGridScattererConnector*> clientToClientConnector_ ;
576      public:
577         CGridScattererConnector* getClientToClientConnector(CContextClient* client) { return clientToClientConnector_[client] ;} // make some test to see if connector exits for the given client
578 
579
580      private:
[1934]581         map<CContextClient*,CGridGathererConnector*> clientFromServerConnector_  ;
[1930]582      public:
[1934]583         CGridGathererConnector* getClientFromServerConnector(CContextClient* client) { return clientFromServerConnector_[client];}
[1930]584         void computeClientFromServerConnector(void) ;
585
[1934]586      private:
587         CGridScattererConnector* serverToClientConnector_=nullptr ;
588      public:
589         CGridScattererConnector* getServerToClientConnector(void) { if (serverToClientConnector_==nullptr) computeServerToClientConnector() ; return serverToClientConnector_;}
590         void computeServerToClientConnector(void) ;
591      private:
592         map<CContextClient*, CGridScattererConnector*> clientToServerConnector_ ;
593      public:
594         CGridScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;} // make some test to see if connector exits for the given client
595         
596      private:
597         CGridGathererConnector* serverFromClientConnector_ = nullptr ;
598      public:
599         CGridGathererConnector* getServerFromClientConnector(void) { if (serverFromClientConnector_==nullptr) computeServerFromClientConnector() ; return serverFromClientConnector_;}
600         void computeServerFromClientConnector(void) ;
601
[219]602   }; // class CGrid
603
604   ///--------------------------------------------------------------
605
[369]606   template <int n>
[1869]607   void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored)
[1622]608   TRY
[219]609   {
[1294]610//#ifdef __XIOS_DEBUG
[369]611      if (this->getDataSize() != field.numElements())
612         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const",
[680]613                << "[ Awaiting data of size = " << this->getDataSize() << ", "
[421]614                << "Received data size = "      << field.numElements() << " ] "
[955]615                << "The data array does not have the right size! "
[1343]616                << "Grid = " << this->getId())
[1294]617//#endif
[650]618      this->storeField_arr(field.dataFirst(), stored);
[219]619   }
[1622]620   CATCH
[219]621
[1918]622/* obsolete
[593]623   template <int n>
[1869]624   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)
[1637]625   {
626//#ifdef __XIOS_DEBUG
627      if (this->getDataSize() != field.numElements())
628         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const",
629                << "[ Awaiting data of size = " << this->getDataSize() << ", "
630                << "Received data size = "      << field.numElements() << " ] "
631                << "The data array does not have the right size! "
632                << "Grid = " << this->getId())
633//#endif
634      this->maskField_arr(field.dataFirst(), stored);
635   }
[1918]636*/
637   template <int n>
638   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)
639   {
640      auto connector = getModelToWorkflowConnector() ;
[1637]641
[1918]642      if (connector->getSrcSize() != field.numElements())
643         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const",
644                << "[ Awaiting data of size = " << this->getDataSize() << ", "
645                << "Received data size = "      << field.numElements() << " ] "
646                << "The data array does not have the right size! "
647                << "Grid = " << this->getId())
648      const double nanValue = std::numeric_limits<double>::quiet_NaN();
649      connector->transfer(field, stored, nanValue) ;
650   }
651
652
653
[1637]654   template <int n>
[1869]655   void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field)
[1622]656   TRY
[593]657   {
[1294]658//#ifdef __XIOS_DEBUG
[593]659      if (this->getDataSize() != field.numElements())
660         ERROR("void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const",
661                << "[ Size of the data = " << this->getDataSize() << ", "
662                << "Output data size = "   << field.numElements() << " ] "
[955]663                << "The ouput array does not have the right size! "
[1343]664                << "Grid = " << this->getId())
[1294]665//#endif
[593]666      this->restoreField_arr(stored, field.dataFirst());
667   }
[1622]668   CATCH
[593]669
[1250]670   /*!
671     This function removes the effect of mask on received data on the server.
672     This function only serve for the checking purpose. TODO: Something must be done to seperate mask and data_index from each other in received data
673     \data data received data with masking effect on the server
674     \outData data without masking effect
675   */
676   template <int N>
[1869]677   void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData)
[1622]678   TRY
[1250]679   {     
680     uncompressField_arr(data.dataFirst(), outData);
681   }
[1622]682   CATCH
[1250]683
[567]684   template<int N>
685   void CGrid::checkGridMask(CArray<bool,N>& gridMask,
[664]686                             const std::vector<CArray<bool,1>* >& domainMasks,
[567]687                             const std::vector<CArray<bool,1>* >& axisMasks,
[887]688                             const CArray<int,1>& axisDomainOrder,
[821]689                             bool createMask)
[1622]690   TRY
[567]691   {
[1637]692     int idx = 0;
693     int numElement = axisDomainOrder.numElements();
694     int dim = domainMasks.size() * 2 + axisMasks.size();
695     std::vector<CDomain*> domainP = this->getDomains();
696     std::vector<CAxis*> axisP = this->getAxis();
[567]697
[1637]698     std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim);
699     std::vector<int> currentIndex(dim);
700     int idxDomain = 0, idxAxis = 0;
701    for (int i = 0; i < numElement; ++i)
702    {
703      indexMap[i] = idx;
704      if (2 == axisDomainOrder(i)) {
705          eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni;
706          eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj;
707          idx += 2; ++idxDomain;
708      }
709      else if (1 == axisDomainOrder(i)) {
710//        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements();
711        eachDimSize[indexMap[i]] = axisP[idxAxis]->n;
712        ++idx; ++idxAxis;
713      }
714      else {};
715    }
716
717    if (!gridMask.isEmpty() && !createMask)
718    {
719      for (int i = 0; i < dim; ++i)
[567]720      {
[1637]721        if (gridMask.extent(i) != eachDimSize[i])
722          ERROR("CGrid::checkMask(void)",
723                << "The mask has one dimension whose size is different from the one of the local grid." << std::endl
724                << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl
725                << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl
726                << "Grid = " << this->getId())
[567]727      }
[1637]728    }
729    else {
730        CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
731        gridMask = true;
732    }
[567]733
[1637]734    int ssize = gridMask.numElements();
735    idx = 0;
736    while (idx < ssize)
737    {
738      for (int i = 0; i < dim-1; ++i)
[567]739      {
[1637]740        if (idxLoop[i] == eachDimSize[i])
[567]741        {
[1637]742          idxLoop[i] = 0;
743          ++idxLoop[i+1];
[567]744        }
745      }
746
[1637]747      // Find out outer index
748      idxDomain = idxAxis = 0;
749      bool maskValue = true;
750      for (int i = 0; i < numElement; ++i)
[567]751      {
[1637]752        if (2 == axisDomainOrder(i))
[567]753        {
[1637]754          int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]];
755          if (idxTmp < (*domainMasks[idxDomain]).numElements())
756            maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp);
757          else
758            maskValue = false;
759          ++idxDomain;
[567]760        }
[1637]761        else if (1 == axisDomainOrder(i))
[567]762        {
[1637]763          int idxTmp = idxLoop[indexMap[i]];
764          if (idxTmp < (*axisMasks[idxAxis]).numElements())
765            maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp);
766          else
767            maskValue = false;
[1421]768
[1637]769          ++idxAxis;
[567]770        }
[1637]771      }
[567]772
[1637]773      int maskIndex = idxLoop[0];
774      int mulDim = 1;
775      for (int k = 1; k < dim; ++k)
776      {
777        mulDim *= eachDimSize[k-1];
778        maskIndex += idxLoop[k]*mulDim;
779      }
780      *(gridMask.dataFirst()+maskIndex) &= maskValue;
[1564]781
[1637]782      ++idxLoop[0];
783      ++idx;
784    }
[567]785   }
[1622]786   CATCH_DUMP_ATTR
[567]787
[1129]788   template<int N>
789   void CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,
790                                  const std::vector<int>& eachDimSize,
791                                  bool newValue)
[1622]792   TRY
[1129]793   {
794      if (N != eachDimSize.size())
795      {
796        // ERROR("CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,
797        //                                  const std::vector<int>& eachDimSize,
798        //                                  bool newValue)",
799        //       << "Dimension size of the mask is different from input dimension size." << std::endl
800        //       << "Mask dimension is " << N << "." << std::endl
801        //       << "Input dimension is " << eachDimSize.size() << "." << std::endl
[1343]802        //       << "Grid = " << this->getId())
[1129]803      }
804      CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
805      gridMask = newValue;
806   }
[1622]807   CATCH_DUMP_ATTR
[1129]808                                 
809
[623]810   /*!
811     Modify the current mask of grid, the local index to be modified will take value false
812     \param [in/out] gridMask current mask of grid
813     \param [in] indexToModify local index to modify
814   */
815   template<int N>
[1129]816   void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify)
[1622]817   TRY
[1129]818   {     
[623]819     int num = indexToModify.numElements();
820     for (int idx = 0; idx < num; ++idx)
821     {
822       *(gridMask.dataFirst()+indexToModify(idx)) = valueToModify;
823     }
824   }
[1622]825   CATCH_DUMP_ATTR
826
[219]827   ///--------------------------------------------------------------
828
[1397]829
830
[219]831   // Declare/Define CGridGroup and CGridDefinition
832   DECLARE_GROUP(CGrid);
833
834   ///--------------------------------------------------------------
835
[335]836} // namespace xios
[219]837
[591]838#endif // __XIOS_CGrid__
Note: See TracBrowser for help on using the repository browser.