Changeset 1973 for XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp
- Timestamp:
- 11/05/20 12:58:34 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp
r1943 r1973 75 75 enum EEventId 76 76 { 77 EVENT_ID_ INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR,77 EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR, 78 78 EVENT_ID_SEND_MASK, 79 79 … … 117 117 StdSize getLocalDataSize(void) ; 118 118 119 /// Entrees-sorties de champs 120 template <int n> 121 void inputField(const CArray<double,n>& field, CArray<double,1>& stored) ; 122 template <int n> 123 void maskField(const CArray<double,n>& field, CArray<double,1>& stored) ; 124 template <int n> 125 void outputField(const CArray<double,1>& stored, CArray<double,n>& field) ; 126 template <int n> 127 void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) ; 128 119 129 120 virtual void parse(xml::CXMLNode& node); 130 121 … … 155 146 156 147 public: 157 void computeIndexServer(void);158 148 void computeIndex(void); 159 149 void computeIndexScalarGrid(); 160 void computeWrittenIndex();161 150 void solveDomainAxisRef(bool areAttributesChecked); 162 151 void checkElementsAttributes(void) ; … … 202 191 203 192 static bool dispatchEvent(CEventServer& event); 204 static void recvIndex(CEventServer& event);205 void recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server);206 207 public:208 void sendIndex(CContextClient* client, const string& gridId="");209 private:210 set<CContextClient*> sendIndex_done_ ;211 193 212 194 public: 213 void sendIndexScalarGrid(CContextClient* client, const string& gridId="");214 private:215 set<CContextClient*> sendIndexScalarGrid_done_ ;216 217 public:218 195 void setContextClient(CContextClient* contextClient); 219 196 220 void computeDomConServer();221 std::map<int, int> getDomConServerSide();222 197 std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, bool bufferForWriting = false); 223 198 std::map<int, StdSize> getDataBufferSize(CContextClient* client, const std::string& id = "", bool bufferForWriting = false); … … 237 212 bool doGridHaveDataToWrite(); 238 213 bool doGridHaveDataDistributed(CContextClient* client = 0); 239 size_t getWrittenDataSize() ;240 int getNumberWrittenIndexes() const;241 int getTotalNumberWrittenIndexes() const;242 int getOffsetWrittenIndexes() const;243 214 244 215 CGridTransformation* getTransformations(); … … 255 226 256 227 void completeGrid(CGrid* transformGridSrc = 0); 257 void doAutoDistribution(CGrid* transformGridSrc);258 228 bool isTransformed(); 259 229 void setTransformed(); … … 271 241 272 242 bool hasMask(void) const; 273 void checkMask(void);274 void createMask(void);275 void modifyMask(const CArray<int,1>& indexToModify, bool valueToModify = false);276 void modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue = false);277 278 243 /** get mask pointer stored in mask_1d, or mask_2d, or..., or mask_7d */ 279 244 CArray<bool,1> mask_ ; 280 245 CArray<bool,1>& getMask(void) ; 281 246 282 void computeGridGlobalDimension(const std::vector<CDomain*>& domains, 283 const std::vector<CAxis*>& axis, 284 const std::vector<CScalar*>& scalars, 285 const CArray<int,1>& axisDomainOrder); 286 287 void computeGridIndexToFileServer(CContextClient* client) ; 288 289 private: 247 private: 290 248 /** Client-like distribution calculated based on the knowledge of the entire grid */ 291 249 CDistributionClient* clientDistribution_; … … 298 256 299 257 private: 300 /** Server-like distribution calculated upon receiving indexes */301 CDistributionServer* serverDistribution_;302 void computeServerDistribution(void) ;303 bool computeServerDistribution_done_=false ;304 public:305 CDistributionServer* getServerDistribution(void) { if (!computeServerDistribution_done_) computeServerDistribution() ; return serverDistribution_ ;}306 307 308 private:309 template<int N>310 void checkGridMask(CArray<bool,N>& gridMask,311 const std::vector<CArray<bool,1>* >& domainMasks,312 const std::vector<CArray<bool,1>* >& axisMasks,313 const CArray<int,1>& axisDomainOrder,314 bool createMask = false);315 316 template<int N>317 void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify);318 319 template<int N>320 void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue);321 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) ;326 327 258 void setVirtualDomainGroup(CDomainGroup* newVDomainGroup); 328 259 void setVirtualAxisGroup(CAxisGroup* newVAxisGroup); … … 339 270 void checkAttributesAfterTransformation(); 340 271 void setTransformationAlgorithms(); 341 void computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,342 const CContextClient* client,343 CClientServerMapping::GlobalIndexMap& globalIndexOnServer);344 272 int computeGridGlobalDimension(std::vector<int>& globalDim, 345 273 const std::vector<CDomain*> domains, … … 348 276 const CArray<int,1>& axisDomainOrder); 349 277 int getDistributedDimension(); 350 351 void computeConnectedClients(CContextClient* client); 352 set<CContextClient*> computeConnectedClients_done_ ; 353 354 void computeConnectedClientsScalarGrid(CContextClient* client); 355 set<CContextClient*> computeConnectedClientsScalarGrid_done_ ; 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 */ 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_ ;} 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. */ 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_ ;} 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 399 private: 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 403 * nbReadSender_[context_client_size] [rank_client] -> the number of server participating to a send message for a client of rank "rank_client" 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_; 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 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 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_ ; } 434 435 public: 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. 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_; 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. 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_; 449 450 public: 278 public: 279 451 280 bool isDataDistributed(void) ; 452 281 private: … … 455 284 std::list<CContextClient*> clients; 456 285 std::set<CContextClient*> clientsSet; 457 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 client463 */464 map<int, CArray<size_t, 1> > outGlobalIndexFromClient_;465 public:466 map<int, CArray<size_t, 1> >& getOutGlobalIndexFromClient() { return outGlobalIndexFromClient_ ;}467 286 468 287 private: … … 476 295 std::vector<std::string> axisList_, domList_, scalarList_; 477 296 bool isAxisListSet, isDomListSet, isScalarListSet; 478 479 CClientServerMapping* clientServerMap_;480 int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_;481 297 482 298 /** Map storing local ranks of connected receivers. Key = size of receiver's intracomm. … … 499 315 500 316 bool isTransformed_, isGenerated_; 501 bool computedWrittenIndex_;502 317 503 318 std::vector<int> axisPositionInGrid_; … … 511 326 bool hasTransform_; 512 327 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.520 */521 // std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;522 std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;523 524 525 328 ////////////////////////////////////////////////////////////////////////////////////// 526 329 // this part is related to distribution, element definition, views and connectors // … … 602 405 }; // class CGrid 603 406 604 ///--------------------------------------------------------------605 606 template <int n>607 void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored)608 TRY609 {610 //#ifdef __XIOS_DEBUG611 if (this->getDataSize() != field.numElements())612 ERROR("void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const",613 << "[ Awaiting data of size = " << this->getDataSize() << ", "614 << "Received data size = " << field.numElements() << " ] "615 << "The data array does not have the right size! "616 << "Grid = " << this->getId())617 //#endif618 this->storeField_arr(field.dataFirst(), stored);619 }620 CATCH621 622 /* obsolete623 template <int n>624 void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)625 {626 //#ifdef __XIOS_DEBUG627 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 //#endif634 this->maskField_arr(field.dataFirst(), stored);635 }636 */637 template <int n>638 void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)639 {640 auto connector = getModelToWorkflowConnector() ;641 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 654 template <int n>655 void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field)656 TRY657 {658 //#ifdef __XIOS_DEBUG659 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() << " ] "663 << "The ouput array does not have the right size! "664 << "Grid = " << this->getId())665 //#endif666 this->restoreField_arr(stored, field.dataFirst());667 }668 CATCH669 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 data673 \data data received data with masking effect on the server674 \outData data without masking effect675 */676 template <int N>677 void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData)678 TRY679 {680 uncompressField_arr(data.dataFirst(), outData);681 }682 CATCH683 684 template<int N>685 void CGrid::checkGridMask(CArray<bool,N>& gridMask,686 const std::vector<CArray<bool,1>* >& domainMasks,687 const std::vector<CArray<bool,1>* >& axisMasks,688 const CArray<int,1>& axisDomainOrder,689 bool createMask)690 TRY691 {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();697 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)720 {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::endl724 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl725 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl726 << "Grid = " << this->getId())727 }728 }729 else {730 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);731 gridMask = true;732 }733 734 int ssize = gridMask.numElements();735 idx = 0;736 while (idx < ssize)737 {738 for (int i = 0; i < dim-1; ++i)739 {740 if (idxLoop[i] == eachDimSize[i])741 {742 idxLoop[i] = 0;743 ++idxLoop[i+1];744 }745 }746 747 // Find out outer index748 idxDomain = idxAxis = 0;749 bool maskValue = true;750 for (int i = 0; i < numElement; ++i)751 {752 if (2 == axisDomainOrder(i))753 {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 else758 maskValue = false;759 ++idxDomain;760 }761 else if (1 == axisDomainOrder(i))762 {763 int idxTmp = idxLoop[indexMap[i]];764 if (idxTmp < (*axisMasks[idxAxis]).numElements())765 maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp);766 else767 maskValue = false;768 769 ++idxAxis;770 }771 }772 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;781 782 ++idxLoop[0];783 ++idx;784 }785 }786 CATCH_DUMP_ATTR787 788 template<int N>789 void CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,790 const std::vector<int>& eachDimSize,791 bool newValue)792 TRY793 {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::endl800 // << "Mask dimension is " << N << "." << std::endl801 // << "Input dimension is " << eachDimSize.size() << "." << std::endl802 // << "Grid = " << this->getId())803 }804 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);805 gridMask = newValue;806 }807 CATCH_DUMP_ATTR808 809 810 /*!811 Modify the current mask of grid, the local index to be modified will take value false812 \param [in/out] gridMask current mask of grid813 \param [in] indexToModify local index to modify814 */815 template<int N>816 void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify)817 TRY818 {819 int num = indexToModify.numElements();820 for (int idx = 0; idx < num; ++idx)821 {822 *(gridMask.dataFirst()+indexToModify(idx)) = valueToModify;823 }824 }825 CATCH_DUMP_ATTR826 827 ///--------------------------------------------------------------828 829 830 831 407 // Declare/Define CGridGroup and CGridDefinition 832 408 DECLARE_GROUP(CGrid);
Note: See TracChangeset
for help on using the changeset viewer.