29 , isChecked(false), relFiles(), isClientChecked(false), nbSenders(), indSrv_(), connectedServerRank_()
30 , hasBounds(false), hasArea(false), isCompressible_(false), isUnstructed_(false)
31 , isClientAfterTransformationChecked(false), hasLonLat(false)
32 , isRedistributed_(false), hasPole(false)
33 , lonvalue(), latvalue(), bounds_lonvalue(), bounds_latvalue()
34 , globalLocalIndexMap_(), computedWrittenIndex_(false)
35 , clients(), hasLatInReadFile_(false), hasBoundsLatInReadFile_(false)
36 , hasLonInReadFile_(false), hasBoundsLonInReadFile_(false)
42 , isChecked(false), relFiles(), isClientChecked(false), nbSenders(), indSrv_(), connectedServerRank_()
43 , hasBounds(false), hasArea(false), isCompressible_(false), isUnstructed_(false)
44 , isClientAfterTransformationChecked(false), hasLonLat(false)
45 , isRedistributed_(false), hasPole(false)
46 , lonvalue(), latvalue(), bounds_lonvalue(), bounds_latvalue()
47 , globalLocalIndexMap_(), computedWrittenIndex_(false)
48 , clients(), hasLatInReadFile_(false), hasBoundsLatInReadFile_(false)
49 , hasLonInReadFile_(false), hasBoundsLonInReadFile_(false)
69 CDomain* domain = CDomainGroup::get(
"domain_definition")->createChild();
105 MPI_Comm_size(writtenCom, &writtenSize);
106 return numberWrittenIndexes_[writtenSize];
118 MPI_Comm_size(writtenCom, &writtenSize);
119 return totalNumberWrittenIndexes_[writtenSize];
131 MPI_Comm_size(writtenCom, &writtenSize);
132 return offsetWrittenIndexes_[writtenSize];
140 MPI_Comm_size(writtenCom, &writtenSize);
141 return compressedIndexToWriteOnServer[writtenSize];
156 std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client);
158 if (client->isServerLeader())
161 size_t size = 11 *
sizeof(size_t);
163 const std::list<int>& ranks = client->getRanksServerLeader();
164 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
166 if (size > attributesSizes[*itRank])
167 attributesSizes[*itRank] = size;
171 std::unordered_map<int, vector<size_t> >::const_iterator itIndexEnd = indSrv_[client->serverSize].end();
173 for (
size_t k = 0; k < connectedServerRank_[client->serverSize].size(); ++k)
175 int rank = connectedServerRank_[client->serverSize][k];
176 std::unordered_map<int, std::vector<size_t> >::const_iterator it = indSrv_[client->serverSize].find(rank);
177 size_t idxCount = (it != itIndexEnd) ? it->second.size() : 0;
187 size_t size =
CEventClient::headerSize + getId().size() +
sizeof(size_t) + std::max(sizeIndexEvent, sizeLonLatEvent);
188 if (size > attributesSizes[rank])
189 attributesSizes[rank] = size;
192 return attributesSizes;
210 return (this->relFiles.find(filename) != this->relFiles.end());
217 return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
226 bool distributed = !((!ni.isEmpty() && (ni == ni_glo) && !nj.isEmpty() && (nj ==
nj_glo)) ||
228 bool distributed_glo ;
252 this->relFiles.insert(filename);
259 this->relFilesCompressed.insert(filename);
276 bool hasValues =
true;
298 if (this->isRedistributed_)
return;
300 this->isRedistributed_ =
true;
306 int rankOnDomain = rankClient%nbLocalDomain;
308 if (ni_glo.isEmpty() || ni_glo <= 0 )
310 ERROR(
"CDomain::redistribute(int nbLocalDomain)",
311 <<
"[ Id = " << this->getId() <<
" ] "
312 <<
"The global domain is badly defined,"
313 <<
" check the \'ni_glo\' value !")
318 ERROR(
"CDomain::redistribute(int nbLocalDomain)",
319 <<
"[ Id = " << this->getId() <<
" ] "
320 <<
"The global domain is badly defined,"
321 <<
" check the \'nj_glo\' value !")
324 if ((type_attr::rectilinear ==
type) || (type_attr::curvilinear ==
type))
326 int globalDomainSize = ni_glo *
nj_glo;
327 if (globalDomainSize <= nbLocalDomain)
329 for (
int idx = 0; idx < nbLocalDomain; ++idx)
331 if (rankOnDomain < globalDomainSize)
333 int iIdx = rankOnDomain % ni_glo;
334 int jIdx = rankOnDomain / ni_glo;
335 ibegin.setValue(iIdx); jbegin.setValue(jIdx);
336 ni.setValue(1); nj.setValue(1);
340 ibegin.setValue(0); jbegin.setValue(0);
341 ni.setValue(0); nj.setValue(0);
347 float njGlo = nj_glo.getValue();
348 float niGlo = ni_glo.getValue();
349 int nbProcOnX, nbProcOnY, range;
352 float yOverXRatio = njGlo/niGlo;
354 nbProcOnX = std::ceil(std::sqrt(nbLocalDomain/yOverXRatio));
355 nbProcOnY = std::ceil(((
float)nbLocalDomain)/nbProcOnX);
359 std::vector<int> ibeginVec(nbProcOnX,0), jbeginVec(nbProcOnY,0);
360 std::vector<int> niVec(nbProcOnX), njVec(nbProcOnY);
361 for (
int i = 1; i < nbProcOnX; ++i)
363 range = ni_glo / nbProcOnX;
364 if (i < (ni_glo%nbProcOnX)) ++range;
366 ibeginVec[i] = ibeginVec[i-1] + niVec[i-1];
368 niVec[nbProcOnX-1] = ni_glo - ibeginVec[nbProcOnX-1];
371 for (
int j = 1; j < nbProcOnY; ++j)
373 range = nj_glo / nbProcOnY;
374 if (j < (nj_glo%nbProcOnY)) ++range;
376 jbeginVec[j] = jbeginVec[j-1] + njVec[j-1];
378 njVec[nbProcOnY-1] = nj_glo - jbeginVec[nbProcOnY-1];
381 int iIdx = rankOnDomain % nbProcOnX;
382 int jIdx = rankOnDomain / nbProcOnX;
384 if (rankOnDomain != (nbLocalDomain-1))
386 ibegin.setValue(ibeginVec[iIdx]);
387 jbegin.setValue(jbeginVec[jIdx]);
388 nj.setValue(njVec[jIdx]);
389 ni.setValue(niVec[iIdx]);
393 ibegin.setValue(ibeginVec[iIdx]);
394 jbegin.setValue(jbeginVec[jIdx]);
395 nj.setValue(njVec[jIdx]);
396 ni.setValue(ni_glo - ibeginVec[iIdx]);
404 int globalDomainSize = ni_glo *
nj_glo;
405 if (globalDomainSize <= nbLocalDomain)
407 for (
int idx = 0; idx < nbLocalDomain; ++idx)
409 if (rankOnDomain < globalDomainSize)
411 int iIdx = rankOnDomain % ni_glo;
412 int jIdx = rankOnDomain / ni_glo;
413 ibegin.setValue(iIdx); jbegin.setValue(jIdx);
414 ni.setValue(1); nj.setValue(1);
418 ibegin.setValue(0); jbegin.setValue(0);
419 ni.setValue(0); nj.setValue(0);
425 float njGlo = nj_glo.getValue();
426 float niGlo = ni_glo.getValue();
427 std::vector<int> ibeginVec(nbLocalDomain,0);
428 std::vector<int> niVec(nbLocalDomain);
429 for (
int i = 1; i < nbLocalDomain; ++i)
431 int range = ni_glo / nbLocalDomain;
432 if (i < (ni_glo%nbLocalDomain)) ++range;
434 ibeginVec[i] = ibeginVec[i-1] + niVec[i-1];
436 niVec[nbLocalDomain-1] = ni_glo - ibeginVec[nbLocalDomain-1];
438 int iIdx = rankOnDomain % nbLocalDomain;
439 ibegin.setValue(ibeginVec[iIdx]);
441 ni.setValue(niVec[iIdx]);
446 for(
int idx = 0; idx < ni; ++idx)
i_index(idx)=ibegin+idx;
450 ibegin.setValue(this->
i_index(0));
452 ni.setValue(this->
i_index.numElements());
469 case type_attr::rectilinear:
472 case type_attr::curvilinear:
475 case type_attr::unstructured:
494 if (!lonvalue_rectilinear_read_from_file.isEmpty() && lonvalue_2d.isEmpty() && lonvalue_1d.isEmpty())
496 lonvalue_1d.resize(ni);
497 for (
int idx = 0; idx < ni; ++idx)
498 lonvalue_1d(idx) = lonvalue_rectilinear_read_from_file(idx+ibegin);
499 lon_start.setValue(lonvalue_rectilinear_read_from_file(0));
500 lon_end.setValue(lonvalue_rectilinear_read_from_file(ni_glo-1));
504 if (!lonvalue_2d.isEmpty()) lonvalue_2d.free();
505 lonvalue_1d.resize(ni);
506 double lonRange = lon_end - lon_start;
507 double lonStep = (1 == ni_glo.getValue()) ? lonRange : lonRange/
double(ni_glo.getValue()-1);
510 for (
int i = 0; i < ni; ++i)
512 if (0 == (ibegin + i))
514 lonvalue_1d(i) = lon_start;
516 else if (ni_glo == (ibegin + i + 1))
518 lonvalue_1d(i) = lon_end;
522 lonvalue_1d(i) = (ibegin + i) * lonStep + lon_start;
528 if (!latvalue_rectilinear_read_from_file.isEmpty() && latvalue_2d.isEmpty() && latvalue_1d.isEmpty())
530 latvalue_1d.resize(nj);
531 for (
int idx = 0; idx < nj; ++idx)
532 latvalue_1d(idx) = latvalue_rectilinear_read_from_file(idx+jbegin);
533 lat_start.setValue(latvalue_rectilinear_read_from_file(0));
534 lat_end.setValue(latvalue_rectilinear_read_from_file(
nj_glo-1));
538 if (!latvalue_2d.isEmpty()) latvalue_1d.free();
539 latvalue_1d.resize(nj);
541 double latRange = lat_end - lat_start;
542 double latStep = (1 ==
nj_glo.getValue()) ? latRange : latRange/
double(
nj_glo.getValue()-1);
544 for (
int j = 0; j < nj; ++j)
546 if (0 == (jbegin + j))
548 latvalue_1d(j) = lat_start;
550 else if (
nj_glo == (jbegin + j + 1))
552 latvalue_1d(j) = lat_end;
556 latvalue_1d(j) = (jbegin + j) * latStep + lat_start;
570 if (!lonvalue_curvilinear_read_from_file.isEmpty() && lonvalue_2d.isEmpty() && lonvalue_1d.isEmpty())
572 lonvalue_2d.resize(ni,nj);
573 for (
int jdx = 0; jdx < nj; ++jdx)
574 for (
int idx = 0; idx < ni; ++idx)
575 lonvalue_2d(idx,jdx) = lonvalue_curvilinear_read_from_file(idx, jdx);
577 lonvalue_curvilinear_read_from_file.free();
580 if (!latvalue_curvilinear_read_from_file.isEmpty() && latvalue_2d.isEmpty() && latvalue_1d.isEmpty())
582 latvalue_2d.resize(ni,nj);
583 for (
int jdx = 0; jdx < nj; ++jdx)
584 for (
int idx = 0; idx < ni; ++idx)
585 latvalue_2d(idx,jdx) = latvalue_curvilinear_read_from_file(idx, jdx);
587 latvalue_curvilinear_read_from_file.free();
590 if (!bounds_lonvalue_curvilinear_read_from_file.isEmpty() && bounds_lon_2d.isEmpty() && bounds_lon_1d.isEmpty())
592 bounds_lon_2d.resize(
nvertex,ni,nj);
593 for (
int jdx = 0; jdx < nj; ++jdx)
594 for (
int idx = 0; idx < ni; ++idx)
595 for (
int ndx = 0; ndx <
nvertex; ++ndx)
596 bounds_lon_2d(ndx,idx,jdx) = bounds_lonvalue_curvilinear_read_from_file(ndx,idx, jdx);
598 bounds_lonvalue_curvilinear_read_from_file.free();
601 if (!bounds_latvalue_curvilinear_read_from_file.isEmpty() && bounds_lat_2d.isEmpty() && bounds_lat_1d.isEmpty())
603 bounds_lat_2d.resize(
nvertex,ni,nj);
604 for (
int jdx = 0; jdx < nj; ++jdx)
605 for (
int idx = 0; idx < ni; ++idx)
606 for (
int ndx = 0; ndx <
nvertex; ++ndx)
607 bounds_lat_2d(ndx,idx,jdx) = bounds_latvalue_curvilinear_read_from_file(ndx,idx, jdx);
609 bounds_latvalue_curvilinear_read_from_file.free();
624 for(
int idx = 0; idx < ni; ++idx)
i_index(idx)=ibegin+idx;
627 if (!lonvalue_unstructured_read_from_file.isEmpty() && lonvalue_1d.isEmpty())
630 for (
int idx = 0; idx < ni; ++idx)
631 lonvalue_1d(idx) = lonvalue_unstructured_read_from_file(idx);
634 lonvalue_unstructured_read_from_file.free();
637 if (!latvalue_unstructured_read_from_file.isEmpty() && latvalue_1d.isEmpty())
639 latvalue_1d.resize(ni);
640 for (
int idx = 0; idx < ni; ++idx)
641 latvalue_1d(idx) = latvalue_unstructured_read_from_file(idx);
644 latvalue_unstructured_read_from_file.free();
647 if (!bounds_lonvalue_unstructured_read_from_file.isEmpty() && bounds_lon_1d.isEmpty())
650 bounds_lon_1d.resize(nbVertex,ni);
651 for (
int idx = 0; idx < ni; ++idx)
652 for (
int jdx = 0; jdx < nbVertex; ++jdx)
653 bounds_lon_1d(jdx,idx) = bounds_lonvalue_unstructured_read_from_file(jdx, idx);
656 bounds_lonvalue_unstructured_read_from_file.free();
659 if (!bounds_latvalue_unstructured_read_from_file.isEmpty() && bounds_lat_1d.isEmpty())
662 bounds_lat_1d.resize(nbVertex,ni);
663 for (
int idx = 0; idx < ni; ++idx)
664 for (
int jdx = 0; jdx < nbVertex; ++jdx)
665 bounds_lat_1d(jdx,idx) = bounds_latvalue_unstructured_read_from_file(jdx, idx);
668 bounds_latvalue_unstructured_read_from_file.free();
683 lon_g.resize(ni_glo) ;
693 MPI_Allgather(&v,1,MPI_INT,ibegin_g,1,MPI_INT,client->
intraComm) ;
695 MPI_Allgather(&v,1,MPI_INT,jbegin_g,1,MPI_INT,client->
intraComm) ;
697 MPI_Allgather(&v,1,MPI_INT,ni_g,1,MPI_INT,client->
intraComm) ;
699 MPI_Allgather(&v,1,MPI_INT,nj_g,1,MPI_INT,client->
intraComm) ;
701 MPI_Allgatherv(lon.dataFirst(),ni,MPI_DOUBLE,lon_g.dataFirst(),ni_g, ibegin_g,MPI_DOUBLE,client->
intraComm) ;
702 MPI_Allgatherv(lat.dataFirst(),nj,MPI_DOUBLE,lat_g.dataFirst(),nj_g, jbegin_g,MPI_DOUBLE,client->
intraComm) ;
717 const int nvertexValue = 4;
718 boundsLon.resize(nvertexValue,ni*nj);
722 double lonStepStart = lon(1)-lon(0);
723 bounds_lon_start=lon(0) - lonStepStart/2;
724 double lonStepEnd = lon(ni_glo-1)-lon(ni_glo-2);
725 bounds_lon_end=lon(ni_glo-1) + lonStepEnd/2;
726 double errorBoundsLon = std::abs(360-std::abs(bounds_lon_end-bounds_lon_start));
729 if (errorBoundsLon < std::abs(lonStepStart)*1e-1 || errorBoundsLon < std::abs(lonStepEnd)*1e-1 )
731 bounds_lon_start= (lon(0) + lon(ni_glo-1)-360)/2 ;
732 bounds_lon_end= (lon(0) +360 + lon(ni_glo-1))/2 ;
737 if (bounds_lon_start.isEmpty()) bounds_lon_start=-180. ;
738 if (bounds_lon_end.isEmpty()) bounds_lon_end=180.-1e-8 ;
745 boundsLon(0,k) = boundsLon(1,k) = (0 == (ibegin + i)) ? bounds_lon_start
746 : (lon(ibegin + i)+lon(ibegin + i-1))/2;
747 boundsLon(2,k) = boundsLon(3,k) = ((ibegin + i + 1) == ni_glo) ? bounds_lon_end
748 : (lon(ibegin + i + 1)+lon(ibegin + i))/2;
752 boundsLat.resize(nvertexValue,nj*ni);
753 bool isNorthPole=false ;
754 bool isSouthPole=false ;
762 double latStepStart = lat(1)-lat(0);
763 if (isNorthPole) bounds_lat_start=lat(0);
766 bounds_lat_start=lat(0)-latStepStart/2;
767 if (bounds_lat_start >= 90 ) bounds_lat_start=90 ;
768 else if (bounds_lat_start <= -90 ) bounds_lat_start=-90 ;
769 else if (bounds_lat_start <= 90 && bounds_lat_start >= lat(0))
771 if ( std::abs(90-bounds_lat_start) <= 0.1*std::abs(latStepStart)) bounds_lat_start=90 ;
773 else if (bounds_lat_start >= -90 && bounds_lat_start <= lat(0))
775 if ( std::abs(-90 - bounds_lat_start) <= 0.1*std::abs(latStepStart)) bounds_lat_start=-90 ;
780 if (isSouthPole) bounds_lat_end=lat(
nj_glo-1);
783 bounds_lat_end=lat(
nj_glo-1)+latStepEnd/2;
785 if (bounds_lat_end >= 90 ) bounds_lat_end=90 ;
786 else if (bounds_lat_end <= -90 ) bounds_lat_end=-90 ;
787 else if (bounds_lat_end <= 90 && bounds_lat_end >= lat(
nj_glo-1))
789 if ( std::abs(90-bounds_lat_end) <= 0.1*std::abs(latStepEnd)) bounds_lat_end=90 ;
791 else if (bounds_lat_end >= -90 && bounds_lat_end <= lat(
nj_glo-1))
793 if ( std::abs(-90 - bounds_lat_end) <= 0.1*std::abs(latStepEnd)) bounds_lat_end=-90 ;
799 if (bounds_lat_start.isEmpty()) bounds_lat_start=-90. ;
800 if (bounds_lat_end.isEmpty()) bounds_lat_end=90 ;
807 boundsLat(1,k) = boundsLat(2,k) = (0 == (jbegin + j)) ? bounds_lat_start
808 : (lat(jbegin + j)+lat(jbegin + j-1))/2;
809 boundsLat(0,k) = boundsLat(3,k) = ((jbegin + j +1) ==
nj_glo) ? bounds_lat_end
810 : (lat(jbegin + j + 1)+lat(jbegin + j))/2;
823 ERROR(
"CDomain::checkDomain(void)",
825 <<
"The domain type is mandatory, "
826 <<
"please define the 'type' attribute.")
829 if (
type == type_attr::gaussian)
832 type.setValue(type_attr::unstructured) ;
834 else if (
type == type_attr::rectilinear)
hasPole=true ;
836 if (
type == type_attr::unstructured)
838 if (ni_glo.isEmpty())
840 ERROR(
"CDomain::checkDomain(void)",
842 <<
"The global domain is badly defined, "
843 <<
"the mandatory 'ni_glo' attribute is missing.")
845 else if (ni_glo <= 0)
847 ERROR(
"CDomain::checkDomain(void)",
849 <<
"The global domain is badly defined, "
850 <<
"'ni_glo' attribute should be strictly positive so 'ni_glo = " << ni_glo.getValue() <<
"' is invalid.")
858 for(
int i=0;i<ni;++i) j_index(i)=0;
861 area.transposeSelf(1, 0);
864 if (ni_glo.isEmpty())
866 ERROR(
"CDomain::checkDomain(void)",
868 <<
"The global domain is badly defined, "
869 <<
"the mandatory 'ni_glo' attribute is missing.")
871 else if (ni_glo <= 0)
873 ERROR(
"CDomain::checkDomain(void)",
875 <<
"The global domain is badly defined, "
876 <<
"'ni_glo' attribute should be strictly positive so 'ni_glo = " << ni_glo.getValue() <<
"' is invalid.")
881 ERROR(
"CDomain::checkDomain(void)",
883 <<
"The global domain is badly defined, "
884 <<
"the mandatory 'nj_glo' attribute is missing.")
888 ERROR(
"CDomain::checkDomain(void)",
890 <<
"The global domain is badly defined, "
891 <<
"'nj_glo' attribute should be strictly positive so 'nj_glo = " <<
nj_glo.getValue() <<
"' is invalid.")
900 for (
int j = 0; j < nj; ++j)
901 for (
int i = 0; i < ni; ++i)
i_index(i+j*ni) = i+ibegin;
904 if (j_index.isEmpty())
907 for (
int j = 0; j < nj; ++j)
908 for (
int i = 0; i < ni; ++i) j_index(i+j*ni) = j+jbegin;
926 if ((ni.getValue() < 0 || ibegin.getValue() < 0) || ((ibegin.getValue() + ni.getValue()) > ni_glo.getValue()))
928 ERROR(
"CDomain::checkLocalIDomain(void)",
930 <<
"The local domain is wrongly defined,"
931 <<
" check the attributes 'ni_glo' (" << ni_glo.getValue() <<
"), 'ni' (" << ni.getValue() <<
") and 'ibegin' (" << ibegin.getValue() <<
")");
942 int minIndex = ni_glo - 1;
944 for (
int idx = 0; idx <
i_index.numElements(); ++idx)
949 ni = maxIndex - minIndex + 1;
950 minIIndex = minIIndex;
955 if (ibegin.isEmpty()) ibegin = minIIndex;
957 else if (ibegin.isEmpty() && ni.isEmpty())
962 else if ((!ibegin.isEmpty() && ni.isEmpty()) || (ibegin.isEmpty() && !ni.isEmpty()))
964 ERROR(
"CDomain::checkLocalIDomain(void)",
966 <<
"The local domain is wrongly defined," << endl
967 <<
"i_index is empty and either 'ni' or 'ibegin' is not defined. "
968 <<
"If 'ni' and 'ibegin' are used to define a domain, both of them must not be empty.");
972 if ((ni.getValue() < 0 || ibegin.getValue() < 0))
974 ERROR(
"CDomain::checkLocalIDomain(void)",
976 <<
"The local domain is wrongly defined,"
977 <<
" check the attributes 'ni_glo' (" << ni_glo.getValue() <<
"), 'ni' (" << ni.getValue() <<
") and 'ibegin' (" << ibegin.getValue() <<
")");
987 if (j_index.isEmpty() && !jbegin.isEmpty() && !nj.isEmpty())
989 if ((nj.getValue() < 0 || jbegin.getValue() < 0) || (jbegin.getValue() + nj.getValue()) >
nj_glo.getValue())
991 ERROR(
"CDomain::checkLocalJDomain(void)",
993 <<
"The local domain is wrongly defined,"
994 <<
" check the attributes 'nj_glo' (" <<
nj_glo.getValue() <<
"), 'nj' (" << nj.getValue() <<
") and 'jbegin' (" << jbegin.getValue() <<
")");
998 if (!j_index.isEmpty())
1000 int minJIndex = (0 < j_index.numElements()) ? j_index(0) : 0;
1004 int minIndex =
nj_glo - 1;
1006 for (
int idx = 0; idx < j_index.numElements(); ++idx)
1008 if (j_index(idx) < minIndex) minIndex = j_index(idx);
1009 if (j_index(idx) > maxIndex) maxIndex = j_index(idx);
1011 nj = maxIndex - minIndex + 1;
1012 minJIndex = minIndex;
1016 if (jbegin.isEmpty()) jbegin = minJIndex;
1018 else if (jbegin.isEmpty() && nj.isEmpty())
1025 if ((nj.getValue() < 0 || jbegin.getValue() < 0))
1027 ERROR(
"CDomain::checkLocalJDomain(void)",
1029 <<
"The local domain is wrongly defined,"
1030 <<
" check the attributes 'nj_glo' (" <<
nj_glo.getValue() <<
"), 'nj' (" << nj.getValue() <<
") and 'jbegin' (" << jbegin.getValue() <<
")");
1040 if (!mask_1d.isEmpty() && !mask_2d.isEmpty())
1041 ERROR(
"CDomain::checkMask(void)",
1043 <<
"Both mask_1d and mask_2d are defined but only one can be used at the same time." << std::endl
1044 <<
"Please define only one mask: 'mask_1d' or 'mask_2d'.");
1046 if (!mask_1d.isEmpty() && mask_2d.isEmpty())
1048 if (mask_1d.numElements() !=
i_index.numElements())
1049 ERROR(
"CDomain::checkMask(void)",
1051 <<
"'mask_1d' does not have the same size as the local domain." << std::endl
1052 <<
"Local size is " <<
i_index.numElements() <<
"." << std::endl
1053 <<
"Mask size is " << mask_1d.numElements() <<
".");
1056 if (mask_1d.isEmpty() && !mask_2d.isEmpty())
1058 if (mask_2d.extent(0) != ni || mask_2d.extent(1) != nj)
1059 ERROR(
"CDomain::checkMask(void)",
1061 <<
"The mask does not have the same size as the local domain." << std::endl
1062 <<
"Local size is " << ni.getValue() <<
" x " << nj.getValue() <<
"." << std::endl
1063 <<
"Mask size is " << mask_2d.extent(0) <<
" x " << mask_2d.extent(1) <<
".");
1066 if (!mask_2d.isEmpty())
1069 for (
int j = 0; j < nj; ++j)
1070 for (
int i = 0; i < ni; ++i)
domainMask(i+j*ni) = mask_2d(i,j);
1073 else if (mask_1d.isEmpty())
1091 if (data_dim.isEmpty())
1093 data_dim.setValue(1);
1095 else if (!(data_dim.getValue() == 1 || data_dim.getValue() == 2))
1097 ERROR(
"CDomain::checkDomainData(void)",
1099 <<
"The data dimension is invalid, 'data_dim' must be 1 or 2 not << " << data_dim.getValue() <<
".");
1102 if (data_ibegin.isEmpty())
1103 data_ibegin.setValue(0);
1104 if (data_jbegin.isEmpty())
1105 data_jbegin.setValue(0);
1107 if (data_ni.isEmpty())
1109 data_ni.setValue((data_dim == 1) ? (ni.getValue() * nj.getValue()) : ni.getValue());
1111 else if (data_ni.getValue() < 0)
1113 ERROR(
"CDomain::checkDomainData(void)",
1115 <<
"The data size cannot be negative ('data_ni' = " << data_ni.getValue() <<
").");
1118 if (data_nj.isEmpty())
1120 data_nj.setValue((data_dim.getValue() == 1) ? (ni.getValue() * nj.getValue()) : nj.getValue());
1122 else if (data_nj.getValue() < 0)
1124 ERROR(
"CDomain::checkDomainData(void)",
1126 <<
"The data size cannot be negative ('data_nj' = " << data_nj.getValue() <<
").");
1137 if (!data_i_index.isEmpty())
1139 if (!data_j_index.isEmpty() &&
1140 data_j_index.numElements() != data_i_index.numElements())
1142 ERROR(
"CDomain::checkCompression(void)",
1144 <<
"'data_i_index' and 'data_j_index' arrays must have the same size." << std::endl
1145 <<
"'data_i_index' size = " << data_i_index.numElements() << std::endl
1146 <<
"'data_j_index' size = " << data_j_index.numElements());
1151 if (data_j_index.isEmpty())
1153 ERROR(
"CDomain::checkCompression(void)",
1155 <<
"'data_j_index' must be defined when 'data_i_index' is set and 'data_dim' is 2.");
1157 for (
int k=0; k<data_i_index.numElements(); ++k)
1159 i = data_i_index(k)+data_ibegin ;
1160 j = data_j_index(k)+data_jbegin ;
1161 if (i>=0 && i<ni && j>=0 && j<nj)
1166 data_i_index(k) = -1;
1167 data_j_index(k) = -1;
1172 data_i_index(k) = -1;
1173 data_j_index(k) = -1;
1179 if (data_j_index.isEmpty())
1181 data_j_index.resize(data_ni);
1184 for (
int k=0; k<data_i_index.numElements(); ++k)
1186 i=data_i_index(k)+data_ibegin ;
1192 data_i_index(k) = -1;
1200 if (data_dim == 2 && !data_j_index.isEmpty())
1201 ERROR(
"CDomain::checkCompression(void)",
1203 <<
"'data_i_index' must be defined when 'data_j_index' is set and 'data_dim' is 2.");
1207 data_i_index.resize(data_ni);
1208 data_j_index.resize(data_ni);
1211 for (
int k = 0; k < data_ni; ++k)
1217 data_i_index(k) = k;
1219 data_i_index(k) = -1;
1222 data_i_index(k) = -1;
1227 const int dsize = data_ni * data_nj;
1228 data_i_index.resize(dsize);
1229 data_j_index.resize(dsize);
1231 for(
int count = 0, kj = 0; kj < data_nj; ++kj)
1233 for(
int ki = 0; ki < data_ni; ++ki, ++
count)
1235 i = ki + data_ibegin;
1236 j = kj + data_jbegin;
1238 if (i>=0 && i<ni && j>=0 && j<nj)
1242 data_i_index(
count) = ki;
1243 data_j_index(
count) = kj;
1247 data_i_index(
count) = -1;
1248 data_j_index(
count) = -1;
1253 data_i_index(
count) = -1;
1254 data_j_index(
count) = -1;
1270 size_t dn=data_i_index.numElements() ;
1278 i=data_i_index(k)+data_ibegin ;
1279 j=data_j_index(k)+data_jbegin ;
1280 if (i>=0 && i<ni && j>=0 && j<nj)
1288 i=data_i_index(k)+data_ibegin ;
1289 if (i>=0 && i<
i_index.numElements())
1303 isCompressible_ = !mask_1d.isEmpty() || !mask_2d.isEmpty() || !data_i_index.isEmpty();
1316 bool lonlatValueExisted = (0 !=
lonvalue.numElements()) || (0 !=
latvalue.numElements());
1320 if (!lonvalue_2d.isEmpty() && !lonlatValueExisted)
1330 for (
int j = 0; j < nj; ++j)
1332 for (
int i = 0; i < ni; ++i)
1341 for (
int n = 0; n <
nvertex; ++n)
1350 else if (!lonvalue_1d.isEmpty() && !lonlatValueExisted)
1352 if (type_attr::rectilinear ==
type)
1354 if (ni == lonvalue_1d.numElements() && nj == latvalue_1d.numElements())
1364 for (
int j = 0; j < nj; ++j)
1366 for (
int i = 0; i < ni; ++i)
1375 for (
int n = 0; n <
nvertex; ++n)
1384 else if (
i_index.numElements() == lonvalue_1d.numElements() && j_index.numElements() == latvalue_1d.numElements() && !lonlatValueExisted)
1395 ERROR(
"CDomain::completeLonClient(void)",
1397 <<
"'lonvalue_1d' and 'latvalue_1d' does not have the same size as the local domain." << std::endl
1398 <<
"'lonvalue_1d' size is " << lonvalue_1d.numElements()
1399 <<
" and 'latvalue_1d' size is " << latvalue_1d.numElements() << std::endl
1400 <<
" They should be correspondingly " << ni.getValue() <<
" and " << nj.getValue() <<
" or " << std::endl
1401 <<
i_index.numElements() <<
" and " << j_index.numElements() <<
".");
1403 else if (
type == type_attr::curvilinear ||
type == type_attr::unstructured && !lonlatValueExisted)
1418 for (
int j = 0; j < nj; ++j)
1420 for (
int i = 0; i < ni; ++i)
1436 bool lonlatValueExisted = (0 !=
lonvalue.numElements()) || (0 !=
latvalue.numElements());
1437 if (!lonvalue_2d.isEmpty() && lonlatValueExisted)
1439 lonvalue_2d.resize(ni,nj);
1440 latvalue_2d.resize(ni,nj);
1443 bounds_lon_2d.resize(
nvertex, ni, nj);
1444 bounds_lat_2d.resize(
nvertex, ni, nj);
1447 for (
int j = 0; j < nj; ++j)
1449 for (
int i = 0; i < ni; ++i)
1458 for (
int n = 0; n <
nvertex; ++n)
1467 else if (!lonvalue_1d.isEmpty() && lonlatValueExisted)
1469 if (type_attr::rectilinear ==
type)
1471 if (ni == lonvalue_1d.numElements() && nj == latvalue_1d.numElements())
1481 for (
int j = 0; j < nj; ++j)
1483 for (
int i = 0; i < ni; ++i)
1492 for (
int n = 0; n <
nvertex; ++n)
1501 else if (
i_index.numElements() == lonvalue_1d.numElements() && j_index.numElements() == latvalue_1d.numElements() && !lonlatValueExisted)
1512 ERROR(
"CDomain::completeLonClient(void)",
1514 <<
"'lonvalue_1d' and 'latvalue_1d' does not have the same size as the local domain." << std::endl
1515 <<
"'lonvalue_1d' size is " << lonvalue_1d.numElements()
1516 <<
" and 'latvalue_1d' size is " << latvalue_1d.numElements() << std::endl
1517 <<
" They should be correspondingly " << ni.getValue() <<
" and " << nj.getValue() <<
" or " << std::endl
1518 <<
i_index.numElements() <<
" and " << j_index.numElements() <<
".");
1520 else if (
type == type_attr::curvilinear ||
type == type_attr::unstructured && !lonlatValueExisted)
1540 if (!bounds_lon_1d.isEmpty() && !bounds_lon_2d.isEmpty())
1541 ERROR(
"CDomain::checkBounds(void)",
1543 <<
"Only one longitude boundary attribute can be used but both 'bounds_lon_1d' and 'bounds_lon_2d' are defined." << std::endl
1544 <<
"Define only one longitude boundary attribute: 'bounds_lon_1d' or 'bounds_lon_2d'.");
1546 if (!bounds_lat_1d.isEmpty() && !bounds_lat_2d.isEmpty())
1547 ERROR(
"CDomain::checkBounds(void)",
1549 <<
"Only one latitude boundary attribute can be used but both 'bounds_lat_1d' and 'bounds_lat_2d' are defined." << std::endl
1550 <<
"Define only one latitude boundary attribute: 'bounds_lat_1d' or 'bounds_lat_2d'.");
1552 if ((!bounds_lon_1d.isEmpty() && bounds_lat_1d.isEmpty()) || (bounds_lon_1d.isEmpty() && !bounds_lat_1d.isEmpty()))
1554 ERROR(
"CDomain::checkBounds(void)",
1556 <<
"Only 'bounds_lon_1d' or 'bounds_lat_1d' is defined." << std::endl
1557 <<
"Please define either both attributes or none.");
1560 if ((!bounds_lon_2d.isEmpty() && bounds_lat_2d.isEmpty()) || (bounds_lon_2d.isEmpty() && !bounds_lat_2d.isEmpty()))
1562 ERROR(
"CDomain::checkBounds(void)",
1564 <<
"Only 'bounds_lon_2d' or 'bounds_lat_2d' is defined." << std::endl
1565 <<
"Please define either both attributes or none.");
1568 if (!bounds_lon_1d.isEmpty() &&
nvertex.getValue() != bounds_lon_1d.extent(0))
1569 ERROR(
"CDomain::checkBounds(void)",
1571 <<
"'bounds_lon_1d' dimension is not compatible with 'nvertex'." << std::endl
1572 <<
"'bounds_lon_1d' dimension is " << bounds_lon_1d.extent(0)
1573 <<
" but nvertex is " <<
nvertex.getValue() <<
".");
1575 if (!bounds_lon_2d.isEmpty() &&
nvertex.getValue() != bounds_lon_2d.extent(0))
1576 ERROR(
"CDomain::checkBounds(void)",
1578 <<
"'bounds_lon_2d' dimension is not compatible with 'nvertex'." << std::endl
1579 <<
"'bounds_lon_2d' dimension is " << bounds_lon_2d.extent(0)
1580 <<
" but nvertex is " <<
nvertex.getValue() <<
".");
1582 if (!bounds_lon_1d.isEmpty() && lonvalue_1d.isEmpty())
1583 ERROR(
"CDomain::checkBounds(void)",
1585 <<
"Since 'bounds_lon_1d' is defined, 'lonvalue_1d' must be defined too." << std::endl);
1587 if (!bounds_lon_2d.isEmpty() && lonvalue_2d.isEmpty())
1588 ERROR(
"CDomain::checkBounds(void)",
1590 <<
"Since 'bounds_lon_2d' is defined, 'lonvalue_2d' must be defined too." << std::endl);
1592 if (!bounds_lat_1d.isEmpty() &&
nvertex.getValue() != bounds_lat_1d.extent(0))
1593 ERROR(
"CDomain::checkBounds(void)",
1595 <<
"'bounds_lat_1d' dimension is not compatible with 'nvertex'." << std::endl
1596 <<
"'bounds_lat_1d' dimension is " << bounds_lat_1d.extent(0)
1597 <<
" but nvertex is " <<
nvertex.getValue() <<
".");
1599 if (!bounds_lat_2d.isEmpty() &&
nvertex.getValue() != bounds_lat_2d.extent(0))
1600 ERROR(
"CDomain::checkBounds(void)",
1602 <<
"'bounds_lat_2d' dimension is not compatible with 'nvertex'." << std::endl
1603 <<
"'bounds_lat_2d' dimension is " << bounds_lat_2d.extent(0)
1604 <<
" but nvertex is " <<
nvertex.getValue() <<
".");
1606 if (!bounds_lat_1d.isEmpty() && latvalue_1d.isEmpty())
1607 ERROR(
"CDomain::checkBounds(void)",
1609 <<
"Since 'bounds_lat_1d' is defined, 'latvalue_1d' must be defined too." << std::endl);
1611 if (!bounds_lat_2d.isEmpty() && latvalue_2d.isEmpty())
1612 ERROR(
"CDomain::checkBounds(void)",
1613 <<
"Since 'bounds_lat_2d' is defined, 'latvalue_2d' must be defined too." << std::endl);
1616 hasBounds = (!bounds_lat_1d.isEmpty() || !bounds_lat_2d.isEmpty() );
1618 else if (hasBoundValues)
1636 if (area.extent(0) != ni || area.extent(1) != nj)
1638 ERROR(
"CDomain::checkArea(void)",
1640 <<
"The area does not have the same size as the local domain." << std::endl
1641 <<
"Local size is " << ni.getValue() <<
" x " << nj.getValue() <<
"." << std::endl
1642 <<
"Area size is " << area.extent(0) <<
" x " << area.extent(1) <<
".");
1664 (!latvalue_2d.isEmpty() && !lonvalue_2d.isEmpty());
1665 bool hasLonLatValue = (0 !=
lonvalue.numElements()) || (0 !=
latvalue.numElements());
1668 if (!lonvalue_1d.isEmpty() && !lonvalue_2d.isEmpty())
1669 ERROR(
"CDomain::checkLonLat()",
1671 <<
"Only one longitude attribute can be used but both 'lonvalue_1d' and 'lonvalue_2d' are defined." << std::endl
1672 <<
"Define only one longitude attribute: 'lonvalue_1d' or 'lonvalue_2d'.");
1674 if (!lonvalue_1d.isEmpty() && lonvalue_2d.isEmpty())
1676 if ((type_attr::rectilinear !=
type) && (lonvalue_1d.numElements() !=
i_index.numElements()))
1677 ERROR(
"CDomain::checkLonLat()",
1679 <<
"'lonvalue_1d' does not have the same size as the local domain." << std::endl
1680 <<
"Local size is " <<
i_index.numElements() <<
"." << std::endl
1681 <<
"'lonvalue_1d' size is " << lonvalue_1d.numElements() <<
".");
1684 if (lonvalue_1d.isEmpty() && !lonvalue_2d.isEmpty())
1686 if (lonvalue_2d.extent(0) != ni || lonvalue_2d.extent(1) != nj)
1687 ERROR(
"CDomain::checkLonLat()",
1689 <<
"'lonvalue_2d' does not have the same size as the local domain." << std::endl
1690 <<
"Local size is " << ni.getValue() <<
" x " << nj.getValue() <<
"." << std::endl
1691 <<
"'lonvalue_2d' size is " << lonvalue_2d.extent(0) <<
" x " << lonvalue_2d.extent(1) <<
".");
1694 if (!latvalue_1d.isEmpty() && !latvalue_2d.isEmpty())
1695 ERROR(
"CDomain::checkLonLat()",
1697 <<
"Only one latitude attribute can be used but both 'latvalue_1d' and 'latvalue_2d' are defined." << std::endl
1698 <<
"Define only one latitude attribute: 'latvalue_1d' or 'latvalue_2d'.");
1700 if (!latvalue_1d.isEmpty() && latvalue_2d.isEmpty())
1702 if ((type_attr::rectilinear !=
type) && (latvalue_1d.numElements() !=
i_index.numElements()))
1703 ERROR(
"CDomain::checkLonLat()",
1705 <<
"'latvalue_1d' does not have the same size as the local domain." << std::endl
1706 <<
"Local size is " <<
i_index.numElements() <<
"." << std::endl
1707 <<
"'latvalue_1d' size is " << latvalue_1d.numElements() <<
".");
1710 if (latvalue_1d.isEmpty() && !latvalue_2d.isEmpty())
1712 if (latvalue_2d.extent(0) != ni || latvalue_2d.extent(1) != nj)
1713 ERROR(
"CDomain::checkLonLat()",
1715 <<
"'latvalue_2d' does not have the same size as the local domain." << std::endl
1716 <<
"Local size is " << ni.getValue() <<
" x " << nj.getValue() <<
"." << std::endl
1717 <<
"'latvalue_2d' size is " << latvalue_2d.extent(0) <<
" x " << latvalue_2d.extent(1) <<
".");
1840 for (
int p = 0; p < nbSrvPools; ++p)
1846 bool doComputeGlobalIndexServer =
true;
1853 int i,j,i_ind,j_ind, nbIndex=
i_index.numElements();
1854 int globalIndexCount =
i_index.numElements();
1859 for (i = 0; i < nbIndex; ++i)
1863 globalIndex = i_ind + j_ind * ni_glo;
1864 globalIndexDomain(i) = globalIndex;
1869 for (i = 0; i < nbIndex; ++i)
1873 size_t globalSizeIndex = 1, indexBegin, indexEnd;
1875 std::vector<int> nGlobDomain(2);
1876 nGlobDomain[0] = this->ni_glo;
1877 nGlobDomain[1] = this->
nj_glo;
1878 for (
int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i];
1880 if (globalSizeIndex <= clientSize)
1882 indexBegin = rank%globalSizeIndex;
1883 indexEnd = indexBegin;
1887 for (
int i = 0; i < clientSize; ++i)
1889 range = globalSizeIndex / clientSize;
1890 if (i < (globalSizeIndex%clientSize)) ++range;
1892 indexBegin += range;
1894 indexEnd = indexBegin + range - 1;
1900 std::vector<int> serverZeroIndex;
1904 std::list<int> serverZeroIndexLeader;
1905 std::list<int> serverZeroIndexNotLeader;
1907 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
1908 *it = serverZeroIndex[*it];
1914 CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexDomainOnServer.begin(),
1915 ite = globalIndexDomainOnServer.end();
1916 indSrv_[nbServer].swap(globalIndexDomainOnServer);
1918 for (it =
indSrv_[nbServer].begin(); it != ite; ++it)
1921 for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
1931 std::vector<int> counts (clientSize);
1932 std::vector<int> displs (clientSize);
1935 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->
intraComm) ;
1936 for (
int i = 0; i < clientSize-1; ++i)
1938 displs[i+1] = displs[i] + counts[i];
1940 std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]);
1941 MPI_Gatherv(&(
connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->
intraComm);
1943 if ((allConnectedServers.size() != nbServer) && (rank == 0))
1945 std::vector<bool> isSrvConnected (nbServer,
false);
1946 for (
int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] =
true;
1947 for (
int i = 0; i < nbServer; ++i)
1953 delete clientServerMap;
1974 std::vector<int> nBegin(2), nSize(2), nBeginGlobal(2), nGlob(2);
1975 nBegin[0] = ibegin; nBegin[1] = jbegin;
1976 nSize[0] = ni; nSize[1] = nj;
1977 nBeginGlobal[0] = 0; nBeginGlobal[1] = 0;
1978 nGlob[0] = ni_glo; nGlob[1] =
nj_glo;
1982 size_t nbWritten = 0, indGlo;
1986 itSrve = writtenGlobalIndex.end(), itSrv;
1990 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
2009 int writtenCommSize;
2010 MPI_Comm_size(writtenComm, &writtenCommSize);
2016 size_t nbWritten = 0, indGlo;
2020 std::vector<int> nBegin(2), nSize(2), nBeginGlobal(2), nGlob(2);
2021 nBegin[0] = ibegin; nBegin[1] = jbegin;
2022 nSize[0] = ni; nSize[1] = nj;
2023 nBeginGlobal[0] = 0; nBeginGlobal[1] = 0;
2024 nGlob[0] = ni_glo; nGlob[1] =
nj_glo;
2031 itSrve = writtenGlobalIndex.end(), itSrv;
2032 std::unordered_map<size_t,size_t> localGlobalIndexMap;
2033 for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
2044 for (
int idx = 0; idx < data_i_index.numElements(); ++idx)
2046 if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
2054 for (
int idx = 0; idx < data_i_index.numElements(); ++idx)
2056 if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
2065 MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, writtenComm) ;
2067 if (distributed_glo)
2100 int ns, n, i, j,
ind, nv, idx;
2101 std::list<CContextClient*>::iterator it;
2109 list<CMessage> list_msgsIndex;
2110 list<CArray<int,1> > list_indGlob;
2112 std::unordered_map<int, vector<size_t> >::const_iterator itIndex, iteIndex;
2113 iteIndex =
indSrv_[serverSize].end();
2118 itIndex =
indSrv_[serverSize].find(rank);
2119 if (iteIndex != itIndex)
2120 nbIndGlob = itIndex->second.size();
2125 for (n = 0; n < nbIndGlob; ++n)
2127 indGlob(n) =
static_cast<int>(itIndex->second[n]);
2130 list_msgsIndex.push_back(
CMessage());
2131 list_msgsIndex.back() << this->
getId() << (int)
type;
2133 list_msgsIndex.back() << list_indGlob.back();
2135 eventIndex.
push(rank,
nbSenders[serverSize][rank], list_msgsIndex.back());
2151 std::list<CContextClient*>::iterator it;
2156 std::vector<int> nGlobDomain(2);
2157 nGlobDomain[0] = this->ni_glo;
2158 nGlobDomain[1] = this->
nj_glo;
2164 std::vector<std::vector<int> > serverIndexBegin = serverDescription.
getServerIndexBegin();
2170 std::list<CMessage> msgs;
2173 for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
2176 const int ibegin_srv = serverIndexBegin[*itRank][0];
2177 const int jbegin_srv = serverIndexBegin[*itRank][1];
2178 const int ni_srv = serverDimensionSizes[*itRank][0];
2179 const int nj_srv = serverDimensionSizes[*itRank][1];
2183 msg << this->
getId() ;
2185 msg << ni_srv << ibegin_srv << nj_srv << jbegin_srv;
2186 msg << ni_glo.getValue() <<
nj_glo.getValue();
2189 event.push(*itRank,1,msg);
2206 int ns, n, i, j,
ind, nv, idx;
2207 std::list<CContextClient*>::iterator it;
2217 list<CMessage> list_msgsArea;
2218 list<CArray<double,1> > list_area;
2220 std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
2221 iteMap =
indSrv_[serverSize].end();
2226 it =
indSrv_[serverSize].find(rank);
2228 nbData = it->second.size();
2231 const std::vector<size_t>& temp = it->second;
2232 for (n = 0; n < nbData; ++n)
2234 idx =
static_cast<int>(it->second[n]);
2238 list_msgsArea.push_back(
CMessage());
2240 list_msgsArea.back() << list_area.back();
2241 eventArea.
push(rank,
nbSenders[serverSize][rank], list_msgsArea.back());
2258 int ns, n, i, j,
ind, nv, idx;
2259 std::list<CContextClient*>::iterator it;
2269 list<CMessage> list_msgsLon, list_msgsLat;
2270 list<CArray<double,1> > list_lon, list_lat;
2271 list<CArray<double,2> > list_boundslon, list_boundslat;
2273 std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
2274 iteMap =
indSrv_[serverSize].end();
2279 it =
indSrv_[serverSize].find(rank);
2281 nbData = it->second.size();
2294 const std::vector<size_t>& temp = it->second;
2295 for (n = 0; n < nbData; ++n)
2297 idx =
static_cast<int>(it->second[n]);
2307 for (nv = 0; nv <
nvertex; ++nv)
2315 list_msgsLon.push_back(
CMessage());
2316 list_msgsLat.push_back(
CMessage());
2320 list_msgsLon.back() << list_lon.back();
2324 list_msgsLon.back() << list_boundslon.back();
2329 list_msgsLat.back() << list_lat.back();
2333 list_msgsLat.back() << list_boundslat.back();
2336 eventLon.
push(rank,
nbSenders[serverSize][rank], list_msgsLon.back());
2337 eventLat.
push(rank,
nbSenders[serverSize][rank], list_msgsLat.back());
2354 int ns, n, i, j,
ind, nv, idx;
2355 std::list<CContextClient*>::iterator it;
2365 list<CMessage> list_msgsDataIndex;
2366 list<CArray<int,1> > list_data_i_index, list_data_j_index;
2368 int nbIndex =
i_index.numElements();
2370 int njByIndex = max(j_index) - min(j_index) + 1;
2371 int dataIindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : niByIndex;
2372 int dataJindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : njByIndex;
2380 for (idx = 0; idx < data_i_index.numElements(); ++idx)
2382 int dataIidx = data_i_index(idx) + data_ibegin;
2383 int dataJidx = data_j_index(idx) + data_jbegin;
2384 if ((0 <= dataIidx) && (dataIidx < dataIindexBound) &&
2385 (0 <= dataJidx) && (dataJidx < dataJindexBound))
2387 dataIIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1;
2388 dataJIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1;
2392 std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
2393 iteMap =
indSrv_[serverSize].end();
2398 it =
indSrv_[serverSize].find(rank);
2400 nbData = it->second.size();
2404 const std::vector<size_t>& temp = it->second;
2405 for (n = 0; n < nbData; ++n)
2407 idx =
static_cast<int>(it->second[n]);
2409 list_data_i_index.back()(n) = dataIIndex(i);
2410 list_data_j_index.back()(n) = dataJIndex(i);
2413 list_msgsDataIndex.push_back(
CMessage());
2414 list_msgsDataIndex.back() << this->
getId();
2415 list_msgsDataIndex.back() << list_data_i_index.back() << list_data_j_index.back();
2416 eventDataIndex.
push(rank,
nbSenders[serverSize][rank], list_msgsDataIndex.back());
2456 ERROR(
"bool CDomain::dispatchEvent(CEventServer& event)",
2457 <<
"Unknown Event");
2472 std::map<int, CBufferIn*> rankBuffers;
2474 list<CEventServer::SSubEvent>::iterator it;
2475 for (it = event.subEvents.begin(); it !=
event.subEvents.end(); ++it)
2478 *buffer >> domainId;
2479 rankBuffers[it->rank] = buffer;
2493 int nbReceived = rankBuffers.size(), i,
ind, index, type_int, iIndex, jIndex;
2496 std::map<int, CBufferIn*>::iterator it = rankBuffers.begin(), ite = rankBuffers.end();
2498 for (ind = 0; it != ite; ++it, ++
ind)
2503 type.setValue((type_attr::t_enum)type_int);
2506 for (i = 0; i < nbReceived; ++i)
2513 j_index.resize(nbIndGlob);
2514 int nbIndexGlobMax = nbIndGlob, nbIndLoc;
2517 for (i = 0; i < nbReceived; ++i)
2520 for (ind = 0; ind < tmp.numElements(); ++
ind)
2525 iIndex = (index%ni_glo)-ibegin;
2526 iIndex = (iIndex < 0) ? 0 : iIndex;
2527 jIndex = (index/ni_glo)-jbegin;
2528 jIndex = (jIndex < 0) ? 0 : jIndex;
2529 nbIndLoc = iIndex + ni * jIndex;
2530 i_index(nbIndGlob) = index % ni_glo;
2531 j_index(nbIndGlob) = index / ni_glo;
2541 j_index.resize(nbIndGlob);
2546 j_index.resizeAndPreserve(nbIndGlob);
2575 int ni_tmp, ibegin_tmp, nj_tmp, jbegin_tmp;
2576 int ni_glo_tmp, nj_glo_tmp;
2577 buffer >>
isUnstructed_ >> ni_tmp >> ibegin_tmp >> nj_tmp >> jbegin_tmp
2578 >> ni_glo_tmp >> nj_glo_tmp
2581 ni.setValue(ni_tmp);
2582 ibegin.setValue(ibegin_tmp);
2583 nj.setValue(nj_tmp);
2584 jbegin.setValue(jbegin_tmp);
2585 ni_glo.setValue(ni_glo_tmp);
2586 nj_glo.setValue(nj_glo_tmp);
2598 std::map<int, CBufferIn*> rankBuffers;
2600 list<CEventServer::SSubEvent>::iterator it;
2601 for (it = event.subEvents.begin(); it !=
event.subEvents.end(); ++it)
2604 *buffer >> domainId;
2605 rankBuffers[it->rank] = buffer;
2607 get(domainId)->
recvLon(rankBuffers);
2618 int nbReceived = rankBuffers.size(), i,
ind, index, iindex, jindex, lInd;
2620 ERROR(
"void CDomain::recvLon(std::map<int, CBufferIn*>& rankBuffers)",
2621 <<
"The number of sending clients is not correct."
2622 <<
"Expected number: " <<
recvClientRanks_.size() <<
" but received " << nbReceived);
2624 vector<CArray<double,1> > recvLonValue(nbReceived);
2625 vector<CArray<double,2> > recvBoundsLonValue(nbReceived);
2629 CBufferIn& buffer = *(rankBuffers[rank]);
2632 buffer >> recvLonValue[i];
2635 buffer >> recvBoundsLonValue[i];
2641 for (i = 0; i < nbReceived; ++i)
2643 nbLonInd += recvLonValue[i].numElements();
2647 info (0) <<
"If domain " << this->getDomainOutputName() <<
" does not have overlapped regions between processes "
2648 <<
"something must be wrong with longitude index "<< std::endl;
2659 for (i = 0; i < nbReceived; ++i)
2663 for (ind = 0; ind < tmp.numElements(); ++
ind)
2669 for (
int nv = 0; nv <
nvertex; ++nv)
2686 std::map<int, CBufferIn*> rankBuffers;
2688 list<CEventServer::SSubEvent>::iterator it;
2689 for (it = event.subEvents.begin(); it !=
event.subEvents.end(); ++it)
2692 *buffer >> domainId;
2693 rankBuffers[it->rank] = buffer;
2695 get(domainId)->
recvLat(rankBuffers);
2706 int nbReceived = rankBuffers.size(), i,
ind, index, iindex, jindex, lInd;
2708 ERROR(
"void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)",
2709 <<
"The number of sending clients is not correct."
2710 <<
"Expected number: " <<
recvClientRanks_.size() <<
" but received " << nbReceived);
2712 vector<CArray<double,1> > recvLatValue(nbReceived);
2713 vector<CArray<double,2> > recvBoundsLatValue(nbReceived);
2717 CBufferIn& buffer = *(rankBuffers[rank]);
2720 buffer >> recvLatValue[i];
2723 buffer >> recvBoundsLatValue[i];
2729 for (i = 0; i < nbReceived; ++i)
2731 nbLatInd += recvLatValue[i].numElements();
2735 info (0) <<
"If domain " << this->getDomainOutputName() <<
" does not have overlapped regions between processes "
2736 <<
"something must be wrong with latitude index "<< std::endl;
2747 for (i = 0; i < nbReceived; ++i)
2751 for (ind = 0; ind < tmp.numElements(); ++
ind)
2758 for (
int nv = 0; nv <
nvertex; ++nv)
2776 std::map<int, CBufferIn*> rankBuffers;
2778 list<CEventServer::SSubEvent>::iterator it;
2779 for (it = event.subEvents.begin(); it !=
event.subEvents.end(); ++it)
2782 *buffer >> domainId;
2783 rankBuffers[it->rank] = buffer;
2785 get(domainId)->
recvArea(rankBuffers);
2796 int nbReceived = rankBuffers.size(), i,
ind, index, lInd;
2798 ERROR(
"void CDomain::recvArea(std::map<int, CBufferIn*>& rankBuffers)",
2799 <<
"The number of sending clients is not correct."
2800 <<
"Expected number: " <<
recvClientRanks_.size() <<
" but received " << nbReceived);
2802 vector<CArray<double,1> > recvAreaValue(nbReceived);
2806 CBufferIn& buffer = *(rankBuffers[rank]);
2809 buffer >> recvAreaValue[i];
2815 for (i = 0; i < nbReceived; ++i)
2817 nbAreaInd += recvAreaValue[i].numElements();
2821 info (0) <<
"If domain " << this->getDomainOutputName() <<
" does not have overlapped regions between processes "
2822 <<
"something must be wrong with area index "<< std::endl;
2827 for (i = 0; i < nbReceived; ++i)
2831 for (ind = 0; ind < tmp.numElements(); ++
ind)
2852 vector<StdString> excludedAttr;
2853 excludedAttr.push_back(
"domain_ref");
2855 if (!objEqual)
return objEqual;
2860 TransMapTypes::const_iterator it, itb, ite;
2861 std::vector<ETranformationType> thisTransType, objTransType;
2862 for (it = thisTrans.begin(); it != thisTrans.end(); ++it)
2863 thisTransType.push_back(it->first);
2864 for (it = objTrans.begin(); it != objTrans.end(); ++it)
2865 objTransType.push_back(it->first);
2867 if (thisTransType.size() != objTransType.size())
return false;
2868 for (
int idx = 0; idx < thisTransType.size(); ++idx)
2869 objEqual &= (thisTransType[idx] == objTransType[idx]);
2883 std::map<int, CBufferIn*> rankBuffers;
2885 list<CEventServer::SSubEvent>::iterator it;
2886 for (it = event.subEvents.begin(); it !=
event.subEvents.end(); ++it)
2889 *buffer >> domainId;
2890 rankBuffers[it->rank] = buffer;
2908 int nbReceived = rankBuffers.size(), i,
ind, index, indexI, indexJ, type_int, lInd;
2910 ERROR(
"void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)",
2911 <<
"The number of sending clients is not correct."
2912 <<
"Expected number: " <<
recvClientRanks_.size() <<
" but received " << nbReceived);
2914 vector<CArray<int,1> > recvDataIIndex(nbReceived),recvDataJIndex(nbReceived);
2918 CBufferIn& buffer = *(rankBuffers[rank]);
2919 buffer >> recvDataIIndex[i];
2920 buffer >> recvDataJIndex[i];
2923 int nbIndex =
i_index.numElements();
2925 dataIIndex = -1; dataJIndex = -1;
2928 for (i = 0; i < nbReceived; ++i)
2933 if ((tmpI.numElements() != tmpInd.numElements()) || (tmpJ.numElements() != tmpInd.numElements()))
2934 ERROR(
"void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)",
2935 <<
"The number of global received index is not coherent with the number of received data index."
2936 <<
"Expected number of global index: " << tmpI.numElements() <<
" but received " << tmpInd.numElements());
2938 for (ind = 0; ind < tmpI.numElements(); ++
ind)
2941 dataIIndex(lInd) = (-1 == dataIIndex(lInd)) ? tmpI(ind) : dataIIndex(lInd);
2942 dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd);
2946 int nbCompressedData = 0;
2947 for (ind = 0; ind < dataIIndex.numElements(); ++
ind)
2949 indexI = dataIIndex(ind); indexJ = dataJIndex(ind);
2950 if ((0 <= indexI) && (0 <= indexJ))
2954 data_i_index.resize(nbCompressedData);
2955 data_j_index.resize(nbCompressedData);
2957 nbCompressedData = 0;
2958 for (ind = 0; ind < dataIIndex.numElements(); ++
ind)
2960 indexI = dataIIndex(ind); indexJ = dataJIndex(ind);
2961 if ((0 <= indexI) && (0 <= indexJ))
2963 data_i_index(nbCompressedData) = (1 == data_dim) ? ind : ind % ni;
2964 data_j_index(nbCompressedData) = (1 == data_dim) ? 0 : ind / ni;
2970 data_ibegin.setValue(0);
2971 data_jbegin.setValue(0);
3019 if (src->hasTransformation())
3036 std::vector<CDomain*> refDomains;
3039 refDomains.push_back(domain);
3040 domain = domain->getDirectDomainReference();
3044 for (
size_t i = 0; i < refDomains.size(); ++i)
3054 clients.push_back(contextClient) ;
3070 if (node.goToChildElement())
3076 if (node.getAttributes().end() != node.getAttributes().find(
"id"))
3077 { nodeId = node.getAttributes()[
"id"]; }
3079 nodeElementName = node.getElementName();
3090 ERROR(
"void CDomain::parse(xml::CXMLNode & node)",
3091 <<
"The transformation " << nodeElementName <<
" has not been supported yet.");
3093 }
while (node.goToNextElement()) ;
3094 node.goToParentElement();
void checkLocalJDomain(void)
This class contains information that describe distribution of servers.
static const size_t headerSize
static bool _dummyTransformationMapList
CATCH CDomainAlgorithmReorder::CDomainAlgorithmReorder(CDomain *domainDestination, CDomain *domainSource, CReorderDomain *reorderDomain if)(domainDestination->type!=CDomain::type_attr::rectilinear)
static void computeLeader(int clientRank, int clientSize, int serverSize, std::list< int > &rankRecvLeader, std::list< int > &rankRecvNotLeader)
void sendEvent(CEventClient &event)
In case of attached mode, the current context must be reset to context for client.
bool IsWritten(const StdString &filename) const
void fillInRectilinearBoundLonLat(CArray< double, 1 > &lon, CArray< double, 1 > &lat, CArray< double, 2 > &boundsLon, CArray< double, 2 > &boundsLat)
MPI_Comm intraComm
Communicator of client group.
virtual size_t size(void) const
void computeConnectedClients()
Compute the connection of a client to other clients to determine which clients to send attributes to...
#define DEFINE_REF_FUNC(type, name_)
static bool initializeTransformationMap(std::map< StdString, ETranformationType > &m)
bool isCompressible_
True if and only if the data defined on the domain can be outputted in a compressed way...
std::map< int, int > numberWrittenIndexes_
enum xios::transformation_type ETranformationType
////////////////////// Définitions ////////////////////// ///
static void recvIndex(CEventServer &event)
Receive index event from clients(s)
void sendCheckedAttributes()
std::set< StdString > relFiles
static bool dispatchEvent(CEventServer &event)
bool distributionAttributesHaveValue() const
Verify if all distribution information of a domain are available This checking verifies the definitio...
CArray< bool, 1 > localMask
int getNumberWrittenIndexes(MPI_Comm writtenCom)
Returns the number of indexes written by each server.
CArray< bool, 1 > domainMask
void checkDomainData(void)
static CMesh * getMesh(StdString, int)
bool isDistributed(void) const
bool isEqual(CDomain *domain)
Compare two domain objects.
int clientSize
Size of client group.
void sendIndex()
Send global index from client to connected client(s)
void assignMesh(const StdString, const int)
TransMapTypes getAllTransformations()
Get all transformation current domain has.
CArray< int, 1 > & i_index
std::vector< CContextClient * > clientPrimServer
void computeWrittenCompressedIndex(MPI_Comm)
CContextServer * server
Concrete context server.
static ENodeType GetType(void)
void solveInheritanceTransformation()
Go through the hierarchy to find the domain from which the transformations must be inherited...
std::vector< int > computeServerGlobalIndexInRange(const std::pair< size_t, size_t > &indexBeginEnd, int positionDimensionDistributed=1)
Compute global index assigned to a server with a range.E.g: if a grid has 100 points and there are 2 ...
static void recvArea(CEventServer &event)
Receive area event from clients(s)
std::vector< std::vector< int > > getServerDimensionSizes() const
Get size of each dimension on distributed server.
CArray< int, 1 > & getCompressedIndexToWriteOnServer(MPI_Comm writtenCom)
void checkAttributesOnClient()
void fillInUnstructuredLonLat()
void sendDistributionAttributes()
Send distribution from client to other clients Because a client in a level knows correctly the grid d...
const std::list< int > & getRanksServerLeader(void) const
Get leading server in the group of connected server.
void duplicateTransformation(CDomain *)
void checkAttributesOnClientAfterTransformation()
void checkAttributes(void)
Vérifications ///.
const StdString & getId(void) const
Accesseurs ///.
Description of index distribution on server(s).
std::vector< std::vector< int > > getServerIndexBegin() const
Get index begin of each dimension on distributed server.
const GlobalIndexMap & getGlobalIndexOnServer() const
Return global index of data on each connected server.
void sendArea()
Send area from client to connected client(s)
bool isWrittenCompressed(const StdString &filename) const
This class computes index of data which are sent to server as well as index of data on server side...
TransMapTypes transformationMap_
std::vector< int > recvClientRanks_
void convertLonLatValue()
void completeLonLatClient(void)
void sendDataIndex()
Send data index to corresponding connected clients.
CTransformation< CDomain >::TransformationMapTypes TransMapTypes
static void recvLon(CEventServer &event)
Receive longitude event from clients(s)
CArray< double, 2 > bounds_lonvalue
CArray< double, 1 > lonvalue
std::map< int, map< int, int > > nbSenders
const CArray< size_t, 1 > & getGlobalIndex() const
Get rank of current process.
static void recvDistributionAttributes(CEventServer &event)
Receive attributes event from clients(s)
bool computedWrittenIndex_
virtual void computeServerIndexMapping(const CArray< size_t, 1 > &globalIndexOnClient, int nbServer)=0
CArray< double, 1 > areavalue
const std::set< StdString > & getRelFiles(void) const
CDomain(void)
Constructeurs ///.
void fillInCurvilinearLonLat()
std::unordered_map< int, std::vector< size_t > > GlobalIndexMap
CATCH CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CScalar *scalarDestination, CScalar *scalarSource, CReduceScalarToScalar *algo ERROR)("CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CScalar* scalarDestination, CScalar* scalarSource, CReduceScalarToScalar* algo)",<< "Operation must be defined."<< "Scalar source "<< scalarSource->getId()<< std::endl<< "Scalar destination "<< scalarDestination->getId())
A context can be both on client and on server side.
void checkLocalIDomain(void)
std::map< int, int > offsetWrittenIndexes_
////////////////////// Déclarations ////////////////////// ///
void push(int rank, int nbSender, CMessage &msg)
virtual bool isEmpty(void) const
virtual ~CDomain(void)
Destructeur ///.
void sendAttributes()
Send all attributes from client to connected clients The attributes will be rebuilt on receiving side...
bool isClientAfterTransformationChecked
void fillInLonLat()
Fill in longitude and latitude whose values are read from file.
CArray< double, 1 > latvalue
void resizeAndPreserve(const TinyVector< int, N_rank > &extent)
void checkEligibilityForCompressedOutput(void)
int clientRank
Rank of current client.
std::map< int, StdSize > getAttributesBufferSize(CContextClient *client, bool bufferForWriting=false)
Compute the minimum buffer size required to send the attributes to the server(s). ...
std::map< int, std::unordered_map< int, vector< size_t > > > indSrv_
void setTransformations(const TransMapTypes &)
Set transformation for current domain.
void addRelFile(const StdString &filename)
Mutateur ///.
void computeLocalMask(void)
int serverSize
Size of server group.
virtual void parse(xml::CXMLNode &node)
void sendLonLat()
Send longitude and latitude from client to servers Each client send long and lat information to corre...
void fillInRectilinearLonLat()
Fill in the values for lonvalue_1d and latvalue_1d of rectilinear domain Range of longitude value fro...
bool isCompressible(void) const
Test whether the data defined on the domain can be outputted in a compressed way. ...
static std::map< StdString, ETranformationType > transformationMapList_
void computeWrittenIndex()
Compute index to write data.
int getOffsetWrittenIndexes(MPI_Comm writtenCom)
Returns the offset of indexes written by each server.
void computeServerDistribution(bool doComputeGlobalIndex=false, int positionDimensionDistributed=1)
Compute pre-defined global index distribution of server(s).
Index distribution on client side.
void checkCompression(void)
enum xios::_node_type ENodeType
////////////////////// Définitions ////////////////////// ///
static bool dispatchEvent(CEventServer &event)
CArray< double, 2 > bounds_latvalue
which implements a simple distributed hashed table; Moreover, by extending with hierarchical structur...
std::unordered_map< size_t, size_t > globalLocalIndexMap_
std::map< int, CArray< int, 1 > > indGlob_
void AllgatherRectilinearLonLat(CArray< double, 1 > &lon, CArray< double, 1 > &lat, CArray< double, 1 > &lon_g, CArray< double, 1 > &lat_g)
std::map< int, std::vector< int > > connectedServerRank_
const std::unordered_map< size_t, int > & getGlobalIndexRange() const
Get global index calculated by computeServerGlobalIndexInRange.
static std::map< int, int > computeConnectedClients(int nbServer, int nbClient, MPI_Comm &clientIntraComm, const std::vector< int > &connectedServerRank)
Compute how many clients each server will receive data from On client can send data to several server...
std::map< int, CArray< int, 1 > > compressedIndexToWriteOnServer
std::set< CContextClient * > clientsSet
CTransformation< CDomain > * addTransformation(ETranformationType transType, const StdString &id="")
static StdString GetDefName(void)
size_t getGlobalWrittenSize()
std::map< int, int > totalNumberWrittenIndexes_
ENodeType getType(void) const
Accesseurs ///.
bool hasTransformation()
Check whether a domain has transformation.
bool isEqual(const string &id, const vector< StdString > &excludedAttrs)
static StdString GetName(void)
Accesseurs statiques ///.
CArray< int, 1 > localIndexToWriteOnServer
static void recvDataIndex(CEventServer &event)
Receive data index event from clients(s)
static void recvLat(CEventServer &event)
Receive latitude event from clients(s)
virtual void parse(xml::CXMLNode &node)
Parse children nodes of a domain in xml file.
The class, for now, plays a role of computing local index for writing data on server.
void redistribute(int nbLocalDomain)
Redistribute RECTILINEAR or CURVILINEAR domain with a number of local domains.
void setContextClient(CContextClient *contextClient)
std::list< CContextClient * > clients
static CContext * getCurrent(void)
Get current context.
CContextClient * client
Concrete contex client.
bool isServerLeader(void) const
Check if client connects to leading server.
int getTotalNumberWrittenIndexes(MPI_Comm writtenCom)
Returns the total number of indexes written by the servers.
static StdString & GetCurrentContextId(void)
Accesseurs ///.
static CDomain * createDomain()
void reference(const CArray< T_numtype, N_rank > &array)
void addRelFileCompressed(const StdString &filename)