/*! \file server_distribution_description.hpp \author Ha NGUYEN \since 04 Jan 2015 \date 24 Jul 2015 \brief Description of index distribution on server(s). */ #include "server_distribution_description.hpp" #include "exception.hpp" namespace xios { CServerDistributionDescription::CServerDistributionDescription(const std::vector& globalDimensionSize) : nGlobal_(globalDimensionSize), indexBegin_(), dimensionSizes_(), globalIndex_(), vecGlobalIndex_() { } CServerDistributionDescription::~CServerDistributionDescription() { /* Nothing to do */ } /*! Compute pre-defined global index distribution of server(s). \param [in] nServer number of server \param [in] doComputeGlobalIndex flag to compute global index on each server. By default, false \param [in] serType type of server distribution. For now, we can distribute server by band or plan */ void CServerDistributionDescription::computeServerDistribution(int nServer, int positionDimensionDistributed, bool doComputeGlobalIndex, ServerDistributionType serType) { switch (serType) { 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, ServerDistributionType distributionType) { switch (distributionType) { 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(); 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_; } } // namespace xios