/*! \file server_distribution_description.hpp \author Ha NGUYEN \since 04 Jan 2015 \date 11 Jan 2016 \brief Description of index distribution on server(s). */ #include "server_distribution_description.hpp" #include "exception.hpp" namespace xios { /*! \param [in] globalDimensionSize global dimension of grid \param [in] nServer number of server \param [in] serType type of server distribution. For now, we can distribute server by band or plan */ CServerDistributionDescription::CServerDistributionDescription(const std::vector& globalDimensionSize, int nServer, ServerDistributionType serType) : nGlobal_(globalDimensionSize), indexBegin_(), dimensionSizes_(), globalIndex_(), vecGlobalIndex_(), serverType_(serType), nServer_(nServer), positionDimensionDistributed_(1) { } CServerDistributionDescription::~CServerDistributionDescription() { /* Nothing to do */ } /*! Compute pre-defined global index distribution of server(s). \param [in] doComputeGlobalIndex flag to compute global index on each server. By default, false */ void CServerDistributionDescription::computeServerDistribution(bool doComputeGlobalIndex, int positionDimensionDistributed) { switch (serverType_) { case BAND_DISTRIBUTION: computeBandDistribution(nServer_, positionDimensionDistributed); break; default: break; } if (doComputeGlobalIndex) { vecGlobalIndex_.resize(nServer_); int dim = nGlobal_.size(); std::vector currentIndex(dim); for (int idxServer = 0; idxServer < nServer_; ++idxServer) { size_t ssize = 1, idx = 0; for (int j = 0; j < dim; ++j) ssize *= dimensionSizes_[idxServer][j]; vecGlobalIndex_[idxServer].resize(ssize); std::vector idxLoop(dim,0); int innerLoopSize = dimensionSizes_[idxServer][0]; while (idx& indexBeginEnd, int positionDimensionDistributed) { switch (serverType_) { case BAND_DISTRIBUTION: computeBandDistribution(nServer_, positionDimensionDistributed); break; default: break; } size_t indexBegin = indexBeginEnd.first; size_t indexEnd = indexBeginEnd.second; if (indexBegin > indexEnd) ERROR("CServerDistributionDescription::computeServerGlobalIndexInRange", << "Index begin is larger than index end"); int dim = nGlobal_.size(); std::vector currentIndex(dim); for (int idxServer = 0; idxServer < nServer_; ++idxServer) { size_t ssize = 1, idx = 0; for (int j = 0; j < dim; ++j) ssize *= dimensionSizes_[idxServer][j]; std::vector idxLoop(dim,0); int innerLoopSize = dimensionSizes_[idxServer][0]; while (idx(globalIndex, idxServer)); ++idx; } idxLoop[0] += innerLoopSize; } } } /*! Compute global index of servers with band distribution \param [in] nServer number of server */ void CServerDistributionDescription::computeBandDistribution(int nServer, int positionDimensionDistributed) { int dim = nGlobal_.size(); positionDimensionDistributed_ = positionDimensionDistributed; if (1 == dim) positionDimensionDistributed_ = 0; if (positionDimensionDistributed_ > dim) ERROR("CServerDistributionDescription::computeBandDistribution(int nServer, int positionDimensionDistributed)", << "Position of distributed dimension is invalid" << std::endl << "Position of distributed dimension is " << positionDimensionDistributed_ << "Dimension " << dim) indexBegin_.resize(nServer); dimensionSizes_.resize(nServer); for (int i = 0; i< nServer; ++i) { indexBegin_[i].resize(dim); dimensionSizes_[i].resize(dim); } int njRangeSize; int nGlobTemp = 0; std::vector njRangeBegin(nServer,0); std::vector njRangeEnd(nServer,0); int positionDistributed = (1 > CServerDistributionDescription::getServerDimensionSizes() const { return dimensionSizes_; } /*! Get index begin of each dimension on distributed server \return index begin of dimensions on server(s) */ std::vector > CServerDistributionDescription::getServerIndexBegin() const { return indexBegin_; } /*! Get global index on distributed server \return global index on server(s) */ const std::vector >& CServerDistributionDescription::getGlobalIndex() const { return vecGlobalIndex_; } /*! Get global index calculated by computeServerGlobalIndexInRange */ const boost::unordered_map& CServerDistributionDescription::getGlobalIndexRange() const { return globalIndex_; } int CServerDistributionDescription::getDimensionDistributed() { return ((1