Changeset 1869 for XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp
- Timestamp:
- 04/15/20 13:23:39 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp
r1853 r1869 1721 1721 CATCH_DUMP_ATTR 1722 1722 1723 void CDomain::checkAttributesOnClientAfterTransformation() 1724 TRY 1725 { 1726 CContext* context=CContext::getCurrent() ; 1727 1728 if (this->isClientAfterTransformationChecked) return; 1729 if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER) 1730 { 1731 this->computeConnectedClients(); 1732 if (hasLonLat) 1733 if (context->getServiceType()==CServicesManager::CLIENT) 1734 this->completeLonLatClient(); 1735 } 1736 1737 this->isClientAfterTransformationChecked = true; 1723 void CDomain::checkAttributes(void) 1724 TRY 1725 { 1726 if (this->checkAttributes_done_) return; 1727 this->checkDomain(); 1728 this->checkLonLat(); 1729 this->checkBounds(); 1730 this->checkArea(); 1731 this->checkMask(); 1732 this->checkDomainData(); 1733 this->checkCompression(); 1734 this->computeLocalMask() ; 1735 this->completeLonLatClient(); 1736 this->checkAttributes_done_ = true; 1738 1737 } 1739 1738 CATCH_DUMP_ATTR … … 1770 1769 } 1771 1770 CATCH_DUMP_ATTR 1772 1773 // Send all checked attributes to server 1771 1772 // ym obselete, to be removed 1773 void CDomain::checkAttributesOnClientAfterTransformation() 1774 TRY 1775 { 1776 CContext* context=CContext::getCurrent() ; 1777 1778 if (this->isClientAfterTransformationChecked) return; 1779 if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER) 1780 { 1781 // this->computeConnectedClients(); 1782 if (hasLonLat) 1783 if (context->getServiceType()==CServicesManager::CLIENT) 1784 this->completeLonLatClient(); 1785 } 1786 1787 this->isClientAfterTransformationChecked = true; 1788 } 1789 CATCH_DUMP_ATTR 1790 1791 // Send all checked attributes to server 1774 1792 void CDomain::sendCheckedAttributes() 1775 1793 TRY … … 1788 1806 CATCH_DUMP_ATTR 1789 1807 1808 /* old version 1790 1809 void CDomain::checkAttributes(void) 1791 1810 TRY … … 1820 1839 } 1821 1840 CATCH_DUMP_ATTR 1822 1841 */ 1842 1823 1843 /*! 1824 1844 Compute the connection of a client to other clients to determine which clients to send attributes to. … … 1827 1847 A client connects to other clients which holds the same global index as it. 1828 1848 */ 1829 void CDomain::computeConnectedClients( )1849 void CDomain::computeConnectedClients(CContextClient* client) 1830 1850 TRY 1831 1851 { 1852 if (computeConnectedClients_done_.count(client)==0) return ; 1853 else computeConnectedClients_done_.insert(client) ; 1854 1832 1855 CContext* context=CContext::getCurrent() ; 1833 set<int> listNbServer ; 1834 1835 for (auto client : clients) 1856 1857 int nbServer = client->serverSize; 1858 int nbClient = client->clientSize; 1859 int rank = client->clientRank; 1860 1861 if (listNbServer_.count(nbServer) == 0) 1836 1862 { 1837 1838 int nbServer = client->serverSize; 1839 int nbClient = client->clientSize; 1840 int rank = client->clientRank; 1841 bool doComputeGlobalIndexServer = true; 1842 1843 if (listNbServer.find(nbServer)==listNbServer.end()) 1844 { 1845 listNbServer.insert(nbServer) ; 1863 listNbServer_.insert(nbServer) ; 1846 1864 1847 if (connectedServerRank_.find(nbServer) != connectedServerRank_.end()) 1848 { 1849 nbSenders.erase(nbServer); 1850 connectedServerRank_.erase(nbServer); 1851 } 1852 1853 if (indSrv_.find(nbServer) == indSrv_.end()) 1854 { 1855 int i,j,i_ind,j_ind, nbIndex=i_index.numElements(); 1856 int globalIndexCount = i_index.numElements(); 1857 // Fill in index 1858 CArray<size_t,1> globalIndexDomain(nbIndex); 1859 size_t globalIndex; 1860 1861 for (i = 0; i < nbIndex; ++i) 1865 if (connectedServerRank_.find(nbServer) != connectedServerRank_.end()) 1866 { 1867 nbSenders.erase(nbServer); 1868 connectedServerRank_.erase(nbServer); 1869 } 1870 1871 if (indSrv_.find(nbServer) == indSrv_.end()) 1872 { 1873 int i,j,i_ind,j_ind, nbIndex=i_index.numElements(); 1874 int globalIndexCount = i_index.numElements(); 1875 // Fill in index 1876 CArray<size_t,1> globalIndexDomain(nbIndex); 1877 size_t globalIndex; 1878 1879 for (i = 0; i < nbIndex; ++i) 1880 { 1881 i_ind=i_index(i); 1882 j_ind=j_index(i); 1883 globalIndex = i_ind + j_ind * ni_glo; 1884 globalIndexDomain(i) = globalIndex; 1885 } 1886 1887 if (globalLocalIndexMap_.empty()) 1888 for (i = 0; i < nbIndex; ++i) globalLocalIndexMap_[globalIndexDomain(i)] = i; 1889 1890 1891 size_t globalSizeIndex = 1, indexBegin, indexEnd; 1892 int range, clientSize = client->clientSize; 1893 std::vector<int> nGlobDomain(2); 1894 nGlobDomain[0] = this->ni_glo; 1895 nGlobDomain[1] = this->nj_glo; 1896 for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i]; 1897 indexBegin = 0; 1898 if (globalSizeIndex <= clientSize) 1899 { 1900 indexBegin = rank%globalSizeIndex; 1901 indexEnd = indexBegin; 1902 } 1903 else 1904 { 1905 for (int i = 0; i < clientSize; ++i) 1862 1906 { 1863 i_ind=i_index(i);1864 j_ind=j_index(i);1865 globalIndex = i_ind + j_ind * ni_glo;1866 globalIndexDomain(i) = globalIndex;1907 range = globalSizeIndex / clientSize; 1908 if (i < (globalSizeIndex%clientSize)) ++range; 1909 if (i == client->clientRank) break; 1910 indexBegin += range; 1867 1911 } 1868 1869 if (globalLocalIndexMap_.empty()) 1870 { 1871 for (i = 0; i < nbIndex; ++i) 1872 globalLocalIndexMap_[globalIndexDomain(i)] = i; 1873 } 1874 1875 size_t globalSizeIndex = 1, indexBegin, indexEnd; 1876 int range, clientSize = client->clientSize; 1877 std::vector<int> nGlobDomain(2); 1878 nGlobDomain[0] = this->ni_glo; 1879 nGlobDomain[1] = this->nj_glo; 1880 for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i]; 1881 indexBegin = 0; 1882 if (globalSizeIndex <= clientSize) 1883 { 1884 indexBegin = rank%globalSizeIndex; 1885 indexEnd = indexBegin; 1886 } 1887 else 1888 { 1889 for (int i = 0; i < clientSize; ++i) 1890 { 1891 range = globalSizeIndex / clientSize; 1892 if (i < (globalSizeIndex%clientSize)) ++range; 1893 if (i == client->clientRank) break; 1894 indexBegin += range; 1895 } 1896 indexEnd = indexBegin + range - 1; 1897 } 1898 1899 // Even if servers have no index, they must received something from client 1900 // We only use several client to send "empty" message to these servers 1901 CServerDistributionDescription serverDescription(nGlobDomain, nbServer); 1902 std::vector<int> serverZeroIndex; 1903 if (isUnstructed_) serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0); 1904 else serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 1); 1905 1906 std::list<int> serverZeroIndexLeader; 1907 std::list<int> serverZeroIndexNotLeader; 1908 CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 1909 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 1910 *it = serverZeroIndex[*it]; 1911 1912 CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 1913 clientServerMap->computeServerIndexMapping(globalIndexDomain, nbServer); 1914 CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer(); 1915 1916 CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexDomainOnServer.begin(), 1917 ite = globalIndexDomainOnServer.end(); 1918 indSrv_[nbServer].swap(globalIndexDomainOnServer); 1919 connectedServerRank_[nbServer].clear(); 1920 for (it = indSrv_[nbServer].begin(); it != ite; ++it) 1921 connectedServerRank_[nbServer].push_back(it->first); 1922 1923 for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 1924 connectedServerRank_[nbServer].push_back(*it); 1925 1926 // Even if a client has no index, it must connect to at least one server and 1927 // send an "empty" data to this server 1928 if (connectedServerRank_[nbServer].empty()) 1929 connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 1930 1931 // Now check if all servers have data to receive. If not, master client will send empty data. 1932 // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 1933 std::vector<int> counts (clientSize); 1934 std::vector<int> displs (clientSize); 1935 displs[0] = 0; 1936 int localCount = connectedServerRank_[nbServer].size() ; 1937 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 1938 for (int i = 0; i < clientSize-1; ++i) 1939 { 1940 displs[i+1] = displs[i] + counts[i]; 1941 } 1942 std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]); 1943 MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 1944 1945 if ((allConnectedServers.size() != nbServer) && (rank == 0)) 1946 { 1947 std::vector<bool> isSrvConnected (nbServer, false); 1948 for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 1949 for (int i = 0; i < nbServer; ++i) 1950 { 1951 if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i); 1952 } 1953 } 1954 nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 1955 delete clientServerMap; 1956 } 1912 indexEnd = indexBegin + range - 1; 1913 } 1914 1915 // Even if servers have no index, they must received something from client 1916 // We only use several client to send "empty" message to these servers 1917 CServerDistributionDescription serverDescription(nGlobDomain, nbServer); 1918 std::vector<int> serverZeroIndex; 1919 if (isUnstructed_) serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0); 1920 else serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 1); 1921 1922 std::list<int> serverZeroIndexLeader; 1923 std::list<int> serverZeroIndexNotLeader; 1924 CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 1925 for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 1926 *it = serverZeroIndex[*it]; 1927 1928 CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 1929 clientServerMap->computeServerIndexMapping(globalIndexDomain, nbServer); 1930 CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer(); 1931 1932 CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexDomainOnServer.begin(), ite = globalIndexDomainOnServer.end(); 1933 indSrv_[nbServer].swap(globalIndexDomainOnServer); 1934 connectedServerRank_[nbServer].clear(); 1935 for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first); 1936 1937 for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 1938 connectedServerRank_[nbServer].push_back(*it); 1939 1940 // Even if a client has no index, it must connect to at least one server and 1941 // send an "empty" data to this server 1942 if (connectedServerRank_[nbServer].empty()) 1943 connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 1944 1945 // Now check if all servers have data to receive. If not, master client will send empty data. 1946 // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 1947 std::vector<int> counts (clientSize); 1948 std::vector<int> displs (clientSize); 1949 displs[0] = 0; 1950 int localCount = connectedServerRank_[nbServer].size() ; 1951 MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 1952 for (int i = 0; i < clientSize-1; ++i) displs[i+1] = displs[i] + counts[i]; 1953 std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]); 1954 MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 1955 1956 if ((allConnectedServers.size() != nbServer) && (rank == 0)) 1957 { 1958 std::vector<bool> isSrvConnected (nbServer, false); 1959 for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 1960 for (int i = 0; i < nbServer; ++i) if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i); 1961 } 1962 nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 1963 delete clientServerMap; 1957 1964 } 1958 1965 } … … 3025 3032 3026 3033 /*! 3034 \brief Check if a domain is completed 3035 Before make any domain processing, we must be sure that all domain informations have 3036 been sent, for exemple when reading a grid in a file or when grid elements are sent by an 3037 other context (coupling). So all direct reference of the domain (domain_ref) must be also completed 3038 \return true if domain and domain reference are completed 3039 */ 3040 bool CDomain::checkIfCompleted(void) 3041 { 3042 if (hasDirectDomainReference()) if (!getDirectDomainReference()->checkIfCompleted()) return false; 3043 return isCompleted_ ; 3044 } 3045 3046 /*! 3047 \brief Set a domain as completed 3048 When all information about a domain have been received, the domain is tagged as completed and is 3049 suitable for processing 3050 */ 3051 void CDomain::setCompleted(void) 3052 { 3053 if (hasDirectDomainReference()) getDirectDomainReference()->setCompleted() ; 3054 isCompleted_=true ; 3055 } 3056 3057 /*! 3058 \brief Set a domain as uncompleted 3059 When informations about a domain are expected from a grid reading from file or coupling, the domain is 3060 tagged as uncompleted and is not suitable for processing 3061 */ 3062 void CDomain::setUncompleted(void) 3063 { 3064 if (hasDirectDomainReference()) getDirectDomainReference()->setUncompleted() ; 3065 isCompleted_=false ; 3066 } 3067 3068 /*! 3027 3069 * Go through the hierarchy to find the domain from which the transformations must be inherited 3028 3070 */
Note: See TracChangeset
for help on using the changeset viewer.