Changeset 1460 for XIOS/dev/branch_openmp/src/node/axis.cpp
- Timestamp:
- 03/22/18 10:43:20 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/branch_openmp/src/node/axis.cpp
r1334 r1460 10 10 #include "context_server.hpp" 11 11 #include "xios_spl.hpp" 12 #include "inverse_axis.hpp"13 #include "zoom_axis.hpp"14 #include "interpolate_axis.hpp"15 12 #include "server_distribution_description.hpp" 16 13 #include "client_server_mapping_distributed.hpp" 17 14 #include "distribution_client.hpp" 18 15 16 using namespace ep_lib; 17 19 18 namespace xios { 20 19 21 /// ////////////////////// D éfinitions ////////////////////// ///20 /// ////////////////////// Definitions ////////////////////// /// 22 21 23 22 CAxis::CAxis(void) 24 23 : CObjectTemplate<CAxis>() 25 , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 24 , CAxisAttributes(), isChecked(false), relFiles() 25 , areClientAttributesChecked_(false) 26 26 , isClientAfterTransformationChecked(false) 27 , isDistributed_(false), hasBounds_(false), isCompressible_(false) 28 , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 29 , transformationMap_(), hasValue(false), hasLabel(false) 27 , hasBounds(false), isCompressible_(false) 28 , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_() 29 , transformationMap_() 30 , hasValue(false), hasLabel(false) 31 , computedWrittenIndex_(false) 32 , clients() 30 33 { 31 34 } … … 33 36 CAxis::CAxis(const StdString & id) 34 37 : CObjectTemplate<CAxis>(id) 35 , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 38 , CAxisAttributes(), isChecked(false), relFiles() 39 , areClientAttributesChecked_(false) 36 40 , isClientAfterTransformationChecked(false) 37 , isDistributed_(false), hasBounds_(false), isCompressible_(false) 38 , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 39 , transformationMap_(), hasValue(false), hasLabel(false) 41 , hasBounds(false), isCompressible_(false) 42 , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_() 43 , transformationMap_() 44 , hasValue(false), hasLabel(false) 45 , computedWrittenIndex_(false) 46 , clients() 40 47 { 41 48 } … … 52 59 m["inverse_axis"] = TRANS_INVERSE_AXIS; 53 60 m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_AXIS; 61 m["reduce_axis"] = TRANS_REDUCE_AXIS_TO_AXIS; 54 62 m["extract_domain"] = TRANS_EXTRACT_DOMAIN_TO_AXIS; 63 m["temporal_splitting"] = TRANS_TEMPORAL_SPLITTING; 64 m["duplicate_scalar"] = TRANS_DUPLICATE_SCALAR_TO_AXIS; 55 65 } 56 66 … … 63 73 (*CAxis::transformationMapList_ptr)["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_AXIS; 64 74 (*CAxis::transformationMapList_ptr)["extract_domain"] = TRANS_EXTRACT_DOMAIN_TO_AXIS; 75 (*CAxis::transformationMapList_ptr)["reduce_axis"] = TRANS_REDUCE_AXIS_TO_AXIS; 76 (*CAxis::transformationMapList_ptr)["temporal_splitting"] = TRANS_TEMPORAL_SPLITTING; 77 (*CAxis::transformationMapList_ptr)["duplicate_scalar"] = TRANS_DUPLICATE_SCALAR_TO_AXIS; 65 78 } 66 79 … … 84 97 bool CAxis::isDistributed(void) const 85 98 { 86 return isDistributed_; 99 bool distributed = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 100 (!this->n.isEmpty() && (this->n != this->n_glo)); 101 // A same stupid condition to make sure that if there is only one client, axis 102 // should be considered to be distributed. This should be a temporary solution 103 distributed |= (1 == CContext::getCurrent()->client->clientSize); 104 return distributed; 87 105 } 88 106 … … 109 127 //---------------------------------------------------------------- 110 128 111 const std::vector<int>& CAxis::getIndexesToWrite(void) const112 {113 return indexesToWrite;114 }115 116 129 /*! 117 130 Returns the number of indexes written by each server. 118 131 \return the number of indexes written by each server 119 132 */ 120 int CAxis::getNumberWrittenIndexes() const 121 { 122 return numberWrittenIndexes_; 133 int CAxis::getNumberWrittenIndexes(ep_lib::MPI_Comm writtenCom) 134 { 135 int writtenSize; 136 ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 137 return numberWrittenIndexes_[writtenSize]; 123 138 } 124 139 … … 127 142 \return the total number of indexes written by the servers 128 143 */ 129 int CAxis::getTotalNumberWrittenIndexes() const 130 { 131 return totalNumberWrittenIndexes_; 144 int CAxis::getTotalNumberWrittenIndexes(ep_lib::MPI_Comm writtenCom) 145 { 146 int writtenSize; 147 ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 148 return totalNumberWrittenIndexes_[writtenSize]; 132 149 } 133 150 … … 136 153 \return the offset of indexes written by each server 137 154 */ 138 int CAxis::getOffsetWrittenIndexes() const 139 { 140 return offsetWrittenIndexes_; 155 int CAxis::getOffsetWrittenIndexes(ep_lib::MPI_Comm writtenCom) 156 { 157 int writtenSize; 158 ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 159 return offsetWrittenIndexes_[writtenSize]; 160 } 161 162 CArray<int, 1>& CAxis::getCompressedIndexToWriteOnServer(ep_lib::MPI_Comm writtenCom) 163 { 164 int writtenSize; 165 ep_lib::MPI_Comm_size(writtenCom, &writtenSize); 166 return compressedIndexToWriteOnServer[writtenSize]; 141 167 } 142 168 143 169 //---------------------------------------------------------------- 144 170 145 /*!171 /*! 146 172 * Compute the minimum buffer size required to send the attributes to the server(s). 147 173 * 148 174 * \return A map associating the server rank with its minimum buffer size. 149 175 */ 150 std::map<int, StdSize> CAxis::getAttributesBufferSize() 151 { 152 CContextClient* client = CContext::getCurrent()->client; 153 154 std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(); 155 156 bool isNonDistributed = (n == n_glo); 176 std::map<int, StdSize> CAxis::getAttributesBufferSize(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid, 177 CServerDistributionDescription::ServerDistributionType distType) 178 { 179 180 std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client); 181 182 // bool isNonDistributed = (n_glo == n); 183 bool isDistributed = (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 184 || (index.numElements() != n_glo); 157 185 158 186 if (client->isServerLeader()) … … 161 189 size_t size = 6 * sizeof(size_t); 162 190 // size estimation for sendNonDistributedValue 163 if (isNonDistributed) 164 size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0)); 191 if (!isDistributed) 192 { 193 // size = std::max(size, CArray<double,1>::size(n_glo) + (isCompressible_ ? CArray<int,1>::size(n_glo) : 0)); 194 size += CArray<int,1>::size(n_glo); 195 size += CArray<int,1>::size(n_glo); 196 size += CArray<bool,1>::size(n_glo); 197 size += CArray<double,1>::size(n_glo); 198 if (hasBounds) 199 size += CArray<double,2>::size(2*n_glo); 200 if (hasLabel) 201 size += CArray<StdString,1>::size(n_glo); 202 } 165 203 size += CEventClient::headerSize + getId().size() + sizeof(size_t); 166 204 … … 171 209 attributesSizes[*itRank] = size; 172 210 } 211 const std::list<int>& ranksNonLeaders = client->getRanksServerNotLeader(); 212 for (std::list<int>::const_iterator itRank = ranksNonLeaders.begin(), itRankEnd = ranksNonLeaders.end(); itRank != itRankEnd; ++itRank) 213 { 214 if (size > attributesSizes[*itRank]) 215 attributesSizes[*itRank] = size; 216 } 217 173 218 } 174 219 175 if ( !isNonDistributed)220 if (isDistributed) 176 221 { 177 222 // size estimation for sendDistributedValue 178 std::map<int, std::vector<size_t> >::const_iterator it, ite = indSrv_.end();179 for (it = indSrv_ .begin(); it != ite; ++it)223 boost::unordered_map<int, vector<size_t> >::const_iterator it, ite = indSrv_[client->serverSize].end(); 224 for (it = indSrv_[client->serverSize].begin(); it != ite; ++it) 180 225 { 181 size_t sizeIndexEvent = CArray<int,1>::size(it->second.size()); 182 if (isCompressible_) 183 sizeIndexEvent += CArray<int,1>::size(indWrittenSrv_[it->first].size()); 184 185 size_t sizeValEvent = CArray<double,1>::size(it->second.size()); 186 if (hasBounds_) 187 sizeValEvent += CArray<double,2>::size(2 * it->second.size()); 188 226 size_t size = 6 * sizeof(size_t); 227 size += CArray<int,1>::size(it->second.size()); 228 size += CArray<int,1>::size(it->second.size()); 229 size += CArray<bool,1>::size(it->second.size()); 230 size += CArray<double,1>::size(it->second.size()); 231 if (hasBounds) 232 size += CArray<double,2>::size(2 * it->second.size()); 189 233 if (hasLabel) 190 size ValEvent+= CArray<StdString,1>::size(it->second.size());191 192 size _t size = CEventClient::headerSize + getId().size() + sizeof(size_t) + std::max(sizeIndexEvent, sizeValEvent);234 size += CArray<StdString,1>::size(it->second.size()); 235 236 size += CEventClient::headerSize + getId().size() + sizeof(size_t); 193 237 if (size > attributesSizes[it->first]) 194 238 attributesSizes[it->first] = size; … … 213 257 } 214 258 215 void CAxis::fillInValues(const CArray<double,1>& values) 216 { 217 this->value = values; 218 } 219 259 /*! 260 Check common attributes of an axis. 261 This check should be done in the very beginning of work flow 262 */ 220 263 void CAxis::checkAttributes(void) 221 264 { … … 260 303 } 261 304 305 // Remove this check because it doen't make sense in case of a hole or overlapping axes 262 306 if (!this->value.isEmpty()) 263 307 { 264 StdSize true_size = value.numElements();265 if (this->n.getValue() != true_size)266 ERROR("CAxis::checkAttributes(void)",267 << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "268 << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");308 // StdSize true_size = value.numElements(); 309 // if (this->n.getValue() != true_size) 310 // ERROR("CAxis::checkAttributes(void)", 311 // << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 312 // << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 269 313 this->hasValue = true; 270 314 } 271 315 272 this->checkData();273 this->checkZoom();274 this->checkMask();275 316 this->checkBounds(); 276 this->checkLabel(); 277 278 isDistributed_ = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 279 (!this->n.isEmpty() && (this->n != this->n_glo)); 280 281 // A same stupid condition to make sure that if there is only one client, axis 282 // should be considered to be distributed. This should be a temporary solution 283 isDistributed_ |= (1 == CContext::getCurrent()->client->clientSize); 284 } 285 317 318 CContext* context=CContext::getCurrent(); 319 if (context->hasClient) 320 { 321 this->checkData(); 322 this->checkZoom(); 323 this->checkMask(); 324 this->checkLabel(); 325 } 326 } 327 328 /*! 329 Check the validity of data and fill in values if any. 330 */ 286 331 void CAxis::checkData() 287 332 { … … 306 351 } 307 352 353 /*! 354 Check validity of zoom info and fill in values if any. 355 */ 308 356 void CAxis::checkZoom(void) 309 357 { 310 358 if (global_zoom_begin.isEmpty()) global_zoom_begin.setValue(0); 311 359 if (global_zoom_n.isEmpty()) global_zoom_n.setValue(n_glo.getValue()); 312 } 313 360 if (zoom_index.isEmpty()) 361 { 362 zoom_index.setValue(index.getValue()); 363 } 364 if (zoom_n.isEmpty()) zoom_n.setValue(n); 365 if (zoom_begin.isEmpty()) zoom_begin.setValue(begin); 366 } 367 368 size_t CAxis::getGlobalWrittenSize(void) 369 { 370 if (zoomByIndex()) return global_zoom_index.numElements(); 371 else return global_zoom_n ; 372 } 373 374 /*! 375 Check validity of mask info and fill in values if any. 376 */ 314 377 void CAxis::checkMask() 315 378 { … … 333 396 } 334 397 335 void CAxis::checkBounds() 336 { 337 if (!bounds.isEmpty()) 338 { 339 if (bounds.extent(0) != 2 || bounds.extent(1) != n) 340 ERROR("CAxis::checkAttributes(void)", 341 << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl 342 << "Axis size is " << n.getValue() << "." << std::endl 343 << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << "."); 344 hasBounds_ = true; 345 } 346 else hasBounds_ = false; 347 } 398 /*! 399 Check validity of bounds info and fill in values if any. 400 */ 401 void CAxis::checkBounds() 402 { 403 if (!bounds.isEmpty()) 404 { 405 if (bounds.extent(0) != 2 || bounds.extent(1) != n) 406 ERROR("CAxis::checkAttributes(void)", 407 << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl 408 << "Axis size is " << n.getValue() << "." << std::endl 409 << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << "."); 410 hasBounds = true; 411 } 412 else hasBounds = false; 413 } 348 414 349 415 void CAxis::checkLabel() … … 360 426 else hasLabel = false; 361 427 } 428 429 /*! 430 Check whether we can do compressed output 431 */ 362 432 void CAxis::checkEligibilityForCompressedOutput() 363 433 { … … 366 436 } 367 437 438 /* 439 Check whether we do zooming by indexing 440 return true if do zooming by index 441 */ 368 442 bool CAxis::zoomByIndex() 369 443 { … … 371 445 } 372 446 447 /*! 448 Dispatch event from the lower communication layer then process event according to its type 449 */ 373 450 bool CAxis::dispatchEvent(CEventServer& event) 374 { 375 if (SuperClass::dispatchEvent(event)) return true; 376 else 377 { 378 switch(event.type) 379 { 380 case EVENT_ID_SERVER_ATTRIBUT : 381 recvServerAttribut(event); 382 return true; 383 break; 384 case EVENT_ID_INDEX: 385 recvIndex(event); 451 { 452 if (SuperClass::dispatchEvent(event)) return true; 453 else 454 { 455 switch(event.type) 456 { 457 case EVENT_ID_DISTRIBUTION_ATTRIBUTE : 458 recvDistributionAttribute(event); 386 459 return true; 387 460 break; 388 case EVENT_ID_DISTRIBUTED_VALUE: 389 recvDistributedValue(event); 390 return true; 391 break; 392 case EVENT_ID_NON_DISTRIBUTED_VALUE: 393 recvNonDistributedValue(event); 394 return true; 395 break; 396 default : 397 ERROR("bool CAxis::dispatchEvent(CEventServer& event)", 398 << "Unknown Event"); 399 return false; 400 } 401 } 402 } 403 461 case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES: 462 recvNonDistributedAttributes(event); 463 return true; 464 break; 465 case EVENT_ID_DISTRIBUTED_ATTRIBUTES: 466 recvDistributedAttributes(event); 467 return true; 468 break; 469 default : 470 ERROR("bool CAxis::dispatchEvent(CEventServer& event)", 471 << "Unknown Event"); 472 return false; 473 } 474 } 475 } 476 477 /*! 478 Check attributes on client side (This name is still adequate???) 479 */ 404 480 void CAxis::checkAttributesOnClient() 405 481 { 406 482 if (this->areClientAttributesChecked_) return; 407 483 408 this->checkAttributes(); 484 CContext* context=CContext::getCurrent(); 485 if (context->hasClient && !context->hasServer) this->checkAttributes(); 409 486 410 487 this->areClientAttributesChecked_ = true; 411 488 } 412 489 490 /* 491 The (spatial) transformation sometimes can change attributes of an axis (e.g zoom can change mask or generate can change whole attributes) 492 Therefore, we should recheck them. 493 */ 413 494 void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid, 414 495 CServerDistributionDescription::ServerDistributionType distType) … … 418 499 if (this->isClientAfterTransformationChecked) return; 419 500 if (context->hasClient) 420 { 421 if (n.getValue() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType); 501 { 502 if (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 503 computeConnectedClients(globalDim, orderPositionInGrid, distType); 504 else if (index.numElements() != n_glo) computeConnectedClients(globalDim, orderPositionInGrid, CServerDistributionDescription::ROOT_DISTRIBUTION); 422 505 } 423 506 … … 425 508 } 426 509 427 // Send all checked attributes to server 510 /* 511 Send all checked attributes to server? (We dont have notion of server any more so client==server) 512 \param [in] globalDim global dimension of grid containing this axis 513 \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 514 \param [in] distType distribution type of the server. For now, we only have band distribution. 515 516 */ 428 517 void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 429 518 CServerDistributionDescription::ServerDistributionType distType) … … 434 523 435 524 if (this->isChecked) return; 436 if (context->hasClient) 525 if (context->hasClient) sendAttributes(globalDim, orderPositionInGrid, distType); 526 527 this->isChecked = true; 528 } 529 530 /*! 531 Send attributes from one client to other clients 532 \param[in] globalDim global dimension of grid which contains this axis 533 \param[in] order 534 */ 535 void CAxis::sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 536 CServerDistributionDescription::ServerDistributionType distType) 537 { 538 sendDistributionAttribute(globalDim, orderPositionInGrid, distType); 539 540 // if (index.numElements() == n_glo.getValue()) 541 if ((orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 542 || (index.numElements() != n_glo)) 437 543 { 438 sendServerAttribut(globalDim, orderPositionInGrid, distType); 439 if (hasValue) sendValue(); 544 sendDistributedAttributes(); 440 545 } 441 442 this->isChecked = true;443 }444 445 void CAxis::sendValue()446 {447 if (n.getValue() == n_glo.getValue())448 sendNonDistributedValue();449 546 else 450 sendDistributedValue(); 451 } 452 453 void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid, 547 { 548 sendNonDistributedAttributes(); 549 } 550 } 551 552 /* 553 Compute the connection between group of clients (or clients/servers). 554 (E.g: Suppose we have 2 group of clients in two model: A (client role) connect to B (server role), 555 this function calculate number of clients B connect to one client of A) 556 \param [in] globalDim global dimension of grid containing this axis 557 \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 558 \param [in] distType distribution type of the server. For now, we only have band distribution. 559 */ 560 void CAxis::computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid, 454 561 CServerDistributionDescription::ServerDistributionType distType) 455 562 { 456 563 CContext* context = CContext::getCurrent(); 457 CContextClient* client = context->client; 458 int nbServer = client->serverSize; 459 int range, clientSize = client->clientSize; 460 int rank = client->clientRank; 461 462 size_t ni = this->n.getValue(); 463 size_t ibegin = this->begin.getValue(); 464 size_t zoom_end = global_zoom_begin+global_zoom_n-1; 465 size_t nZoomCount = 0; 466 size_t nbIndex = index.numElements(); 467 468 int end = (0 == n) ? begin : begin + n - 1; 469 int zoom_size = zoomByIndex() ? global_zoom_index.numElements() : global_zoom_n; 470 int minInd = min(index); 471 int maxInd = max(index); 472 for (size_t idx = 0; idx < zoom_size; ++idx) 473 { 474 size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 475 if (globalZoomIndex >= minInd && globalZoomIndex <= maxInd) ++nZoomCount; 476 } 477 478 /* for (size_t idx = 0; idx < nbIndex; ++idx) 479 { 480 size_t globalIndex = index(idx); 481 if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount; 482 }*/ 564 565 int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 566 567 connectedServerRank_.clear(); 568 nbSenders.clear(); 569 570 for (int p = 0; p < nbSrvPools; ++p) 571 { 572 CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 573 int nbServer = client->serverSize; 574 int range, clientSize = client->clientSize; 575 int rank = client->clientRank; 576 577 if (connectedServerRank_.find(nbServer) == connectedServerRank_.end()) 578 { 579 size_t ni = this->n.getValue(); 580 size_t ibegin = this->begin.getValue(); 581 size_t global_zoom_end = global_zoom_begin+global_zoom_n-1; 582 size_t nZoomCount = 0; 583 size_t nbIndex = index.numElements(); 584 585 // First of all, we should compute the mapping of the global index and local index of the current client 586 if (globalLocalIndexMap_.empty()) 587 { 588 for (size_t idx = 0; idx < nbIndex; ++idx) 589 { 590 globalLocalIndexMap_[index(idx)] = idx; 591 } 592 } 593 594 // Calculate the compressed index if any 595 std::set<int> writtenInd; 596 if (isCompressible_) 597 { 598 for (int idx = 0; idx < data_index.numElements(); ++idx) 599 { 600 int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 601 602 if (ind >= 0 && ind < ni && mask(ind)) 603 { 604 ind += ibegin; 605 if (ind >= global_zoom_begin && ind <= global_zoom_end) 606 writtenInd.insert(ind); 607 } 608 } 609 } 610 611 // Compute the global index of the current client (process) hold 612 std::vector<int> nGlobAxis(1); 613 nGlobAxis[0] = n_glo.getValue(); 614 615 size_t globalSizeIndex = 1, indexBegin, indexEnd; 616 for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i]; 617 indexBegin = 0; 618 if (globalSizeIndex <= clientSize) 619 { 620 indexBegin = rank%globalSizeIndex; 621 indexEnd = indexBegin; 622 } 623 else 624 { 625 for (int i = 0; i < clientSize; ++i) 626 { 627 range = globalSizeIndex / clientSize; 628 if (i < (globalSizeIndex%clientSize)) ++range; 629 if (i == client->clientRank) break; 630 indexBegin += range; 631 } 632 indexEnd = indexBegin + range - 1; 633 } 634 635 CArray<size_t,1> globalIndex(index.numElements()); 636 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 637 globalIndex(idx) = index(idx); 638 639 // Describe the distribution of server side 640 641 CServerDistributionDescription serverDescription(nGlobAxis, nbServer, distType); 642 643 std::vector<int> serverZeroIndex; 644 serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0); 645 646 std::list<int> serverZeroIndexLeader; 647 std::list<int> serverZeroIndexNotLeader; 648 CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 649 650 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 651 *it = serverZeroIndex[*it]; 652 653 // Find out the connection between client and server side 654 CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 655 clientServerMap->computeServerIndexMapping(globalIndex, nbServer); 656 CClientServerMapping::GlobalIndexMap& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer(); 657 658 indSrv_[nbServer].swap(globalIndexAxisOnServer); 659 660 if (distType==CServerDistributionDescription::ROOT_DISTRIBUTION) 661 { 662 for(int i=1; i<nbServer; ++i) 663 { 664 indSrv_[nbServer].insert(pair<int, vector<size_t> >(i,indSrv_[nbServer][0]) ) ; 665 } 666 667 serverZeroIndexLeader.clear() ; 668 } 669 670 CClientServerMapping::GlobalIndexMap::const_iterator it = indSrv_[nbServer].begin(), 671 ite = indSrv_[nbServer].end(); 672 673 for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first); 674 675 for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 676 connectedServerRank_[nbServer].push_back(*it); 677 678 // Even if a client has no index, it must connect to at least one server and 679 // send an "empty" data to this server 680 if (connectedServerRank_[nbServer].empty()) 681 connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 682 683 nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 684 685 delete clientServerMap; 686 } 687 } 688 } 689 690 /* 691 Compute the index of data to write into file 692 (Different from the previous version, this version of XIOS allows data be written into file (classical role), 693 or transfered to another clients) 694 */ 695 void CAxis::computeWrittenIndex() 696 { 697 if (computedWrittenIndex_) return; 698 computedWrittenIndex_ = true; 699 700 CContext* context=CContext::getCurrent(); 701 CContextServer* server = context->server; 702 703 // We describe the distribution of client (server) on which data are written 704 std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 705 nBegin[0] = zoom_begin; 706 nSize[0] = zoom_n; 707 nBeginGlobal[0] = 0; 708 nGlob[0] = n_glo; 709 CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob); 710 const CArray<size_t,1>& writtenGlobalIndex = srvDist.getGlobalIndex(); 711 712 // Because all written data are local on a client, 713 // we need to compute the local index on the server from its corresponding global index 714 size_t nbWritten = 0, indGlo; 715 boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 716 ite = globalLocalIndexMap_.end(), it; 717 CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 718 itSrve = writtenGlobalIndex.end(), itSrv; 719 if (!zoomByIndex()) 720 { 721 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 722 { 723 indGlo = *itSrv; 724 if (ite != globalLocalIndexMap_.find(indGlo)) 725 { 726 ++nbWritten; 727 } 728 } 729 730 localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 731 // localIndexToWriteOnServer.resize(nbWritten); 732 733 nbWritten = 0; 734 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 735 { 736 indGlo = *itSrv; 737 if (ite != globalLocalIndexMap_.find(indGlo)) 738 { 739 localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 740 ++nbWritten; 741 } 742 } 743 } 744 else 745 { 746 nbWritten = 0; 747 boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 748 ite = globalLocalIndexMap_.end(), it; 749 for (int i = 0; i < zoom_index.numElements(); ++i) 750 { 751 if (ite != globalLocalIndexMap_.find(zoom_index(i))) 752 ++nbWritten; 753 } 754 755 localIndexToWriteOnServer.resize(nbWritten); 756 757 nbWritten = 0; 758 for (int i = 0; i < zoom_index.numElements(); ++i) 759 { 760 if (ite != globalLocalIndexMap_.find(zoom_index(i))) 761 { 762 localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[zoom_index(i)]; 763 ++nbWritten; 764 } 765 } 766 } 767 768 } 769 770 void CAxis::computeWrittenCompressedIndex(ep_lib::MPI_Comm writtenComm) 771 { 772 int writtenCommSize; 773 ep_lib::MPI_Comm_size(writtenComm, &writtenCommSize); 774 if (compressedIndexToWriteOnServer.find(writtenCommSize) != compressedIndexToWriteOnServer.end()) 775 return; 776 777 if (isCompressible()) 778 { 779 size_t nbWritten = 0, indGlo; 780 CContext* context=CContext::getCurrent(); 781 CContextServer* server = context->server; 782 783 // We describe the distribution of client (server) on which data are written 784 std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 785 nBegin[0] = zoom_begin; 786 nSize[0] = zoom_n; 787 nBeginGlobal[0] = 0; 788 nGlob[0] = n_glo; 789 CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob); 790 const CArray<size_t,1>& writtenGlobalIndex = srvDist.getGlobalIndex(); 791 boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 792 ite = globalLocalIndexMap_.end(), it; 793 794 CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 795 itSrve = writtenGlobalIndex.end(), itSrv; 796 boost::unordered_map<size_t,size_t> localGlobalIndexMap; 797 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 798 { 799 indGlo = *itSrv; 800 if (ite != globalLocalIndexMap_.find(indGlo)) 801 { 802 localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 803 ++nbWritten; 804 } 805 } 806 807 nbWritten = 0; 808 for (int idx = 0; idx < data_index.numElements(); ++idx) 809 { 810 if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 811 { 812 ++nbWritten; 813 } 814 } 815 816 compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 817 nbWritten = 0; 818 for (int idx = 0; idx < data_index.numElements(); ++idx) 819 { 820 if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 821 { 822 compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)]; 823 ++nbWritten; 824 } 825 } 826 827 numberWrittenIndexes_[writtenCommSize] = nbWritten; 828 if (isDistributed()) 829 { 830 831 ep_lib::MPI_Allreduce(&numberWrittenIndexes_[writtenCommSize], &totalNumberWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 832 ep_lib::MPI_Scan(&numberWrittenIndexes_[writtenCommSize], &offsetWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 833 offsetWrittenIndexes_[writtenCommSize] -= numberWrittenIndexes_[writtenCommSize]; 834 } 835 else 836 totalNumberWrittenIndexes_[writtenCommSize] = numberWrittenIndexes_[writtenCommSize]; 837 } 838 } 839 840 /*! 841 Send distribution information from a group of client (client role) to another group of client (server role) 842 The distribution of a group of client (server role) is imposed by the group of client (client role) 843 \param [in] globalDim global dimension of grid containing this axis 844 \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 845 \param [in] distType distribution type of the server. For now, we only have band distribution. 846 */ 847 void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid, 848 CServerDistributionDescription::ServerDistributionType distType) 849 { 850 std::list<CContextClient*>::iterator it; 851 for (it=clients.begin(); it!=clients.end(); ++it) 852 { 853 CContextClient* client = *it; 854 int nbServer = client->serverSize; 855 856 CServerDistributionDescription serverDescription(globalDim, nbServer); 857 serverDescription.computeServerDistribution(); 858 859 std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin(); 860 std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes(); 861 862 CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE); 863 if (client->isServerLeader()) 864 { 865 std::list<CMessage> msgs; 866 867 const std::list<int>& ranks = client->getRanksServerLeader(); 868 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 869 { 870 // Use const int to ensure CMessage holds a copy of the value instead of just a reference 871 const int begin = serverIndexBegin[*itRank][orderPositionInGrid]; 872 const int ni = serverDimensionSizes[*itRank][orderPositionInGrid]; 873 const int end = begin + ni - 1; 874 875 msgs.push_back(CMessage()); 876 CMessage& msg = msgs.back(); 877 msg << this->getId(); 878 msg << ni << begin << end; 879 msg << isCompressible_; 880 881 event.push(*itRank,1,msg); 882 } 883 client->sendEvent(event); 884 } 885 else client->sendEvent(event); 886 } 887 } 888 889 /* 890 Receive distribution attribute from another client 891 \param [in] event event containing data of these attributes 892 */ 893 void CAxis::recvDistributionAttribute(CEventServer& event) 894 { 895 CBufferIn* buffer = event.subEvents.begin()->buffer; 896 string axisId; 897 *buffer >> axisId; 898 get(axisId)->recvDistributionAttribute(*buffer); 899 } 900 901 /* 902 Receive distribution attribute from another client 903 \param [in] buffer buffer containing data of these attributes 904 */ 905 void CAxis::recvDistributionAttribute(CBufferIn& buffer) 906 { 907 int ni_srv, begin_srv, end_srv; 908 int global_zoom_end, zoom_end; 909 bool zoomIndex = zoomByIndex(); 483 910 484 CArray<size_t,1> globalIndexAxis(nbIndex); 485 for (size_t idx = 0; idx < nbIndex; ++idx) 486 { 487 globalIndexAxis(idx) = (size_t)index(idx); 488 } 489 490 std::vector<size_t> globalAxisZoom(nZoomCount); 491 nZoomCount = 0; 492 for (size_t idx = 0; idx < zoom_size; ++idx) 493 { 494 size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 495 if (globalZoomIndex >= minInd && globalZoomIndex <= maxInd) 496 { 497 globalAxisZoom[nZoomCount] = globalZoomIndex; 498 ++nZoomCount; 499 } 500 } 501 502 std::set<int> writtenInd; 503 if (isCompressible_) 504 { 911 std::vector<int> zoom_index_tmp; 912 std::vector<int>::iterator itZoomBegin, itZoomEnd, itZoom; 913 914 buffer >> ni_srv >> begin_srv >> end_srv; 915 buffer >> isCompressible_; 916 917 // Set up new local size of axis on the receiving clients 918 n.setValue(ni_srv); 919 begin.setValue(begin_srv); 920 921 // If we have zoom by index then process it 922 if (zoomIndex) 923 { 924 zoom_index_tmp.resize(global_zoom_index.numElements()); 925 std::copy(global_zoom_index.begin(), global_zoom_index.end(), zoom_index_tmp.begin()); 926 std::sort(zoom_index_tmp.begin(), zoom_index_tmp.end()); 927 itZoomBegin = std::lower_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), begin_srv); 928 itZoomEnd = std::upper_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), end_srv); 929 int sz = std::distance(itZoomBegin, itZoomEnd); 930 zoom_index.resize(sz); 931 itZoom = itZoomBegin; 932 for (int i = 0; i < sz; ++i, ++itZoom) 933 { 934 zoom_index(i) = *(itZoom); 935 } 936 } 937 938 global_zoom_begin = zoomIndex ? 0 : global_zoom_begin ; 939 global_zoom_n = zoomIndex ? zoom_index_tmp.size() : global_zoom_n; 940 global_zoom_end = global_zoom_begin + global_zoom_n - 1; 941 942 zoom_begin = zoomIndex ? std::distance(zoom_index_tmp.begin(), itZoomBegin) 943 : global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ; 944 zoom_end = zoomIndex ? std::distance(zoom_index_tmp.begin(), itZoomEnd) - 1 945 : global_zoom_end < end_srv ? global_zoom_end : end_srv ; 946 zoom_n = zoom_end - zoom_begin + 1; 947 948 if (zoom_n<=0) 949 { 950 zoom_n = 0; zoom_begin=global_zoom_begin; //0; zoom_begin = 0; 951 } 952 953 if (n_glo == n) 954 { 955 zoom_begin = zoomIndex ? std::distance(itZoomBegin, zoom_index_tmp.begin()) 956 : global_zoom_begin; 957 zoom_n = zoomIndex ? zoom_index_tmp.size() : global_zoom_n; 958 } 959 } 960 961 /* 962 Send attributes of axis from a group of client to other group of clients/servers 963 on supposing that these attributes are not distributed among the sending group 964 In the future, if new attributes are added, they should also be processed in this function 965 */ 966 void CAxis::sendNonDistributedAttributes() 967 { 968 std::list<CContextClient*>::iterator it; 969 for (it=clients.begin(); it!=clients.end(); ++it) 970 { 971 CContextClient* client = *it; 972 973 CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES); 974 size_t nbIndex = index.numElements(); 975 size_t nbDataIndex = 0; 976 505 977 for (int idx = 0; idx < data_index.numElements(); ++idx) 506 978 { 507 int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 508 509 if (ind >= 0 && ind < ni && mask(ind)) 510 { 511 ind += ibegin; 512 if (ind >= global_zoom_begin && ind <= zoom_end) 513 writtenInd.insert(ind); 514 } 515 } 516 } 517 518 CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer); 519 int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed(); 520 CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer; 521 if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side* 522 { 523 std::vector<int> nGlobAxis(1); 524 nGlobAxis[0] = n_glo.getValue(); 525 526 size_t globalSizeIndex = 1, indexBegin, indexEnd; 527 for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i]; 528 indexBegin = 0; 529 if (globalSizeIndex <= clientSize) 530 { 531 indexBegin = rank%globalSizeIndex; 532 indexEnd = indexBegin; 533 } 534 else 535 { 536 for (int i = 0; i < clientSize; ++i) 537 { 538 range = globalSizeIndex / clientSize; 539 if (i < (globalSizeIndex%clientSize)) ++range; 540 if (i == client->clientRank) break; 541 indexBegin += range; 542 } 543 indexEnd = indexBegin + range - 1; 544 } 545 546 CServerDistributionDescription serverDescription(nGlobAxis, nbServer); 547 serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd)); 548 CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 549 clientServerMap->computeServerIndexMapping(globalIndexAxis); 550 globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer(); 551 delete clientServerMap; 552 } 553 else 554 { 555 std::vector<size_t> globalIndexServer(n_glo.getValue()); 556 for (size_t idx = 0; idx < n_glo.getValue(); ++idx) 557 { 558 globalIndexServer[idx] = idx; 559 } 560 561 for (int idx = 0; idx < nbServer; ++idx) 562 { 563 globalIndexAxisOnServer[idx] = globalIndexServer; 564 } 565 } 566 567 CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(), 568 ite = globalIndexAxisOnServer.end(); 569 std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(), 570 iteVec = (globalAxisZoom).end(); 571 indSrv_.clear(); 572 indWrittenSrv_.clear(); 573 for (; it != ite; ++it) 574 { 575 int rank = it->first; 576 const std::vector<size_t>& globalIndexTmp = it->second; 577 int nb = globalIndexTmp.size(); 578 579 for (int i = 0; i < nb; ++i) 580 { 581 if (std::binary_search(itbVec, iteVec, globalIndexTmp[i])) 582 { 583 indSrv_[rank].push_back(globalIndexTmp[i]); 584 } 585 586 if (writtenInd.count(globalIndexTmp[i])) 587 { 588 indWrittenSrv_[rank].push_back(globalIndexTmp[i]); 589 } 590 } 591 } 592 593 connectedServerRank_.clear(); 594 for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) { 595 connectedServerRank_.push_back(it->first); 596 } 597 598 if (!indSrv_.empty()) 599 { 600 std::map<int, vector<size_t> >::const_iterator itIndSrv = indSrv_.begin(), 601 iteIndSrv = indSrv_.end(); 602 connectedServerRank_.clear(); 603 for (; itIndSrv != iteIndSrv; ++itIndSrv) 604 connectedServerRank_.push_back(itIndSrv->first); 605 } 606 nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_); 607 } 608 609 void CAxis::sendNonDistributedValue() 610 { 611 CContext* context = CContext::getCurrent(); 612 CContextClient* client = context->client; 613 CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_VALUE); 614 615 int zoom_end = global_zoom_begin + global_zoom_n - 1; 616 int nb = 0; 617 /* for (size_t idx = 0; idx < n; ++idx) 618 { 619 size_t globalIndex = begin + idx; 620 if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nb; 621 }*/ 622 623 int end = (0 == n) ? begin : begin + n - 1; 624 int zoom_size = zoomByIndex() ? global_zoom_index.numElements() : global_zoom_n; 625 for (size_t idx = 0; idx < zoom_size; ++idx) 626 { 627 size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 628 if (globalZoomIndex >= begin && globalZoomIndex <= end) ++nb; 629 } 630 631 int nbWritten = 0; 632 if (isCompressible_) 633 { 979 int ind = data_index(idx); 980 if (ind >= 0 && ind < nbIndex) ++nbDataIndex; 981 } 982 983 CArray<int,1> dataIndex(nbDataIndex); 984 nbDataIndex = 0; 634 985 for (int idx = 0; idx < data_index.numElements(); ++idx) 635 986 { 636 int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n); 637 638 if (ind >= 0 && ind < n && mask(ind)) 639 { 640 ind += begin; 641 if (ind >= global_zoom_begin && ind <= zoom_end) 642 ++nbWritten; 643 } 644 } 645 } 646 647 CArray<double,1> val(nb); 648 nb = 0; 649 /* for (size_t idx = 0; idx < n; ++idx) 650 { 651 size_t globalIndex = begin + idx; 652 if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) 653 { 654 val(nb) = value(idx); 655 ++nb; 656 } 657 }*/ 658 659 for (size_t idx = 0; idx < zoom_size; ++idx) 660 { 661 size_t globalZoomIndex = zoomByIndex() ? global_zoom_index(idx) : global_zoom_begin + idx; 662 if (globalZoomIndex >= begin && globalZoomIndex <= end) 663 { 664 val(nb) = value(globalZoomIndex-begin); 665 ++nb; 666 } 667 } 668 669 CArray<int, 1> writtenInd(nbWritten); 670 nbWritten = 0; 671 if (isCompressible_) 672 { 673 for (int idx = 0; idx < data_index.numElements(); ++idx) 674 { 675 int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n); 676 677 if (ind >= 0 && ind < n && mask(ind)) 678 { 679 ind += begin; 680 if (ind >= global_zoom_begin && ind <= zoom_end) 681 { 682 writtenInd(nbWritten) = ind; 683 ++nbWritten; 684 } 685 } 686 } 687 } 688 689 if (client->isServerLeader()) 690 { 691 std::list<CMessage> msgs; 692 693 const std::list<int>& ranks = client->getRanksServerLeader(); 694 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 695 { 696 msgs.push_back(CMessage()); 697 CMessage& msg = msgs.back(); 698 msg << this->getId(); 699 msg << val; 700 if (isCompressible_) 701 msg << writtenInd; 702 event.push(*itRank, 1, msg); 703 } 704 client->sendEvent(event); 705 } 706 else client->sendEvent(event); 707 } 708 709 void CAxis::sendDistributedValue(void) 710 { 711 int ns, n, i, j, ind, nv, idx; 712 CContext* context = CContext::getCurrent(); 713 CContextClient* client=context->client; 714 715 // send value for each connected server 716 CEventClient eventIndex(getType(), EVENT_ID_INDEX); 717 CEventClient eventVal(getType(), EVENT_ID_DISTRIBUTED_VALUE); 718 719 list<CMessage> list_msgsIndex, list_msgsVal; 720 list<CArray<int,1> > list_indi; 721 list<CArray<int,1> > list_writtenInd; 722 list<CArray<double,1> > list_val; 723 list<CArray<double,2> > list_bounds; 724 list<CArray<StdString,1> > list_label; 725 726 std::map<int, std::vector<size_t> >::const_iterator it, iteMap; 727 iteMap = indSrv_.end(); 728 for (int k = 0; k < connectedServerRank_.size(); ++k) 729 { 730 int nbData = 0; 731 int rank = connectedServerRank_[k]; 732 it = indSrv_.find(rank); 733 if (iteMap != it) 734 nbData = it->second.size(); 735 736 list_indi.push_back(CArray<int,1>(nbData)); 737 list_val.push_back(CArray<double,1>(nbData)); 738 739 if (hasBounds_) 740 { 741 list_bounds.push_back(CArray<double,2>(2,nbData)); 742 } 743 744 if (hasLabel) 745 { 746 list_label.push_back(CArray<StdString,1>(nbData)); 747 } 748 749 CArray<int,1>& indi = list_indi.back(); 750 CArray<double,1>& val = list_val.back(); 751 752 for (n = 0; n < nbData; ++n) 753 { 754 idx = static_cast<int>(it->second[n]); 755 ind = idx - begin; 756 757 val(n) = value(ind); 758 indi(n) = idx; 759 760 if (hasBounds_) 761 { 762 CArray<double,2>& boundsVal = list_bounds.back(); 763 boundsVal(0, n) = bounds(0,n); 764 boundsVal(1, n) = bounds(1,n); 765 } 766 767 if (hasLabel) 768 { 769 CArray<StdString,1>& labelVal = list_label.back(); 770 labelVal(n) = label(n); 771 } 772 } 773 774 list_msgsIndex.push_back(CMessage()); 775 list_msgsIndex.back() << this->getId() << list_indi.back(); 776 777 if (isCompressible_) 778 { 779 std::vector<int>& writtenIndSrc = indWrittenSrv_[rank]; 780 list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size())); 781 CArray<int,1>& writtenInd = list_writtenInd.back(); 782 783 for (n = 0; n < writtenInd.numElements(); ++n) 784 writtenInd(n) = writtenIndSrc[n]; 785 786 list_msgsIndex.back() << writtenInd; 787 } 788 789 list_msgsVal.push_back(CMessage()); 790 list_msgsVal.back() << this->getId() << list_val.back(); 791 792 if (hasBounds_) 793 { 794 list_msgsVal.back() << list_bounds.back(); 795 } 796 797 if (hasLabel) 798 { 799 list_msgsVal.back() << list_label.back(); 800 } 801 802 eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back()); 803 eventVal.push(rank, nbConnectedClients_[rank], list_msgsVal.back()); 804 } 805 806 client->sendEvent(eventIndex); 807 client->sendEvent(eventVal); 808 } 809 810 void CAxis::recvIndex(CEventServer& event) 811 { 812 CAxis* axis; 813 987 int ind = data_index(idx); 988 if (ind >= 0 && ind < nbIndex) 989 { 990 dataIndex(nbDataIndex) = ind; 991 ++nbDataIndex; 992 } 993 } 994 995 if (client->isServerLeader()) 996 { 997 std::list<CMessage> msgs; 998 999 const std::list<int>& ranks = client->getRanksServerLeader(); 1000 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1001 { 1002 msgs.push_back(CMessage()); 1003 CMessage& msg = msgs.back(); 1004 msg << this->getId(); 1005 msg << index.getValue() << dataIndex << mask.getValue(); 1006 msg << hasValue; 1007 if (hasValue) msg << value.getValue(); 1008 msg << hasBounds; 1009 if (hasBounds) msg << bounds.getValue(); 1010 msg << hasLabel; 1011 if (hasLabel) msg << label.getValue(); 1012 1013 event.push(*itRank, 1, msg); 1014 } 1015 client->sendEvent(event); 1016 } 1017 else client->sendEvent(event); 1018 } 1019 } 1020 1021 /* 1022 Receive the non-distributed attributes from another group of clients 1023 \param [in] event event containing data of these attributes 1024 */ 1025 void CAxis::recvNonDistributedAttributes(CEventServer& event) 1026 { 814 1027 list<CEventServer::SSubEvent>::iterator it; 815 1028 for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) … … 818 1031 string axisId; 819 1032 *buffer >> axisId; 820 axis = get(axisId); 821 axis->recvIndex(it->rank, *buffer); 822 } 823 824 if (axis->isCompressible_) 825 { 826 std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end()); 827 828 CContextServer* server = CContext::getCurrent()->server; 829 axis->numberWrittenIndexes_ = axis->indexesToWrite.size(); 830 MPI_Allreduce(&axis->numberWrittenIndexes_, &axis->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 831 MPI_Scan(&axis->numberWrittenIndexes_, &axis->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 832 axis->offsetWrittenIndexes_ -= axis->numberWrittenIndexes_; 833 } 834 } 835 836 void CAxis::recvIndex(int rank, CBufferIn& buffer) 837 { 838 buffer >> indiSrv_[rank]; 839 840 if (isCompressible_) 841 { 842 CArray<int, 1> writtenIndexes; 843 buffer >> writtenIndexes; 844 indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements()); 845 for (int i = 0; i < writtenIndexes.numElements(); ++i) 846 indexesToWrite.push_back(writtenIndexes(i)); 847 } 848 } 849 850 void CAxis::recvDistributedValue(CEventServer& event) 851 { 1033 get(axisId)->recvNonDistributedAttributes(it->rank, *buffer); 1034 } 1035 } 1036 1037 /* 1038 Receive the non-distributed attributes from another group of clients 1039 \param [in] rank rank of the sender 1040 \param [in] buffer buffer containing data sent from the sender 1041 */ 1042 void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer) 1043 { 1044 CArray<int,1> tmp_index, tmp_data_index, tmp_zoom_index; 1045 CArray<bool,1> tmp_mask; 1046 CArray<double,1> tmp_val; 1047 CArray<double,2> tmp_bnds; 1048 CArray<string,1> tmp_label; 1049 1050 buffer >> tmp_index; 1051 index.reference(tmp_index); 1052 buffer >> tmp_data_index; 1053 data_index.reference(tmp_data_index); 1054 buffer >> tmp_mask; 1055 mask.reference(tmp_mask); 1056 1057 buffer >> hasValue; 1058 if (hasValue) 1059 { 1060 buffer >> tmp_val; 1061 value.reference(tmp_val); 1062 } 1063 1064 buffer >> hasBounds; 1065 if (hasBounds) 1066 { 1067 buffer >> tmp_bnds; 1068 bounds.reference(tmp_bnds); 1069 } 1070 1071 buffer >> hasLabel; 1072 if (hasLabel) 1073 { 1074 buffer >> tmp_label; 1075 label.reference(tmp_label); 1076 } 1077 1078 // Some value should be reset here 1079 data_begin.setValue(0); 1080 globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 1081 // for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx); 1082 for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[index(idx)] = idx; 1083 } 1084 1085 /* 1086 Send attributes of axis from a group of client to other group of clients/servers 1087 on supposing that these attributes are distributed among the clients of the sending group 1088 In the future, if new attributes are added, they should also be processed in this function 1089 */ 1090 void CAxis::sendDistributedAttributes(void) 1091 { 1092 int ns, n, i, j, ind, nv, idx; 1093 std::list<CContextClient*>::iterator it; 1094 1095 for (it=clients.begin(); it!=clients.end(); ++it) 1096 { 1097 CContextClient* client = *it; 1098 int nbServer = client->serverSize; 1099 1100 CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES); 1101 1102 list<CMessage> listData; 1103 list<CArray<int,1> > list_indi, list_dataInd, list_zoomInd; 1104 list<CArray<bool,1> > list_mask; 1105 list<CArray<double,1> > list_val; 1106 list<CArray<double,2> > list_bounds; 1107 list<CArray<string,1> > list_label; 1108 1109 int nbIndex = index.numElements(); 1110 CArray<int,1> dataIndex(nbIndex); 1111 dataIndex = -1; 1112 for (idx = 0; idx < data_index.numElements(); ++idx) 1113 { 1114 if (0 <= data_index(idx) && data_index(idx) < nbIndex) 1115 dataIndex(idx) = 1; 1116 } 1117 1118 boost::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap; 1119 iteMap = indSrv_[nbServer].end(); 1120 for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k) 1121 { 1122 int nbData = 0; 1123 int rank = connectedServerRank_[nbServer][k]; 1124 it = indSrv_[nbServer].find(rank); 1125 if (iteMap != it) 1126 nbData = it->second.size(); 1127 1128 list_indi.push_back(CArray<int,1>(nbData)); 1129 list_dataInd.push_back(CArray<int,1>(nbData)); 1130 list_mask.push_back(CArray<bool,1>(nbData)); 1131 1132 if (hasValue) 1133 list_val.push_back(CArray<double,1>(nbData)); 1134 1135 if (hasBounds) 1136 list_bounds.push_back(CArray<double,2>(2,nbData)); 1137 1138 if (hasLabel) 1139 list_label.push_back(CArray<string,1>(nbData)); 1140 1141 CArray<int,1>& indi = list_indi.back(); 1142 CArray<int,1>& dataIndi = list_dataInd.back(); 1143 CArray<bool,1>& maskIndi = list_mask.back(); 1144 1145 for (n = 0; n < nbData; ++n) 1146 { 1147 idx = static_cast<int>(it->second[n]); 1148 indi(n) = idx; 1149 1150 ind = globalLocalIndexMap_[idx]; 1151 dataIndi(n) = dataIndex(ind); 1152 maskIndi(n) = mask(ind); 1153 1154 if (hasValue) 1155 { 1156 CArray<double,1>& val = list_val.back(); 1157 val(n) = value(ind); 1158 } 1159 1160 if (hasBounds) 1161 { 1162 CArray<double,2>& boundsVal = list_bounds.back(); 1163 boundsVal(0, n) = bounds(0,ind); 1164 boundsVal(1, n) = bounds(1,ind); 1165 } 1166 1167 if (hasLabel) 1168 { 1169 CArray<string,1>& labelVal = list_label.back(); 1170 labelVal(n) = label(ind); 1171 } 1172 } 1173 1174 listData.push_back(CMessage()); 1175 listData.back() << this->getId() 1176 << list_indi.back() << list_dataInd.back() << list_mask.back(); 1177 1178 listData.back() << hasValue; 1179 if (hasValue) 1180 listData.back() << list_val.back(); 1181 1182 listData.back() << hasBounds; 1183 if (hasBounds) 1184 listData.back() << list_bounds.back(); 1185 1186 listData.back() << hasLabel; 1187 if (hasLabel) 1188 listData.back() << list_label.back(); 1189 1190 eventData.push(rank, nbSenders[nbServer][rank], listData.back()); 1191 } 1192 1193 client->sendEvent(eventData); 1194 } 1195 } 1196 1197 /* 1198 Receive the distributed attributes from another group of clients 1199 \param [in] event event containing data of these attributes 1200 */ 1201 void CAxis::recvDistributedAttributes(CEventServer& event) 1202 { 1203 string axisId; 1204 vector<int> ranks; 1205 vector<CBufferIn*> buffers; 1206 852 1207 list<CEventServer::SSubEvent>::iterator it; 853 1208 for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 854 1209 { 1210 ranks.push_back(it->rank); 855 1211 CBufferIn* buffer = it->buffer; 856 string axisId;857 1212 *buffer >> axisId; 858 get(axisId)->recvDistributedValue(it->rank, *buffer); 859 } 860 } 861 862 void CAxis::recvDistributedValue(int rank, CBufferIn& buffer) 863 { 864 CArray<int,1> &indi = indiSrv_[rank]; 865 CArray<double,1> val; 866 CArray<double,2> boundsVal; 867 CArray<StdString,1> labelVal; 868 869 buffer >> val; 870 if (hasBounds_) buffer >> boundsVal; 871 if (hasLabel) buffer >> labelVal; 872 873 int i, j, ind_srv; 874 for (int ind = 0; ind < indi.numElements(); ++ind) 875 { 876 i = indi(ind); 877 ind_srv = i - zoom_begin_srv; 878 value_srv(ind_srv) = val(ind); 879 if (hasBounds_) 880 { 881 bound_srv(0,ind_srv) = boundsVal(0, ind); 882 bound_srv(1,ind_srv) = boundsVal(1, ind); 883 } 884 1213 buffers.push_back(buffer); 1214 } 1215 get(axisId)->recvDistributedAttributes(ranks, buffers); 1216 } 1217 1218 /* 1219 Receive the non-distributed attributes from another group of clients 1220 \param [in] ranks rank of the sender 1221 \param [in] buffers buffer containing data sent from the sender 1222 */ 1223 void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers) 1224 { 1225 int nbReceived = ranks.size(), idx, ind, gloInd, locInd; 1226 vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived), vec_zoomInd(nbReceived); 1227 vector<CArray<bool,1> > vec_mask(nbReceived); 1228 vector<CArray<double,1> > vec_val(nbReceived); 1229 vector<CArray<double,2> > vec_bounds(nbReceived); 1230 vector<CArray<string,1> > vec_label(nbReceived); 1231 1232 for (idx = 0; idx < nbReceived; ++idx) 1233 { 1234 CBufferIn& buffer = *buffers[idx]; 1235 buffer >> vec_indi[idx]; 1236 buffer >> vec_dataInd[idx]; 1237 buffer >> vec_mask[idx]; 1238 1239 buffer >> hasValue; 1240 if (hasValue) 1241 buffer >> vec_val[idx]; 1242 1243 buffer >> hasBounds; 1244 if (hasBounds) 1245 buffer >> vec_bounds[idx]; 1246 1247 buffer >> hasLabel; 885 1248 if (hasLabel) 886 { 887 label_srv(ind_srv) = labelVal( ind); 888 } 889 890 } 891 } 892 893 void CAxis::recvNonDistributedValue(CEventServer& event) 894 { 895 CAxis* axis; 896 897 list<CEventServer::SSubEvent>::iterator it; 898 for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 899 { 900 CBufferIn* buffer = it->buffer; 901 string axisId; 902 *buffer >> axisId; 903 axis = get(axisId); 904 axis->recvNonDistributedValue(it->rank, *buffer); 905 } 906 907 if (axis->isCompressible_) 908 { 909 std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end()); 910 911 axis->numberWrittenIndexes_ = axis->totalNumberWrittenIndexes_ = axis->indexesToWrite.size(); 912 axis->offsetWrittenIndexes_ = 0; 913 } 914 } 915 916 void CAxis::recvNonDistributedValue(int rank, CBufferIn& buffer) 917 { 918 CArray<double,1> val; 919 buffer >> val; 920 921 for (int ind = 0; ind < val.numElements(); ++ind) 922 { 923 value_srv(ind) = val(ind); 924 if (hasBounds_) 925 { 926 bound_srv(0,ind) = bounds(0,ind); 927 bound_srv(1,ind) = bounds(1,ind); 928 } 929 if (hasLabel) 930 { 931 label_srv(ind) = label(ind); 932 } 933 } 934 935 if (isCompressible_) 936 { 937 CArray<int, 1> writtenIndexes; 938 buffer >> writtenIndexes; 939 indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements()); 940 for (int i = 0; i < writtenIndexes.numElements(); ++i) 941 indexesToWrite.push_back(writtenIndexes(i)); 942 } 943 } 944 945 void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid, 946 CServerDistributionDescription::ServerDistributionType distType) 947 { 948 CContext* context = CContext::getCurrent(); 949 CContextClient* client = context->client; 950 int nbServer = client->serverSize; 951 952 CServerDistributionDescription serverDescription(globalDim, nbServer); 953 serverDescription.computeServerDistribution(); 954 955 std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin(); 956 std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes(); 957 958 CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT); 959 if (client->isServerLeader()) 960 { 961 std::list<CMessage> msgs; 962 963 const std::list<int>& ranks = client->getRanksServerLeader(); 964 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 965 { 966 // Use const int to ensure CMessage holds a copy of the value instead of just a reference 967 const int begin = serverIndexBegin[*itRank][orderPositionInGrid]; 968 const int ni = serverDimensionSizes[*itRank][orderPositionInGrid]; 969 const int end = begin + ni - 1; 970 const bool zoomIndex = zoomByIndex(); 971 972 msgs.push_back(CMessage()); 973 CMessage& msg = msgs.back(); 974 msg << this->getId(); 975 msg << ni << begin << end; 976 msg << global_zoom_begin.getValue() << global_zoom_n.getValue(); 977 msg << isCompressible_; 978 msg << zoomIndex; 979 if (zoomIndex) 980 msg << global_zoom_index.getValue(); 981 982 event.push(*itRank,1,msg); 983 } 984 client->sendEvent(event); 985 } 986 else client->sendEvent(event); 987 } 988 989 void CAxis::recvServerAttribut(CEventServer& event) 990 { 991 CBufferIn* buffer = event.subEvents.begin()->buffer; 992 string axisId; 993 *buffer >> axisId; 994 get(axisId)->recvServerAttribut(*buffer); 995 } 996 997 void CAxis::recvServerAttribut(CBufferIn& buffer) 998 { 999 int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_n_tmp; 1000 bool zoomIndex; 1001 CArray<int,1> zoom_index_recv; 1002 std::vector<int> zoom_index_tmp; 1003 std::vector<int>::iterator itZoomBeginSrv, itZoomEndSrv, itZoomSrv; 1004 1005 buffer >> ni_srv >> begin_srv >> end_srv; 1006 buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp; 1007 buffer >> isCompressible_; 1008 buffer >> zoomIndex; 1009 if (zoomIndex) 1010 { 1011 buffer >> zoom_index_recv; 1012 global_zoom_index.reference(zoom_index_recv); 1013 zoom_index_tmp.resize(global_zoom_index.numElements()); 1014 std::copy(global_zoom_index.begin(), global_zoom_index.end(), zoom_index_tmp.begin()); 1015 std::sort(zoom_index_tmp.begin(), zoom_index_tmp.end()); 1016 itZoomBeginSrv = std::lower_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), begin_srv); 1017 itZoomEndSrv = std::upper_bound(zoom_index_tmp.begin(), zoom_index_tmp.end(), end_srv); 1018 int sz = std::distance(itZoomBeginSrv, itZoomEndSrv); 1019 zoom_index_srv.resize(sz); 1020 itZoomSrv = itZoomBeginSrv; 1021 for (int i = 0; i < sz; ++i, ++itZoomSrv) 1022 { 1023 zoom_index_srv(i) = *(itZoomSrv); 1024 } 1025 } 1026 1027 global_zoom_begin = global_zoom_begin_tmp; 1028 global_zoom_n = global_zoom_n_tmp; 1029 int global_zoom_end = global_zoom_begin + global_zoom_n - 1; 1030 1031 zoom_begin_srv = zoomIndex ? std::distance(itZoomBeginSrv, zoom_index_tmp.begin()) 1032 : global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ; 1033 zoom_end_srv = zoomIndex ? std::distance(zoom_index_tmp.begin(), itZoomEndSrv) - 1 1034 : global_zoom_end < end_srv ? global_zoom_end : end_srv ; 1035 zoom_size_srv = zoom_end_srv - zoom_begin_srv + 1; 1036 1037 global_zoom_begin_srv = zoomIndex ? 0 : global_zoom_begin ; 1038 global_zoom_size_srv = zoomIndex ? zoom_index_tmp.size() : global_zoom_n; 1039 1040 if (zoom_size_srv<=0) 1041 { 1042 zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0; 1043 } 1044 1045 if (n_glo == n) 1046 { 1047 zoom_begin_srv = zoomIndex ? std::distance(itZoomBeginSrv, zoom_index_tmp.begin()) 1048 : global_zoom_begin; 1049 zoom_size_srv = zoomIndex ? zoom_index_tmp.size() 1050 : global_zoom_n; 1051 } 1249 buffer >> vec_label[idx]; 1250 } 1251 1252 // Estimate size of index array 1253 int nbIndexGlob = 0; 1254 for (idx = 0; idx < nbReceived; ++idx) 1255 { 1256 nbIndexGlob += vec_indi[idx].numElements(); 1257 } 1258 1259 // Recompute global index 1260 // Take account of the overlapped index 1261 index.resize(nbIndexGlob); 1262 globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 1263 nbIndexGlob = 0; 1264 for (idx = 0; idx < nbReceived; ++idx) 1265 { 1266 CArray<int,1>& tmp = vec_indi[idx]; 1267 for (ind = 0; ind < tmp.numElements(); ++ind) 1268 { 1269 gloInd = tmp(ind); 1270 if (0 == globalLocalIndexMap_.count(gloInd)) 1271 { 1272 index(nbIndexGlob) = gloInd % n_glo; 1273 globalLocalIndexMap_[gloInd] = nbIndexGlob; 1274 ++nbIndexGlob; 1275 } 1276 } 1277 } 1278 1279 // Resize index to its real size 1280 if (nbIndexGlob==0) index.resize(nbIndexGlob) ; 1281 else index.resizeAndPreserve(nbIndexGlob); 1282 1283 int nbData = nbIndexGlob; 1284 CArray<int,1> nonCompressedData(nbData); 1285 nonCompressedData = -1; 1286 mask.resize(nbData); 1052 1287 if (hasValue) 1053 { 1054 value_srv.resize(zoom_size_srv); 1055 if (hasBounds_) bound_srv.resize(2,zoom_size_srv); 1056 if (hasLabel) label_srv.resize(zoom_size_srv); 1057 } 1288 value.resize(nbData); 1289 if (hasBounds) 1290 bounds.resize(2,nbData); 1291 if (hasLabel) 1292 label.resize(nbData); 1293 1294 nbData = 0; 1295 for (idx = 0; idx < nbReceived; ++idx) 1296 { 1297 CArray<int,1>& indi = vec_indi[idx]; 1298 CArray<int,1>& dataIndi = vec_dataInd[idx]; 1299 CArray<bool,1>& maskIndi = vec_mask[idx]; 1300 int nb = indi.numElements(); 1301 for (int n = 0; n < nb; ++n) 1302 { 1303 locInd = globalLocalIndexMap_[size_t(indi(n))]; 1304 1305 nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd); 1306 1307 if (!mask(locInd)) // Only rewrite mask if it's not true 1308 mask(locInd) = maskIndi(n); 1309 1310 if (hasValue) 1311 value(locInd) = vec_val[idx](n); 1312 1313 if (hasBounds) 1314 { 1315 bounds(0,locInd) = vec_bounds[idx](0,n); 1316 bounds(1,locInd) = vec_bounds[idx](1,n); 1317 } 1318 1319 if (hasLabel) 1320 label(locInd) = vec_label[idx](n); 1321 } 1322 } 1323 1324 int nbCompressedData = 0; 1325 for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 1326 { 1327 if (0 <= nonCompressedData(idx)) 1328 ++nbCompressedData; 1329 } 1330 1331 data_index.resize(nbCompressedData); 1332 nbCompressedData = 0; 1333 for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 1334 { 1335 if (0 <= nonCompressedData(idx)) 1336 { 1337 data_index(nbCompressedData) = idx % n; 1338 ++nbCompressedData; 1339 } 1340 } 1341 1342 data_begin.setValue(0); 1058 1343 } 1059 1344 … … 1090 1375 } 1091 1376 1377 /* 1378 Add transformation into axis. This function only servers for Fortran interface 1379 \param [in] transType transformation type 1380 \param [in] id identifier of the transformation object 1381 */ 1092 1382 CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id) 1093 1383 { … … 1096 1386 } 1097 1387 1388 /* 1389 Check whether an axis has (spatial) transformation 1390 */ 1098 1391 bool CAxis::hasTransformation() 1099 1392 { … … 1101 1394 } 1102 1395 1396 /* 1397 Set transformation 1398 \param [in] axisTrans transformation to set 1399 */ 1103 1400 void CAxis::setTransformations(const TransMapTypes& axisTrans) 1104 1401 { … … 1106 1403 } 1107 1404 1405 /* 1406 Return all transformation held by the axis 1407 \return transformation the axis has 1408 */ 1108 1409 CAxis::TransMapTypes CAxis::getAllTransformations(void) 1109 1410 { … … 1111 1412 } 1112 1413 1414 /* 1415 Duplicate transformation of another axis 1416 \param [in] src axis whose transformations are copied 1417 */ 1113 1418 void CAxis::duplicateTransformation(CAxis* src) 1114 1419 { … … 1140 1445 } 1141 1446 1447 void CAxis::setContextClient(CContextClient* contextClient) 1448 { 1449 if (clientsSet.find(contextClient)==clientsSet.end()) 1450 { 1451 clients.push_back(contextClient) ; 1452 clientsSet.insert(contextClient); 1453 } 1454 } 1455 1142 1456 void CAxis::parse(xml::CXMLNode & node) 1143 1457 {
Note: See TracChangeset
for help on using the changeset viewer.