Changeset 1637 for XIOS/trunk/src/node
- Timestamp:
- 01/14/19 13:33:48 (5 years ago)
- Location:
- XIOS/trunk/src/node
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/node/axis.cpp
r1622 r1637 274 274 TRY 275 275 { 276 if (this->n_glo.isEmpty()) 276 CContext* context=CContext::getCurrent(); 277 278 if (this->n_glo.isEmpty()) 277 279 ERROR("CAxis::checkAttributes(void)", 278 280 << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " … … 314 316 } 315 317 316 // Remove this check because it doesn't make sense in case of a hole or overlapping axes317 318 if (!this->value.isEmpty()) 318 319 { 319 // StdSize true_size = value.numElements(); 320 // if (this->n.getValue() != true_size) 321 // ERROR("CAxis::checkAttributes(void)", 322 // << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 323 // << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 320 // Avoid this check at writing because it fails in case of a hole 321 if (context->hasClient) 322 { 323 StdSize true_size = value.numElements(); 324 if (this->n.getValue() != true_size) 325 ERROR("CAxis::checkAttributes(void)", 326 << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 327 << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size 328 << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 329 } 324 330 this->hasValue = true; 325 331 } … … 327 333 this->checkBounds(); 328 334 329 CContext* context=CContext::getCurrent();330 335 if (context->hasClient) 331 336 { 337 this->checkMask(); 332 338 this->checkData(); 333 this->checkMask();334 339 this->checkLabel(); 335 340 } … … 338 343 339 344 /*! 340 Check the validity of data and fill in values if any.345 Check the validity of data, fill in values if any, and apply mask. 341 346 */ 342 347 void CAxis::checkData() … … 359 364 { 360 365 data_index.resize(data_n); 361 for (int i = 0; i < data_n; ++i) data_index(i) = i; 362 } 366 for (int i = 0; i < data_n; ++i) 367 { 368 if ((i+data_begin) >= 0 && (i+data_begin<n)) 369 { 370 if (mask(i+data_begin)) 371 data_index(i) = i+data_begin; 372 else 373 data_index(i) = -1; 374 } 375 else 376 data_index(i) = -1; 377 } 378 } 379 else 380 { 381 if (data_index.numElements() != data_n) 382 { 383 ERROR("CAxis::checkData(void)", 384 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 385 << "The size of data_index = "<< data_index.numElements() << "is not equal to the data size data_n = " << data_n.getValue() << ")."); 386 } 387 for (int i = 0; i < data_n; ++i) 388 { 389 if ((i+data_begin) >= 0 && (i+data_begin<n) && !mask(i+data_begin)) 390 data_index(i) = -1; 391 } 392 } 393 363 394 } 364 395 CATCH_DUMP_ATTR … … 377 408 if (!mask.isEmpty()) 378 409 { 379 if (mask.extent(0) != n) 380 ERROR("CAxis::checkMask(void)", 381 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 382 << "The mask does not have the same size as the local domain." << std::endl 383 << "Local size is " << n.getValue() << "." << std::endl 384 << "Mask size is " << mask.extent(0) << "."); 385 } 386 else // (mask.isEmpty()) 387 { // If no mask was defined, we create a default one without any masked point. 388 mask.resize(n); 389 for (int i = 0; i < n; ++i) 390 { 391 mask(i) = true; 392 } 410 if (mask.extent(0) != n) 411 { 412 ERROR("CAxis::checkMask(void)", 413 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] " 414 << "The mask does not have the same size as the local domain." << std::endl 415 << "Local size is " << n.getValue() << "." << std::endl 416 << "Mask size is " << mask.extent(0) << "."); 417 } 418 } 419 else 420 { 421 mask.resize(n); 422 mask = true; 393 423 } 394 424 } … … 598 628 599 629 // Calculate the compressed index if any 600 std::set<int> writtenInd;601 if (isCompressible_)602 {603 for (int idx = 0; idx < data_index.numElements(); ++idx)604 {605 int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);606 607 if (ind >= 0 && ind < ni && mask(ind))608 {609 ind += ibegin;610 writtenInd.insert(ind);611 }612 }613 }630 // std::set<int> writtenInd; 631 // if (isCompressible_) 632 // { 633 // for (int idx = 0; idx < data_index.numElements(); ++idx) 634 // { 635 // int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 636 // 637 // if (ind >= 0 && ind < ni && mask(ind)) 638 // { 639 // ind += ibegin; 640 // writtenInd.insert(ind); 641 // } 642 // } 643 // } 614 644 615 645 // Compute the global index of the current client (process) hold … … 680 710 connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 681 711 682 712 nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 683 713 684 714 delete clientServerMap; … … 718 748 CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 719 749 itSrve = writtenGlobalIndex.end(), itSrv; 750 751 localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 752 nbWritten = 0; 720 753 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 721 754 { … … 723 756 if (ite != globalLocalIndexMap_.find(indGlo)) 724 757 { 725 ++nbWritten;726 }727 }728 729 localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());730 // localIndexToWriteOnServer.resize(nbWritten);731 732 nbWritten = 0;733 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)734 {735 indGlo = *itSrv;736 if (ite != globalLocalIndexMap_.find(indGlo))737 {738 758 localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 739 ++nbWritten; 740 } 741 } 759 } 760 else 761 { 762 localIndexToWriteOnServer(nbWritten) = -1; 763 } 764 ++nbWritten; 765 } 766 742 767 } 743 768 CATCH_DUMP_ATTR … … 780 805 } 781 806 } 807 // 808 // nbWritten = 0; 809 // for (int idx = 0; idx < data_index.numElements(); ++idx) 810 // { 811 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 812 // { 813 // ++nbWritten; 814 // } 815 // } 816 // 817 // compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 818 // nbWritten = 0; 819 // for (int idx = 0; idx < data_index.numElements(); ++idx) 820 // { 821 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 822 // { 823 // compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)]; 824 // ++nbWritten; 825 // } 826 // } 782 827 783 828 nbWritten = 0; … … 1027 1072 1028 1073 /* 1029 Send a ttributes of axis from a group of client to other group of clients/servers1030 onsupposing that these attributes are distributed among the clients of the sending group1031 In thefuture, if new attributes are added, they should also be processed in this function1074 Send axis attributes from a group of clients to another group of clients/servers 1075 supposing that these attributes are distributed among the clients of the sending group 1076 In future, if new attributes are added, they should also be processed in this function 1032 1077 */ 1033 1078 void CAxis::sendDistributedAttributes(void) 1034 1079 TRY 1035 1080 { 1036 int ns, n, i, j, ind, nv, idx;1081 int ind, idx; 1037 1082 std::list<CContextClient*>::iterator it; 1038 1083 … … 1046 1091 list<CMessage> listData; 1047 1092 list<CArray<int,1> > list_indi, list_dataInd; 1048 list<CArray<bool,1> > list_mask;1049 1093 list<CArray<double,1> > list_val; 1050 1094 list<CArray<double,2> > list_bounds; 1051 1095 list<CArray<string,1> > list_label; 1052 1096 1097 // Cut off the ghost points 1053 1098 int nbIndex = index.numElements(); 1054 1099 CArray<int,1> dataIndex(nbIndex); … … 1057 1102 { 1058 1103 if (0 <= data_index(idx) && data_index(idx) < nbIndex) 1059 dataIndex( idx) = 1;1104 dataIndex(data_index(idx)) = 1; 1060 1105 } 1061 1106 … … 1064 1109 for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k) 1065 1110 { 1066 int nbData = 0 ;1111 int nbData = 0, nbDataCount = 0; 1067 1112 int rank = connectedServerRank_[nbServer][k]; 1068 1113 it = indSrv_[nbServer].find(rank); … … 1071 1116 1072 1117 list_indi.push_back(CArray<int,1>(nbData)); 1073 list_dataInd.push_back(CArray<int,1>(nbData)); 1074 list_mask.push_back(CArray<bool,1>(nbData)); 1118 list_dataInd.push_back(CArray<int,1>(nbData)); 1075 1119 1076 1120 if (hasValue) … … 1084 1128 1085 1129 CArray<int,1>& indi = list_indi.back(); 1086 CArray<int,1>& dataIndi = list_dataInd.back(); 1087 CArray<bool,1>& maskIndi = list_mask.back();1088 1089 for ( n = 0; n < nbData; ++n)1130 CArray<int,1>& dataIndi = list_dataInd.back(); 1131 dataIndi = -1; 1132 1133 for (int n = 0; n < nbData; ++n) 1090 1134 { 1091 1135 idx = static_cast<int>(it->second[n]); … … 1094 1138 ind = globalLocalIndexMap_[idx]; 1095 1139 dataIndi(n) = dataIndex(ind); 1096 maskIndi(n) = mask(ind);1097 1140 1098 1141 if (hasValue) … … 1118 1161 listData.push_back(CMessage()); 1119 1162 listData.back() << this->getId() 1120 << list_indi.back() << list_dataInd.back() << list_mask.back();1163 << list_indi.back() << list_dataInd.back(); 1121 1164 1122 1165 listData.back() << hasValue; … … 1173 1216 int nbReceived = ranks.size(), idx, ind, gloInd, locInd; 1174 1217 vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived); 1175 vector<CArray<bool,1> > vec_mask(nbReceived);1176 1218 vector<CArray<double,1> > vec_val(nbReceived); 1177 1219 vector<CArray<double,2> > vec_bounds(nbReceived); … … 1183 1225 buffer >> vec_indi[idx]; 1184 1226 buffer >> vec_dataInd[idx]; 1185 buffer >> vec_mask[idx];1186 1227 1187 1228 buffer >> hasValue; … … 1220 1261 if (0 == globalLocalIndexMap_.count(gloInd)) 1221 1262 { 1222 index(nbInd Loc) = gloInd % n_glo;1223 globalLocalIndexMap_[gloInd] = nbInd Loc;1263 index(nbIndexGlob) = gloInd % n_glo; 1264 globalLocalIndexMap_[gloInd] = nbIndexGlob; 1224 1265 ++nbIndexGlob; 1225 1266 } … … 1234 1275 CArray<int,1> nonCompressedData(nbData); 1235 1276 nonCompressedData = -1; 1236 mask.resize(nbData); 1277 // Mask is incorporated into data_index and is not sent/received anymore 1278 mask.resize(0); 1237 1279 if (hasValue) 1238 1280 value.resize(nbData); … … 1247 1289 CArray<int,1>& indi = vec_indi[idx]; 1248 1290 CArray<int,1>& dataIndi = vec_dataInd[idx]; 1249 CArray<bool,1>& maskIndi = vec_mask[idx];1250 1291 int nb = indi.numElements(); 1251 1292 for (int n = 0; n < nb; ++n) … … 1255 1296 nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd); 1256 1297 1257 if (!mask(locInd)) // Only rewrite mask if it's not true1258 mask(locInd) = maskIndi(n);1259 1260 1298 if (hasValue) 1261 1299 value(locInd) = vec_val[idx](n); … … 1272 1310 } 1273 1311 1274 int nbCompressedData = 0; 1312 int nbCompressedData = 0; 1275 1313 for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 1276 1314 { 1277 1315 if (0 <= nonCompressedData(idx)) 1278 ++nbCompressedData; 1316 ++nbCompressedData; 1279 1317 } 1280 1318 … … 1286 1324 { 1287 1325 data_index(nbCompressedData) = idx % n; 1288 ++nbCompressedData; 1326 ++nbCompressedData; 1289 1327 } 1290 1328 } 1291 1329 1292 1330 data_begin.setValue(0); 1331 data_n.setValue(data_index.numElements()); 1293 1332 } 1294 1333 CATCH_DUMP_ATTR -
XIOS/trunk/src/node/axis.hpp
r1562 r1637 126 126 bool hasLabel; 127 127 128 CArray< size_t,1> localIndexToWriteOnServer;128 CArray<int,1> localIndexToWriteOnServer; 129 129 130 130 private: -
XIOS/trunk/src/node/domain.cpp
r1622 r1637 179 179 // size estimation for sendIndex (and sendArea which is always smaller or equal) 180 180 size_t sizeIndexEvent = 2 * sizeof(size_t) + 2 * CArray<int,1>::size(idxCount); 181 // if (isCompressible_)182 // {183 // std::map<int, std::vector<int> >::const_iterator itWritten = indWrittenSrv_.find(rank);184 // size_t writtenIdxCount = (itWritten != itWrittenIndexEnd) ? itWritten->second.size() : 0;185 // sizeIndexEvent += CArray<int,1>::size(writtenIdxCount);186 // }187 181 188 182 // size estimation for sendLonLat … … 1139 1133 TRY 1140 1134 { 1135 int i,j,ind; 1141 1136 if (!data_i_index.isEmpty()) 1142 1137 { … … 1159 1154 << "'data_j_index' must be defined when 'data_i_index' is set and 'data_dim' is 2."); 1160 1155 } 1156 for (int k=0; k<data_i_index.numElements(); ++k) 1157 { 1158 i = data_i_index(k)+data_ibegin ; 1159 j = data_j_index(k)+data_jbegin ; 1160 if (i>=0 && i<ni && j>=0 && j<nj) 1161 { 1162 ind=j*ni+i ; 1163 if (!domainMask(ind)) 1164 { 1165 data_i_index(k) = -1; 1166 data_j_index(k) = -1; 1167 } 1168 } 1169 else 1170 { 1171 data_i_index(k) = -1; 1172 data_j_index(k) = -1; 1173 } 1174 } 1161 1175 } 1162 1176 else // (1 == data_dim) … … 1165 1179 { 1166 1180 data_j_index.resize(data_ni); 1167 for (int j = 0; j < data_ni; ++j) data_j_index(j) = 0; 1181 data_j_index = 0; 1182 } 1183 for (int k=0; k<data_i_index.numElements(); ++k) 1184 { 1185 i=data_i_index(k)+data_ibegin ; 1186 if (i>=0 && i < domainMask.size()) 1187 { 1188 if (!domainMask(i)) data_i_index(k) = -1; 1189 } 1190 else 1191 data_i_index(k) = -1; 1192 1193 if (!domainMask(i)) data_i_index(k) = -1; 1168 1194 } 1169 1195 } … … 1180 1206 data_i_index.resize(data_ni); 1181 1207 data_j_index.resize(data_ni); 1182 1183 for (int i = 0; i < data_ni; ++i) 1208 data_j_index = 0; 1209 1210 for (int k = 0; k < data_ni; ++k) 1184 1211 { 1185 data_i_index(i) = i; 1186 data_j_index(i) = 0; 1212 i=k+data_ibegin ; 1213 if (i>=0 && i < domainMask.size()) 1214 { 1215 if (domainMask(i)) 1216 data_i_index(k) = k; 1217 else 1218 data_i_index(k) = -1; 1219 } 1220 else 1221 data_i_index(k) = -1; 1187 1222 } 1188 1223 } … … 1193 1228 data_j_index.resize(dsize); 1194 1229 1195 for(int count = 0, j = 0; j < data_nj; ++j)1230 for(int count = 0, kj = 0; kj < data_nj; ++kj) 1196 1231 { 1197 for(int i = 0; i < data_ni; ++i, ++count)1232 for(int ki = 0; ki < data_ni; ++ki, ++count) 1198 1233 { 1199 data_i_index(count) = i; 1200 data_j_index(count) = j; 1234 i = ki + data_ibegin; 1235 j = kj + data_jbegin; 1236 ind=j*ni+i ; 1237 if (i>=0 && i<ni && j>=0 && j<nj) 1238 { 1239 if (domainMask(ind)) 1240 { 1241 data_i_index(count) = ki; 1242 data_j_index(count) = kj; 1243 } 1244 else 1245 { 1246 data_i_index(count) = -1; 1247 data_j_index(count) = -1; 1248 } 1249 } 1250 else 1251 { 1252 data_i_index(count) = -1; 1253 data_j_index(count) = -1; 1254 } 1201 1255 } 1202 1256 } … … 1872 1926 connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 1873 1927 1928 // Now check if all servers have data to receive. If not, master client will send empty data. 1929 // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 1930 std::vector<int> counts (clientSize); 1931 std::vector<int> displs (clientSize); 1932 displs[0] = 0; 1933 int localCount = connectedServerRank_[nbServer].size() ; 1934 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 1935 for (int i = 0; i < clientSize-1; ++i) 1936 { 1937 displs[i+1] = displs[i] + counts[i]; 1938 } 1939 std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]); 1940 MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 1941 1942 if ((allConnectedServers.size() != nbServer) && (rank == 0)) 1943 { 1944 std::vector<bool> isSrvConnected (nbServer, false); 1945 for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 1946 for (int i = 0; i < nbServer; ++i) 1947 { 1948 if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i); 1949 } 1950 } 1874 1951 nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 1875 1952 delete clientServerMap; … … 1908 1985 itSrve = writtenGlobalIndex.end(), itSrv; 1909 1986 1910 // for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)1911 // {1912 // indGlo = *itSrv;1913 // if (ite != globalLocalIndexMap_.find(indGlo))1914 // {1915 // ++nbWritten;1916 // }1917 // }1918 1919 // localIndexToWriteOnServer.resize(nbWritten);1920 1987 localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 1921 1922 1988 nbWritten = 0; 1923 1989 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) … … 1927 1993 { 1928 1994 localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 1929 ++nbWritten;1930 1995 } 1931 1996 else 1932 1997 { 1933 localIndexToWriteOnServer(nbWritten) = 0; 1934 ++nbWritten; 1935 } 1936 } 1937 1938 // if (isCompressible()) 1939 // { 1940 // nbWritten = 0; 1941 // std::unordered_map<size_t,size_t> localGlobalIndexMap; 1942 // for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 1943 // { 1944 // indGlo = *itSrv; 1945 // if (ite != globalLocalIndexMap_.find(indGlo)) 1946 // { 1947 // localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 1948 // ++nbWritten; 1949 // } 1950 // } 1951 1952 // nbWritten = 0; 1953 // for (int idx = 0; idx < data_i_index.numElements(); ++idx) 1954 // { 1955 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 1956 // { 1957 // ++nbWritten; 1958 // } 1959 // } 1960 1961 // compressedIndexToWriteOnServer.resize(nbWritten); 1962 // nbWritten = 0; 1963 // for (int idx = 0; idx < data_i_index.numElements(); ++idx) 1964 // { 1965 // if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 1966 // { 1967 // compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_i_index(idx)]; 1968 // ++nbWritten; 1969 // } 1970 // } 1971 1972 // numberWrittenIndexes_ = nbWritten; 1973 // if (isDistributed()) 1974 // { 1975 // MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 1976 // MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 1977 // offsetWrittenIndexes_ -= numberWrittenIndexes_; 1978 // } 1979 // else 1980 // totalNumberWrittenIndexes_ = numberWrittenIndexes_; 1981 // } 1998 localIndexToWriteOnServer(nbWritten) = -1; 1999 } 2000 ++nbWritten; 2001 } 1982 2002 } 1983 2003 CATCH_DUMP_ATTR … … 2063 2083 sendDistributionAttributes(); 2064 2084 sendIndex(); 2065 sendMask();2066 2085 sendLonLat(); 2067 2086 sendArea(); … … 2174 2193 2175 2194 /*! 2176 Send mask index from client to connected(s) clients2177 */2178 void CDomain::sendMask()2179 TRY2180 {2181 int ns, n, i, j, ind, nv, idx;2182 std::list<CContextClient*>::iterator it;2183 for (it=clients.begin(); it!=clients.end(); ++it)2184 {2185 CContextClient* client = *it;2186 int serverSize = client->serverSize;2187 2188 // send area for each connected server2189 CEventClient eventMask(getType(), EVENT_ID_MASK);2190 2191 list<CMessage> list_msgsMask;2192 list<CArray<bool,1> > list_mask;2193 2194 std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;2195 iteMap = indSrv_[serverSize].end();2196 for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)2197 {2198 int nbData = 0;2199 int rank = connectedServerRank_[serverSize][k];2200 it = indSrv_[serverSize].find(rank);2201 if (iteMap != it)2202 nbData = it->second.size();2203 list_mask.push_back(CArray<bool,1>(nbData));2204 2205 const std::vector<size_t>& temp = it->second;2206 for (n = 0; n < nbData; ++n)2207 {2208 idx = static_cast<int>(it->second[n]);2209 list_mask.back()(n) = domainMask(globalLocalIndexMap_[idx]);2210 }2211 2212 list_msgsMask.push_back(CMessage());2213 list_msgsMask.back() << this->getId() << list_mask.back();2214 eventMask.push(rank, nbSenders[serverSize][rank], list_msgsMask.back());2215 }2216 client->sendEvent(eventMask);2217 }2218 }2219 CATCH_DUMP_ATTR2220 2221 /*!2222 2195 Send area from client to connected client(s) 2223 2196 */ … … 2458 2431 case EVENT_ID_INDEX: 2459 2432 recvIndex(event); 2460 return true;2461 break;2462 case EVENT_ID_MASK:2463 recvMask(event);2464 2433 return true; 2465 2434 break; … … 2555 2524 jIndex = (jIndex < 0) ? 0 : jIndex; 2556 2525 nbIndLoc = iIndex + ni * jIndex; 2557 if (nbIndLoc < nbIndexGlobMax) 2558 { 2559 i_index(nbIndLoc) = index % ni_glo; 2560 j_index(nbIndLoc) = index / ni_glo; 2561 globalLocalIndexMap_[index] = nbIndLoc; 2562 ++nbIndGlob; 2563 } 2564 // i_index(nbIndGlob) = index % ni_glo; 2565 // j_index(nbIndGlob) = index / ni_glo; 2566 // globalLocalIndexMap_[index] = nbIndGlob; 2567 // ++nbIndGlob; 2526 i_index(nbIndGlob) = index % ni_glo; 2527 j_index(nbIndGlob) = index / ni_glo; 2528 globalLocalIndexMap_[index] = nbIndGlob; 2529 ++nbIndGlob; 2568 2530 } 2569 2531 } … … 2580 2542 j_index.resizeAndPreserve(nbIndGlob); 2581 2543 } 2544 2545 domainMask.resize(0); // Mask is not defined anymore on servers 2582 2546 } 2583 2547 CATCH … … 2619 2583 2620 2584 } 2621 CATCH_DUMP_ATTR 2622 2623 /*! 2624 Receive area event from clients(s) 2625 \param[in] event event contain info about rank and associated area 2626 */ 2627 void CDomain::recvMask(CEventServer& event) 2628 TRY 2629 { 2630 string domainId; 2631 std::map<int, CBufferIn*> rankBuffers; 2632 2633 list<CEventServer::SSubEvent>::iterator it; 2634 for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 2635 { 2636 CBufferIn* buffer = it->buffer; 2637 *buffer >> domainId; 2638 rankBuffers[it->rank] = buffer; 2639 } 2640 get(domainId)->recvMask(rankBuffers); 2641 } 2642 CATCH 2643 2644 /*! 2645 Receive mask information from client(s) 2646 \param[in] rankBuffers rank of sending client and the corresponding receive buffer 2647 */ 2648 void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers) 2649 TRY 2650 { 2651 int nbReceived = rankBuffers.size(), i, ind, index, lInd; 2652 if (nbReceived != recvClientRanks_.size()) 2653 ERROR("void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers)", 2654 << "The number of sending clients is not correct." 2655 << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived); 2656 2657 vector<CArray<bool,1> > recvMaskValue(nbReceived); 2658 for (i = 0; i < recvClientRanks_.size(); ++i) 2659 { 2660 int rank = recvClientRanks_[i]; 2661 CBufferIn& buffer = *(rankBuffers[rank]); 2662 buffer >> recvMaskValue[i]; 2663 } 2664 2665 int nbMaskInd = 0; 2666 for (i = 0; i < nbReceived; ++i) 2667 { 2668 nbMaskInd += recvMaskValue[i].numElements(); 2669 } 2670 2671 if (nbMaskInd != globalLocalIndexMap_.size()) 2672 info (0) << "If domain " << this->getDomainOutputName() <<" does not have overlapped regions between processes " 2673 << "something must be wrong with mask index "<< std::endl; 2674 2675 nbMaskInd = globalLocalIndexMap_.size(); 2676 mask_1d.resize(nbMaskInd); 2677 domainMask.resize(nbMaskInd); 2678 mask_1d = false; 2679 2680 for (i = 0; i < nbReceived; ++i) 2681 { 2682 CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]]; 2683 CArray<bool,1>& tmp = recvMaskValue[i]; 2684 for (ind = 0; ind < tmp.numElements(); ++ind) 2685 { 2686 lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 2687 if (!mask_1d(lInd)) // Only rewrite mask_1d if it's not true 2688 mask_1d(lInd) = tmp(ind); 2689 } 2690 } 2691 domainMask=mask_1d ; 2692 } 2693 CATCH_DUMP_ATTR 2694 2585 CATCH_DUMP_ATTR 2695 2586 /*! 2696 2587 Receive longitude event from clients(s) … … 3046 2937 dataIIndex(lInd) = (-1 == dataIIndex(lInd)) ? tmpI(ind) : dataIIndex(lInd); // Only fill in dataIndex if there is no data 3047 2938 dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd); 3048 3049 if (!domainMask(lInd)) // Include mask info into data index on the RECEIVE getServerDimensionSizes3050 {3051 dataIIndex(lInd) = dataJIndex(lInd) = -1;3052 }3053 2939 } 3054 2940 } -
XIOS/trunk/src/node/domain.hpp
r1578 r1637 49 49 { 50 50 EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT, 51 EVENT_ID_AREA, EVENT_ID_MASK,51 EVENT_ID_AREA, 52 52 EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT 53 53 } ; … … 142 142 CArray<double, 1> areavalue; 143 143 144 CArray< size_t,1> localIndexToWriteOnServer;144 CArray<int,1> localIndexToWriteOnServer; 145 145 146 146 CArray<bool, 1> domainMask; // mask_1d, mask_2d -> domainMask … … 175 175 void sendIndex(); 176 176 void sendDistributionAttributes(); 177 void sendMask();178 177 void sendArea(); 179 178 void sendLonLat(); … … 186 185 static void recvDistributionAttributes(CEventServer& event); 187 186 static void recvIndex(CEventServer& event); 188 static void recvMask(CEventServer& event);189 187 static void recvLon(CEventServer& event); 190 188 static void recvLat(CEventServer& event); … … 193 191 void recvDistributionAttributes(CBufferIn& buffer); 194 192 void recvIndex(std::map<int, CBufferIn*>& rankBuffers); 195 void recvMask(std::map<int, CBufferIn*>& rankBuffers);196 193 void recvLon(std::map<int, CBufferIn*>& rankBuffers); 197 194 void recvLat(std::map<int, CBufferIn*>& rankBuffers); -
XIOS/trunk/src/node/field.cpp
r1622 r1637 1122 1122 { 1123 1123 if (!instantDataFilter) 1124 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true));1124 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false)); 1125 1125 1126 1126 … … 1138 1138 { 1139 1139 if (!instantDataFilter) 1140 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true));1140 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, false)); 1141 1141 1142 1142 // If the field data is to be read by the client or/and written to a file … … 1184 1184 { 1185 1185 checkTimeAttributes(); 1186 instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, f req_offset, true,1186 instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 1187 1187 detectMissingValues, defaultValue)); 1188 1188 } … … 1190 1190 { 1191 1191 if (check_if_active.isEmpty()) check_if_active = false; 1192 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, NoneDu, false,1192 instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false, 1193 1193 detectMissingValues, defaultValue)); 1194 1194 } … … 1275 1275 { 1276 1276 checkTimeAttributes(); 1277 serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, f req_offset, true,1277 serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 1278 1278 detectMissingValues, defaultValue)); 1279 1279 } … … 1292 1292 { 1293 1293 if (check_if_active.isEmpty()) check_if_active = false; 1294 clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, NoneDu, false,1294 clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, true, NoneDu, false, 1295 1295 detectMissingValues, defaultValue)); 1296 1296 } … … 1887 1887 CATCH 1888 1888 1889 bool CField::hasGridMask(void) const 1890 TRY 1891 { 1892 return (this->grid->hasMask()); 1893 } 1894 CATCH 1895 1889 1896 DEFINE_REF_FUNC(Field,field) 1890 1897 } // namespace xios -
XIOS/trunk/src/node/field.hpp
r1542 r1637 209 209 bool hasExpression(void) const; 210 210 211 bool hasGridMask(void) const; 212 211 213 public: 212 214 /// Propriétés privées /// -
XIOS/trunk/src/node/grid.cpp
r1622 r1637 364 364 } 365 365 CATCH_DUMP_ATTR 366 bool CGrid::hasMask() const 367 TRY 368 { 369 return (!mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty() || 370 !mask_4d.isEmpty() || !mask_5d.isEmpty() || !mask_6d.isEmpty() || !mask_7d.isEmpty()); 371 } 372 CATCH 366 373 367 374 /* … … 453 460 CATCH_DUMP_ATTR 454 461 455 /*!456 A grid can have multiple dimension, so can its mask in the form of multi-dimension array.457 It's not a good idea to store all multi-dimension arrays corresponding to each mask.458 One of the ways is to convert this array into 1-dimension one and every process is taken place on it.459 \param [in] multi-dimension array grid mask460 */461 462 void CGrid::getLocalMask(CArray<bool,1>& localMask)463 TRY464 {465 std::vector<CDomain*> domainP = this->getDomains();466 std::vector<CAxis*> axisP = this->getAxis();467 int dim = domainP.size() * 2 + axisP.size();468 469 switch (dim)470 {471 case 0:472 getLocalMask(mask_0d, localMask);473 break;474 case 1:475 getLocalMask(mask_1d, localMask);476 break;477 case 2:478 getLocalMask(mask_2d, localMask);479 break;480 case 3:481 getLocalMask(mask_3d, localMask);482 break;483 case 4:484 getLocalMask(mask_4d, localMask);485 break;486 case 5:487 getLocalMask(mask_5d, localMask);488 break;489 case 6:490 getLocalMask(mask_6d, localMask);491 break;492 case 7:493 getLocalMask(mask_7d, localMask);494 break;495 default:496 break;497 }498 }499 CATCH_DUMP_ATTR500 501 462 /* 502 463 Modify value of mask in a certain index … … 736 697 CContext* context = CContext::getCurrent(); 737 698 738 CContextClient* client = context->client; // Here it's not important which contextClient to recuperate699 CContextClient* client = context->client; 739 700 int rank = client->clientRank; 740 701 741 702 clientDistribution_ = new CDistributionClient(rank, this); 742 703 // Get local data index on client 743 storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size()); 744 int nbStoreIndex = storeIndex_client.numElements(); 704 int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size(); 705 int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size(); 706 // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise 707 storeIndex_client.resize(nbStoreIndex); 708 storeMask_client.resize(nbStoreGridMask); 745 709 for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 710 for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client(idx) = (clientDistribution_->getLocalMaskIndexOnClient())[idx]; 746 711 747 712 if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); … … 884 849 if (connectedServerRank_[receiverSize].empty()) 885 850 connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 851 852 // Now check if all servers have data to receive. If not, master client will send empty data. 853 // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 854 std::vector<int> counts (client->clientSize); 855 std::vector<int> displs (client->clientSize); 856 displs[0] = 0; 857 int localCount = connectedServerRank_[receiverSize].size() ; 858 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 859 for (int i = 0; i < client->clientSize-1; ++i) 860 { 861 displs[i+1] = displs[i] + counts[i]; 862 } 863 std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]); 864 MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 865 866 if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0)) 867 { 868 std::vector<bool> isSrvConnected (receiverSize, false); 869 for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 870 for (int i = 0; i < receiverSize; ++i) 871 { 872 if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i); 873 } 874 } 886 875 887 876 nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); … … 1369 1358 CATCH 1370 1359 1360 void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const 1361 { 1362 const StdSize size = storeIndex_client.numElements(); 1363 stored.resize(size); 1364 const double nanValue = std::numeric_limits<double>::quiet_NaN(); 1365 1366 if (storeMask_client.numElements() != 0) 1367 for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue; 1368 else 1369 for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 1370 } 1371 1371 1372 void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 1372 1373 TRY … … 1836 1837 nGlob.push_back(1); 1837 1838 } 1838 1839 modifyMaskSize(nSize, false);1840 1841 // These below codes are reserved for future1842 CDistributionServer srvDist(server->intraCommRank, nBegin, nSize, nBeginGlobal, nGlob);1843 map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),1844 ite = outGlobalIndexFromClient.end(), it;1845 const CDistributionServer::GlobalLocalMap& globalLocalMask = srvDist.getGlobalLocalIndex();1846 CDistributionServer::GlobalLocalMap::const_iterator itSrv;1847 size_t nb = 0;1848 for (it = itb; it != ite; ++it)1849 {1850 CArray<size_t,1>& globalInd = it->second;1851 for (size_t idx = 0; idx < globalInd.numElements(); ++idx)1852 {1853 if (globalLocalMask.end() != globalLocalMask.find(globalInd(idx))) ++nb;1854 }1855 }1856 1857 CArray<int,1> indexToModify(nb);1858 nb = 0;1859 for (it = itb; it != ite; ++it)1860 {1861 CArray<size_t,1>& globalInd = it->second;1862 for (size_t idx = 0; idx < globalInd.numElements(); ++idx)1863 {1864 itSrv = globalLocalMask.find(globalInd(idx));1865 if (globalLocalMask.end() != itSrv)1866 {1867 indexToModify(nb) = itSrv->second;1868 ++nb;1869 }1870 }1871 }1872 1873 modifyMask(indexToModify, true);1874 1839 } 1875 1840 -
XIOS/trunk/src/node/grid.hpp
r1622 r1637 94 94 template <int n> 95 95 void inputField(const CArray<double,n>& field, CArray<double,1>& stored) const; 96 template <int n> 97 void maskField(const CArray<double,n>& field, CArray<double,1>& stored) const; 96 98 template <int n> 97 99 void outputField(const CArray<double,1>& stored, CArray<double,n>& field) const; … … 203 205 bool hasTransform(); 204 206 size_t getGlobalWrittenSize(void) ; 205 void getLocalMask(CArray<bool,1>& localMask) ;206 template<int N>207 void getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) ;208 207 public: 209 208 CArray<int, 1> storeIndex_client; 209 CArray<bool, 1> storeMask_client; 210 210 211 211 /** Map containing indexes that will be sent in sendIndex(). */ … … 247 247 CArray<size_t,1> indexFromClients; 248 248 249 bool hasMask(void) const; 249 250 void checkMask(void); 250 251 void createMask(void); … … 273 274 void restoreField_arr(const CArray<double, 1>& stored, double* const data) const; 274 275 void uncompressField_arr(const double* const data, CArray<double, 1>& outData) const; 276 void maskField_arr(const double* const data, CArray<double, 1>& stored) const; 275 277 276 278 void setVirtualDomainGroup(CDomainGroup* newVDomainGroup); … … 387 389 388 390 template <int n> 391 void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) const 392 { 393 //#ifdef __XIOS_DEBUG 394 if (this->getDataSize() != field.numElements()) 395 ERROR("void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const", 396 << "[ Awaiting data of size = " << this->getDataSize() << ", " 397 << "Received data size = " << field.numElements() << " ] " 398 << "The data array does not have the right size! " 399 << "Grid = " << this->getId()) 400 //#endif 401 this->maskField_arr(field.dataFirst(), stored); 402 } 403 404 template <int n> 389 405 void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const 390 406 TRY … … 424 440 TRY 425 441 { 426 if (!gridMask.isEmpty() || createMask) 427 { 428 int idx = 0; 429 int numElement = axisDomainOrder.numElements(); 430 int dim = domainMasks.size() * 2 + axisMasks.size(); 431 std::vector<CDomain*> domainP = this->getDomains(); 432 std::vector<CAxis*> axisP = this->getAxis(); 433 434 std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 435 std::vector<int> currentIndex(dim); 436 int idxDomain = 0, idxAxis = 0; 442 int idx = 0; 443 int numElement = axisDomainOrder.numElements(); 444 int dim = domainMasks.size() * 2 + axisMasks.size(); 445 std::vector<CDomain*> domainP = this->getDomains(); 446 std::vector<CAxis*> axisP = this->getAxis(); 447 448 std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 449 std::vector<int> currentIndex(dim); 450 int idxDomain = 0, idxAxis = 0; 451 for (int i = 0; i < numElement; ++i) 452 { 453 indexMap[i] = idx; 454 if (2 == axisDomainOrder(i)) { 455 eachDimSize[indexMap[i]] = domainP[idxDomain]->ni; 456 eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 457 idx += 2; ++idxDomain; 458 } 459 else if (1 == axisDomainOrder(i)) { 460 // eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 461 eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 462 ++idx; ++idxAxis; 463 } 464 else {}; 465 } 466 467 if (!gridMask.isEmpty() && !createMask) 468 { 469 for (int i = 0; i < dim; ++i) 470 { 471 if (gridMask.extent(i) != eachDimSize[i]) 472 ERROR("CGrid::checkMask(void)", 473 << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 474 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 475 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 476 << "Grid = " << this->getId()) 477 } 478 } 479 else { 480 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 481 gridMask = true; 482 } 483 484 int ssize = gridMask.numElements(); 485 idx = 0; 486 while (idx < ssize) 487 { 488 for (int i = 0; i < dim-1; ++i) 489 { 490 if (idxLoop[i] == eachDimSize[i]) 491 { 492 idxLoop[i] = 0; 493 ++idxLoop[i+1]; 494 } 495 } 496 497 // Find out outer index 498 idxDomain = idxAxis = 0; 499 bool maskValue = true; 437 500 for (int i = 0; i < numElement; ++i) 438 501 { 439 indexMap[i] = idx; 440 if (2 == axisDomainOrder(i)) { 441 eachDimSize[indexMap[i]] = domainP[idxDomain]->ni; 442 eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 443 idx += 2; ++idxDomain; 502 if (2 == axisDomainOrder(i)) 503 { 504 int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 505 if (idxTmp < (*domainMasks[idxDomain]).numElements()) 506 maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 507 else 508 maskValue = false; 509 ++idxDomain; 444 510 } 445 else if (1 == axisDomainOrder(i)) { 446 // eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 447 eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 448 ++idx; ++idxAxis; 511 else if (1 == axisDomainOrder(i)) 512 { 513 int idxTmp = idxLoop[indexMap[i]]; 514 if (idxTmp < (*axisMasks[idxAxis]).numElements()) 515 maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 516 else 517 maskValue = false; 518 519 ++idxAxis; 449 520 } 450 else {};451 } 452 453 // if (!gridMask.isEmpty() && !createMask) 454 if (!createMask)521 } 522 523 int maskIndex = idxLoop[0]; 524 int mulDim = 1; 525 for (int k = 1; k < dim; ++k) 455 526 { 456 for (int i = 0; i < dim; ++i) 457 { 458 if (gridMask.extent(i) != eachDimSize[i]) 459 ERROR("CGrid::checkMask(void)", 460 << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 461 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 462 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 463 << "Grid = " << this->getId()) 464 } 465 } 466 else { 467 CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 468 gridMask = true; 469 } 470 471 int ssize = gridMask.numElements(); 472 idx = 0; 473 while (idx < ssize) 474 { 475 for (int i = 0; i < dim-1; ++i) 476 { 477 if (idxLoop[i] == eachDimSize[i]) 478 { 479 idxLoop[i] = 0; 480 ++idxLoop[i+1]; 481 } 482 } 483 484 // Find out outer index 485 idxDomain = idxAxis = 0; 486 bool maskValue = true; 487 for (int i = 0; i < numElement; ++i) 488 { 489 if (2 == axisDomainOrder(i)) 490 { 491 int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 492 if (idxTmp < (*domainMasks[idxDomain]).numElements()) 493 maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 494 else 495 maskValue = false; 496 ++idxDomain; 497 } 498 else if (1 == axisDomainOrder(i)) 499 { 500 int idxTmp = idxLoop[indexMap[i]]; 501 if (idxTmp < (*axisMasks[idxAxis]).numElements()) 502 maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 503 else 504 maskValue = false; 505 506 ++idxAxis; 507 } 508 } 509 510 int maskIndex = idxLoop[0]; 511 int mulDim = 1; 512 for (int k = 1; k < dim; ++k) 513 { 514 mulDim *= eachDimSize[k-1]; 515 maskIndex += idxLoop[k]*mulDim; 516 } 517 *(gridMask.dataFirst()+maskIndex) &= maskValue; 518 519 ++idxLoop[0]; 520 ++idx; 521 } 522 } 527 mulDim *= eachDimSize[k-1]; 528 maskIndex += idxLoop[k]*mulDim; 529 } 530 *(gridMask.dataFirst()+maskIndex) &= maskValue; 531 532 ++idxLoop[0]; 533 ++idx; 534 } 523 535 } 524 536 CATCH_DUMP_ATTR … … 565 577 ///-------------------------------------------------------------- 566 578 567 /*! 568 A grid can have multiple dimension, so can its mask in the form of multi-dimension array. 569 It's not a good idea to store all multi-dimension arrays corresponding to each mask. 570 One of the ways is to convert this array into 1-dimension one and every process is taken place on it. 571 \param [in] multi-dimension array grid mask 572 */ 573 template<int N> 574 void CGrid::getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) 575 TRY 576 { 577 if (gridMask.isEmpty()) return ; 578 int dim = gridMask.dimensions(); 579 std::vector<int> dimensionSizes(dim); 580 for (int i = 0; i < dim; ++i) dimensionSizes[i] = gridMask.extent(i); 581 582 std::vector<int> idxLoop(dim,0); 583 int ssize = gridMask.numElements(), idx = 0; 584 localMask.resize(ssize); 585 while (idx < ssize) 586 { 587 for (int i = 0; i < dim-1; ++i) 588 { 589 if (idxLoop[i] == dimensionSizes[i]) 590 { 591 idxLoop[i] = 0; 592 ++idxLoop[i+1]; 593 } 594 } 595 596 int maskIndex = idxLoop[0]; 597 int mulDim = 1; 598 for (int k = 1; k < dim; ++k) 599 { 600 mulDim *= dimensionSizes[k-1]; 601 maskIndex += idxLoop[k]*mulDim; 602 } 603 localMask(maskIndex) = *(gridMask.dataFirst()+maskIndex); 604 605 ++idxLoop[0]; 606 ++idx; 607 } 608 } 609 CATCH_DUMP_ATTR 579 610 580 611 581 // Declare/Define CGridGroup and CGridDefinition
Note: See TracChangeset
for help on using the changeset viewer.