- Timestamp:
- 11/05/20 12:58:34 (4 years ago)
- Location:
- XIOS/dev/dev_ym/XIOS_COUPLING/src
- Files:
-
- 2 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.cpp
r1934 r1973 1 #include "source_filter.hpp"2 1 #include "grid.hpp" 3 2 #include "exception.hpp" -
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp
r1956 r1973 898 898 CATCH_DUMP_ATTR 899 899 900 void CContext::postProcessingGlobalAttributes() 901 TRY 902 { 903 if (allProcessed) return; 904 905 // create intercommunicator with servers. 906 // not sure it is the good place to be called here 907 createServerInterComm() ; 908 909 910 // After xml is parsed, there are some more works with post processing 911 postProcessing(); 912 913 // Distribute files between secondary servers according to the data size 914 distributeFiles(this->enabledWriteModeFiles); 915 916 // Check grid and calculate its distribution 917 checkGridEnabledFields(); 918 919 setClientServerBuffer(client, (serviceType_==CServicesManager::CLIENT) ) ; 920 for (int i = 0; i < clientPrimServer.size(); ++i) 921 setClientServerBuffer(clientPrimServer[i], true); 922 923 924 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) 925 { 926 if (serviceType_==CServicesManager::GATHERER) 927 { 928 for (auto it=clientPrimServer.begin(); it!=clientPrimServer.end();++it) 929 { 930 this->sendAllAttributesToServer(*it); // Send all attributes of current context to server 931 CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(*it); // Send all attributes of current calendar 932 } 933 } 934 else 935 { 936 this->sendAllAttributesToServer(client); // Send all attributes of current context to server 937 CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(client); // Send all attributes of current calendar 938 } 939 940 941 // We have enough information to send to server 942 // First of all, send all enabled files 943 sendEnabledFiles(this->enabledWriteModeFiles); 944 // We only use server-level 1 (for now) to read data 945 if (serviceType_==CServicesManager::CLIENT) sendEnabledFiles(this->enabledReadModeFiles); 946 947 // Then, send all enabled fields 948 sendEnabledFieldsInFiles(this->enabledWriteModeFiles); 949 950 if (serviceType_==CServicesManager::CLIENT) sendEnabledFieldsInFiles(this->enabledReadModeFiles); 951 952 // Then, check whether we have domain_ref, axis_ref or scalar_ref attached to the enabled fields 953 // If any, so send them to server 954 sendRefDomainsAxisScalars(this->enabledWriteModeFiles); 955 956 if (serviceType_==CServicesManager::CLIENT) sendRefDomainsAxisScalars(this->enabledReadModeFiles); 957 958 // Check whether enabled fields have grid_ref, if any, send this info to server 959 sendRefGrid(this->enabledFiles); 960 // This code may be useful in the future when we want to seperate completely read and write 961 // sendRefGrid(this->enabledWriteModeFiles); 962 // if (!hasServer) 963 // sendRefGrid(this->enabledReadModeFiles); 964 965 // A grid of enabled fields composed of several components which must be checked then their 966 // checked attributes should be sent to server 967 sendGridComponentEnabledFieldsInFiles(this->enabledFiles); // This code can be seperated in two (one for reading, another for writing) 968 969 // We have a xml tree on the server side and now, it should be also processed 970 sendPostProcessing(); 971 972 // Finally, we send information of grid itself to server 973 sendGridEnabledFieldsInFiles(this->enabledWriteModeFiles); 974 975 if (serviceType_==CServicesManager::CLIENT) sendGridEnabledFieldsInFiles(this->enabledReadModeFiles); 976 977 } 978 allProcessed = true; 979 } 980 CATCH_DUMP_ATTR 981 982 void CContext::sendPostProcessingGlobalAttributes() 983 TRY 984 { 985 986 int nbSrvPools ; 987 if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ; 988 else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ; 989 else nbSrvPools = 0 ; 990 CContextClient* contextClientTmp ; 991 992 for (int i = 0; i < nbSrvPools; ++i) 993 { 994 if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ; 995 else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ; 996 997 CEventClient event(getType(),EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES); 998 999 if (contextClientTmp->isServerLeader()) 1000 { 1001 CMessage msg; 1002 const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 1003 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1004 event.push(*itRank,1,msg); 1005 contextClientTmp->sendEvent(event); 1006 } 1007 else contextClientTmp->sendEvent(event); 1008 } 1009 } 1010 CATCH_DUMP_ATTR 1011 1012 void CContext::recvPostProcessingGlobalAttributes(CEventServer& event) 1013 TRY 1014 { 1015 CBufferIn* buffer=event.subEvents.begin()->buffer; 1016 getCurrent()->recvPostProcessingGlobalAttributes(*buffer); 1017 } 1018 CATCH 1019 1020 void CContext::recvPostProcessingGlobalAttributes(CBufferIn& buffer) 1021 TRY 1022 { 1023 postProcessingGlobalAttributes(); 1024 } 1025 CATCH_DUMP_ATTR 1026 900 1027 901 /*! 1028 902 \brief Close all the context defintion and do processing data … … 1136 1010 for(auto field : couplerOutField) 1137 1011 { 1138 field->computeGridIndexToFileServer() ; // same kind of index than for file server -> in future distribution may change1139 } 1140 if (first) setClientServerBuffer(couplerOutField, true) ; // set buffer context 1141 1012 // connect to couplerOut -> to do 1013 } 1014 if (first) setClientServerBuffer(couplerOutField, true) ; // set buffer context --> to check 1015 1142 1016 bool couplersReady ; 1143 1017 do … … 1179 1053 { 1180 1054 field->connectToFileServer(garbageCollector) ; // connect the field to server filter 1181 field->computeGridIndexToFileServer() ; // compute grid index for transfer to the server context 1182 } 1183 setClientServerBuffer(fileOutField, true) ; // set buffer context 1055 } 1056 setClientServerBuffer(fileOutField, true) ; // set buffer context --> to review 1184 1057 for(auto field : fileOutField) field->sendFieldToFileServer() ; 1185 1058 } … … 1247 1120 { 1248 1121 field->connectToServerInput(garbageCollector) ; // connect the field to server filter 1249 // obsolete field->computeGridIndexToFileServer() ; // compute grid index for transfer to the server context1250 1122 field->sendFieldToInputFileServer() ; 1251 1123 fileInFields_.push_back(field) ; … … 1291 1163 } while (!ok) ; 1292 1164 1293 return ; 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 // For now, only read files with client and only one level server 1305 // if (hasClient && !hasServer) findEnabledReadModeFiles(); 1306 1307 // Find all enabled fields of each file 1308 findAllEnabledFieldsInFiles(this->enabledWriteModeFiles); 1309 findAllEnabledFieldsInFiles(this->enabledReadModeFiles); 1310 1311 // For now, only read files with client and only one level server 1312 // if (hasClient && !hasServer) 1313 // findAllEnabledFieldsInFiles(this->enabledReadModeFiles); 1314 1315 if (serviceType_==CServicesManager::CLIENT) 1316 { 1317 initReadFiles(); 1318 // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 1319 this->readAttributesOfEnabledFieldsInReadModeFiles(); 1320 } 1321 1322 // Only search and rebuild all reference objects of enable fields, don't transform 1323 this->solveOnlyRefOfEnabledFields(); 1324 1325 // Search and rebuild all reference object of enabled fields, and transform 1326 this->solveAllRefOfEnabledFieldsAndTransform(); 1327 1328 // Find all fields with read access from the public API 1329 if (serviceType_==CServicesManager::CLIENT) findFieldsWithReadAccess(); 1330 // and solve the all reference for them 1331 if (serviceType_==CServicesManager::CLIENT) solveAllRefOfFieldsWithReadAccess(); 1332 1333 isPostProcessed = true; 1334 1335 1336 1337 // Distribute files between secondary servers according to the data size 1338 distributeFiles(this->enabledWriteModeFiles); 1339 1340 // Check grid and calculate its distribution 1341 checkGridEnabledFields(); 1342 1343 setClientServerBuffer(client, (serviceType_==CServicesManager::CLIENT) ) ; 1344 for (int i = 0; i < clientPrimServer.size(); ++i) 1345 setClientServerBuffer(clientPrimServer[i], true); 1346 1347 1348 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) 1349 { 1350 if (serviceType_==CServicesManager::GATHERER) 1351 { 1352 for (auto it=clientPrimServer.begin(); it!=clientPrimServer.end();++it) 1353 { 1354 this->sendAllAttributesToServer(*it); // Send all attributes of current context to server 1355 CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(*it); // Send all attributes of current calendar 1356 } 1357 } 1358 else 1359 { 1360 this->sendAllAttributesToServer(client); // Send all attributes of current context to server 1361 CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(client); // Send all attributes of current calendar 1362 } 1363 1364 // We have enough information to send to server 1365 // First of all, send all enabled files 1366 sendEnabledFiles(this->enabledWriteModeFiles); 1367 // We only use server-level 1 (for now) to read data 1368 if (serviceType_==CServicesManager::CLIENT) sendEnabledFiles(this->enabledReadModeFiles); 1369 1370 // Then, send all enabled fields 1371 sendEnabledFieldsInFiles(this->enabledWriteModeFiles); 1372 1373 if (serviceType_==CServicesManager::CLIENT) sendEnabledFieldsInFiles(this->enabledReadModeFiles); 1374 1375 // Then, check whether we have domain_ref, axis_ref or scalar_ref attached to the enabled fields 1376 // If any, so send them to server 1377 sendRefDomainsAxisScalars(this->enabledWriteModeFiles); 1378 1379 if (serviceType_==CServicesManager::CLIENT) sendRefDomainsAxisScalars(this->enabledReadModeFiles); 1380 1381 // Check whether enabled fields have grid_ref, if any, send this info to server 1382 sendRefGrid(this->enabledFiles); 1383 // This code may be useful in the future when we want to seperate completely read and write 1384 // sendRefGrid(this->enabledWriteModeFiles); 1385 // if (!hasServer) 1386 // sendRefGrid(this->enabledReadModeFiles); 1387 1388 // A grid of enabled fields composed of several components which must be checked then their 1389 // checked attributes should be sent to server 1390 sendGridComponentEnabledFieldsInFiles(this->enabledFiles); // This code can be seperated in two (one for reading, another for writing) 1391 1392 // We have a xml tree on the server side and now, it should be also processed 1393 sendPostProcessing(); 1394 1395 // Finally, we send information of grid itself to server 1396 sendGridEnabledFieldsInFiles(this->enabledWriteModeFiles); 1397 1398 if (serviceType_==CServicesManager::CLIENT) sendGridEnabledFieldsInFiles(this->enabledReadModeFiles); 1399 } 1400 allProcessed = true; 1401 1402 1403 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendPostProcessingGlobalAttributes(); 1404 1405 // There are some processings that should be done after all of above. For example: check mask or index 1406 this->buildFilterGraphOfEnabledFields(); 1407 1408 if (serviceType_==CServicesManager::CLIENT) 1409 { 1410 buildFilterGraphOfFieldsWithReadAccess(); 1411 postProcessFilterGraph(); // For coupling in, modify this later 1412 } 1413 1414 checkGridEnabledFields(); 1415 1416 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendProcessingGridOfEnabledFields(); 1417 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendCloseDefinition(); 1418 1419 // Nettoyage de l'arborescence 1420 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) CleanTree(); // Only on client side?? 1421 1422 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendCreateFileHeader(); 1423 if (serviceType_==CServicesManager::CLIENT) startPrefetchingOfEnabledReadModeFiles(); 1424 1425 CTimer::get("Context : close definition").suspend() ; 1165 CTimer::get("Context : close definition").suspend() ; 1426 1166 } 1427 1167 CATCH_DUMP_ATTR 1168 1169 1170 vector<CField*> CContext::findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles) 1171 TRY 1172 { 1173 vector<CField*> fields ; 1174 for(auto file : activeFiles) 1175 { 1176 const vector<CField*>&& fieldList=file->getEnabledFields() ; 1177 for(auto field : fieldList) field->setFileOut(file) ; 1178 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1179 } 1180 return fields ; 1181 } 1182 CATCH_DUMP_ATTR 1183 1184 vector<CField*> CContext::findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles) 1185 TRY 1186 { 1187 vector<CField*> fields ; 1188 for(auto file : activeFiles) 1189 { 1190 const vector<CField*>&& fieldList=file->getEnabledFields() ; 1191 for(auto field : fieldList) field->setFileIn(file) ; 1192 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1193 } 1194 return fields ; 1195 } 1196 CATCH_DUMP_ATTR 1197 1198 vector<CField*> CContext::findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut) 1199 TRY 1200 { 1201 vector<CField*> fields ; 1202 for (auto couplerOut :activeCouplerOut) 1203 { 1204 const vector<CField*>&& fieldList=couplerOut->getEnabledFields() ; 1205 for(auto field : fieldList) field->setCouplerOut(couplerOut) ; 1206 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1207 } 1208 return fields ; 1209 } 1210 CATCH_DUMP_ATTR 1211 1212 vector<CField*> CContext::findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn) 1213 TRY 1214 { 1215 vector<CField*> fields ; 1216 for (auto couplerIn :activeCouplerIn) 1217 { 1218 const vector<CField*>&& fieldList=couplerIn->getEnabledFields() ; 1219 for(auto field : fieldList) field->setCouplerIn(couplerIn) ; 1220 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1221 } 1222 return fields ; 1223 } 1224 CATCH_DUMP_ATTR 1428 1225 1429 1226 /*! … … 1440 1237 } 1441 1238 1442 // ym obsolete now to be removed 1443 void CContext::closeDefinition_old(void) 1444 TRY 1445 { 1446 CTimer::get("Context : close definition").resume() ; 1447 1448 // 1449 postProcessingGlobalAttributes(); 1450 1451 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendPostProcessingGlobalAttributes(); 1452 1453 // There are some processings that should be done after all of above. For example: check mask or index 1454 this->buildFilterGraphOfEnabledFields(); 1455 1456 if (serviceType_==CServicesManager::CLIENT) 1457 { 1458 buildFilterGraphOfFieldsWithReadAccess(); 1459 postProcessFilterGraph(); // For coupling in, modify this later 1460 } 1461 1462 checkGridEnabledFields(); 1463 1464 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendProcessingGridOfEnabledFields(); 1465 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendCloseDefinition(); 1466 1467 // Nettoyage de l'arborescence 1468 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) CleanTree(); // Only on client side?? 1469 1470 if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendCreateFileHeader(); 1471 if (serviceType_==CServicesManager::CLIENT) startPrefetchingOfEnabledReadModeFiles(); 1472 1473 CTimer::get("Context : close definition").suspend() ; 1474 } 1475 CATCH_DUMP_ATTR 1476 1477 vector<CField*> CContext::findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 1478 TRY 1479 { 1480 vector<CField*> fields ; 1481 for (unsigned int i = 0; i < activeFiles.size(); i++) 1482 { 1483 const vector<CField*>&& field=activeFiles[i]->getEnabledFields() ; 1484 fields.insert(fields.end(),field.begin(),field.end()); 1485 } 1486 return fields ; 1487 } 1488 CATCH_DUMP_ATTR 1489 1490 vector<CField*> CContext::findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles) 1491 TRY 1492 { 1493 vector<CField*> fields ; 1494 for(auto file : activeFiles) 1495 { 1496 const vector<CField*>&& fieldList=file->getEnabledFields() ; 1497 for(auto field : fieldList) field->setFileOut(file) ; 1498 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1499 } 1500 return fields ; 1501 } 1502 CATCH_DUMP_ATTR 1503 1504 vector<CField*> CContext::findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles) 1505 TRY 1506 { 1507 vector<CField*> fields ; 1508 for(auto file : activeFiles) 1509 { 1510 const vector<CField*>&& fieldList=file->getEnabledFields() ; 1511 for(auto field : fieldList) field->setFileIn(file) ; 1512 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1513 } 1514 return fields ; 1515 } 1516 CATCH_DUMP_ATTR 1517 1518 vector<CField*> CContext::findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut) 1519 TRY 1520 { 1521 vector<CField*> fields ; 1522 for (auto couplerOut :activeCouplerOut) 1523 { 1524 const vector<CField*>&& fieldList=couplerOut->getEnabledFields() ; 1525 for(auto field : fieldList) field->setCouplerOut(couplerOut) ; 1526 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1527 } 1528 return fields ; 1529 } 1530 CATCH_DUMP_ATTR 1531 1532 vector<CField*> CContext::findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn) 1533 TRY 1534 { 1535 vector<CField*> fields ; 1536 for (auto couplerIn :activeCouplerIn) 1537 { 1538 const vector<CField*>&& fieldList=couplerIn->getEnabledFields() ; 1539 for(auto field : fieldList) field->setCouplerIn(couplerIn) ; 1540 fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 1541 } 1542 return fields ; 1543 } 1544 CATCH_DUMP_ATTR 1545 1546 1547 1239 1548 1240 void CContext::readAttributesOfEnabledFieldsInReadModeFiles() 1549 1241 TRY … … 2110 1802 return true; 2111 1803 break; 2112 case EVENT_ID_POST_PROCESS:2113 recvPostProcessing(event);2114 return true;2115 1804 case EVENT_ID_SEND_REGISTRY: 2116 1805 recvRegistry(event); 2117 return true;2118 break;2119 case EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES:2120 recvPostProcessingGlobalAttributes(event);2121 return true;2122 break;2123 case EVENT_ID_PROCESS_GRID_ENABLED_FIELDS:2124 recvProcessingGridOfEnabledFields(event);2125 1806 return true; 2126 1807 break; … … 2288 1969 if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::OUT_SERVER) 2289 1970 createFileHeader(); 2290 }2291 CATCH_DUMP_ATTR2292 2293 //! Client side: Send a message to do some post processing on server2294 void CContext::sendProcessingGridOfEnabledFields()2295 TRY2296 {2297 int nbSrvPools ;2298 if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ;2299 else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ;2300 else nbSrvPools = 0 ;2301 CContextClient* contextClientTmp ;2302 2303 for (int i = 0; i < nbSrvPools; ++i)2304 {2305 if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ;2306 else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ;2307 2308 CEventClient event(getType(),EVENT_ID_PROCESS_GRID_ENABLED_FIELDS);2309 2310 if (contextClientTmp->isServerLeader())2311 {2312 CMessage msg;2313 const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();2314 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)2315 event.push(*itRank,1,msg);2316 contextClientTmp->sendEvent(event);2317 }2318 else contextClientTmp->sendEvent(event);2319 }2320 }2321 CATCH_DUMP_ATTR2322 2323 //! Server side: Receive a message to do some post processing2324 void CContext::recvProcessingGridOfEnabledFields(CEventServer& event)2325 TRY2326 {2327 CBufferIn* buffer=event.subEvents.begin()->buffer;2328 // nothing to do, no call ??!!2329 }2330 CATCH2331 2332 //! Client side: Send a message to do some post processing on server2333 void CContext::sendPostProcessing()2334 TRY2335 {2336 int nbSrvPools ;2337 if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ;2338 else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ;2339 else nbSrvPools = 0 ;2340 CContextClient* contextClientTmp ;2341 2342 for (int i = 0; i < nbSrvPools; ++i)2343 {2344 if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ;2345 else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ;2346 CEventClient event(getType(),EVENT_ID_POST_PROCESS);2347 if (contextClientTmp->isServerLeader())2348 {2349 CMessage msg;2350 const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();2351 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)2352 event.push(*itRank,1,msg);2353 contextClientTmp->sendEvent(event);2354 }2355 else contextClientTmp->sendEvent(event);2356 }2357 }2358 CATCH_DUMP_ATTR2359 2360 //! Server side: Receive a message to do some post processing2361 void CContext::recvPostProcessing(CEventServer& event)2362 TRY2363 {2364 CBufferIn* buffer=event.subEvents.begin()->buffer;2365 getCurrent()->recvPostProcessing(*buffer);2366 }2367 CATCH2368 2369 //! Server side: Receive a message to do some post processing2370 void CContext::recvPostProcessing(CBufferIn& buffer)2371 TRY2372 {2373 CCalendarWrapper::get(CCalendarWrapper::GetDefName())->createCalendar();2374 postProcessing();2375 }2376 CATCH_DUMP_ATTR2377 2378 2379 /*!2380 \brief Do some simple post processings after parsing xml file2381 After the xml file (iodef.xml) is parsed, it is necessary to build all relations among2382 created object, e.g: inhertance among fields, domain, axis. After that, all fiels as well as their parents (reference fields),2383 which will be written out into netcdf files, are processed2384 */2385 void CContext::postProcessing()2386 TRY2387 {2388 if (isPostProcessed) return;2389 2390 // Make sure the calendar was correctly created2391 if (!calendar)2392 ERROR("CContext::postProcessing()", << "A calendar must be defined for the context \"" << getId() << "!\"")2393 else if (calendar->getTimeStep() == NoneDu)2394 ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"")2395 // Calendar first update to set the current date equals to the start date2396 calendar->update(0);2397 2398 // Find all inheritance in xml structure2399 this->solveAllInheritance();2400 2401 // ShowTree(info(10));2402 2403 // Check if some axis, domains or grids are eligible to for compressed indexed output.2404 // Warning: This must be done after solving the inheritance and before the rest of post-processing2405 //checkAxisDomainsGridsEligibilityForCompressedOutput(); // only for field written on IO_SERVER service ????2406 2407 // Check if some automatic time series should be generated2408 // Warning: This must be done after solving the inheritance and before the rest of post-processing2409 prepareTimeseries();2410 2411 //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir.2412 findEnabledFiles();2413 findEnabledWriteModeFiles();2414 findEnabledReadModeFiles();2415 findEnabledCouplerIn();2416 findEnabledCouplerOut();2417 createCouplerInterCommunicator() ;2418 2419 // Find all enabled fields of each file2420 const vector<CField*>&& fileOutField = findAllEnabledFieldsInFiles(this->enabledWriteModeFiles);2421 const vector<CField*>&& fileInField = findAllEnabledFieldsInFiles(this->enabledReadModeFiles);2422 const vector<CField*>&& CouplerOutField = findAllEnabledFieldsCouplerOut(this->enabledCouplerOut);2423 const vector<CField*>&& CouplerInField = findAllEnabledFieldsCouplerIn(this->enabledCouplerIn);2424 2425 2426 2427 // For now, only read files with client and only one level server2428 // if (hasClient && !hasServer) findEnabledReadModeFiles();2429 2430 2431 // For now, only read files with client and only one level server2432 // if (hasClient && !hasServer)2433 // findAllEnabledFieldsInFiles(this->enabledReadModeFiles);2434 2435 if (serviceType_==CServicesManager::CLIENT)2436 {2437 initReadFiles();2438 // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis)2439 this->readAttributesOfEnabledFieldsInReadModeFiles();2440 }2441 2442 // Only search and rebuild all reference objects of enable fields, don't transform2443 this->solveOnlyRefOfEnabledFields();2444 2445 // Search and rebuild all reference object of enabled fields, and transform2446 this->solveAllRefOfEnabledFieldsAndTransform();2447 2448 // Find all fields with read access from the public API2449 if (serviceType_==CServicesManager::CLIENT) findFieldsWithReadAccess();2450 // and solve the all reference for them2451 if (serviceType_==CServicesManager::CLIENT) solveAllRefOfFieldsWithReadAccess();2452 2453 isPostProcessed = true;2454 1971 } 2455 1972 CATCH_DUMP_ATTR -
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp
r1956 r1973 53 53 EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR, 54 54 EVENT_ID_CREATE_FILE_HEADER,EVENT_ID_CONTEXT_FINALIZE, 55 EVENT_ID_POST_PROCESS, EVENT_ID_SEND_REGISTRY, 56 EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES, 57 EVENT_ID_PROCESS_GRID_ENABLED_FIELDS, 55 EVENT_ID_SEND_REGISTRY, 58 56 EVENT_ID_CONTEXT_FINALIZE_CLIENT, 59 57 EVENT_ID_COUPLER_IN_READY, … … 117 115 118 116 void closeDefinition(void); 119 void closeDefinition_old(void);120 117 121 118 // to be removed … … 140 137 void createFileHeader(void); 141 138 void initReadFiles(void); 142 void prepareTimeseries(void);139 void prepareTimeseries(void); 143 140 void solveOnlyRefOfEnabledFields(void); 144 141 void buildFilterGraphOfEnabledFields(); … … 150 147 void solveAllRefOfFieldsWithReadAccess(); 151 148 void buildFilterGraphOfFieldsWithReadAccess(); 152 void postProcessing();153 void postProcessingGlobalAttributes();154 149 void triggerLateFields(void) ; 155 150 void solveAllRefOfEnabledFieldsAndTransform(void); … … 183 178 void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles); 184 179 void sendRefGrid(const std::vector<CFile*>& activeFiles); 185 void sendPostProcessing();186 void sendPostProcessingGlobalAttributes();187 void sendProcessingGridOfEnabledFields();188 180 //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers 189 181 void sendRegistry(void) ; … … 206 198 static void recvSolveInheritanceContext(CEventServer& event); 207 199 void recvSolveInheritanceContext(CBufferIn& buffer); 208 static void recvPostProcessing(CEventServer& event);209 void recvPostProcessing(CBufferIn& buffer);210 static void recvProcessingGridOfEnabledFields(CEventServer& event);211 static void recvPostProcessingGlobalAttributes(CEventServer& event);212 void recvPostProcessingGlobalAttributes(CBufferIn& buffer);213 200 static void recvRegistry(CEventServer& event) ; 214 201 void recvRegistry(CBufferIn& buffer) ; //!< registry is received by the servers -
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp
r1962 r1973 15 15 #include <set> 16 16 #include "garbage_collector.hpp" 17 #include "source_filter.hpp"18 17 #include "pass_through_filter.hpp" 19 18 #include "filter_expr_node.hpp" … … 624 623 } 625 624 626 solveCheckMaskIndex(doSending2Server);627 625 } 628 626 CATCH_DUMP_ATTR … … 865 863 } 866 864 867 /*! 868 * Compute grid index needed to send grid and data to server 869 */ 870 void CField::computeGridIndexToFileServer(void) 871 { 872 grid_->computeGridIndexToFileServer(client) ; 873 } 874 865 875 866 /*! 876 867 * Connect field to a source filter to receive data from model. -
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp
r1962 r1973 240 240 void connectToServerToClient(CGarbageCollector& gc) ; 241 241 242 void computeGridIndexToFileServer(void) ;243 244 242 void setContextClientDataBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize, 245 243 map<CContextClient*,map<int,size_t>>& maxEventSize, -
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field_impl.hpp
r1949 r1973 9 9 #include "timer.hpp" 10 10 #include "array_new.hpp" 11 #include "source_filter.hpp"12 11 13 12 -
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp
r1960 r1973 36 36 , vAxisGroup_(), axisList_(), isAxisListSet(false) 37 37 , vScalarGroup_(), scalarList_(), isScalarListSet(false) 38 , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 39 , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 38 , clientDistribution_(0), isIndexSent(false) 40 39 , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 41 40 , isCompressible_(false) 42 41 , transformations_(0), isTransformed_(false) 43 42 , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 44 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 45 , computedWrittenIndex_(false) 43 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_() 46 44 , clients() 47 45 { … … 57 55 , vAxisGroup_(), axisList_(), isAxisListSet(false) 58 56 , vScalarGroup_(), scalarList_(), isScalarListSet(false) 59 , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 60 , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 57 , clientDistribution_(0), isIndexSent(false) 61 58 , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 62 59 , isCompressible_(false) 63 60 , transformations_(0), isTransformed_(false) 64 61 , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 65 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 66 , computedWrittenIndex_(false) 62 , gridSrc_(), hasTransform_(false), isGenerated_(false), order_() 67 63 , clients() 68 64 { … … 75 71 { 76 72 if (0 != clientDistribution_) delete clientDistribution_; 77 if (0 != serverDistribution_) delete serverDistribution_;78 if (0 != clientServerMap_) delete clientServerMap_;79 73 if (0 != transformations_) delete transformations_; 80 74 } … … 859 853 this->checkAttributesAfterTransformation(); 860 854 861 // TODO: Transfer grid attributes862 //if (!context->hasClient && context->hasServer) this->createMask();863 this->computeIndex();864 865 855 if (!(this->hasTransform() && !this->isTransformed())) 866 856 this->isChecked = true; … … 897 887 return mask_ ; 898 888 } 899 /* 900 Create mask of grid from mask of its components 901 */ 902 void CGrid::createMask(void) 903 TRY 904 { 905 using namespace std; 906 std::vector<CDomain*> domainP = this->getDomains(); 907 std::vector<CAxis*> axisP = this->getAxis(); 908 int dim = domainP.size() * 2 + axisP.size(); 909 910 std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 911 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 912 std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 913 for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 914 915 switch (dim) { 916 case 1: 917 checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order, true); 918 break; 919 case 2: 920 checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order, true); 921 break; 922 case 3: 923 checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order, true); 924 break; 925 case 4: 926 checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order, true); 927 break; 928 case 5: 929 checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order, true); 930 break; 931 case 6: 932 checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order, true); 933 break; 934 case 7: 935 checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order, true); 936 break; 937 default: 938 break; 939 } 940 } 941 CATCH_DUMP_ATTR 942 943 /* 944 Check validity of grid's mask by using the masks of its components 945 */ 946 void CGrid::checkMask(void) 947 TRY 948 { 949 using namespace std; 950 std::vector<CDomain*> domainP = this->getDomains(); 951 std::vector<CAxis*> axisP = this->getAxis(); 952 int dim = domainP.size() * 2 + axisP.size(); 953 954 std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 955 for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 956 std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 957 for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 958 959 switch (dim) { 960 case 1: 961 checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order); 962 break; 963 case 2: 964 checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order); 965 break; 966 case 3: 967 checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order); 968 break; 969 case 4: 970 checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order); 971 break; 972 case 5: 973 checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order); 974 break; 975 case 6: 976 checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order); 977 break; 978 case 7: 979 checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order); 980 break; 981 default: 982 break; 983 } 984 } 985 CATCH_DUMP_ATTR 986 987 /* 988 Modify value of mask in a certain index 989 This function can be used to correct the mask of grid after being constructed with createMask 990 \param [in] indexToModify 991 \param [in] modifyValue 992 */ 993 void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue) 994 TRY 995 { 996 using namespace std; 997 std::vector<CDomain*> domainP = this->getDomains(); 998 std::vector<CAxis*> axisP = this->getAxis(); 999 int dim = domainP.size() * 2 + axisP.size(); 1000 1001 switch (dim) { 1002 case 0: 1003 modifyGridMask(mask_0d, indexToModify, modifyValue); 1004 break; 1005 case 1: 1006 modifyGridMask(mask_1d, indexToModify, modifyValue); 1007 break; 1008 case 2: 1009 modifyGridMask(mask_2d, indexToModify, modifyValue); 1010 break; 1011 case 3: 1012 modifyGridMask(mask_3d, indexToModify, modifyValue); 1013 break; 1014 case 4: 1015 modifyGridMask(mask_4d, indexToModify, modifyValue); 1016 break; 1017 case 5: 1018 modifyGridMask(mask_5d, indexToModify, modifyValue); 1019 break; 1020 case 6: 1021 modifyGridMask(mask_6d, indexToModify, modifyValue); 1022 break; 1023 case 7: 1024 modifyGridMask(mask_7d, indexToModify, modifyValue); 1025 break; 1026 default: 1027 break; 1028 } 1029 } 1030 CATCH_DUMP_ATTR 1031 1032 /* 1033 Change the mask size. This function is used on reconstructing mask in server side 1034 \param [in] newDimensionSize 1035 \param [in] newValue 1036 */ 1037 void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue) 1038 TRY 1039 { 1040 std::vector<CDomain*> domainP = this->getDomains(); 1041 std::vector<CAxis*> axisP = this->getAxis(); 1042 int dim = domainP.size() * 2 + axisP.size(); 1043 1044 switch (dim) { 1045 case 0: 1046 modifyGridMaskSize(mask_0d, newDimensionSize, newValue); 1047 break; 1048 case 1: 1049 modifyGridMaskSize(mask_1d, newDimensionSize, newValue); 1050 break; 1051 case 2: 1052 modifyGridMaskSize(mask_2d, newDimensionSize, newValue); 1053 break; 1054 case 3: 1055 modifyGridMaskSize(mask_3d, newDimensionSize, newValue); 1056 break; 1057 case 4: 1058 modifyGridMaskSize(mask_4d, newDimensionSize, newValue); 1059 break; 1060 case 5: 1061 modifyGridMaskSize(mask_5d, newDimensionSize, newValue); 1062 break; 1063 case 6: 1064 modifyGridMaskSize(mask_6d, newDimensionSize, newValue); 1065 break; 1066 case 7: 1067 modifyGridMaskSize(mask_7d, newDimensionSize, newValue); 1068 break; 1069 default: 1070 break; 1071 } 1072 } 1073 CATCH_DUMP_ATTR 1074 889 890 1075 891 //--------------------------------------------------------------- 1076 892 … … 1130 946 CATCH_DUMP_ATTR 1131 947 1132 /*! 1133 Compute the index to for write data into a file 1134 */ 1135 void CGrid::computeWrittenIndex() 1136 TRY 1137 { 1138 if (computedWrittenIndex_) return; 1139 computedWrittenIndex_ = true; 1140 1141 if (isScalarGrid()) 1142 { 1143 size_t nbWritten = 1; 1144 int writtenIndex = 0; 1145 1146 localIndexToWriteOnClient_.resize(nbWritten); 1147 localIndexToWriteOnServer_.resize(nbWritten); 1148 localIndexToWriteOnServer_(0) = writtenIndex; 1149 localIndexToWriteOnClient_(0) = writtenIndex; 1150 1151 return; 1152 } 1153 1154 size_t nbWritten = 0, indGlo; 1155 CDistributionClient::GlobalLocalDataMap& globalDataIndex = getClientDistribution()->getGlobalDataIndexOnClient(); 1156 CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(), 1157 ite = globalDataIndex.end(), it; 1158 const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex(); 1159 CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(), 1160 itSrve = globalLocalIndex.end(), itSrv; 1161 for (it = itb; it != ite; ++it) 1162 { 1163 indGlo = it->first; 1164 if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten; 1165 } 1166 1167 localIndexToWriteOnClient_.resize(nbWritten); 1168 localIndexToWriteOnServer_.resize(nbWritten); 1169 1170 { 1171 numberWrittenIndexes_ = nbWritten; 1172 if (isDataDistributed()) 1173 { 1174 CContext* context = CContext::getCurrent(); 1175 MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, context->intraComm_); 1176 MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, context->intraComm_); 1177 offsetWrittenIndexes_ -= numberWrittenIndexes_; 1178 } 1179 else 1180 totalNumberWrittenIndexes_ = numberWrittenIndexes_; 1181 } 1182 1183 nbWritten = 0; 1184 for (it = itb; it != ite; ++it) 1185 { 1186 indGlo = it->first; 1187 itSrv = globalLocalIndex.find(indGlo); 1188 if (itSrve != itSrv) 1189 { 1190 localIndexToWriteOnServer_(nbWritten) = itSrv->second; 1191 localIndexToWriteOnClient_(nbWritten) = it->second; 1192 ++nbWritten; 1193 } 1194 } 1195 } 1196 CATCH_DUMP_ATTR 1197 1198 1199 1200 /*! 1201 Compute the global index of grid to send to server as well as the connected server of the current client. 1202 First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know 1203 their global index. We can have a map of global index of grid and local index that each client holds 1204 Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s) 1205 of the current client. 1206 */ 1207 void CGrid::computeGridIndexToFileServer(CContextClient* client) 1208 { 1209 if (isScalarGrid()) computeConnectedClientsScalarGrid(client); 1210 else computeConnectedClients(client); 1211 1212 // compute indices for client/server transfer for domain 1213 for (const auto& domainId : domList_) CDomain::get(domainId)->computeConnectedClients(client); 1214 1215 1216 // compute indices for client/server transfer for axis 1217 std::vector<CAxis*> axisList = this->getAxis(); 1218 for(int i=0 ; i<axisList.size(); i++) axisList[i] -> computeConnectedClients(client, getGlobalDimension(),getAxisPositionInGrid()[i]) ; 1219 } 1220 //--------------------------------------------------------------- 1221 948 949 //--------------------------------------------------------------- 950 CDistributionClient* CGrid::getClientDistribution() 951 TRY 952 { 953 if (!computeClientDistribution_done_) computeClientDistribution() ; 954 return clientDistribution_; 955 } 956 CATCH_DUMP_ATTR 1222 957 1223 958 void CGrid::computeClientDistribution(void) … … 1231 966 } 1232 967 1233 void CGrid::computeStoreIndex_client(void)1234 {1235 if (computeStoreIndex_client_done_) return ;1236 else computeStoreIndex_client_done_ = true ;1237 if (isScalarGrid())1238 {1239 storeIndex_client_.resize(1);1240 storeIndex_client_(0) = 0;1241 }1242 else1243 {1244 CDistributionClient* clientDistribution = getClientDistribution() ;1245 const std::vector<int>& localDataIndex = clientDistribution->getLocalDataIndexOnClient() ;1246 int nbStoreIndex = localDataIndex.size() ;1247 storeIndex_client_.resize(nbStoreIndex);1248 for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client_(idx) = localDataIndex[idx];1249 }1250 }1251 1252 void CGrid::computeStoreMask_client(void)1253 {1254 if (computeStoreMask_client_done_) return ;1255 else computeStoreMask_client_done_ = true ;1256 if (isScalarGrid())1257 {1258 storeMask_client_.resize(1);1259 storeMask_client_(0) = true;1260 }1261 else1262 {1263 CDistributionClient* clientDistribution = getClientDistribution() ;1264 const std::vector<bool>& localMaskIndex = clientDistribution->getLocalMaskIndexOnClient() ;1265 int nbMaskIndex = localMaskIndex.size() ;1266 storeMask_client_.resize(nbMaskIndex);1267 for (int idx = 0; idx < nbMaskIndex; ++idx) storeMask_client_(idx) = localMaskIndex[idx];1268 }1269 }1270 1271 1272 void CGrid::computeOutLocalIndexStoreOnClient(void)1273 {1274 if (computeOutLocalIndexStoreOnClient_done_) return ;1275 else computeOutLocalIndexStoreOnClient_done_=true ;1276 1277 if (isScalarGrid())1278 {1279 auto& outGlobalIndexFromClient = getOutGlobalIndexFromClient();1280 auto itb = outGlobalIndexFromClient.begin(), ite = outGlobalIndexFromClient.end() ;1281 for (auto it = itb; it != ite; ++it)1282 {1283 int rank = it->first;1284 CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];1285 outLocalIndexStoreOnClient_.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));1286 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient_[rank];1287 if (1 != globalIndex.numElements())1288 ERROR("void CGrid::computeClientIndexScalarGrid()",1289 << "Something wrong happened. "1290 << "Number of received global index on scalar grid should equal to 1"1291 << "Number of received global index " << globalIndex.numElements() << ".");1292 1293 localIndex(0) = globalIndex(0);1294 }1295 }1296 else1297 {1298 CDistributionClient::GlobalLocalDataMap& globalDataIndex = getClientDistribution()->getGlobalDataIndexOnClient();1299 CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end();1300 auto& outGlobalIndexFromClient = getOutGlobalIndexFromClient();1301 auto itb = outGlobalIndexFromClient.begin(), ite = outGlobalIndexFromClient.end() ;1302 1303 for (auto it = itb; it != ite; ++it)1304 {1305 int rank = it->first;1306 CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];1307 outLocalIndexStoreOnClient_.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));1308 CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient_[rank];1309 size_t nbIndex = 0;1310 1311 // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance1312 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)1313 if (itGloe != globalDataIndex.find(globalIndex(idx))) ++nbIndex;1314 1315 if (nbIndex != localIndex.numElements())1316 ERROR("void CGrid::computeClientIndex()",1317 << "Number of local index on client is different from number of received global index"1318 << "Rank of sent client " << rank <<"."1319 << "Number of local index " << nbIndex << ". "1320 << "Number of received global index " << localIndex.numElements() << ".");1321 1322 nbIndex = 0;1323 for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)1324 if (itGloe != globalDataIndex.find(globalIndex(idx)))1325 localIndex(idx) = globalDataIndex[globalIndex(idx)];1326 }1327 }1328 }1329 968 1330 969 bool CGrid::isDataDistributed(void) … … 1333 972 } 1334 973 1335 /*! 1336 Compute connected receivers and indexes to be sent to these receivers. 1337 */ 1338 void CGrid::computeConnectedClients(CContextClient* client) 1339 TRY 1340 { 1341 if (computeConnectedClients_done_.count(client)!=0) return ; 1342 else computeConnectedClients_done_.insert(client) ; 1343 1344 CContext* context = CContext::getCurrent(); 1345 1346 set<int> listReceiverSize ; 1347 int receiverSize = client->serverSize; 1348 1349 if (listReceiverSize.find(receiverSize)==listReceiverSize.end()) 1350 { 1351 listReceiverSize.insert(receiverSize) ; 1352 if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end()) 1353 { 1354 // delete corresponding map in case of recompute, probably because a grid could has been modifiedd 1355 // by a transformation 1356 connectedServerRank_.erase(receiverSize); 1357 connectedDataSize_.erase(receiverSize); 1358 globalIndexOnServer_.erase(receiverSize); 1359 nbSenders_.erase(receiverSize); 1360 } 1361 1362 if (!doGridHaveDataDistributed(client)) 1363 { 1364 if (client->isServerLeader()) 1365 { 1366 size_t ssize = getClientDistribution()->getLocalDataIndexOnClient().size(); 1367 const std::list<int>& ranks = client->getRanksServerLeader(); 1368 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 1369 { 1370 connectedServerRank_[receiverSize].push_back(*itRank); 1371 connectedDataSize_[receiverSize][*itRank] = ssize; 1372 } 1373 } 1374 return; 1375 } 1376 1377 // Compute mapping between client and server 1378 std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 1379 CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 1380 std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 1381 client->clientRank, 1382 client->clientSize, 1383 axis_domain_order, 1384 getDistributedDimension()); 1385 1386 // Even if servers have no index, they must received something from client 1387 // We only use several client to send "empty" message to these servers 1388 std::list<int> serverZeroIndexLeader; 1389 std::list<int> serverZeroIndexNotLeader; 1390 CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 1391 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 1392 *it = serverZeroIndex[*it]; 1393 1394 if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 1395 computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 1396 1397 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getClientDistribution()->getGlobalLocalDataSendToServer(); 1398 CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 1399 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 1400 itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 1401 iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 1402 1403 for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 1404 { 1405 int serverRank = itGlobalMap->first; 1406 int indexSize = itGlobalMap->second.size(); 1407 const std::vector<size_t>& indexVec = itGlobalMap->second; 1408 for (int idx = 0; idx < indexSize; ++idx) 1409 { 1410 itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 1411 if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 1412 { 1413 if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 1414 connectedDataSize_[receiverSize][serverRank] = 1; 1415 else 1416 ++connectedDataSize_[receiverSize][serverRank]; 1417 } 1418 } 1419 } 1420 1421 // Connected servers which really have index 1422 for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 1423 connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 1424 1425 // Connected servers which have no index at all 1426 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 1427 connectedServerRank_[receiverSize].push_back(*it); 1428 1429 // Even if a client has no index, it must connect to at least one server and 1430 // send an "empty" data to this server 1431 if (connectedServerRank_[receiverSize].empty()) 1432 connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 1433 1434 // Now check if all servers have data to receive. If not, master client will send empty data. 1435 // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 1436 std::vector<int> counts (client->clientSize); 1437 std::vector<int> displs (client->clientSize); 1438 displs[0] = 0; 1439 int localCount = connectedServerRank_[receiverSize].size() ; 1440 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 1441 for (int i = 0; i < client->clientSize-1; ++i) displs[i+1] = displs[i] + counts[i]; 1442 std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]); 1443 MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 1444 1445 if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0)) 1446 { 1447 std::vector<bool> isSrvConnected (receiverSize, false); 1448 for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 1449 for (int i = 0; i < receiverSize; ++i) if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i); 1450 } 1451 1452 nbSenders_[receiverSize] = CClientServerMapping::computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 1453 } 1454 } 1455 CATCH_DUMP_ATTR 1456 974 1457 975 /*! 1458 976 Compute the global index of grid to send to server as well as the connected server of the current client. … … 1487 1005 if (context->getServiceType()==CServicesManager::OUT_SERVER) 1488 1006 { 1489 computeWrittenIndex() ;1490 if (serverDistribution_!=0) serverDistribution_->partialClear() ;1491 1007 if (clientDistribution_!=0) clientDistribution_->partialClear() ; 1492 outGlobalIndexFromClient_.clear() ;1493 1008 } 1494 1009 } 1495 1010 CATCH_DUMP_ATTR 1496 1011 1497 /*! 1498 Compute the global of (client) grid to send to server with the global index of each element of grid 1499 Each element of grid has its own global index associated to a groups of server. We only search for the global index of each element whose 1500 server is the same, then calculate the global index of grid. This way can reduce so much the time for executing DHT, which only needs to run 1501 on each element whose size is much smaller than one of whole grid. 1502 \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 1503 \param [in] client contextClient 1504 \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 1505 */ 1506 void CGrid::computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 1507 const CContextClient* client, 1508 CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 1509 TRY 1510 { 1511 int serverSize = client->serverSize; 1512 1513 std::vector<CDomain*> domList = getDomains(); 1514 std::vector<CAxis*> axisList = getAxis(); 1515 1516 // Some pre-calculations of global index on each element of current grid. 1517 int nbElement = axis_domain_order.numElements(); 1518 std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 1519 int domainIdx = 0, axisIdx = 0, scalarIdx = 0; 1520 std::vector<size_t> elementNGlobal(nbElement); 1521 elementNGlobal[0] = 1; 1522 size_t globalSize = 1; 1523 for (int idx = 0; idx < nbElement; ++idx) 1524 { 1525 elementNGlobal[idx] = globalSize; 1526 size_t elementSize; 1527 size_t elementGlobalSize = 1; 1528 if (2 == axis_domain_order(idx)) // This is domain 1529 { 1530 elementSize = domList[domainIdx]->i_index.numElements(); 1531 globalIndexElement[idx].resize(elementSize); 1532 for (int jdx = 0; jdx < elementSize; ++jdx) 1533 { 1534 globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 1535 } 1536 elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 1537 ++domainIdx; 1538 } 1539 else if (1 == axis_domain_order(idx)) // This is axis 1540 { 1541 elementSize = axisList[axisIdx]->index.numElements(); 1542 globalIndexElement[idx].resize(elementSize); 1543 for (int jdx = 0; jdx < elementSize; ++jdx) 1544 { 1545 globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 1546 } 1547 elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 1548 ++axisIdx; 1549 } 1550 else // Of course, this is scalar 1551 { 1552 globalIndexElement[idx].resize(1); 1553 globalIndexElement[idx](0) = 0; 1554 elementGlobalSize = 1; 1555 } 1556 globalSize *= elementGlobalSize; 1557 } 1558 1559 std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 1560 std::vector<std::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 1561 CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server 1562 // Number of temporary distributed global index held by each client for each server 1563 // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank 1564 CArray<int,1> nbIndexOnServerTmp(serverSize); 1565 for (int idx = 0; idx < nbElement; ++idx) 1566 { 1567 nbIndexOnServer = 0; 1568 const std::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 1569 const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 1570 CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 1571 clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 1572 const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 1573 CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 1574 ite = globalIndexElementOnServerMap.end(), it; 1575 for (it = itb; it != ite; ++it) 1576 { 1577 const std::vector<int>& tmp = it->second; 1578 nbIndexOnServerTmp = 0; 1579 for (int i = 0; i < tmp.size(); ++i) 1580 { 1581 if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]); 1582 } 1583 nbIndexOnServer += nbIndexOnServerTmp; 1584 } 1585 1586 for (int i = 0; i < serverSize; ++i) 1587 { 1588 if (0 != nbIndexOnServer(i)) 1589 { 1590 globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i)); 1591 elementOnServer[idx][i] = true; 1592 } 1593 } 1594 1595 nbIndexOnServer = 0; 1596 for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 1597 { 1598 it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 1599 if (it != ite) 1600 { 1601 const std::vector<int>& tmp = it->second; 1602 nbIndexOnServerTmp = 0; 1603 for (int i = 0; i < tmp.size(); ++i) 1604 { 1605 if (0 == nbIndexOnServerTmp(tmp[i])) 1606 { 1607 globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first; 1608 ++nbIndexOnServerTmp(tmp[i]); 1609 } 1610 } 1611 nbIndexOnServer += nbIndexOnServerTmp; 1612 } 1613 } 1614 } 1615 1616 // Determine server which contain global source index 1617 std::vector<bool> intersectedProc(serverSize, true); 1618 for (int idx = 0; idx < nbElement; ++idx) 1619 { 1620 std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 1621 intersectedProc.begin(), intersectedProc.begin(), 1622 std::logical_and<bool>()); 1623 } 1624 1625 std::vector<int> srcRank; 1626 for (int idx = 0; idx < serverSize; ++idx) 1627 { 1628 if (intersectedProc[idx]) srcRank.push_back(idx); 1629 } 1630 1631 // Compute the global index of grid from global index of each element. 1632 for (int i = 0; i < srcRank.size(); ++i) 1633 { 1634 size_t ssize = 1; 1635 int rankSrc = srcRank[i]; 1636 std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 1637 std::vector<size_t> currentIndex(nbElement,0); 1638 for (int idx = 0; idx < nbElement; ++idx) 1639 { 1640 ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 1641 globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 1642 } 1643 globalIndexOnServer[rankSrc].resize(ssize); 1644 1645 std::vector<int> idxLoop(nbElement,0); 1646 int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 1647 size_t idx = 0; 1648 while (idx < ssize) 1649 { 1650 for (int ind = 0; ind < nbElement; ++ind) 1651 { 1652 if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 1653 { 1654 idxLoop[ind] = 0; 1655 ++idxLoop[ind+1]; 1656 } 1657 1658 currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 1659 } 1660 1661 for (int ind = 0; ind < innnerLoopSize; ++ind) 1662 { 1663 currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 1664 size_t globalSrcIndex = 0; 1665 for (int idxElement = 0; idxElement < nbElement; ++idxElement) 1666 { 1667 globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 1668 } 1669 globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 1670 ++idx; 1671 ++idxLoop[0]; 1672 } 1673 } 1674 } 1675 } 1676 CATCH_DUMP_ATTR 1012 1677 1013 //---------------------------------------------------------------- 1678 1014 … … 1783 1119 //---------------------------------------------------------------- 1784 1120 1785 void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored)1786 TRY1787 {1788 auto& storeIndex_client = getStoreIndex_client() ;1789 const StdSize size = storeIndex_client.numElements();1790 1791 stored.resize(size);1792 for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];1793 }1794 CATCH1795 1796 void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data)1797 TRY1798 {1799 auto& storeIndex_client=getStoreIndex_client() ;1800 const StdSize size = storeIndex_client.numElements();1801 1802 for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i);1803 }1804 CATCH1805 1806 void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored)1807 {1808 auto& storeIndex_client=getStoreIndex_client() ;1809 auto& storeMask_client=getStoreMask_client() ;1810 1811 const StdSize size = storeIndex_client.numElements();1812 stored.resize(size);1813 const double nanValue = std::numeric_limits<double>::quiet_NaN();1814 1815 if (storeMask_client.numElements() != 0)1816 for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue;1817 else1818 for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];1819 }1820 1821 void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out)1822 TRY1823 {1824 const std::vector<int>& localMaskedDataIndex = getClientDistribution()->getLocalMaskedDataIndexOnClient();1825 const int size = localMaskedDataIndex.size();1826 for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i];1827 }1828 CATCH1829 1830 1831 void CGrid::computeConnectedClientsScalarGrid(CContextClient* client)1832 TRY1833 {1834 if (computeConnectedClientsScalarGrid_done_.count(client)!=0) return ;1835 1836 CContext* context = CContext::getCurrent();1837 1838 set<int> listReceiverSize ;1839 1840 int receiverSize = client->serverSize;1841 1842 if (listReceiverSize.find(receiverSize)==listReceiverSize.end())1843 {1844 listReceiverSize.insert(receiverSize) ;1845 if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end())1846 {1847 // delete corresponding map in case of recompute, probably because a grid could has been modifiedd1848 // by a transformation1849 connectedServerRank_.erase(receiverSize);1850 connectedDataSize_.erase(receiverSize);1851 globalIndexOnServer_.erase(receiverSize);1852 nbSenders_.erase(receiverSize);1853 }1854 1855 if (client->isServerLeader())1856 {1857 const std::list<int>& ranks = client->getRanksServerLeader();1858 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)1859 {1860 int rank = *itRank;1861 int nb = 1;1862 connectedServerRank_[receiverSize].push_back(rank);1863 connectedDataSize_[receiverSize][rank] = nb;1864 nbSenders_[receiverSize][rank] = nb;1865 }1866 }1867 else1868 {1869 const std::list<int>& ranks = client->getRanksServerNotLeader();1870 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)1871 {1872 int rank = *itRank;1873 int nb = 1;1874 connectedServerRank_[receiverSize].push_back(rank);1875 connectedDataSize_[receiverSize][rank] = nb;1876 nbSenders_[receiverSize][rank] = nb;1877 }1878 }1879 }1880 1881 computeConnectedClientsScalarGrid_done_.insert(client) ;1882 }1883 CATCH_DUMP_ATTR1884 1885 void CGrid::sendIndexScalarGrid(CContextClient* client, const string& gridId)1886 TRY1887 {1888 if (sendIndexScalarGrid_done_.count(client)!=0) return ;1889 else sendIndexScalarGrid_done_.insert(client) ;1890 1891 CContext* context = CContext::getCurrent();1892 1121 1893 string serverGridId = gridId.empty() ? serverGridId=this->getId() : serverGridId=gridId ;1894 1895 int receiverSize = client->serverSize;1896 1897 CEventClient event(getType(), EVENT_ID_INDEX);1898 list<CMessage> listMsg;1899 list<CArray<size_t,1> > listOutIndex;1900 1901 if (client->isServerLeader())1902 {1903 const std::list<int>& ranks = client->getRanksServerLeader();1904 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)1905 {1906 int rank = *itRank;1907 int nb = 1;1908 storeIndex_toSrv_[client].insert(std::make_pair(rank, CArray<int,1>(nb)));1909 listOutIndex.push_back(CArray<size_t,1>(nb));1910 1911 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv_[client][rank];1912 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();1913 1914 for (int k = 0; k < nb; ++k)1915 {1916 outGlobalIndexOnServer(k) = 0;1917 outLocalIndexToServer(k) = 0;1918 }1919 1920 if (context->getServiceType()==CServicesManager::CLIENT) // -> what about for coupling probably unusefull to be check1921 storeIndex_fromSrv_.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));1922 1923 listMsg.push_back(CMessage());1924 listMsg.back() << serverGridId << isCompressible_ << listOutIndex.back();1925 1926 event.push(rank, 1, listMsg.back());1927 }1928 client->sendEvent(event);1929 }1930 else1931 {1932 const std::list<int>& ranks = client->getRanksServerNotLeader();1933 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)1934 {1935 int rank = *itRank;1936 int nb = 1;1937 CArray<int, 1> outLocalIndexToServer(nb);1938 for (int k = 0; k < nb; ++k)1939 {1940 outLocalIndexToServer(k) = 0;1941 }1942 1943 if (context->getServiceType()==CServicesManager::CLIENT)1944 storeIndex_fromSrv_.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));1945 }1946 client->sendEvent(event);1947 }1948 }1949 CATCH_DUMP_ATTR1950 1951 void CGrid::sendIndex(CContextClient* client, const string& gridId)1952 TRY1953 {1954 if (sendIndex_done_.count(client)!=0) return ;1955 else sendIndex_done_.insert(client) ;1956 CContext* context = CContext::getCurrent();1957 string serverGridId = gridId.empty() ? this->getId() : gridId ;1958 1959 1960 1961 int receiverSize = client->serverSize;1962 1963 CEventClient event(getType(), EVENT_ID_INDEX);1964 int rank;1965 list<CMessage> listMsg;1966 list<CArray<size_t,1> > listOutIndex;1967 const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getClientDistribution()->getGlobalLocalDataSendToServer();1968 CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex,1969 iteIndex = globalLocalIndexSendToServer.end();1970 itIndex = itbIndex;1971 1972 if (!doGridHaveDataDistributed(client))1973 {1974 if (client->isServerLeader())1975 {1976 int indexSize = globalLocalIndexSendToServer.size();1977 CArray<size_t,1> outGlobalIndexOnServer(indexSize);1978 CArray<int,1> outLocalIndexToServer(indexSize);1979 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)1980 {1981 outGlobalIndexOnServer(idx) = itIndex->first;1982 outLocalIndexToServer(idx) = itIndex->second;1983 }1984 1985 const std::list<int>& ranks = client->getRanksServerLeader();1986 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)1987 {1988 storeIndex_toSrv_[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));1989 if (context->getServiceType()==CServicesManager::CLIENT) // -> what about for coupling probably unusefull to be check1990 storeIndex_fromSrv_.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));1991 1992 listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));1993 1994 listMsg.push_back(CMessage());1995 listMsg.back() << serverGridId << isCompressible_ << listOutIndex.back();1996 1997 event.push(*itRank, 1, listMsg.back());1998 }1999 client->sendEvent(event);2000 }2001 else2002 {2003 int indexSize = globalLocalIndexSendToServer.size();2004 CArray<int,1> outLocalIndexToServer(indexSize);2005 for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)2006 {2007 outLocalIndexToServer(idx) = itIndex->second;2008 }2009 2010 const std::list<int>& ranks = client->getRanksServerNotLeader();2011 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)2012 {2013 storeIndex_fromSrv_.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));2014 }2015 client->sendEvent(event);2016 }2017 }2018 else2019 {2020 CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;2021 itGlobalMap = globalIndexOnServer_[receiverSize].begin();2022 iteGlobalMap = globalIndexOnServer_[receiverSize].end();2023 2024 std::map<int,std::vector<int> >localIndexTmp;2025 std::map<int,std::vector<size_t> > globalIndexTmp;2026 for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)2027 {2028 int serverRank = itGlobalMap->first;2029 int indexSize = itGlobalMap->second.size();2030 const std::vector<size_t>& indexVec = itGlobalMap->second;2031 for (int idx = 0; idx < indexSize; ++idx)2032 {2033 itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);2034 if (iteIndex != itIndex)2035 {2036 globalIndexTmp[serverRank].push_back(itIndex->first);2037 localIndexTmp[serverRank].push_back(itIndex->second);2038 }2039 }2040 }2041 2042 for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns)2043 {2044 rank = connectedServerRank_[receiverSize][ns];2045 int nb = 0;2046 if (globalIndexTmp.end() != globalIndexTmp.find(rank))2047 nb = globalIndexTmp[rank].size();2048 2049 storeIndex_toSrv_[client].insert(make_pair(rank, CArray<int,1>(nb)));2050 listOutIndex.push_back(CArray<size_t,1>(nb));2051 2052 CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv_[client][rank];2053 CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();2054 2055 for (int k = 0; k < nb; ++k)2056 {2057 outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);2058 outLocalIndexToServer(k) = localIndexTmp[rank].at(k);2059 }2060 2061 storeIndex_fromSrv_.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer)));2062 listMsg.push_back(CMessage());2063 listMsg.back() << serverGridId << isCompressible_ << listOutIndex.back();2064 2065 event.push(rank, nbSenders_[receiverSize][rank], listMsg.back());2066 }2067 client->sendEvent(event);2068 }2069 }2070 CATCH_DUMP_ATTR2071 2072 void CGrid::recvIndex(CEventServer& event)2073 TRY2074 {2075 string gridId;2076 vector<int> ranks;2077 vector<CBufferIn*> buffers;2078 2079 list<CEventServer::SSubEvent>::iterator it;2080 for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)2081 {2082 ranks.push_back(it->rank);2083 CBufferIn* buffer = it->buffer;2084 *buffer >> gridId;2085 buffers.push_back(buffer);2086 }2087 get(gridId)->recvIndex(ranks, buffers, event.getContextServer());2088 }2089 CATCH2090 2091 void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server)2092 TRY2093 {2094 CContextClient* client = server->getAssociatedClient();2095 connectedServerRankRead_ = ranks;2096 for (int n = 0; n < ranks.size(); n++)2097 {2098 int rank = ranks[n];2099 CBufferIn& buffer = *buffers[n];2100 buffer >> isCompressible_; // probably to be removed later2101 CArray<size_t,1> outIndex;2102 buffer >> outIndex;2103 outGlobalIndexFromClient_.insert(std::make_pair(rank, outIndex));2104 connectedDataSizeRead_[rank] = outIndex.numElements();2105 }2106 // ym : displaced to avoid collective call at message reception2107 /*2108 nbReadSenders_[client] = CClientServerMappingDistributed::computeConnectedClients(client->serverSize, client->clientSize,2109 client->intraComm, ranks);2110 */2111 }2112 CATCH_DUMP_ATTR2113 1122 2114 1123 2115 /*!2116 * Compute the number of connected client for a given contextClient and insert it in the nbReadSenders map.2117 * /param[in] client : the given contextClient2118 */2119 void CGrid::computeNbReadSenders(CContextClient* client)2120 TRY2121 2122 {2123 nbReadSenders_[client] = CClientServerMappingDistributed::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRankRead_);2124 }2125 CATCH_DUMP_ATTR2126 2127 void CGrid::computeServerDistribution(void)2128 TRY2129 {2130 if (computeServerDistribution_done_) return ;2131 else computeServerDistribution_done_=true ;2132 2133 CContext* context = CContext::getCurrent();2134 2135 int idx = 0, numElement = axis_domain_order.numElements();2136 int ssize = numElement;2137 std::vector<int> indexMap(numElement);2138 for (int i = 0; i < numElement; ++i)2139 {2140 indexMap[i] = idx;2141 if (2 == axis_domain_order(i))2142 {2143 ++ssize;2144 idx += 2;2145 }2146 else2147 ++idx;2148 }2149 2150 for (int n = 0; n < connectedServerRankRead_.size(); n++)2151 {2152 int rank = connectedServerRankRead_[n];2153 size_t dataSize = 0;2154 2155 if (0 == serverDistribution_)2156 {2157 int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;2158 std::vector<CDomain*> domainList = getDomains();2159 std::vector<CAxis*> axisList = getAxis();2160 std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement);2161 std::vector<CArray<int,1> > globalIndex(numElement);2162 for (int i = 0; i < numElement; ++i)2163 {2164 nGlobElement[i] = globalSize;2165 if (2 == axis_domain_order(i)) //domain2166 {2167 nBegin[indexMap[i]] = domainList[domainId]->ibegin;2168 nSize[indexMap[i]] = domainList[domainId]->ni;2169 nBeginGlobal[indexMap[i]] = 0;2170 nGlob[indexMap[i]] = domainList[domainId]->ni_glo;2171 2172 nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin;2173 nSize[indexMap[i] + 1] = domainList[domainId]->nj;2174 nBeginGlobal[indexMap[i] + 1] = 0;2175 nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;2176 2177 {2178 int count = 0;2179 globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]);2180 for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx)2181 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx)2182 {2183 globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]];2184 ++count;2185 }2186 }2187 2188 ++domainId;2189 }2190 else if (1 == axis_domain_order(i)) // axis2191 {2192 nBegin[indexMap[i]] = axisList[axisId]->begin;2193 nSize[indexMap[i]] = axisList[axisId]->n;2194 nBeginGlobal[indexMap[i]] = 0;2195 nGlob[indexMap[i]] = axisList[axisId]->n_glo;2196 globalIndex[i].resize(nSize[indexMap[i]]);2197 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx)2198 globalIndex[i](idx) = nBegin[indexMap[i]] + idx;2199 2200 ++axisId;2201 }2202 else // scalar2203 {2204 nBegin[indexMap[i]] = 0;2205 nSize[indexMap[i]] = 1;2206 nBeginGlobal[indexMap[i]] = 0;2207 nGlob[indexMap[i]] = 1;2208 globalIndex[i].resize(1);2209 globalIndex[i](0) = 0;2210 ++scalarId;2211 }2212 }2213 dataSize = 1;2214 2215 for (int i = 0; i < nSize.size(); ++i)2216 dataSize *= nSize[i];2217 serverDistribution_ = new CDistributionServer(context->intraCommRank_,2218 globalIndex, axis_domain_order,2219 nBegin, nSize, nBeginGlobal, nGlob);2220 }2221 }2222 }2223 CATCH_DUMP_ATTR2224 2225 2226 2227 2228 2229 2230 /* old interface => transform into compute receivedIndex2231 void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server)2232 TRY2233 {2234 CContext* context = CContext::getCurrent();2235 connectedServerRankRead_ = ranks;2236 2237 nbReadSenders_.clear();2238 CContextClient* client = server->getAssociatedClient();2239 2240 int idx = 0, numElement = axis_domain_order.numElements();2241 int ssize = numElement;2242 std::vector<int> indexMap(numElement);2243 for (int i = 0; i < numElement; ++i)2244 {2245 indexMap[i] = idx;2246 if (2 == axis_domain_order(i))2247 {2248 ++ssize;2249 idx += 2;2250 }2251 else2252 ++idx;2253 }2254 2255 for (int n = 0; n < ranks.size(); n++)2256 {2257 int rank = ranks[n];2258 CBufferIn& buffer = *buffers[n];2259 2260 buffer >> isCompressible_;2261 size_t dataSize = 0;2262 2263 if (0 == serverDistribution_)2264 {2265 int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;2266 std::vector<CDomain*> domainList = getDomains();2267 std::vector<CAxis*> axisList = getAxis();2268 std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement);2269 std::vector<CArray<int,1> > globalIndex(numElement);2270 for (int i = 0; i < numElement; ++i)2271 {2272 nGlobElement[i] = globalSize;2273 if (2 == axis_domain_order(i)) //domain2274 {2275 nBegin[indexMap[i]] = domainList[domainId]->ibegin;2276 nSize[indexMap[i]] = domainList[domainId]->ni;2277 nBeginGlobal[indexMap[i]] = 0;2278 nGlob[indexMap[i]] = domainList[domainId]->ni_glo;2279 2280 nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin;2281 nSize[indexMap[i] + 1] = domainList[domainId]->nj;2282 nBeginGlobal[indexMap[i] + 1] = 0;2283 nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;2284 2285 {2286 int count = 0;2287 globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]);2288 for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx)2289 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx)2290 {2291 globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]];2292 ++count;2293 }2294 }2295 2296 ++domainId;2297 }2298 else if (1 == axis_domain_order(i)) // axis2299 {2300 nBegin[indexMap[i]] = axisList[axisId]->begin;2301 nSize[indexMap[i]] = axisList[axisId]->n;2302 nBeginGlobal[indexMap[i]] = 0;2303 nGlob[indexMap[i]] = axisList[axisId]->n_glo;2304 globalIndex[i].resize(nSize[indexMap[i]]);2305 for (int idx = 0; idx < nSize[indexMap[i]]; ++idx)2306 globalIndex[i](idx) = nBegin[indexMap[i]] + idx;2307 2308 ++axisId;2309 }2310 else // scalar2311 {2312 nBegin[indexMap[i]] = 0;2313 nSize[indexMap[i]] = 1;2314 nBeginGlobal[indexMap[i]] = 0;2315 nGlob[indexMap[i]] = 1;2316 globalIndex[i].resize(1);2317 globalIndex[i](0) = 0;2318 ++scalarId;2319 }2320 }2321 dataSize = 1;2322 2323 for (int i = 0; i < nSize.size(); ++i)2324 dataSize *= nSize[i];2325 serverDistribution_ = new CDistributionServer(context->intraCommRank_,2326 globalIndex, axis_domain_order,2327 nBegin, nSize, nBeginGlobal, nGlob);2328 }2329 2330 CArray<size_t,1> outIndex;2331 buffer >> outIndex;2332 outGlobalIndexFromClient_.insert(std::make_pair(rank, outIndex));2333 connectedDataSizeRead_[rank] = outIndex.numElements();2334 2335 if (doGridHaveDataDistributed(client))2336 {}2337 else2338 {2339 // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER2340 // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar)2341 dataSize = serverDistribution_->getGridSize();2342 }2343 writtenDataSize_ += dataSize;2344 }2345 2346 2347 // Compute mask of the current grid2348 {2349 int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;2350 std::vector<CDomain*> domainList = getDomains();2351 std::vector<CAxis*> axisList = getAxis();2352 int dimSize = 2 * domainList.size() + axisList.size();2353 std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize);2354 for (int i = 0; i < numElement; ++i)2355 {2356 if (2 == axis_domain_order(i)) //domain2357 {2358 nBegin[indexMap[i]] = domainList[domainId]->ibegin;2359 nSize[indexMap[i]] = domainList[domainId]->ni;2360 nBeginGlobal[indexMap[i]] = 0;2361 nGlob[indexMap[i]] = domainList[domainId]->ni_glo;2362 2363 nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin;2364 nSize[indexMap[i] + 1] = domainList[domainId]->nj;2365 nBeginGlobal[indexMap[i] + 1] = 0;2366 nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;2367 ++domainId;2368 }2369 else if (1 == axis_domain_order(i)) // axis2370 {2371 nBegin[indexMap[i]] = axisList[axisId]->begin;2372 nSize[indexMap[i]] = axisList[axisId]->n;2373 nBeginGlobal[indexMap[i]] = 0;2374 nGlob[indexMap[i]] = axisList[axisId]->n_glo;2375 ++axisId;2376 }2377 else // scalar2378 {2379 }2380 }2381 2382 if (nSize.empty()) // Scalar grid2383 {2384 nBegin.push_back(0);2385 nSize.push_back(1);2386 nBeginGlobal.push_back(0);2387 nGlob.push_back(1);2388 }2389 }2390 2391 if (isScalarGrid()) return;2392 2393 nbReadSenders_[client] = CClientServerMappingDistributed::computeConnectedClients(client->serverSize, client->clientSize,2394 client->intraComm, ranks);2395 2396 }2397 CATCH_DUMP_ATTR2398 */2399 2400 2401 1124 /* 2402 1125 Compute on the fly the global dimension of a grid with its elements … … 2495 1218 CATCH_DUMP_ATTR 2496 1219 2497 /*! 2498 Return size of data which is written on each server 2499 Whatever dimension of a grid, data which are written on server must be presented as 2500 an one dimension array. 2501 \return size of data written on server 2502 */ 2503 size_t CGrid::getWrittenDataSize() 2504 TRY 2505 { 2506 return getGridLocalElements()->getView(CElementView::FULL)->getSize() ; 2507 } 2508 CATCH 2509 2510 /*! 2511 Returns the number of indexes written by each server. 2512 \return the number of indexes written by each server 2513 */ 2514 int CGrid::getNumberWrittenIndexes() const 2515 TRY 2516 { 2517 return numberWrittenIndexes_; 2518 } 2519 CATCH 2520 2521 /*! 2522 Returns the total number of indexes written by the servers. 2523 \return the total number of indexes written by the servers 2524 */ 2525 int CGrid::getTotalNumberWrittenIndexes() const 2526 TRY 2527 { 2528 return totalNumberWrittenIndexes_; 2529 } 2530 CATCH 2531 2532 /*! 2533 Returns the offset of indexes written by each server. 2534 \return the offset of indexes written by each server 2535 */ 2536 int CGrid::getOffsetWrittenIndexes() const 2537 TRY 2538 { 2539 return offsetWrittenIndexes_; 2540 } 2541 CATCH 2542 2543 2544 CDistributionClient* CGrid::getClientDistribution() 2545 TRY 2546 { 2547 if (!computeClientDistribution_done_) computeClientDistribution() ; 2548 return clientDistribution_; 2549 } 2550 CATCH_DUMP_ATTR 2551 1220 2552 1221 bool CGrid::doGridHaveDataDistributed(CContextClient* client) 2553 1222 TRY … … 2582 1251 switch(event.type) 2583 1252 { 2584 case EVENT_ID_INDEX :2585 recvIndex(event);2586 return true;2587 break;2588 2589 1253 case EVENT_ID_ADD_DOMAIN : 2590 1254 recvAddDomain(event); … … 2626 1290 gridPtr->sendCreateChild(this->getId(),client); 2627 1291 this->sendAllAttributesToServer(client); 2628 //if (isScalarGrid()) sendIndexScalarGrid(client);2629 //else sendIndex(client);2630 //this->sendAllDomains(client);2631 //this->sendAllAxis(client);2632 //this->sendAllScalars(client);2633 2634 1292 distributeGridToFileServer(client) ; 2635 1293 } … … 3209 1867 if (0 < transformations_->getNbAlgo()) hasTransform_ = true; 3210 1868 3211 // Ok, now need to compute index of grid source 3212 transformGridSrc->checkMaskIndex(false); 3213 } 1869 } 3214 1870 CATCH_DUMP_ATTR 3215 1871 -
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp
r1943 r1973 75 75 enum EEventId 76 76 { 77 EVENT_ID_ INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR,77 EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR, 78 78 EVENT_ID_SEND_MASK, 79 79 … … 117 117 StdSize getLocalDataSize(void) ; 118 118 119 /// Entrees-sorties de champs 120 template <int n> 121 void inputField(const CArray<double,n>& field, CArray<double,1>& stored) ; 122 template <int n> 123 void maskField(const CArray<double,n>& field, CArray<double,1>& stored) ; 124 template <int n> 125 void outputField(const CArray<double,1>& stored, CArray<double,n>& field) ; 126 template <int n> 127 void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) ; 128 119 129 120 virtual void parse(xml::CXMLNode& node); 130 121 … … 155 146 156 147 public: 157 void computeIndexServer(void);158 148 void computeIndex(void); 159 149 void computeIndexScalarGrid(); 160 void computeWrittenIndex();161 150 void solveDomainAxisRef(bool areAttributesChecked); 162 151 void checkElementsAttributes(void) ; … … 202 191 203 192 static bool dispatchEvent(CEventServer& event); 204 static void recvIndex(CEventServer& event);205 void recvIndex(vector<int> ranks, vector<CBufferIn*> buffers, CContextServer* server);206 207 public:208 void sendIndex(CContextClient* client, const string& gridId="");209 private:210 set<CContextClient*> sendIndex_done_ ;211 193 212 194 public: 213 void sendIndexScalarGrid(CContextClient* client, const string& gridId="");214 private:215 set<CContextClient*> sendIndexScalarGrid_done_ ;216 217 public:218 195 void setContextClient(CContextClient* contextClient); 219 196 220 void computeDomConServer();221 std::map<int, int> getDomConServerSide();222 197 std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, bool bufferForWriting = false); 223 198 std::map<int, StdSize> getDataBufferSize(CContextClient* client, const std::string& id = "", bool bufferForWriting = false); … … 237 212 bool doGridHaveDataToWrite(); 238 213 bool doGridHaveDataDistributed(CContextClient* client = 0); 239 size_t getWrittenDataSize() ;240 int getNumberWrittenIndexes() const;241 int getTotalNumberWrittenIndexes() const;242 int getOffsetWrittenIndexes() const;243 214 244 215 CGridTransformation* getTransformations(); … … 255 226 256 227 void completeGrid(CGrid* transformGridSrc = 0); 257 void doAutoDistribution(CGrid* transformGridSrc);258 228 bool isTransformed(); 259 229 void setTransformed(); … … 271 241 272 242 bool hasMask(void) const; 273 void checkMask(void);274 void createMask(void);275 void modifyMask(const CArray<int,1>& indexToModify, bool valueToModify = false);276 void modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue = false);277 278 243 /** get mask pointer stored in mask_1d, or mask_2d, or..., or mask_7d */ 279 244 CArray<bool,1> mask_ ; 280 245 CArray<bool,1>& getMask(void) ; 281 246 282 void computeGridGlobalDimension(const std::vector<CDomain*>& domains, 283 const std::vector<CAxis*>& axis, 284 const std::vector<CScalar*>& scalars, 285 const CArray<int,1>& axisDomainOrder); 286 287 void computeGridIndexToFileServer(CContextClient* client) ; 288 289 private: 247 private: 290 248 /** Client-like distribution calculated based on the knowledge of the entire grid */ 291 249 CDistributionClient* clientDistribution_; … … 298 256 299 257 private: 300 /** Server-like distribution calculated upon receiving indexes */301 CDistributionServer* serverDistribution_;302 void computeServerDistribution(void) ;303 bool computeServerDistribution_done_=false ;304 public:305 CDistributionServer* getServerDistribution(void) { if (!computeServerDistribution_done_) computeServerDistribution() ; return serverDistribution_ ;}306 307 308 private:309 template<int N>310 void checkGridMask(CArray<bool,N>& gridMask,311 const std::vector<CArray<bool,1>* >& domainMasks,312 const std::vector<CArray<bool,1>* >& axisMasks,313 const CArray<int,1>& axisDomainOrder,314 bool createMask = false);315 316 template<int N>317 void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify);318 319 template<int N>320 void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue);321 322 void storeField_arr(const double* const data, CArray<double, 1>& stored) ;323 void restoreField_arr(const CArray<double, 1>& stored, double* const data) ;324 void uncompressField_arr(const double* const data, CArray<double, 1>& outData) ;325 void maskField_arr(const double* const data, CArray<double, 1>& stored) ;326 327 258 void setVirtualDomainGroup(CDomainGroup* newVDomainGroup); 328 259 void setVirtualAxisGroup(CAxisGroup* newVAxisGroup); … … 339 270 void checkAttributesAfterTransformation(); 340 271 void setTransformationAlgorithms(); 341 void computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,342 const CContextClient* client,343 CClientServerMapping::GlobalIndexMap& globalIndexOnServer);344 272 int computeGridGlobalDimension(std::vector<int>& globalDim, 345 273 const std::vector<CDomain*> domains, … … 348 276 const CArray<int,1>& axisDomainOrder); 349 277 int getDistributedDimension(); 350 351 void computeConnectedClients(CContextClient* client); 352 set<CContextClient*> computeConnectedClients_done_ ; 353 354 void computeConnectedClientsScalarGrid(CContextClient* client); 355 set<CContextClient*> computeConnectedClientsScalarGrid_done_ ; 356 357 public: 358 /** Array containing the local index of the grid 359 * storeIndex_client[local_workflow_grid_index] -> local_model_grid_index. 360 * Used to store field from model into the worklow, or to return field into models. 361 * The size of the array is the number of local index of the workflow grid */ 362 CArray<int, 1> storeIndex_client_; 363 void computeStoreIndex_client(void) ; 364 bool computeStoreIndex_client_done_ = false ; 365 CArray<int, 1>& getStoreIndex_client(void) { if (!computeStoreIndex_client_done_) computeStoreIndex_client() ; return storeIndex_client_ ;} 366 367 /** Array containing the grid mask masked defined by the mask_nd grid attribute. 368 * The corresponding masked field value provided by the model will be replaced by a NaN value 369 * in the workflow. */ 370 CArray<bool, 1> storeMask_client_; 371 void computeStoreMask_client(void) ; 372 bool computeStoreMask_client_done_ = false ; 373 CArray<bool, 1>& getStoreMask_client(void) { if (!computeStoreMask_client_done_) computeStoreMask_client() ; return storeMask_client_ ;} 374 375 /** Map containing the indexes on client side that will be sent to each connected server. 376 * storeIndex_toSrv[&contextClient] -> map concerning the contextClient for which the data will be sent (client side) 377 * storeIndex_toSrv[&contextClient][rank] -> array of indexes that will be sent to each "rank" of the connected servers 378 * storeIndex_toSrv[&contextClient][rank](index_of_buffer_sent_to_server) -> local index of the field of the workflow 379 * grid that will be sent to server */ 380 std::map<CContextClient*, map<int, CArray<int, 1> > > storeIndex_toSrv_; 381 382 383 /** Map containing the indexes on client side that will be received from each connected server. 384 * This map is used to agreggate field data received from server (for reading) into a single array, which will be an entry 385 * point of the worklow on client side. 386 * storeIndex_toSrv[rank] -> array of indexes that will be received from each "rank" of the connected servers 387 * storeIndex_toSrv[rank](index_of_buffer_received_from_server) -> local index of the field in the "workflow grid" 388 * that has been received from server */ 389 std::map<int, CArray<int, 1> > storeIndex_fromSrv_; // Support, for now, reading with level-1 server 390 391 392 /** Maps storing the number of participating clients for data sent a specific server for a given contextClient, identified 393 * by the servers communicator size. In future must be direcly identified by context. 394 * nbSender_[context_server_size] -> map the number of client sender by connected rank of servers 395 * nbSender_[context_server_size] [rank_server] -> the number of client participating to a send message for a server of rank "rank_server" 396 * Usefull to indicate in a message the number of participant needed by the transfer protocol */ 397 std::map<int, std::map<int,int> > nbSenders_; 398 399 private: 400 /** Maps storing the number of participating servers for data sent a specific client for a given contextClient. 401 * Symetric of nbSenders_, but for server side which want to send data to client. 402 * nbReadSender_[context_client_size] -> map the number of server sender by connected rank of clients 403 * nbReadSender_[context_client_size] [rank_client] -> the number of server participating to a send message for a client of rank "rank_client" 404 * Usefull to indicate in a message the number of participant needed by the transfer protocol */ 405 std::map<CContextClient*, std::map<int,int> > nbReadSenders_; 406 public: 407 std::map<int,int>& getNbReadSenders(CContextClient* client) 408 { if (nbReadSenders_.count(client)==0) computeNbReadSenders(client) ; return nbReadSenders_[client] ;} 409 private: 410 void computeNbReadSenders(CContextClient* client) ; 411 412 413 // Manh Ha's comment: " A client receives global index from other clients (via recvIndex) 414 // then does mapping these index into local index of STORE_CLIENTINDEX 415 // In this way, store_clientIndex can be used as an input of a source filter 416 // Maybe we need a flag to determine whether a client wants to write. TODO " 417 418 private: 419 /** Map storing received data on server side. This map is the equivalent to the storeIndex_client, but for data received from client 420 * instead that from model. This map is used to concatenate data received from several clients into a single array on server side 421 * which match the local workflow grid. 422 * outLocalIndexStoreOnClient_[client_rank] -> Array of index from client of rank "client_rank" 423 * outLocalIndexStoreOnClient_[client_rank](index of buffer from client) -> local index of the workflow grid 424 * The map is created in CGrid::computeClientIndex and filled upon receiving data in CField::recvUpdateData(). 425 * Symetrically it is also used to send data from a server to several client for reading case. */ 426 map<int, CArray<size_t, 1>> outLocalIndexStoreOnClient_; 427 public: 428 void computeOutLocalIndexStoreOnClient(void) ; 429 private: 430 bool computeOutLocalIndexStoreOnClient_done_ = false ; 431 public: 432 map<int, CArray<size_t, 1>>& getOutLocalIndexStoreOnClient(void) 433 { if (!computeOutLocalIndexStoreOnClient_done_) computeOutLocalIndexStoreOnClient(); return outLocalIndexStoreOnClient_ ; } 434 435 public: 436 /** Indexes calculated based on server-like distribution. 437 * They are used for writing/reading data and only calculated for server level that does the writing/reading. 438 * Along with localIndexToWriteOnClient, these indexes are used to correctly place incoming data. 439 * size of the array : numberWrittenIndexes_ : number of index written in a compressed way 440 * localIndexToWriteOnServer_(compressed_written_index) : -> local uncompressed index that will be written in the file */ 441 CArray<size_t,1> localIndexToWriteOnServer_; 442 443 /** Indexes calculated based on client-like distribution. 444 * They are used for writing/reading data and only calculated for server level that does the writing/reading. 445 * Along with localIndexToWriteOnServer, these indexes are used to correctly place incoming data. 446 * size of the array : numberWrittenIndexes_ 447 * localIndexToWriteOnClient_(compressed_written_index) -> local index of the workflow grid*/ 448 CArray<size_t,1> localIndexToWriteOnClient_; 449 450 public: 278 public: 279 451 280 bool isDataDistributed(void) ; 452 281 private: … … 455 284 std::list<CContextClient*> clients; 456 285 std::set<CContextClient*> clientsSet; 457 458 private:459 /** Map storing received indexes on server side sent by clients. Key = sender rank, value = global index array.460 Later, the global indexes received will be mapped onto local index computed with the local distribution.461 outGlobalIndexFromClient_[rank] -> array of global index send by client of rank "rank"462 outGlobalIndexFromClient_[rank](n) -> global index of datav n sent by client463 */464 map<int, CArray<size_t, 1> > outGlobalIndexFromClient_;465 public:466 map<int, CArray<size_t, 1> >& getOutGlobalIndexFromClient() { return outGlobalIndexFromClient_ ;}467 286 468 287 private: … … 476 295 std::vector<std::string> axisList_, domList_, scalarList_; 477 296 bool isAxisListSet, isDomListSet, isScalarListSet; 478 479 CClientServerMapping* clientServerMap_;480 int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_;481 297 482 298 /** Map storing local ranks of connected receivers. Key = size of receiver's intracomm. … … 499 315 500 316 bool isTransformed_, isGenerated_; 501 bool computedWrittenIndex_;502 317 503 318 std::vector<int> axisPositionInGrid_; … … 511 326 bool hasTransform_; 512 327 513 /** Map storing global indexes of server-like (band-wise) distribution for sending to receivers (client side).514 * Key = size of receiver's intracomm (i.e. number of servers)515 * ~ map<int, umap<int, std::vector<size_t> >> globalIndexOnServer_516 * globalIndexOnServer_[servers_size] -> map for a distribution of size "servers_size" (number of servers)517 * globalIndexOnServer_[servers_size][server_rank] -> array of global index managed by server of rank "server_rank"518 * globalIndexOnServer_[servers_size][server_rank][n] -> global index of data to be send to the server by client based on sub element of the grid.519 * -> grid masking is not included.520 */521 // std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;522 std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;523 524 525 328 ////////////////////////////////////////////////////////////////////////////////////// 526 329 // this part is related to distribution, element definition, views and connectors // … … 602 405 }; // class CGrid 603 406 604 ///--------------------------------------------------------------605 606 template <int n>607 void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored)608 TRY609 {610 //#ifdef __XIOS_DEBUG611 if (this->getDataSize() != field.numElements())612 ERROR("void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const",613 << "[ Awaiting data of size = " << this->getDataSize() << ", "614 << "Received data size = " << field.numElements() << " ] "615 << "The data array does not have the right size! "616 << "Grid = " << this->getId())617 //#endif618 this->storeField_arr(field.dataFirst(), stored);619 }620 CATCH621 622 /* obsolete623 template <int n>624 void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)625 {626 //#ifdef __XIOS_DEBUG627 if (this->getDataSize() != field.numElements())628 ERROR("void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const",629 << "[ Awaiting data of size = " << this->getDataSize() << ", "630 << "Received data size = " << field.numElements() << " ] "631 << "The data array does not have the right size! "632 << "Grid = " << this->getId())633 //#endif634 this->maskField_arr(field.dataFirst(), stored);635 }636 */637 template <int n>638 void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)639 {640 auto connector = getModelToWorkflowConnector() ;641 642 if (connector->getSrcSize() != field.numElements())643 ERROR("void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const",644 << "[ Awaiting data of size = " << this->getDataSize() << ", "645 << "Received data size = " << field.numElements() << " ] "646 << "The data array does not have the right size! "647 << "Grid = " << this->getId())648 const double nanValue = std::numeric_limits<double>::quiet_NaN();649 connector->transfer(field, stored, nanValue) ;650 }651 652 653 654 template <int n>655 void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field)656 TRY657 {658 //#ifdef __XIOS_DEBUG659 if (this->getDataSize() != field.numElements())660 ERROR("void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const",661 << "[ Size of the data = " << this->getDataSize() << ", "662 << "Output data size = " << field.numElements() << " ] "663 << "The ouput array does not have the right size! "664 << "Grid = " << this->getId())665 //#endif666 this->restoreField_arr(stored, field.dataFirst());667 }668 CATCH669 670 /*!671 This function removes the effect of mask on received data on the server.672 This function only serve for the checking purpose. TODO: Something must be done to seperate mask and data_index from each other in received data673 \data data received data with masking effect on the server674 \outData data without masking effect675 */676 template <int N>677 void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData)678 TRY679 {680 uncompressField_arr(data.dataFirst(), outData);681 }682 CATCH683 684 template<int N>685 void CGrid::checkGridMask(CArray<bool,N>& gridMask,686 const std::vector<CArray<bool,1>* >& domainMasks,687 const std::vector<CArray<bool,1>* >& axisMasks,688 const CArray<int,1>& axisDomainOrder,689 bool createMask)690 TRY691 {692 int idx = 0;693 int numElement = axisDomainOrder.numElements();694 int dim = domainMasks.size() * 2 + axisMasks.size();695 std::vector<CDomain*> domainP = this->getDomains();696 std::vector<CAxis*> axisP = this->getAxis();697 698 std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim);699 std::vector<int> currentIndex(dim);700 int idxDomain = 0, idxAxis = 0;701 for (int i = 0; i < numElement; ++i)702 {703 indexMap[i] = idx;704 if (2 == axisDomainOrder(i)) {705 eachDimSize[indexMap[i]] = domainP[idxDomain]->ni;706 eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj;707 idx += 2; ++idxDomain;708 }709 else if (1 == axisDomainOrder(i)) {710 // eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements();711 eachDimSize[indexMap[i]] = axisP[idxAxis]->n;712 ++idx; ++idxAxis;713 }714 else {};715 }716 717 if (!gridMask.isEmpty() && !createMask)718 {719 for (int i = 0; i < dim; ++i)720 {721 if (gridMask.extent(i) != eachDimSize[i])722 ERROR("CGrid::checkMask(void)",723 << "The mask has one dimension whose size is different from the one of the local grid." << std::endl724 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl725 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl726 << "Grid = " << this->getId())727 }728 }729 else {730 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);731 gridMask = true;732 }733 734 int ssize = gridMask.numElements();735 idx = 0;736 while (idx < ssize)737 {738 for (int i = 0; i < dim-1; ++i)739 {740 if (idxLoop[i] == eachDimSize[i])741 {742 idxLoop[i] = 0;743 ++idxLoop[i+1];744 }745 }746 747 // Find out outer index748 idxDomain = idxAxis = 0;749 bool maskValue = true;750 for (int i = 0; i < numElement; ++i)751 {752 if (2 == axisDomainOrder(i))753 {754 int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]];755 if (idxTmp < (*domainMasks[idxDomain]).numElements())756 maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp);757 else758 maskValue = false;759 ++idxDomain;760 }761 else if (1 == axisDomainOrder(i))762 {763 int idxTmp = idxLoop[indexMap[i]];764 if (idxTmp < (*axisMasks[idxAxis]).numElements())765 maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp);766 else767 maskValue = false;768 769 ++idxAxis;770 }771 }772 773 int maskIndex = idxLoop[0];774 int mulDim = 1;775 for (int k = 1; k < dim; ++k)776 {777 mulDim *= eachDimSize[k-1];778 maskIndex += idxLoop[k]*mulDim;779 }780 *(gridMask.dataFirst()+maskIndex) &= maskValue;781 782 ++idxLoop[0];783 ++idx;784 }785 }786 CATCH_DUMP_ATTR787 788 template<int N>789 void CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,790 const std::vector<int>& eachDimSize,791 bool newValue)792 TRY793 {794 if (N != eachDimSize.size())795 {796 // ERROR("CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,797 // const std::vector<int>& eachDimSize,798 // bool newValue)",799 // << "Dimension size of the mask is different from input dimension size." << std::endl800 // << "Mask dimension is " << N << "." << std::endl801 // << "Input dimension is " << eachDimSize.size() << "." << std::endl802 // << "Grid = " << this->getId())803 }804 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);805 gridMask = newValue;806 }807 CATCH_DUMP_ATTR808 809 810 /*!811 Modify the current mask of grid, the local index to be modified will take value false812 \param [in/out] gridMask current mask of grid813 \param [in] indexToModify local index to modify814 */815 template<int N>816 void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify)817 TRY818 {819 int num = indexToModify.numElements();820 for (int idx = 0; idx < num; ++idx)821 {822 *(gridMask.dataFirst()+indexToModify(idx)) = valueToModify;823 }824 }825 CATCH_DUMP_ATTR826 827 ///--------------------------------------------------------------828 829 830 831 407 // Declare/Define CGridGroup and CGridDefinition 832 408 DECLARE_GROUP(CGrid);
Note: See TracChangeset
for help on using the changeset viewer.