Changeset 1460 for XIOS/dev/branch_openmp/src/node/grid.cpp
- Timestamp:
- 03/22/18 10:43:20 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/branch_openmp/src/node/grid.cpp
r1334 r1460 18 18 #include "grid_transformation.hpp" 19 19 #include "grid_generate.hpp" 20 #include "server.hpp" 20 21 21 22 namespace xios { … … 31 32 , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 32 33 , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 33 , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 34 , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 35 , isDataDistributed_(true), isCompressible_(false) 34 36 , transformations_(0), isTransformed_(false) 35 37 , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 36 38 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 39 , computedWrittenIndex_(false) 40 , clients() 37 41 { 38 42 setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); … … 49 53 , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 50 54 , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 51 , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 55 , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 56 , isDataDistributed_(true), isCompressible_(false) 52 57 , transformations_(0), isTransformed_(false) 53 58 , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 54 59 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 60 , computedWrittenIndex_(false) 61 , clients() 55 62 { 56 63 setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group")); … … 87 94 { 88 95 std::vector<int> dataNindex = clientDistribution_->getDataNIndex(); 89 for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i]; 96 for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i]; 90 97 } 91 98 return retvalue; … … 96 103 * 97 104 * \return A map associating the server rank with its minimum buffer size. 105 * TODO: Refactor code 98 106 */ 99 std::map<int, StdSize> CGrid::getAttributesBufferSize( )100 { 101 std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes( );107 std::map<int, StdSize> CGrid::getAttributesBufferSize(CContextClient* client, bool bufferForWriting) 108 { 109 std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client); 102 110 103 111 // The grid indexes require a similar size as the actual data 104 std::map<int, StdSize> dataSizes = getDataBufferSize( );112 std::map<int, StdSize> dataSizes = getDataBufferSize(client, "", bufferForWriting); 105 113 std::map<int, StdSize>::iterator it, itE = dataSizes.end(); 106 114 for (it = dataSizes.begin(); it != itE; ++it) … … 110 118 attributesSizes[it->first] = it->second; 111 119 } 112 120 113 121 // Account for the axis attributes 114 122 std::vector<CAxis*> axisList = getAxis(); 115 123 for (size_t i = 0; i < axisList.size(); ++i) 116 124 { 117 std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize( );125 std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),axisPositionInGrid_[i]); 118 126 for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it) 119 127 { 128 it->second += 2 * sizeof(bool); 120 129 if (it->second > attributesSizes[it->first]) 121 130 attributesSizes[it->first] = it->second; … … 127 136 for (size_t i = 0; i < domList.size(); ++i) 128 137 { 129 std::map<int, StdSize> domAttBuffSize = domList[i]->getAttributesBufferSize( );138 std::map<int, StdSize> domAttBuffSize = domList[i]->getAttributesBufferSize(client); 130 139 for (it = domAttBuffSize.begin(), itE = domAttBuffSize.end(); it != itE; ++it) 131 140 { 141 it->second += 2 * sizeof(bool); 132 142 if (it->second > attributesSizes[it->first]) 133 143 attributesSizes[it->first] = it->second; … … 136 146 137 147 return attributesSizes; 138 148 } 139 149 140 150 /*! 141 * Compute the minimum buffer size required to send the data to the server(s).142 * 151 * Compute the minimum buffer size required to send the data. 152 * \param client contextClient used to determine the size of connected receivers 143 153 * \param id the id used to tag the data 144 * \return A map associating the server rank with its minimum buffer size. 154 * \param bufferForWriting flag indicating if a buffer is used to send data for writing 155 * \return A map associating the sender rank with its minimum buffer size. 145 156 */ 146 std::map<int, StdSize> CGrid::getDataBufferSize(const std::string& id /*= ""*/) 147 { 148 std::map<int, StdSize> dataSizes; 157 std::map<int, StdSize> CGrid::getDataBufferSize(CContextClient* client, const std::string& id /*= ""*/, bool bufferForWriting /*= "false"*/) 158 { 149 159 // The record index is sometimes sent along with the data but we always 150 160 // include it in the size calculation for the sake of simplicity 151 const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size() + 2 * sizeof(size_t); 152 153 std::map<int, size_t>::const_iterator itEnd = connectedDataSize_.end(); 154 for (size_t k = 0; k < connectedServerRank_.size(); ++k) 161 const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size() 162 + 2 * sizeof(size_t) 163 + sizeof(size_t); 164 165 std::map<int, StdSize> dataSizes; 166 int receiverSize = client->serverSize; 167 std::map<int,size_t>& dataSizeMap = bufferForWriting ? connectedDataSize_[receiverSize]: connectedDataSizeRead_; 168 std::vector<int>& connectedServerRanks = bufferForWriting ? connectedServerRank_[receiverSize] : connectedServerRankRead_; 169 170 std::map<int, size_t>::const_iterator itEnd = dataSizeMap.end(); 171 for (size_t k = 0; k < connectedServerRanks.size(); ++k) 155 172 { 156 int rank = connectedServerRank _[k];157 std::map<int, size_t>::const_iterator it = connectedDataSize_.find(rank);173 int rank = connectedServerRanks[k]; 174 std::map<int, size_t>::const_iterator it = dataSizeMap.find(rank); 158 175 size_t count = (it != itEnd) ? it->second : 0; 159 176 … … 164 181 } 165 182 183 size_t CGrid::getGlobalWrittenSize(void) 184 { 185 std::vector<CDomain*> domainP = this->getDomains(); 186 std::vector<CAxis*> axisP = this->getAxis(); 187 188 size_t globalGridSize=1 ; 189 for (std::vector<CDomain*>::iterator it=domainP.begin(); it!=domainP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ; 190 for (std::vector<CAxis*>::iterator it=axisP.begin(); it!=axisP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ; 191 return globalGridSize ; 192 } 193 194 166 195 void CGrid::checkAttributesAfterTransformation() 167 196 { … … 225 254 226 255 //--------------------------------------------------------------- 227 256 /* 257 Find all reference of grid's components and inherite attributes if necessary 258 */ 228 259 void CGrid::solveDomainAxisRef(bool areAttributesChecked) 229 260 { … … 236 267 } 237 268 269 /* 270 Go up hierachy reference and fill in the base reference with attributes of the children 271 This function should be only used after reading component's attributes from file 272 */ 238 273 void CGrid::solveDomainAxisBaseRef() 239 274 { … … 272 307 { 273 308 CContext* context = CContext::getCurrent(); 274 CContextClient* client=context->client; 275 276 if (isScalarGrid()) 277 { 278 if (context->hasClient) 279 if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; } 280 281 if (this->isChecked) return; 282 283 if (context->hasClient) 284 { 285 this->computeIndexScalarGrid(); 309 int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 310 nbSrvPools = 1; 311 for (int p = 0; p < nbSrvPools; ++p) 312 { 313 if (context->hasClient && this->isChecked && doSendingIndex && !isIndexSent) 314 { 315 if (isScalarGrid()) 316 sendIndexScalarGrid(); 317 else 318 sendIndex(); 319 this->isIndexSent = true; 286 320 } 287 321 288 if (!(this->hasTransform() && !this->isTransformed())) 289 this->isChecked = true; 290 return; 322 // Not sure about this 323 //if (!(this->hasTransform() && !this->isTransformed())) 324 // this->isChecked = true; 325 //return; 291 326 } 292 293 if (context->hasClient) 294 if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; } 295 327 296 328 if (this->isChecked) return; 297 298 if (context->hasClient) 299 { 300 this->checkAttributesAfterTransformation(); 301 this->checkMask(); 302 this->computeIndex(); 303 } 304 305 if (!(this->hasTransform() && !this->isTransformed())) 329 this->checkAttributesAfterTransformation(); 330 331 // TODO: Transfer grid attributes 332 //if (!context->hasClient && context->hasServer) this->createMask(); 333 this->computeIndex(); 334 335 if (!(this->hasTransform() && !this->isTransformed())) 306 336 this->isChecked = true; 307 337 308 338 if (!(this->hasTransform() && (!this->isGenerated()))) 309 this->isChecked = true; 310 } 311 339 this->isChecked = true; 340 } 341 342 /* 343 Create mask of grid from mask of its components 344 */ 312 345 void CGrid::createMask(void) 313 346 { … … 318 351 319 352 std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 320 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]-> mask_1d);353 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 321 354 std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 322 355 for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); … … 349 382 } 350 383 384 /* 385 Check validity of grid's mask by using the masks of its components 386 */ 351 387 void CGrid::checkMask(void) 352 388 { … … 357 393 358 394 std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 359 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]-> mask_1d);395 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 360 396 std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 361 397 for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); … … 388 424 } 389 425 390 void CGrid::modifyMask(const CArray<int,1>& indexToModify) 426 427 /*! 428 A grid can have multiple dimension, so can its mask in the form of multi-dimension array. 429 It's not a good idea to store all multi-dimension arrays corresponding to each mask. 430 One of the ways is to convert this array into 1-dimension one and every process is taken place on it. 431 \param [in] multi-dimension array grid mask 432 */ 433 434 void CGrid::getLocalMask(CArray<bool,1>& localMask) 435 { 436 std::vector<CDomain*> domainP = this->getDomains(); 437 std::vector<CAxis*> axisP = this->getAxis(); 438 int dim = domainP.size() * 2 + axisP.size(); 439 440 switch (dim) 441 { 442 case 0: 443 getLocalMask(mask_0d, localMask); 444 break; 445 case 1: 446 getLocalMask(mask_1d, localMask); 447 break; 448 case 2: 449 getLocalMask(mask_2d, localMask); 450 break; 451 case 3: 452 getLocalMask(mask_3d, localMask); 453 break; 454 case 4: 455 getLocalMask(mask_4d, localMask); 456 break; 457 case 5: 458 getLocalMask(mask_5d, localMask); 459 break; 460 case 6: 461 getLocalMask(mask_6d, localMask); 462 break; 463 case 7: 464 getLocalMask(mask_7d, localMask); 465 break; 466 default: 467 break; 468 } 469 } 470 471 /* 472 Modify value of mask in a certain index 473 This function can be used to correct the mask of grid after being constructed with createMask 474 \param [in] indexToModify 475 \param [in] modifyValue 476 */ 477 void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue) 391 478 { 392 479 using namespace std; … … 396 483 397 484 switch (dim) { 485 case 0: 486 modifyGridMask(mask_0d, indexToModify, modifyValue); 487 break; 398 488 case 1: 399 modifyGridMask(mask_1d, indexToModify );489 modifyGridMask(mask_1d, indexToModify, modifyValue); 400 490 break; 401 491 case 2: 402 modifyGridMask(mask_2d, indexToModify );492 modifyGridMask(mask_2d, indexToModify, modifyValue); 403 493 break; 404 494 case 3: 405 modifyGridMask(mask_3d, indexToModify );495 modifyGridMask(mask_3d, indexToModify, modifyValue); 406 496 break; 407 497 case 4: 408 modifyGridMask(mask_ 1d, indexToModify);498 modifyGridMask(mask_4d, indexToModify, modifyValue); 409 499 break; 410 500 case 5: 411 modifyGridMask(mask_ 2d, indexToModify);501 modifyGridMask(mask_5d, indexToModify, modifyValue); 412 502 break; 413 503 case 6: 414 modifyGridMask(mask_ 3d, indexToModify);504 modifyGridMask(mask_6d, indexToModify, modifyValue); 415 505 break; 416 506 case 7: 417 modifyGridMask(mask_3d, indexToModify); 507 modifyGridMask(mask_7d, indexToModify, modifyValue); 508 break; 509 default: 510 break; 511 } 512 } 513 514 /* 515 Change the mask size. This function is used on reconstructing mask in server side 516 \param [in] newDimensionSize 517 \param [in] newValue 518 */ 519 void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue) 520 { 521 std::vector<CDomain*> domainP = this->getDomains(); 522 std::vector<CAxis*> axisP = this->getAxis(); 523 int dim = domainP.size() * 2 + axisP.size(); 524 525 switch (dim) { 526 case 0: 527 modifyGridMaskSize(mask_0d, newDimensionSize, newValue); 528 break; 529 case 1: 530 modifyGridMaskSize(mask_1d, newDimensionSize, newValue); 531 break; 532 case 2: 533 modifyGridMaskSize(mask_2d, newDimensionSize, newValue); 534 break; 535 case 3: 536 modifyGridMaskSize(mask_3d, newDimensionSize, newValue); 537 break; 538 case 4: 539 modifyGridMaskSize(mask_4d, newDimensionSize, newValue); 540 break; 541 case 5: 542 modifyGridMaskSize(mask_5d, newDimensionSize, newValue); 543 break; 544 case 6: 545 modifyGridMaskSize(mask_6d, newDimensionSize, newValue); 546 break; 547 case 7: 548 modifyGridMaskSize(mask_7d, newDimensionSize, newValue); 418 549 break; 419 550 default: … … 486 617 } 487 618 488 std::vector<int> CGrid::getAxisPositionInGrid() const 489 { 490 return axisPositionInGrid_; 619 /*! 620 Compute the index to for write data into a file 621 */ 622 void CGrid::computeWrittenIndex() 623 { 624 if (computedWrittenIndex_) return; 625 computedWrittenIndex_ = true; 626 627 if (isScalarGrid()) 628 { 629 size_t nbWritten = 1; 630 int writtenIndex = 0; 631 632 localIndexToWriteOnClient.resize(nbWritten); 633 localIndexToWriteOnServer.resize(nbWritten); 634 localIndexToWriteOnServer(0) = writtenIndex; 635 localIndexToWriteOnClient(0) = writtenIndex; 636 637 return; 638 } 639 640 size_t nbWritten = 0, indGlo; 641 CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 642 CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(), 643 ite = globalDataIndex.end(), it; 644 const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex(); 645 CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(), 646 itSrve = globalLocalIndex.end(), itSrv; 647 for (it = itb; it != ite; ++it) 648 { 649 indGlo = it->first; 650 if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten; 651 } 652 653 localIndexToWriteOnClient.resize(nbWritten); 654 localIndexToWriteOnServer.resize(nbWritten); 655 656 { 657 numberWrittenIndexes_ = nbWritten; 658 if (isDataDistributed_) 659 { 660 CContextServer* server = CContext::getCurrent()->server; 661 MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 662 MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 663 offsetWrittenIndexes_ -= numberWrittenIndexes_; 664 } 665 else 666 totalNumberWrittenIndexes_ = numberWrittenIndexes_; 667 } 668 669 nbWritten = 0; 670 for (it = itb; it != ite; ++it) 671 { 672 indGlo = it->first; 673 itSrv = globalLocalIndex.find(indGlo); 674 if (itSrve != itSrv) 675 { 676 localIndexToWriteOnServer(nbWritten) = itSrv->second; 677 localIndexToWriteOnClient(nbWritten) = it->second; 678 ++nbWritten; 679 } 680 } 491 681 } 492 682 493 683 //--------------------------------------------------------------- 684 685 /* 686 Compute the global index and its local index taking account mask and data index. 687 These global indexes will be used to compute the connection of this client (sender) to its servers (receivers) 688 (via function computeConnectedClient) 689 These global indexes also correspond to data sent to servers (if any) 690 */ 691 void CGrid::computeClientIndex() 692 { 693 CContext* context = CContext::getCurrent(); 694 695 CContextClient* client = context->client; // Here it's not important which contextClient to recuperate 696 int rank = client->clientRank; 697 698 clientDistribution_ = new CDistributionClient(rank, this); 699 // Get local data index on client 700 storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 701 int nbStoreIndex = storeIndex_client.numElements(); 702 for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 703 704 if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 705 else 706 { 707 // Mapping global index received from clients to the storeIndex_client 708 CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 709 CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 710 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 711 ite = outGlobalIndexFromClient.end(), it; 712 713 for (it = itb; it != ite; ++it) 714 { 715 int rank = it->first; 716 CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 717 outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 718 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 719 size_t nbIndex = 0; 720 721 // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 722 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 723 { 724 if (itGloe != globalDataIndex.find(globalIndex(idx))) 725 { 726 ++nbIndex; 727 } 728 } 729 730 if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 731 ERROR("void CGrid::computeClientIndex()", 732 << "Number of local index on client is different from number of received global index" 733 << "Rank of sent client " << rank <<"." 734 << "Number of local index " << nbIndex << ". " 735 << "Number of received global index " << localIndex.numElements() << "."); 736 737 nbIndex = 0; 738 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 739 { 740 if (itGloe != globalDataIndex.find(globalIndex(idx))) 741 { 742 localIndex(idx) = globalDataIndex[globalIndex(idx)]; 743 } 744 } 745 } 746 } 747 } 748 749 /*! 750 Compute connected receivers and indexes to be sent to these receivers. 751 */ 752 void CGrid::computeConnectedClients() 753 { 754 CContext* context = CContext::getCurrent(); 755 int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size(); 756 connectedServerRank_.clear(); 757 connectedDataSize_.clear(); 758 globalIndexOnServer_.clear(); 759 nbSenders.clear(); 760 761 for (int p = 0; p < nbSrvPools; ++p) 762 { 763 CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p]; 764 int receiverSize = client->serverSize; 765 // connectedServerRank_[client].clear(); 766 767 if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end()) 768 { 769 if (!doGridHaveDataDistributed(client)) 770 { 771 if (client->isServerLeader()) 772 { 773 size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 774 const std::list<int>& ranks = client->getRanksServerLeader(); 775 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 776 { 777 connectedServerRank_[receiverSize].push_back(*itRank); 778 connectedDataSize_[receiverSize][*itRank] = ssize; 779 } 780 } 781 return; 782 } 783 784 // Compute mapping between client and server 785 std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 786 CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 787 std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 788 client->clientRank, 789 client->clientSize, 790 axis_domain_order, 791 getDistributedDimension()); 792 793 // Even if servers have no index, they must received something from client 794 // We only use several client to send "empty" message to these servers 795 std::list<int> serverZeroIndexLeader; 796 std::list<int> serverZeroIndexNotLeader; 797 CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 798 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 799 *it = serverZeroIndex[*it]; 800 801 if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 802 computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 803 804 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 805 CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 806 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 807 itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 808 iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 809 810 for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 811 { 812 int serverRank = itGlobalMap->first; 813 int indexSize = itGlobalMap->second.size(); 814 const std::vector<size_t>& indexVec = itGlobalMap->second; 815 for (int idx = 0; idx < indexSize; ++idx) 816 { 817 itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 818 if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 819 { 820 if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 821 connectedDataSize_[receiverSize][serverRank] = 1; 822 else 823 ++connectedDataSize_[receiverSize][serverRank]; 824 } 825 } 826 } 827 828 // Connected servers which really have index 829 for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 830 connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 831 } 832 833 // Connected servers which have no index at all 834 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 835 connectedServerRank_[receiverSize].push_back(*it); 836 837 // Even if a client has no index, it must connect to at least one server and 838 // send an "empty" data to this server 839 if (connectedServerRank_[receiverSize].empty()) 840 connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 841 842 nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 843 } 844 } 845 } 494 846 495 847 /*! … … 503 855 { 504 856 CContext* context = CContext::getCurrent(); 505 CContextClient* client = context->client; 506 507 // First of all, compute distribution on client side 508 clientDistribution_ = new CDistributionClient(client->clientRank, this); 509 // Get local data index on client 510 storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 511 int nbStoreIndex = storeIndex_client.numElements(); 512 for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 513 isDataDistributed_= clientDistribution_->isDataDistributed(); 514 515 connectedServerRank_.clear(); 516 517 if (!doGridHaveDataDistributed()) 857 if (isScalarGrid()) 518 858 { 519 if (client->isServerLeader()) 520 { 521 size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 522 const std::list<int>& ranks = client->getRanksServerLeader(); 523 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 524 { 525 connectedServerRank_.push_back(*itRank); 526 connectedDataSize_[*itRank] = ssize; 527 } 528 } 529 return; 530 } 531 532 // Compute mapping between client and server 533 std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 534 CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 535 serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 536 client->clientRank, 537 client->clientSize, 538 axis_domain_order, 539 getDistributedDimension()); 540 computeIndexByElement(indexServerOnElement, globalIndexOnServer_); 541 542 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 543 CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 544 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 545 itGlobalMap = itbGlobalMap = globalIndexOnServer_.begin(); 546 iteGlobalMap = globalIndexOnServer_.end(); 547 548 for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 549 { 550 int serverRank = itGlobalMap->first; 551 int indexSize = itGlobalMap->second.size(); 552 const std::vector<size_t>& indexVec = itGlobalMap->second; 553 for (int idx = 0; idx < indexSize; ++idx) 859 computeClientIndexScalarGrid(); 860 if (context->hasClient) 554 861 { 555 itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 556 if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 557 { 558 if (connectedDataSize_.end() == connectedDataSize_.find(serverRank)) 559 connectedDataSize_[serverRank] = 1; 560 else 561 ++connectedDataSize_[serverRank]; 562 } 862 computeConnectedClientsScalarGrid(); 563 863 } 564 864 } 565 566 for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 567 connectedServerRank_.push_back(itGlobalMap->first); 865 else 866 { 867 computeClientIndex(); 868 if (context->hasClient) 869 { 870 computeConnectedClients(); 871 } 568 872 } 569 570 nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_); 873 if (CServer::serverLevel==2) 874 { 875 computeWrittenIndex() ; 876 if (serverDistribution_!=0) serverDistribution_->partialClear() ; 877 if (clientDistribution_!=0) clientDistribution_->partialClear() ; 878 outGlobalIndexFromClient.clear() ; 879 } 571 880 } 572 881 … … 577 886 on each element whose size is much smaller than one of whole grid. 578 887 \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 888 \param [in] client contextClient 579 889 \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 580 890 */ 581 891 void CGrid::computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 892 const CContextClient* client, 582 893 CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 583 894 { 584 CContext* context = CContext::getCurrent();585 CContextClient* client = context->client;586 895 int serverSize = client->serverSize; 896 587 897 std::vector<CDomain*> domList = getDomains(); 588 898 std::vector<CAxis*> axisList = getAxis(); … … 667 977 } 668 978 669 nbIndexOnServer = 0; 670 for (it = itb; it != ite; ++it) 979 nbIndexOnServer = 0; 980 for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 981 { 982 it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 983 if (it != ite) 671 984 { 672 985 const std::vector<int>& tmp = it->second; … … 683 996 } 684 997 } 998 } 685 999 686 1000 // Determine server which contain global source index … … 931 1245 } 932 1246 1247 /* 933 1248 void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field) 934 1249 { … … 960 1275 } 961 1276 } 962 1277 */ 963 1278 //---------------------------------------------------------------- 964 1279 … … 978 1293 } 979 1294 980 void CGrid::computeIndexScalarGrid() 1295 void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 1296 { 1297 const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient(); 1298 const int size = localMaskedDataIndex.size(); 1299 1300 for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i]; 1301 } 1302 1303 1304 void CGrid::computeClientIndexScalarGrid() 1305 { 1306 CContext* context = CContext::getCurrent(); 1307 // int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; // This should be changed soon 1308 // for (int p = 0; p < nbSrvPools; ++p) 1309 { 1310 // CContextClient* client = (context->hasServer) ? (context->hasClient ? context->clientPrimServer[p] : context->client) 1311 // : context->client; 1312 CContextClient* client = context->client; 1313 1314 int rank = client->clientRank; 1315 1316 clientDistribution_ = new CDistributionClient(rank, this); 1317 1318 storeIndex_client.resize(1); 1319 storeIndex_client(0) = 0; 1320 1321 if (0 != serverDistribution_) 1322 { 1323 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 1324 ite = outGlobalIndexFromClient.end(), it; 1325 for (it = itb; it != ite; ++it) 1326 { 1327 int rank = it->first; 1328 CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 1329 outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 1330 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 1331 if (1 != globalIndex.numElements()) 1332 ERROR("void CGrid::computeClientIndexScalarGrid()", 1333 << "Something wrong happened. " 1334 << "Number of received global index on scalar grid should equal to 1" 1335 << "Number of received global index " << globalIndex.numElements() << "."); 1336 1337 localIndex(0) = globalIndex(0); 1338 } 1339 } 1340 } 1341 } 1342 1343 void CGrid::computeConnectedClientsScalarGrid() 1344 { 1345 CContext* context = CContext::getCurrent(); 1346 int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size(); 1347 connectedServerRank_.clear(); 1348 connectedDataSize_.clear(); 1349 nbSenders.clear(); 1350 1351 for (int p = 0; p < nbSrvPools; ++p) 1352 { 1353 CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p]; 1354 int receiverSize = client->serverSize; 1355 1356 // connectedServerRank_[client].clear(); 1357 1358 if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end()) 1359 { 1360 if (client->isServerLeader()) 1361 { 1362 const std::list<int>& ranks = client->getRanksServerLeader(); 1363 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1364 { 1365 int rank = *itRank; 1366 int nb = 1; 1367 connectedServerRank_[receiverSize].push_back(rank); 1368 connectedDataSize_[receiverSize][rank] = nb; 1369 nbSenders[receiverSize][rank] = nb; 1370 } 1371 } 1372 else 1373 { 1374 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1375 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1376 { 1377 int rank = *itRank; 1378 int nb = 1; 1379 connectedServerRank_[receiverSize].push_back(rank); 1380 connectedDataSize_[receiverSize][rank] = nb; 1381 nbSenders[receiverSize][rank] = nb; 1382 } 1383 } 1384 } 1385 isDataDistributed_ = false; 1386 } 1387 } 1388 1389 void CGrid::sendIndexScalarGrid() 981 1390 { 982 1391 CContext* context = CContext::getCurrent(); 983 CContextClient* client=context->client; 984 985 storeIndex_client.resize(1); 986 storeIndex_client(0) = 0; 987 988 connectedServerRank_.clear(); 989 990 if (0 == client->clientRank) 991 { 992 for (int rank = 0; rank < client->serverSize; ++rank) 993 { 994 connectedServerRank_.push_back(rank); 995 connectedDataSize_[rank] = 1; 996 nbSenders[rank] = 1; 997 } 998 } 999 isDataDistributed_ = false; 1000 } 1001 1002 void CGrid::computeCompressedIndex() 1003 { 1004 std::map<size_t, size_t> indexes; 1005 1006 { 1007 std::map<int, CArray<size_t,1> >::const_iterator it = outIndexFromClient.begin(); 1008 std::map<int, CArray<size_t,1> >::const_iterator itEnd = outIndexFromClient.end(); 1009 for (; it != itEnd; ++it) 1010 { 1011 for (int i = 0; i < it->second.numElements(); ++i) 1012 indexes.insert(std::make_pair(it->second(i), 0)); 1013 1014 compressedOutIndexFromClient[it->first].resize(it->second.numElements()); 1015 } 1016 } 1017 1018 { 1019 std::map<size_t, size_t>::iterator it = indexes.begin(); 1020 std::map<size_t, size_t>::iterator itEnd = indexes.end(); 1021 for (size_t i = 0; it != itEnd; ++it, ++i) 1022 it->second = i; 1023 } 1024 1025 { 1026 std::map<int, CArray<size_t,1> >::iterator it = compressedOutIndexFromClient.begin(); 1027 std::map<int, CArray<size_t,1> >::iterator itEnd = compressedOutIndexFromClient.end(); 1028 for (; it != itEnd; ++it) 1029 { 1030 const CArray<size_t,1>& outIndex = outIndexFromClient[it->first]; 1031 for (int i = 0; i < it->second.numElements(); ++i) 1032 it->second(i) = indexes[outIndex(i)]; 1033 } 1034 } 1035 } 1036 1037 void CGrid::sendIndexScalarGrid() 1038 { 1039 CContext* context = CContext::getCurrent(); 1040 CContextClient* client = context->client; 1041 1042 CEventClient event(getType(), EVENT_ID_INDEX); 1043 list<CMessage> listMsg; 1044 list<CArray<size_t,1> > listOutIndex; 1045 1046 if (client->isServerLeader()) 1047 { 1048 const std::list<int>& ranks = client->getRanksServerLeader(); 1049 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1050 { 1051 int rank = *itRank; 1052 int nb = 1; 1053 storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb))); 1054 listOutIndex.push_back(CArray<size_t,1>(nb)); 1055 1056 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank]; 1057 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 1058 1059 for (int k = 0; k < nb; ++k) 1060 { 1061 outGlobalIndexOnServer(k) = 0; 1062 outLocalIndexToServer(k) = 0; 1063 } 1064 1065 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 1066 listMsg.push_back(CMessage()); 1067 listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 1068 1069 event.push(rank, 1, listMsg.back()); 1070 } 1071 client->sendEvent(event); 1072 } 1073 else 1074 { 1075 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1076 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1077 { 1078 int rank = *itRank; 1079 int nb = 1; 1080 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(nb))); 1081 CArray<int, 1>& outLocalIndexToServer = storeIndex_fromSrv[rank]; 1082 for (int k = 0; k < nb; ++k) 1083 { 1084 outLocalIndexToServer(k) = 0; 1085 } 1086 } 1087 client->sendEvent(event); 1088 } 1089 } 1090 1091 void CGrid::sendIndex(void) 1092 { 1093 CContext* context = CContext::getCurrent(); 1094 CContextClient* client = context->client; 1095 1096 CEventClient event(getType(), EVENT_ID_INDEX); 1097 int rank; 1098 list<CMessage> listMsg; 1099 list<CArray<size_t,1> > listOutIndex; 1100 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 1101 CDistributionClient::GlobalLocalDataMap::const_iterator itIndex = globalLocalIndexSendToServer.begin(), 1102 iteIndex = globalLocalIndexSendToServer.end(); 1103 1104 if (!doGridHaveDataDistributed()) 1105 { 1392 storeIndex_toSrv.clear(); 1393 std::list<CContextClient*>::iterator it; 1394 1395 for (it=clients.begin(); it!=clients.end(); ++it) 1396 { 1397 CContextClient* client = *it; 1398 int receiverSize = client->serverSize; 1399 1400 CEventClient event(getType(), EVENT_ID_INDEX); 1401 list<CMessage> listMsg; 1402 list<CArray<size_t,1> > listOutIndex; 1403 1106 1404 if (client->isServerLeader()) 1107 1405 { 1108 int indexSize = globalLocalIndexSendToServer.size();1109 CArray<size_t,1> outGlobalIndexOnServer(indexSize);1110 CArray<int,1> outLocalIndexToServer(indexSize);1111 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)1112 {1113 outGlobalIndexOnServer(idx) = itIndex->first;1114 outLocalIndexToServer(idx) = itIndex->second;1115 }1116 1117 1406 const std::list<int>& ranks = client->getRanksServerLeader(); 1118 1407 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1119 1408 { 1120 storeIndex_toSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1121 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1122 listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 1123 1409 int rank = *itRank; 1410 int nb = 1; 1411 storeIndex_toSrv[client].insert(std::make_pair(rank, CArray<int,1>(nb))); 1412 listOutIndex.push_back(CArray<size_t,1>(nb)); 1413 1414 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 1415 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 1416 1417 for (int k = 0; k < nb; ++k) 1418 { 1419 outGlobalIndexOnServer(k) = 0; 1420 outLocalIndexToServer(k) = 0; 1421 } 1422 1423 if (context->hasClient && !context->hasServer) 1424 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 1425 1426 listMsg.push_back(CMessage()); 1427 listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 1428 1429 event.push(rank, 1, listMsg.back()); 1430 } 1431 client->sendEvent(event); 1432 } 1433 else 1434 { 1435 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1436 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1437 { 1438 int rank = *itRank; 1439 int nb = 1; 1440 CArray<int, 1> outLocalIndexToServer(nb); 1441 for (int k = 0; k < nb; ++k) 1442 { 1443 outLocalIndexToServer(k) = 0; 1444 } 1445 1446 if (context->hasClient && !context->hasServer) 1447 storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 1448 } 1449 client->sendEvent(event); 1450 } 1451 } 1452 } 1453 1454 void CGrid::sendIndex(void) 1455 { 1456 CContext* context = CContext::getCurrent(); 1457 storeIndex_toSrv.clear(); 1458 std::list<CContextClient*>::iterator it; 1459 1460 for (it=clients.begin(); it!=clients.end(); ++it) 1461 { 1462 CContextClient* client = *it; 1463 int receiverSize = client->serverSize; 1464 1465 CEventClient event(getType(), EVENT_ID_INDEX); 1466 int rank; 1467 list<CMessage> listMsg; 1468 list<CArray<size_t,1> > listOutIndex; 1469 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 1470 CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex, 1471 iteIndex = globalLocalIndexSendToServer.end(); 1472 itIndex = itbIndex; 1473 1474 if (!doGridHaveDataDistributed(client)) 1475 { 1476 if (client->isServerLeader()) 1477 { 1478 int indexSize = globalLocalIndexSendToServer.size(); 1479 CArray<size_t,1> outGlobalIndexOnServer(indexSize); 1480 CArray<int,1> outLocalIndexToServer(indexSize); 1481 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 1482 { 1483 outGlobalIndexOnServer(idx) = itIndex->first; 1484 outLocalIndexToServer(idx) = itIndex->second; 1485 } 1486 1487 const std::list<int>& ranks = client->getRanksServerLeader(); 1488 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1489 { 1490 storeIndex_toSrv[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1491 if (context->hasClient && !context->hasServer) 1492 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1493 1494 listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 1495 1496 listMsg.push_back(CMessage()); 1497 listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 1498 1499 event.push(*itRank, 1, listMsg.back()); 1500 } 1501 client->sendEvent(event); 1502 } 1503 else 1504 { 1505 int indexSize = globalLocalIndexSendToServer.size(); 1506 CArray<int,1> outLocalIndexToServer(indexSize); 1507 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 1508 { 1509 outLocalIndexToServer(idx) = itIndex->second; 1510 } 1511 1512 const std::list<int>& ranks = client->getRanksServerNotLeader(); 1513 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1514 { 1515 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 1516 } 1517 client->sendEvent(event); 1518 } 1519 } 1520 else 1521 { 1522 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 1523 itGlobalMap = globalIndexOnServer_[receiverSize].begin(); 1524 iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 1525 1526 std::map<int,std::vector<int> >localIndexTmp; 1527 std::map<int,std::vector<size_t> > globalIndexTmp; 1528 for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 1529 { 1530 int serverRank = itGlobalMap->first; 1531 int indexSize = itGlobalMap->second.size(); 1532 const std::vector<size_t>& indexVec = itGlobalMap->second; 1533 for (int idx = 0; idx < indexSize; ++idx) 1534 { 1535 itIndex = globalLocalIndexSendToServer.find(indexVec[idx]); 1536 if (iteIndex != itIndex) 1537 { 1538 globalIndexTmp[serverRank].push_back(itIndex->first); 1539 localIndexTmp[serverRank].push_back(itIndex->second); 1540 } 1541 } 1542 } 1543 1544 for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns) 1545 { 1546 rank = connectedServerRank_[receiverSize][ns]; 1547 int nb = 0; 1548 if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 1549 nb = globalIndexTmp[rank].size(); 1550 1551 storeIndex_toSrv[client].insert(make_pair(rank, CArray<int,1>(nb))); 1552 listOutIndex.push_back(CArray<size_t,1>(nb)); 1553 1554 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 1555 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 1556 1557 for (int k = 0; k < nb; ++k) 1558 { 1559 outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k); 1560 outLocalIndexToServer(k) = localIndexTmp[rank].at(k); 1561 } 1562 1563 storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 1124 1564 listMsg.push_back(CMessage()); 1125 1565 listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 1126 1566 1127 event.push(*itRank, 1, listMsg.back()); 1128 } 1567 event.push(rank, nbSenders[receiverSize][rank], listMsg.back()); 1568 } 1569 1129 1570 client->sendEvent(event); 1130 1571 } 1131 else1132 {1133 int indexSize = globalLocalIndexSendToServer.size();1134 CArray<int,1> outLocalIndexToServer(indexSize);1135 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)1136 {1137 outLocalIndexToServer(idx) = itIndex->second;1138 }1139 1140 const std::list<int>& ranks = client->getRanksServerNotLeader();1141 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)1142 {1143 storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));1144 }1145 client->sendEvent(event);1146 }1147 }1148 else1149 {1150 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;1151 itGlobalMap = globalIndexOnServer_.begin();1152 iteGlobalMap = globalIndexOnServer_.end();1153 1154 std::map<int,std::vector<int> >localIndexTmp;1155 std::map<int,std::vector<size_t> > globalIndexTmp;1156 for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)1157 {1158 int serverRank = itGlobalMap->first;1159 int indexSize = itGlobalMap->second.size();1160 const std::vector<size_t>& indexVec = itGlobalMap->second;1161 for (int idx = 0; idx < indexSize; ++idx)1162 {1163 itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);1164 if (iteIndex != itIndex)1165 {1166 globalIndexTmp[serverRank].push_back(itIndex->first);1167 localIndexTmp[serverRank].push_back(itIndex->second);1168 }1169 }1170 }1171 1172 for (int ns = 0; ns < connectedServerRank_.size(); ++ns)1173 {1174 rank = connectedServerRank_[ns];1175 int nb = 0;1176 if (globalIndexTmp.end() != globalIndexTmp.find(rank))1177 nb = globalIndexTmp[rank].size();1178 1179 storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));1180 listOutIndex.push_back(CArray<size_t,1>(nb));1181 1182 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];1183 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();1184 1185 for (int k = 0; k < nb; ++k)1186 {1187 outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);1188 outLocalIndexToServer(k) = localIndexTmp[rank].at(k);1189 }1190 1191 storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer)));1192 listMsg.push_back(CMessage());1193 listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();1194 1195 event.push(rank, nbSenders[rank], listMsg.back());1196 }1197 1198 client->sendEvent(event);1199 1572 } 1200 1573 } … … 1220 1593 { 1221 1594 CContext* context = CContext::getCurrent(); 1222 CContextServer* server = context->server; 1223 numberWrittenIndexes_ = totalNumberWrittenIndexes_ = offsetWrittenIndexes_ = 0; 1224 connectedServerRank_ = ranks; 1225 1226 for (int n = 0; n < ranks.size(); n++) 1227 { 1228 int rank = ranks[n]; 1229 CBufferIn& buffer = *buffers[n]; 1230 1231 buffer >> isDataDistributed_ >> isCompressible_; 1232 size_t dataSize = 0; 1233 1234 if (0 == serverDistribution_) 1235 { 1236 int idx = 0, numElement = axis_domain_order.numElements(); 1237 int ssize = numElement; 1238 std::vector<int> indexMap(numElement); 1239 for (int i = 0; i < numElement; ++i) 1240 { 1241 indexMap[i] = idx; 1242 if (2 == axis_domain_order(i)) 1595 connectedServerRankRead_ = ranks; 1596 1597 int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 1598 nbSrvPools = 1; 1599 nbReadSenders.clear(); 1600 for (int p = 0; p < nbSrvPools; ++p) 1601 { 1602 CContextServer* server = (!context->hasClient) ? context->server : context->serverPrimServer[p]; 1603 CContextClient* client = context->client; //(!context->hasClient) ? context->client : context->clientPrimServer[p]; 1604 1605 int idx = 0, numElement = axis_domain_order.numElements(); 1606 int ssize = numElement; 1607 std::vector<int> indexMap(numElement); 1608 for (int i = 0; i < numElement; ++i) 1609 { 1610 indexMap[i] = idx; 1611 if (2 == axis_domain_order(i)) 1612 { 1613 ++ssize; 1614 idx += 2; 1615 } 1616 else 1617 ++idx; 1618 } 1619 1620 for (int n = 0; n < ranks.size(); n++) 1621 { 1622 int rank = ranks[n]; 1623 CBufferIn& buffer = *buffers[n]; 1624 1625 buffer >> isDataDistributed_ >> isCompressible_; 1626 size_t dataSize = 0; 1627 1628 if (0 == serverDistribution_) 1629 { 1630 int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 1631 std::vector<CDomain*> domainList = getDomains(); 1632 std::vector<CAxis*> axisList = getAxis(); 1633 std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize), nGlobElement(numElement); 1634 std::vector<CArray<int,1> > globalZoomIndex(numElement); 1635 for (int i = 0; i < numElement; ++i) 1243 1636 { 1244 ++ssize; 1245 idx += 2; 1637 nGlobElement[i] = globalSize; 1638 if (2 == axis_domain_order(i)) //domain 1639 { 1640 nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin; 1641 nZoomSize[indexMap[i]] = domainList[domainId]->zoom_ni; 1642 nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin; 1643 nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 1644 1645 nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin; 1646 nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj; 1647 nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin; 1648 nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 1649 1650 { 1651 int count = 0; 1652 globalZoomIndex[i].resize(nZoomSize[indexMap[i]]*nZoomSize[indexMap[i]+1]); 1653 for (int jdx = 0; jdx < nZoomSize[indexMap[i]+1]; ++jdx) 1654 for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx) 1655 { 1656 globalZoomIndex[i](count) = (nZoomBegin[indexMap[i]] + idx) + (nZoomBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 1657 ++count; 1658 } 1659 } 1660 1661 ++domainId; 1662 } 1663 else if (1 == axis_domain_order(i)) // axis 1664 { 1665 nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin; 1666 nZoomSize[indexMap[i]] = axisList[axisId]->zoom_n; 1667 nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin; 1668 nGlob[indexMap[i]] = axisList[axisId]->n_glo; 1669 if (axisList[axisId]->zoomByIndex()) 1670 { 1671 globalZoomIndex[i].reference(axisList[axisId]->zoom_index); 1672 } 1673 else 1674 { 1675 globalZoomIndex[i].resize(nZoomSize[indexMap[i]]); 1676 for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx) 1677 globalZoomIndex[i](idx) = nZoomBegin[indexMap[i]] + idx; 1678 } 1679 1680 ++axisId; 1681 } 1682 else // scalar 1683 { 1684 nZoomBegin[indexMap[i]] = 0; 1685 nZoomSize[indexMap[i]] = 1; 1686 nZoomBeginGlobal[indexMap[i]] = 0; 1687 nGlob[indexMap[i]] = 1; 1688 globalZoomIndex[i].resize(1); 1689 globalZoomIndex[i](0) = 0; 1690 ++scalarId; 1691 } 1246 1692 } 1247 else 1248 ++idx; 1249 } 1250 1251 int axisId = 0, domainId = 0, scalarId = 0; 1693 dataSize = 1; 1694 1695 for (int i = 0; i < nZoomSize.size(); ++i) 1696 dataSize *= nZoomSize[i]; 1697 serverDistribution_ = new CDistributionServer(server->intraCommRank, 1698 globalZoomIndex, axis_domain_order, 1699 nZoomBegin, nZoomSize, nZoomBeginGlobal, nGlob); 1700 } 1701 1702 CArray<size_t,1> outIndex; 1703 buffer >> outIndex; 1704 outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex)); 1705 connectedDataSizeRead_[rank] = outIndex.numElements(); 1706 1707 if (doGridHaveDataDistributed(client)) 1708 {} 1709 else 1710 { 1711 // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER 1712 // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar) 1713 dataSize = serverDistribution_->getGridSize(); 1714 } 1715 writtenDataSize_ += dataSize; 1716 } 1717 1718 1719 // Compute mask of the current grid 1720 { 1721 int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 1252 1722 std::vector<CDomain*> domainList = getDomains(); 1253 1723 std::vector<CAxis*> axisList = getAxis(); 1254 std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);1255 std::vector< CArray<int,1> > globalZoomIndex(numElement);1724 int dimSize = 2 * domainList.size() + axisList.size(); 1725 std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize); 1256 1726 for (int i = 0; i < numElement; ++i) 1257 { 1727 { 1258 1728 if (2 == axis_domain_order(i)) //domain 1259 1729 { 1260 n ZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin_srv;1261 n ZoomSize[indexMap[i]] = domainList[domainId]->zoom_ni_srv;1262 n ZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;1730 nBegin[indexMap[i]] = domainList[domainId]->ibegin; 1731 nSize[indexMap[i]] = domainList[domainId]->ni; 1732 nBeginGlobal[indexMap[i]] = 0; 1263 1733 nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 1264 1734 1265 n ZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin_srv;1266 n ZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj_srv;1267 n ZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;1735 nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 1736 nSize[indexMap[i] + 1] = domainList[domainId]->nj; 1737 nBeginGlobal[indexMap[i] + 1] = 0; 1268 1738 nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 1269 1739 1270 {1271 int count = 0;1272 globalZoomIndex[i].resize(nZoomSize[indexMap[i]]*nZoomSize[indexMap[i]+1]);1273 for (int jdx = 0; jdx < nZoomSize[indexMap[i]+1]; ++jdx)1274 for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx)1275 {1276 globalZoomIndex[i](count) = (nZoomBegin[indexMap[i]] + idx) + (nZoomBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]];1277 ++count;1278 }1279 }1280 1740 ++domainId; 1281 1741 } 1282 1742 else if (1 == axis_domain_order(i)) // axis 1283 1743 { 1284 nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv; 1285 nZoomSize[indexMap[i]] = axisList[axisId]->zoom_size_srv; 1286 nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin_srv; 1287 nGlob[indexMap[i]] = axisList[axisId]->n_glo; 1288 if (!axisList[axisId]->global_zoom_index.isEmpty()) 1289 { 1290 globalZoomIndex[i].reference(axisList[axisId]->zoom_index_srv); 1291 } 1292 else 1293 { 1294 globalZoomIndex[i].resize(nZoomSize[indexMap[i]]); 1295 for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx) 1296 globalZoomIndex[i](idx) = nZoomBegin[indexMap[i]] + idx; 1297 } 1298 1744 nBegin[indexMap[i]] = axisList[axisId]->begin; 1745 nSize[indexMap[i]] = axisList[axisId]->n; 1746 nBeginGlobal[indexMap[i]] = 0; 1747 nGlob[indexMap[i]] = axisList[axisId]->n_glo; 1299 1748 ++axisId; 1300 1749 } 1301 1750 else // scalar 1751 { 1752 } 1753 } 1754 1755 if (nSize.empty()) // Scalar grid 1756 { 1757 nBegin.push_back(0); 1758 nSize.push_back(1); 1759 nBeginGlobal.push_back(0); 1760 nGlob.push_back(1); 1761 } 1762 1763 modifyMaskSize(nSize, false); 1764 1765 // These below codes are reserved for future 1766 CDistributionServer srvDist(server->intraCommRank, nBegin, nSize, nBeginGlobal, nGlob); 1767 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 1768 ite = outGlobalIndexFromClient.end(), it; 1769 const CDistributionServer::GlobalLocalMap& globalLocalMask = srvDist.getGlobalLocalIndex(); 1770 CDistributionServer::GlobalLocalMap::const_iterator itSrv; 1771 size_t nb = 0; 1772 for (it = itb; it != ite; ++it) 1773 { 1774 CArray<size_t,1>& globalInd = it->second; 1775 for (size_t idx = 0; idx < globalInd.numElements(); ++idx) 1302 1776 { 1303 nZoomBegin[indexMap[i]] = 0; 1304 nZoomSize[indexMap[i]] = 1; 1305 nZoomBeginGlobal[indexMap[i]] = 0; 1306 nGlob[indexMap[i]] = 1; 1307 globalZoomIndex[i].resize(1); 1308 globalZoomIndex[i](0) = 0; 1309 ++scalarId; 1777 if (globalLocalMask.end() != globalLocalMask.find(globalInd(idx))) ++nb; 1310 1778 } 1311 1779 } 1312 dataSize = 1; 1313 for (int i = 0; i < nZoomSize.size(); ++i) 1314 dataSize *= nZoomSize[i]; 1315 1316 /* serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize, 1317 nZoomBeginGlobal, nGlob);*/ 1318 serverDistribution_ = new CDistributionServer(server->intraCommRank, 1319 globalZoomIndex, axis_domain_order, 1320 nZoomBegin, nZoomSize, nZoomBeginGlobal, nGlob); 1321 } 1322 1323 CArray<size_t,1> outIndex; 1324 buffer >> outIndex; 1325 if (isDataDistributed_) 1326 serverDistribution_->computeLocalIndex(outIndex); 1327 else 1328 { 1329 dataSize = outIndex.numElements(); 1330 for (int i = 0; i < outIndex.numElements(); ++i) outIndex(i) = i; 1331 } 1332 writtenDataSize_ += dataSize; 1333 1334 outIndexFromClient.insert(std::make_pair(rank, outIndex)); 1335 connectedDataSize_[rank] = outIndex.numElements(); 1336 numberWrittenIndexes_ += outIndex.numElements(); 1337 } 1338 1339 // if (isScalarGrid()) return; 1340 1341 if (isDataDistributed_) 1342 { 1343 MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 1344 MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 1345 offsetWrittenIndexes_ -= numberWrittenIndexes_; 1346 } 1347 else 1348 totalNumberWrittenIndexes_ = numberWrittenIndexes_; 1349 1350 nbSenders = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks); 1780 1781 CArray<int,1> indexToModify(nb); 1782 nb = 0; 1783 for (it = itb; it != ite; ++it) 1784 { 1785 CArray<size_t,1>& globalInd = it->second; 1786 for (size_t idx = 0; idx < globalInd.numElements(); ++idx) 1787 { 1788 itSrv = globalLocalMask.find(globalInd(idx)); 1789 if (globalLocalMask.end() != itSrv) 1790 { 1791 indexToModify(nb) = itSrv->second; 1792 ++nb; 1793 } 1794 } 1795 } 1796 1797 modifyMask(indexToModify, true); 1798 } 1799 1800 if (isScalarGrid()) return; 1801 1802 nbReadSenders[client] = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks); 1803 } 1351 1804 } 1352 1805 … … 1366 1819 const CArray<int,1>& axisDomainOrder) 1367 1820 { 1368 globalDim.resize(domains.size()*2+axis.size()+scalars.size()); 1821 // globalDim.resize(domains.size()*2+axis.size()+scalars.size()); 1822 globalDim.resize(domains.size()*2+axis.size()); 1369 1823 int positionDimensionDistributed = 1; 1370 1824 int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0; … … 1396 1850 else 1397 1851 { 1398 globalDim[idx] = 1;1852 // globalDim[idx] = 1; 1399 1853 ++idxScalar; 1400 ++idx;1854 // ++idx; 1401 1855 } 1402 1856 } … … 1484 1938 } 1485 1939 1486 bool CGrid::doGridHaveDataDistributed( )1940 bool CGrid::doGridHaveDataDistributed(CContextClient* client) 1487 1941 { 1488 1942 if (isScalarGrid()) return false; 1943 else if (0 != client) 1944 { 1945 return (isDataDistributed_ || (1 != client->clientSize) || (1 != client->serverSize)); 1946 } 1489 1947 else 1490 return isDataDistributed_; 1948 return isDataDistributed_; 1491 1949 } 1492 1950 … … 1583 2041 void CGrid::sendAddDomain(const string& id) 1584 2042 { 1585 CContext* context=CContext::getCurrent(); 1586 1587 if (! context->hasServer ) 1588 { 1589 CContextClient* client=context->client; 1590 1591 CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN); 1592 if (client->isServerLeader()) 1593 { 1594 CMessage msg; 1595 msg<<this->getId(); 1596 msg<<id; 1597 const std::list<int>& ranks = client->getRanksServerLeader(); 1598 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1599 event.push(*itRank,1,msg); 1600 client->sendEvent(event); 1601 } 1602 else client->sendEvent(event); 1603 } 2043 sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN); 1604 2044 } 1605 2045 … … 1610 2050 void CGrid::sendAddAxis(const string& id) 1611 2051 { 1612 CContext* context=CContext::getCurrent(); 1613 1614 if (! context->hasServer ) 1615 { 1616 CContextClient* client=context->client; 1617 1618 CEventClient event(this->getType(),EVENT_ID_ADD_AXIS); 1619 if (client->isServerLeader()) 1620 { 1621 CMessage msg; 1622 msg<<this->getId(); 1623 msg<<id; 1624 const std::list<int>& ranks = client->getRanksServerLeader(); 1625 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1626 event.push(*itRank,1,msg); 1627 client->sendEvent(event); 1628 } 1629 else client->sendEvent(event); 1630 } 2052 sendAddItem(id, (int)EVENT_ID_ADD_AXIS); 1631 2053 } 1632 2054 … … 1637 2059 void CGrid::sendAddScalar(const string& id) 1638 2060 { 1639 CContext* context=CContext::getCurrent(); 1640 1641 if (! context->hasServer ) 1642 { 1643 CContextClient* client=context->client; 1644 1645 CEventClient event(this->getType(),EVENT_ID_ADD_SCALAR); 1646 if (client->isServerLeader()) 1647 { 1648 CMessage msg; 1649 msg<<this->getId(); 1650 msg<<id; 1651 const std::list<int>& ranks = client->getRanksServerLeader(); 1652 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1653 event.push(*itRank,1,msg); 1654 client->sendEvent(event); 1655 } 1656 else client->sendEvent(event); 1657 } 2061 sendAddItem(id, (int)EVENT_ID_ADD_SCALAR); 1658 2062 } 1659 2063 … … 1746 2150 { 1747 2151 CDomain* pDom = CDomain::get(*it); 1748 if (context->hasClient )2152 if (context->hasClient && !context->hasServer) 1749 2153 { 1750 2154 pDom->solveRefInheritance(apply); … … 1758 2162 { 1759 2163 CAxis* pAxis = CAxis::get(*it); 1760 if (context->hasClient )2164 if (context->hasClient && !context->hasServer) 1761 2165 { 1762 2166 pAxis->solveRefInheritance(apply); … … 1770 2174 { 1771 2175 CScalar* pScalar = CScalar::get(*it); 1772 if (context->hasClient )2176 if (context->hasClient && !context->hasServer) 1773 2177 { 1774 2178 pScalar->solveRefInheritance(apply); … … 2145 2549 } 2146 2550 2551 void CGrid::setContextClient(CContextClient* contextClient) 2552 { 2553 if (clientsSet.find(contextClient)==clientsSet.end()) 2554 { 2555 clients.push_back(contextClient) ; 2556 clientsSet.insert(contextClient); 2557 } 2558 for (int i=0; i<this->getDomains().size(); i++) 2559 this->getDomains()[i]->setContextClient(contextClient); 2560 for (int i=0; i<this->getAxis().size(); i++) 2561 this->getAxis()[i]->setContextClient(contextClient); 2562 } 2563 2147 2564 /*! 2148 2565 Parse a grid, for now, it contains only domain, axis and scalar
Note: See TracChangeset
for help on using the changeset viewer.