/*! \file distribution_server.cpp \author Ha NGUYEN \since 13 Jan 2015 \date 10 Sep 2016 \brief Index distribution on server side. */ #include "distribution_server.hpp" #include "utils.hpp" namespace xios { CDistributionServer::CDistributionServer(int rank, const std::vector& nZoomBegin, const std::vector& nZoomSize, const std::vector& nZoomBeginGlobal, const std::vector& nGlobal) : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_() { createGlobalIndex(); } CDistributionServer::CDistributionServer(int rank, const std::vector >& globalIndexElements, const CArray& elementOrder, const std::vector& nZoomBegin, const std::vector& nZoomSize, const std::vector& nZoomBeginGlobal, const std::vector& nGlobal) : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_() { createGlobalIndex(globalIndexElements, elementOrder); } CDistributionServer::~CDistributionServer() { } /*! Create global index on server side Like the similar function on client side, this function serves on creating global index for data written by the server. The global index is used to calculating local index of data written on each server */ void CDistributionServer::createGlobalIndex() { size_t idx = 0, ssize = 1; for (int i = 0; i < nZoomSize_.size(); ++i) ssize *= nZoomSize_[i]; this->globalIndex_.resize(ssize); std::vector idxLoop(this->getDims(),0); std::vector currentIndex(this->getDims()); int innerLoopSize = nZoomSize_[0]; globalLocalIndexMap_.rehash(std::ceil(ssize/globalLocalIndexMap_.max_load_factor())); while (idxdims_-1; ++i) { if (idxLoop[i] == nZoomSize_[i]) { idxLoop[i] = 0; ++idxLoop[i+1]; } } for (int i = 1; i < this->dims_; ++i) currentIndex[i] = idxLoop[i] + nZoomBegin_[i]; size_t mulDim, globalIndex; for (int i = 0; i < innerLoopSize; ++i) { mulDim = 1; globalIndex = i + nZoomBegin_[0]; for (int k = 1; k < this->dims_; ++k) { mulDim *= nGlobal_[k-1]; globalIndex += (currentIndex[k])*mulDim; } globalLocalIndexMap_[globalIndex] = idx; this->globalIndex_(idx) = globalIndex; ++idx; } idxLoop[0] += innerLoopSize; } } /*! Create global index on server side Like the similar function on client side, this function serves on creating global index for data written by the server. The global index is used to calculating local index of data written on each server \param[in] globalIndexElement global index on server side of each element of grid (scalar, axis, domain) \param[in] elementOrder the order of elements of grid (e.x: domain->axis or domain->scalar) */ void CDistributionServer::createGlobalIndex(const std::vector >& globalIndexElements, const CArray& elementOrder) { int numElement = elementOrder.numElements(), elementIdx = 0; std::vector indexMap(numElement); for (int i = 0; i < numElement; ++i) { indexMap[i] = elementIdx; if (2 == elementOrder(i)) { elementIdx += 2; } else ++elementIdx; } std::vector elementGlobalSize(numElement); size_t globalSize = 1; for (int i = 0; i < numElement; ++i) { int elementType = elementOrder(i); elementGlobalSize[i] = globalSize; if (2 == elementType) // domain { globalSize *= nGlobal_[indexMap[i]+1] * nGlobal_[indexMap[i]]; } else // axis or scalar { globalSize *= nGlobal_[indexMap[i]]; } } size_t ssize = 1; for (int i = 0; i < globalIndexElements.size(); ++i) ssize *= globalIndexElements[i].numElements(); this->globalIndex_.resize(ssize); globalLocalIndexMap_.rehash(std::ceil(ssize/globalLocalIndexMap_.max_load_factor())); std::vector idxLoop(numElement,0); std::vector currentIndex(numElement); int innerLoopSize = globalIndexElements[0].numElements(); size_t idx = 0; while (idxglobalIndex_(idx) = globalIndex; ++idx; } idxLoop[0] += innerLoopSize; } } /*! Compute local index for writing data on server \param [in] globalIndex Global index received from client */ void CDistributionServer::computeLocalIndex(CArray& globalIndex) { size_t ssize = globalIndex.numElements(); size_t localIndexSize = std::min(globalIndex_.numElements(), ssize); CArray localIndex(localIndexSize); GlobalLocalMap::const_iterator ite = globalLocalIndexMap_.end(), it; int i = 0; for (size_t idx = 0; idx < ssize; ++idx) { it = globalLocalIndexMap_.find(globalIndex(idx)); if (ite != it) { localIndex(i) = it->second; ++i; } } globalIndex.reference(localIndex); } /*! Transforms local indexes owned by the server into global indexes \param [in/out] indexes on input, local indexes of the server, on output, the corresponding global indexes */ void CDistributionServer::computeGlobalIndex(CArray& indexes) const { for (int i = 0; i < indexes.numElements(); ++i) { indexes(i) = globalIndex_(indexes(i)); } } /*! Get the size of grid index in server (e.x: sizeGrid *= size of each dimensiion) */ int CDistributionServer::getGridSize() const { return globalLocalIndexMap_.size(); } const std::vector& CDistributionServer::getZoomBeginGlobal() const { return nZoomBeginGlobal_; } const std::vector& CDistributionServer::getZoomBeginServer() const { return nZoomBegin_; } const std::vector& CDistributionServer::getZoomSizeServer() const { return nZoomSize_; } void CDistributionServer::partialClear(void) { GlobalLocalMap void1 ; globalLocalIndexMap_.swap(void1) ; } } // namespace xios