/*! \file distribution_server.cpp \author Ha NGUYEN \since 13 Jan 2015 \date 04 Feb 2015 \brief Index distribution on server side. */ #include "distribution_server.hpp" #include "utils.hpp" namespace xios { CDistributionServer::CDistributionServer(int rank, int dims, const CArray& globalIndex) : CDistribution(rank, dims, globalIndex), nGlobal_(), nZoomSize_(), nZoomBegin_() { } CDistributionServer::CDistributionServer(int rank, const std::vector& nZoomBegin, const std::vector& nZoomSize, const std::vector& nGlobal) : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin) { createGlobalIndex(); } 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) { createGlobalIndex(); } 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]; 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; } this->globalIndex_(idx) = globalIndex; ++idx; } idxLoop[0] += innerLoopSize; } } /*! Compute local index for writing data on server \param [in] globalIndex global index received from client \return local index of written data */ CArray CDistributionServer::computeLocalIndex(const CArray& globalIndex) { int ssize = globalIndex.numElements(); int nbGlobalIndex = this->globalIndex_.numElements(); std::vector::iterator it; std::vector permutIndex(nbGlobalIndex); XIOSAlgorithms::fillInIndex(nbGlobalIndex, permutIndex); XIOSAlgorithms::sortWithIndex(this->globalIndex_, permutIndex); typedef XIOSBinarySearchWithIndex BinarySearch; BinarySearch binarySearch(this->globalIndex_); CArray localIndex(ssize); int idx = 0; for (int i = 0; i < ssize; ++i) { if (binarySearch.search(permutIndex.begin(), permutIndex.end(), globalIndex(i), it)) { localIndex(idx) = *it; ++idx; } } return localIndex; } /*! Compute local index for writing data on server \param [in] globalIndex Global index received from client */ void CDistributionServer::computeLocalIndex(CArray& globalIndex) { int ssize = globalIndex.numElements(); int nbGlobalIndex = this->globalIndex_.numElements(); std::vector::iterator it; std::vector permutIndex(nbGlobalIndex); XIOSAlgorithms::fillInIndex(nbGlobalIndex, permutIndex); XIOSAlgorithms::sortWithIndex(this->globalIndex_, permutIndex); typedef XIOSBinarySearchWithIndex BinarySearch; BinarySearch binarySearch(this->globalIndex_); CArray localIndex(ssize); int idx = 0; for (int i = 0; i < ssize; ++i) { if (binarySearch.search(permutIndex.begin(), permutIndex.end(), globalIndex(i), it)) { localIndex(idx) = *it; ++idx; } } globalIndex = 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)); } } const std::vector& CDistributionServer::getZoomBeginGlobal() const { return nZoomBeginGlobal_; } const std::vector& CDistributionServer::getZoomBeginServer() const { return nZoomBegin_; } const std::vector& CDistributionServer::getZoomSizeServer() const { return nZoomSize_; } } // namespace xios