Changeset 1216
- Timestamp:
- 07/17/17 16:16:11 (7 years ago)
- Location:
- XIOS/dev/XIOS_DEV_CMIP6/src/transformation
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/XIOS_DEV_CMIP6/src/transformation/generic_algorithm_transformation.cpp
r1201 r1216 12 12 #include "client_client_dht_template.hpp" 13 13 #include "utils.hpp" 14 #include "timer.hpp" 14 15 15 16 namespace xios { … … 17 18 CGenericAlgorithmTransformation::CGenericAlgorithmTransformation() 18 19 : transformationMapping_(), transformationWeight_(), transformationPosition_(), 19 idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA) 20 idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA), indexElementSrc_(), 21 computedProcSrcNonTransformedElement_(false) 20 22 { 21 23 } … … 130 132 131 133 typedef boost::unordered_map<int, std::vector<std::pair<int,double> > > SrcToDstMap; 132 133 size_t indexSrcSize = 0; 134 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 135 { 136 TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 137 iteTransMap = transformationMapping_[idxTrans].end(); 138 TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 139 140 itTransWeight = itbTransWeight; 141 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 142 { 143 indexSrcSize += (itTransMap->second).size(); 144 } 145 } 146 147 bool isTransPosEmpty = transformationPosition_.empty(); 148 CArray<size_t,1> transPos; 149 if (!isTransPosEmpty) transPos.resize(transformationMapping_.size()); 150 CArray<size_t,1> indexSrc(indexSrcSize); 151 indexSrcSize = 0; 152 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 153 { 154 TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 155 iteTransMap = transformationMapping_[idxTrans].end(); 156 TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 157 158 // Build mapping between global source element index and global destination element index. 159 itTransWeight = itbTransWeight; 160 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 161 { 162 const std::vector<int>& srcIndex = itTransMap->second; 163 for (int idx = 0; idx < srcIndex.size(); ++idx) 164 { 165 indexSrc(indexSrcSize) = srcIndex[idx]; 166 ++indexSrcSize; 167 } 168 } 169 170 if (!isTransPosEmpty) 171 { 172 TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(); 173 transPos(idxTrans) = itPosMap->second[0]; 174 } 175 } 134 int idx; 176 135 177 136 // compute position of elements on grids … … 184 143 std::vector<CAxis*> axisListSrcP = gridSrc->getAxis(); 185 144 std::vector<CDomain*> domainListSrcP = gridSrc->getDomains(); 186 CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 187 188 // Find out global index source of transformed element on corresponding process. 189 std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc(axisDomainDstOrder.numElements()); 190 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc; 191 for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 192 { 193 if (idx == elementPositionInGrid) 194 computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]); 195 if (2 == axisDomainDstOrder(idx)) // It's domain 196 { 197 if (idx != elementPositionInGrid) 198 computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]], 199 domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]], 200 transPos, 201 globalElementIndexOnProc[idx]); 202 203 } 204 else if (1 == axisDomainDstOrder(idx))//it's an axis 205 { 206 if (idx != elementPositionInGrid) 207 computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]], 208 axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]], 209 transPos, 210 globalElementIndexOnProc[idx]); 211 } 212 else //it's a scalar 213 { 214 if (idx != elementPositionInGrid) 215 computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]], 216 scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]], 217 transPos, 218 globalElementIndexOnProc[idx]); 219 220 } 221 } 222 223 if (!isTransPosEmpty) 224 { 225 for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx) 226 { 227 if (idx != elementPositionInGrid) 228 { 229 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it, 230 ite = globalElementIndexOnProc[idx].end(); 231 for (it = itb; it != ite; ++it) it->second.resize(1); 232 } 233 } 234 } 235 145 CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 146 147 bool isTransPosEmpty = transformationPosition_.empty(); 148 CArray<size_t,1> transPos; 149 if (!isTransPosEmpty) transPos.resize(transformationMapping_.size()); 150 std::set<size_t> allIndexSrc; 151 152 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 153 { 154 TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap, 155 iteTransMap = transformationMapping_[idxTrans].end(); 156 TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight; 157 158 // Build mapping between global source element index and global destination element index. 159 itTransWeight = itbTransWeight; 160 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) 161 { 162 const std::vector<int>& srcIndex = itTransMap->second; 163 for (idx = 0; idx < srcIndex.size(); ++idx) 164 allIndexSrc.insert(srcIndex[idx]); 165 } 166 167 if (!isTransPosEmpty) 168 { 169 TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin(); 170 transPos(idxTrans) = itPosMap->second[0]; 171 } 172 } 173 174 size_t indexSrcSize = 0; 175 CArray<size_t,1> indexSrc(allIndexSrc.size()); 176 for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it, ++indexSrcSize) 177 indexSrc(indexSrcSize) = *it; 178 179 // Flag to indicate whether we will recompute distribution of source global index on processes 180 bool computeGlobalIndexOnProc = false; 181 if (indexElementSrc_.size() != allIndexSrc.size()) 182 computeGlobalIndexOnProc = true; 183 else 184 { 185 for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it) 186 if (0 == indexElementSrc_.count(*it)) 187 { 188 computeGlobalIndexOnProc = true; 189 break; 190 } 191 } 192 193 if (computeGlobalIndexOnProc) 194 indexElementSrc_.swap(allIndexSrc); 195 196 int sendValue = (computeGlobalIndexOnProc) ? 1 : 0; 197 int recvValue = 0; 198 MPI_Allreduce(&sendValue, &recvValue, 1, MPI_INT, MPI_SUM, client->intraComm); 199 computeGlobalIndexOnProc = (1 == recvValue); 200 201 if (computeGlobalIndexOnProc) 202 { 203 // Find out global index source of transformed element on corresponding process. 204 if (globalElementIndexOnProc_.empty()) 205 globalElementIndexOnProc_.resize(axisDomainDstOrder.numElements()); 206 CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc; 207 for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx) 208 { 209 if (idx == elementPositionInGrid) 210 computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]); 211 if (!computedProcSrcNonTransformedElement_) 212 { 213 if (2 == axisDomainDstOrder(idx)) // It's domain 214 { 215 if (idx != elementPositionInGrid) 216 computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]], 217 domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]], 218 transPos, 219 globalElementIndexOnProc_[idx]); 220 221 } 222 else if (1 == axisDomainDstOrder(idx))//it's an axis 223 { 224 if (idx != elementPositionInGrid) 225 computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]], 226 axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]], 227 transPos, 228 globalElementIndexOnProc_[idx]); 229 } 230 else //it's a scalar 231 { 232 if (idx != elementPositionInGrid) 233 computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]], 234 scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]], 235 transPos, 236 globalElementIndexOnProc_[idx]); 237 238 } 239 } 240 } 241 242 if (!isTransPosEmpty && !computedProcSrcNonTransformedElement_) 243 { 244 for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 245 { 246 if (idx != elementPositionInGrid) 247 { 248 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 249 ite = globalElementIndexOnProc_[idx].end(); 250 for (it = itb; it != ite; ++it) it->second.resize(1); 251 } 252 } 253 } 254 255 if (!computedProcSrcNonTransformedElement_) 256 { 257 for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 258 { 259 if (idx != elementPositionInGrid) 260 { 261 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 262 ite = globalElementIndexOnProc_[idx].end(); 263 for (it = itb; it != ite; ++it) procOfNonTransformedElements_.insert(it->first); 264 if (procOfNonTransformedElements_.size() == nbClient) 265 break; 266 } 267 } 268 } 269 270 // Processes contain the source index of transformed element 271 std::set<int> procOfTransformedElement; 272 CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc.begin(), 273 itIdxe = globalIndexOfTransformedElementOnProc.end(), itIdx; 274 for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx) 275 { 276 std::vector<int>& tmp = itIdx->second; 277 for (int i = 0; i < tmp.size(); ++i) 278 procOfTransformedElement.insert(tmp[i]); 279 if (tmp.size() == nbClient) 280 break; 281 } 282 283 std::set<int>& commonProc = (procOfTransformedElement.size() < procOfNonTransformedElements_.size()) ? procOfTransformedElement 284 : (!procOfNonTransformedElements_.empty() ? procOfNonTransformedElements_ : procOfTransformedElement); 285 286 std::vector<int> procContainSrcElementIdx(commonProc.size()); 287 int count = 0; 288 for (std::set<int>::iterator it = commonProc.begin(); it != commonProc.end(); ++it) 289 procContainSrcElementIdx[count++] = *it; 290 291 procContainSrcElementIdx_.swap(procContainSrcElementIdx); 292 293 // For the first time, surely we calculate proc containing non transformed elements 294 if (!computedProcSrcNonTransformedElement_) 295 computedProcSrcNonTransformedElement_ = true; 296 } 297 236 298 for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans) 237 299 { … … 243 305 244 306 // Build mapping between global source element index and global destination element index. 245 boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc [elementPositionInGrid]);246 boost::unordered_map<int,int> tmpCounter;307 boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc_[elementPositionInGrid]); 308 std::set<int> tmpCounter; 247 309 itTransWeight = itbTransWeight; 248 310 for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight) … … 250 312 const std::vector<int>& srcIndex = itTransMap->second; 251 313 const std::vector<double>& weight = itTransWeight->second; 252 for (i nt idx = 0; idx < srcIndex.size(); ++idx)314 for (idx = 0; idx < srcIndex.size(); ++idx) 253 315 { 254 316 src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx])); 255 if (1 == globalIndexOfTransformedElementOnProc.count(srcIndex[idx]) && (0 == tmpCounter.count(srcIndex[idx]))) 256 { 257 tmpCounter[srcIndex[idx]] = 1; 258 std::vector<int>& srcProc = globalIndexOfTransformedElementOnProc[srcIndex[idx]]; 259 for (int j = 0; j < srcProc.size(); ++j) 260 globalElementIndexOnProc[elementPositionInGrid][srcProc[j]].push_back(srcIndex[idx]); 261 } 262 } 263 } 264 317 if (0 == tmpCounter.count(srcIndex[idx])) 318 { 319 tmpCounter.insert(srcIndex[idx]); 320 for (int j = 0; j < procContainSrcElementIdx_.size(); ++j) 321 globalElementIndexOnProc_[elementPositionInGrid][procContainSrcElementIdx_[j]].push_back(srcIndex[idx]); 322 } 323 } 324 } 325 265 326 if (!isTransPosEmpty) 266 327 { 267 for (i nt idx = 0; idx < globalElementIndexOnProc.size(); ++idx)328 for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx) 268 329 { 269 330 if (idx != elementPositionInGrid) 270 331 { 271 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc [idx].begin(), it,272 ite = globalElementIndexOnProc [idx].end();332 boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it, 333 ite = globalElementIndexOnProc_[idx].end(); 273 334 for (it = itb; it != ite; ++it) it->second[0] = transPos(idxTrans); 274 335 } 275 336 } 276 }277 278 std::vector<std::vector<bool> > elementOnProc(axisDomainDstOrder.numElements(), std::vector<bool>(nbClient, false));279 boost::unordered_map<int,std::vector<size_t> >::const_iterator it, itb, ite;280 for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)281 {282 itb = globalElementIndexOnProc[idx].begin();283 ite = globalElementIndexOnProc[idx].end();284 for (it = itb; it != ite; ++it) elementOnProc[idx][it->first] = true;285 }286 287 // Determine procs which contain global source index288 std::vector<bool> intersectedProc(nbClient, true);289 for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)290 {291 std::transform(elementOnProc[idx].begin(), elementOnProc[idx].end(),292 intersectedProc.begin(), intersectedProc.begin(),293 std::logical_and<bool>());294 }295 296 std::vector<int> srcRank;297 for (int idx = 0; idx < nbClient; ++idx)298 {299 if (intersectedProc[idx]) srcRank.push_back(idx);300 337 } 301 338 302 339 // Ok, now compute global index of grid source and ones of grid destination 303 340 computeGlobalGridIndexMapping(elementPositionInGrid, 304 srcRank,341 procContainSrcElementIdx_, //srcRank, 305 342 src2DstMap, 306 343 gridSrc, 307 344 gridDst, 308 globalElementIndexOnProc ,345 globalElementIndexOnProc_, 309 346 globaIndexWeightFromSrcToDst); 310 } 347 } 311 348 } 312 349 -
XIOS/dev/XIOS_DEV_CMIP6/src/transformation/generic_algorithm_transformation.hpp
r1158 r1216 137 137 AlgoTransType type_; 138 138 139 std::set<StdSize> indexElementSrc_; 140 141 std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc_; 142 143 std::vector<int> procContainSrcElementIdx_; // List of processes containing source index of transformed elements 144 std::set<int> procOfNonTransformedElements_; // Processes contain the source index of non-transformed elements 145 146 147 bool computedProcSrcNonTransformedElement_; // Flag to indicate whether we computed proc containing non transformed elements 148 139 149 std::map<int, int> elementPositionInGridSrc2AxisPosition_, elementPositionInGridSrc2DomainPosition_, elementPositionInGridSrc2ScalarPosition_; 140 150 std::map<int, int> elementPositionInGridDst2AxisPosition_, elementPositionInGridDst2DomainPosition_, elementPositionInGridDst2ScalarPosition_;
Note: See TracChangeset
for help on using the changeset viewer.