void saveFull( MultiBlock2D& multiBlock, FileName fName, IndexOrdering::OrderingT ordering ) { global::profiler().start("io"); SparseBlockStructure2D blockStructure(multiBlock.getBoundingBox()); Box2D bbox = multiBlock.getBoundingBox(); if (ordering==IndexOrdering::forward) { plint nBlocks = std::min(bbox.getNx(), (plint)global::mpi().getSize()); std::vector<std::pair<plint,plint> > ranges; util::linearRepartition(bbox.x0, bbox.x1, nBlocks, ranges); for (pluint iRange=0; iRange<ranges.size(); ++iRange) { blockStructure.addBlock ( Box2D( ranges[iRange].first, ranges[iRange].second, bbox.y0, bbox.y1 ), iRange ); } } else if (ordering==IndexOrdering::backward) { plint nBlocks = std::min(bbox.getNy(), (plint)global::mpi().getSize()); std::vector<std::pair<plint,plint> > ranges; util::linearRepartition(bbox.y0, bbox.y1, nBlocks, ranges); for (pluint iRange=0; iRange<ranges.size(); ++iRange) { blockStructure.addBlock ( Box2D( bbox.x0, bbox.x1, ranges[iRange].first, ranges[iRange].second ), iRange ); } } else { // Sparse ordering not defined. PLB_ASSERT( false ); } plint envelopeWidth=1; MultiBlockManagement2D adjacentMultiBlockManagement ( blockStructure, new OneToOneThreadAttribution, envelopeWidth ); MultiBlock2D* multiAdjacentBlock = multiBlock.clone(adjacentMultiBlockManagement); std::vector<plint> offset; std::vector<plint> myBlockIds; std::vector<std::vector<char> > data; bool dynamicContent = false; dumpData(*multiAdjacentBlock, dynamicContent, offset, myBlockIds, data); if (ordering==IndexOrdering::backward && myBlockIds.size()==1) { PLB_ASSERT( data.size()==1 ); Box2D domain; blockStructure.getBulk(myBlockIds[0], domain); plint sizeOfCell = multiAdjacentBlock->sizeOfCell(); PLB_ASSERT( domain.nCells()*sizeOfCell == (plint)data[0].size() ); transposeToBackward( sizeOfCell, domain, data[0] ); } plint totalSize = offset[offset.size()-1]; writeOneBlockXmlSpec(*multiAdjacentBlock, fName, totalSize, ordering); writeRawData(fName, myBlockIds, offset, data); delete multiAdjacentBlock; global::profiler().stop("io"); }
void transposeToBackward(plint sizeOfCell, Box2D const& domain, std::vector<char>& data) { plint nx = domain.getNx(); plint ny = domain.getNy(); std::vector<char> transp(data.size()); for (plint iX=0; iX<nx; ++iX) { for (plint iY=0; iY<ny; ++iY) { plint iForward = sizeOfCell*(iY + ny*iX); plint iBackward = sizeOfCell*(iX + nx*iY); for (plint iByte=0; iByte<sizeOfCell; ++iByte) { transp[iBackward+iByte] = data[iForward+iByte]; } } } transp.swap(data); }
plint Parallelizer2D::computeCost(std::vector<std::vector<Box2D> > const& originalBlocks, Box2D box){ plint totalCost = 0; plint numLevels = originalBlocks.size(); for (plint iLevel=(plint)originalBlocks.size()-1; iLevel>=0; --iLevel){ // convert the box to the current level Box2D levelBox = global::getDefaultMultiScaleManager().scaleBox(box,iLevel-(numLevels-1)); for (pluint iComp=0; iComp<originalBlocks[iLevel].size(); ++iComp){ Box2D currentBox; if (intersect(originalBlocks[iLevel][iComp], levelBox, currentBox)){ plint volume = currentBox.getNx()*currentBox.getNy(); totalCost += (plint) util::twoToThePower(iLevel) * volume; } } } return totalCost; }