#include "xios_manager.hpp" #include "tree_manager.hpp" #include "data_treatment.hpp" #include "nc4_data_output.hpp" #include "attribute_template_impl.hpp" #include "group_template_impl.hpp" namespace xmlioserver { /// ////////////////////// Définitions ////////////////////// /// void CXIOSManager::Initialise(XIOSType type, int * argc, char *** argv) { CXIOSManager::Type = type; if (type != CLIENT) { // Initialisation de la biliothèque MPI si nécessaire comm::CMPIManager::InitialiseServer(argc, argv); ExeName = StdString((*argv)[0]); for (int i = 1; i < *argc; i++) ExeOptions.push_back(StdString((*argv)[i])); } } void CXIOSManager::Finalize(void) { if (CXIOSManager::Type != CLIENT) { // Finalisation de la biliothèque MPI si nécessaire comm::CMPIManager::Finalize(); } } ///------------------------------------------------------------- StdString CXIOSManager::ExeName("unknown"); std::vector CXIOSManager::ExeOptions; CXIOSManager::XIOSType CXIOSManager::Type = CLIENT; CXIOSManager::XIOSStatus CXIOSManager::Status = LOC_UNUSED; StdString CXIOSManager::ClientName("unknown name"); MPI_Comm CXIOSManager::Comm_Client_Server = MPI_COMM_NULL; MPI_Comm CXIOSManager::Comm_Server = MPI_COMM_NULL; xios_map CXIOSManager::Clients; ///-------------------------------------------------------------- void CXIOSManager::RunServer (StdString clientName, MPI_Comm comm_client_server, MPI_Comm comm_server) { using namespace comm; CXIOSManager::Comm_Client_Server = comm_client_server; CXIOSManager::Comm_Server = comm_server; CXIOSManager::Status = LOC_SERVER; // Reconstruction de l'arborescence d'objet à l'aide des données envoyées par chacun des // clients associés à ce serveur. std::vector > clientBuffer; for (int i = 1; i < CMPIManager::GetCommSize(comm_client_server); i++) { while (!CMPIManager::HasReceivedData(comm_client_server, i)){} clientBuffer.push_back(CMPIManager::ReceiveLinearBuffer(comm_client_server, i)); } // La quasi-totalité de l'arborescence est obtenue depuis les informations // fournies par le client 1 du sous-groupe. /* StdString main_data_tree = clientBuffer[0]->getString(0); tree::CTreeManager::FromBinary(main_data_tree); // Obtention des sous-domaines clients. for (StdSize j = 1; j < clientBuffer.size(); j++) { main_data_tree = clientBuffer[j]->getString(0); tree::CTreeManager::DomainsFromBinary(main_data_tree); } */ // Obtention des sous-domaines clients. for (StdSize j = 0; j < clientBuffer.size(); j++) { StdString main_data_tree = clientBuffer[j]->getString(0); tree::CTreeManager::FromBinary(main_data_tree); } StdOStringStream osss; osss << StdString("./def_server_next.") << CMPIManager::GetCommRank(CMPIManager::GetCommWorld()); CTreeManager::PrintTreeToFile(osss.str()); { // Traitement de tous les contextes StdString currentContextId = CObjectFactory::GetCurrentContextId(); std::vector > def_vector = CContext::GetContextGroup()->getChildList(); std::vector >::iterator it = def_vector.begin(), end = def_vector.end(); //for (; it != end; it++ ) { boost::shared_ptr context = *it; CTreeManager::SetCurrentContextId(context->getId()); boost::shared_ptr dt(new data::CDataTreatment (context)); context->setDataTreatment(dt); dt->createDataOutput(); } CTreeManager::SetCurrentContextId(currentContextId); } StdOStringStream oss; oss << StdString("./def_server_end.") << CMPIManager::GetCommRank(CMPIManager::GetCommWorld()); CTreeManager::PrintTreeToFile(oss.str()); } //-------------------------------------------------------------- void CXIOSManager::ShowInformation_CS(MPI_Comm comm_client_server) { using namespace comm; typedef std::pair StdPairStrClient; if (CMPIManager::IsMaster(comm_client_server)) { xios_map::iterator iit = CXIOSManager::Clients.begin(), eend = CXIOSManager::Clients.end(); for (;iit != eend; iit++) { const StdPairStrClient & elem = *iit; } } comm::CMPIManager::Barrier(comm_client_server); } //-------------------------------------------------------------- void CXIOSManager::RunClientServer(MPI_Comm comm_client_server) { using namespace comm; typedef std::pair StdPairStrClient; CXIOSManager::Comm_Client_Server = comm_client_server; CXIOSManager::Comm_Server = comm_client_server; CXIOSManager::ShowInformation_CS(comm_client_server); xios_map::iterator iit = CXIOSManager::Clients.begin(), eend = CXIOSManager::Clients.end(); StdSize start = 0, end = 0; bool isClient = true, isIncl = false, isIncl_ = false; MPI_Comm comm_client = 0, comm_client_grp = 0; comm_client_server = 0; for (;iit != eend; iit++) { const StdPairStrClient & elem = *iit; std::vector clieindex, servindex ; StdSize currentRank = CMPIManager::GetCommRank(); StdString clientName = elem.first; StdSize nbClient = elem.second.nbClient; StdSize nbClientPServer = elem.second.nbClientPServer; StdSize nbServer = (elem.second.nbClient)/(elem.second.nbClientPServer); for (StdSize i = 0; i= start) && (currentRank <= end)) { comm_client_server = comm_; comm_client_grp = comm__; isIncl = true; CXIOSManager::ClientName = clientName; CXIOSManager::Status = LOC_CLIENT; } if (currentRank == start) { isClient = false; isIncl_ = true; CXIOSManager::Comm_Client_Server = comm_; CXIOSManager::Status = LOC_SERVER; } if (clieindex.size() == nbClient) { MPI_Comm comm___ = CMPIManager::CreateComm (CMPIManager::CreateSubGroup(CMPIManager::GetGroupWorld(), clieindex)); if (isIncl) comm_client = comm___; clieindex.clear(); isIncl = false; } start = start + nbClientPServer + 1; } MPI_Comm comm____ = CMPIManager::CreateComm (CMPIManager::CreateSubGroup(CMPIManager::GetGroupWorld(), servindex)); if (isIncl_) CXIOSManager::Comm_Server = comm____; servindex.clear(); isIncl_ = false; } if (isClient && (CXIOSManager::Clients.find(CXIOSManager::ClientName) != CXIOSManager::Clients.end())) { CXIOSManager::Clients[CXIOSManager::ClientName].entry (comm_client, comm_client_grp, comm_client_server); } else if(CXIOSManager::Clients.find(CXIOSManager::ClientName) != CXIOSManager::Clients.end()) { CXIOSManager::RunServer(CXIOSManager::ClientName, CXIOSManager::Comm_Client_Server, CXIOSManager::Comm_Server); } } //--------------------------------------------------------------- void CXIOSManager::RunClient(bool launch, MPI_Comm comm_client) { if (launch) { CXIOSManager::Status = LOC_CLIENT_SERVER; CXIOSManager::Comm_Server = comm_client; (CXIOSManager::Clients.begin()->second.entry) (comm_client, comm_client, comm_client); } else { CXIOSManager::Status = LOC_CLIENT; } } //--------------------------------------------------------------- void CXIOSManager::AddClient(StdString clientName, StdSize nbClient, StdSize nbClientPServer, void (*entry_point)(MPI_Comm, MPI_Comm, MPI_Comm)) { StdSize nbprocess = comm::CMPIManager::GetCommSize(comm::CMPIManager::GetCommWorld()); StdSize nbprocess_used = CXIOSManager::GetNbClient() + CXIOSManager::GetNbServer(); if (nbClient < nbClientPServer) ERROR("CXIOSManager::AddClient(...)", << "nbClient < nbClientPServer"); if ((nbClient % nbClientPServer) != 0) ERROR("CXIOSManager::AddClient(...)", << " (nbClient % nbClientPServer) != 0 !"); if ((nbprocess-nbprocess_used) < (nbClient + nbClient/nbClientPServer)) ERROR("CXIOSManager::AddClient(...)", << " Pas assez de processus disponibles !"); if (CXIOSManager::Clients.find(clientName) != CXIOSManager::Clients.end()) ERROR("CXIOSManager::AddClient(...)", << " Un client portant le même nom existe déjà !"); XIOSClient client = {nbClient, nbClientPServer, entry_point }; CXIOSManager::Clients[clientName] = client; } //--------------------------------------------------------------- StdSize CXIOSManager::GetNbClient(void) { switch (CXIOSManager::Type) { case (CLIENT_SERVER): { StdSize retvalue = 0; typedef std::pair StdPairStrClient; xios_map::iterator iit = CXIOSManager::Clients.begin(), eend = CXIOSManager::Clients.end(); for (;iit != eend; iit++) { const StdPairStrClient & elem = *iit; retvalue += CXIOSManager::GetNbLocClient(elem.first); } return (retvalue); } case (CLIENT): return (comm::CMPIManager::GetCommSize(CXIOSManager::Comm_Server)); case (SERVER): return (comm::CMPIManager::GetCommSize(CXIOSManager::Comm_Client_Server) - 1); default: return (0); } } //--------------------------------------------------------------- StdSize CXIOSManager::GetNbLocClient(const StdString & clientName) { switch (CXIOSManager::Type) { case (CLIENT_SERVER): return (CXIOSManager::Clients[clientName].nbClient); case (CLIENT): case (SERVER): return (CXIOSManager::GetNbClient()); default: return (0); } } //--------------------------------------------------------------- StdSize CXIOSManager::GetNbServer(void) { switch (CXIOSManager::Type) { case (CLIENT_SERVER): { StdSize retvalue = 0; typedef std::pair StdPairStrClient; xios_map::iterator iit = CXIOSManager::Clients.begin(), eend = CXIOSManager::Clients.end(); for (;iit != eend; iit++) { const StdPairStrClient & elem = *iit; retvalue += CXIOSManager::GetNbLocServer(elem.first); } return (retvalue); } case (CLIENT): return (comm::CMPIManager::GetCommSize(CXIOSManager::Comm_Server)); case (SERVER): return (1); default: return (0); } } //--------------------------------------------------------------- StdSize CXIOSManager::GetNbLocServer(const StdString & clientName) { switch (CXIOSManager::Type) { case (CLIENT_SERVER): return (CXIOSManager::Clients[clientName].nbClient / CXIOSManager::Clients[clientName].nbClientPServer); case (CLIENT): case (SERVER): return (CXIOSManager::GetNbServer()); default: return (0); } } //--------------------------------------------------------------- CXIOSManager::XIOSType CXIOSManager::GetType(void) { return (CXIOSManager::Type); } //--------------------------------------------------------------- CXIOSManager::XIOSStatus CXIOSManager::GetStatus(void) { return (CXIOSManager::Status); } //--------------------------------------------------------------- StdString CXIOSManager::GetClientName(void) { return (CXIOSManager::ClientName); } ///-------------------------------------------------------------- } // namespace xmlioserver