From: cvw Date: Tue, 20 Mar 2012 14:12:58 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: V6_main_FINAL~772 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=dcbf69ab84e93d02d1fb339bb0c98230375d6eae;p=tools%2Fmedcoupling.git *** empty log message *** --- diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx index 5ac9f9586..472bacdeb 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx @@ -23,10 +23,12 @@ #include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx" #include "MEDPARTITIONER_ParaDomainSelector.hxx" #include "MEDPARTITIONER_Topology.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" + #ifdef HAVE_MPI2 #include "MEDPARTITIONER_JointFinder.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" #endif + #include "MEDPARTITIONER_Graph.hxx" #include "MEDPARTITIONER_UserGraph.hxx" #include "MEDPARTITIONER_Utils.hxx" @@ -43,9 +45,10 @@ #include #endif -#ifdef MED_ENABLE_PARMETIS +#if defined(MED_ENABLE_PARMETIS) || defined(MED_ENABLE_METIS) #include "MEDPARTITIONER_MetisGraph.hxx" #endif + #ifdef MED_ENABLE_SCOTCH #include "MEDPARTITIONER_ScotchGraph.hxx" #endif @@ -108,8 +111,10 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection //treating faces ///////////////// +#ifdef HAVE_MPI2 if (MyGlobals::_Verbose>0) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif if (MyGlobals::_Is0verbose) std::cout<<"treating faces"<0) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif if (MyGlobals::_Is0verbose) { if (isParallelMode()) @@ -144,15 +151,19 @@ MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection "faceFamily"); //treating groups +#ifdef HAVE_MPI2 if (MyGlobals::_Verbose>0) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif if (MyGlobals::_Is0verbose) std::cout << "treating groups" << std::endl; _family_info=initialCollection.getFamilyInfo(); _group_info=initialCollection.getGroupInfo(); +#ifdef HAVE_MPI2 if (MyGlobals::_Verbose>0) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif if (MyGlobals::_Is0verbose) std::cout << "treating fields" << std::endl; castAllFields(initialCollection,"cellFieldDouble"); @@ -1274,7 +1285,7 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray _mesh[idomain]->getReverseNodalConnectivity(revConn,index); //problem saturation over 1 000 000 nodes for 1 proc if (MyGlobals::_Verbose>100) - std::cout << "proc " << MyGlobals::_Rank << " getReverseNodalConnectivity done on " << nbNodes << " nodes" << std::endl; + std::cout << "proc " << MyGlobals::_Rank << " : getReverseNodalConnectivity done on " << nbNodes << " nodes" << std::endl; int* index_ptr=index->getPointer(); int* revConnPtr=revConn->getPointer(); for (int i=0; i100) - std::cout<< "proc " << MyGlobals::_Rank << " creating graph arcs on nbNodes " << _topology->nbNodes() << std::endl; + std::cout<< "proc " << MyGlobals::_Rank << " : creating graph arcs on nbNodes " << _topology->nbNodes() << std::endl; for (int inode=0; inode<_topology->nbNodes(); inode++) //on all nodes { typedef multimap::const_iterator MI; @@ -1351,7 +1362,7 @@ void MEDPARTITIONER::MeshCollection::buildCellGraph(MEDPARTITIONER::SkyLineArray } if (MyGlobals::_Verbose>100) - std::cout << "proc " << MyGlobals::_Rank << " create skylinearray" << std::endl; + std::cout << "proc " << MyGlobals::_Rank << " : create skylinearray" << std::endl; //filling up index and value to create skylinearray structure std::vector index,value; index.push_back(0); @@ -1435,12 +1446,12 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nb switch (split) { case Graph::METIS: -#ifdef MED_ENABLE_PARMETIS +#if defined(MED_ENABLE_PARMETIS) || defined(MED_ENABLE_METIS) if (MyGlobals::_Verbose>10) std::cout << "METISGraph" << std::endl; cellGraph=new METISGraph(array,edgeweights); #else - throw INTERP_KERNEL::Exception("METIS Graph is not available. Check your products, please."); + throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please."); #endif break; case Graph::SCOTCH: @@ -1449,7 +1460,7 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nb std::cout << "SCOTCHGraph" << std::endl; cellGraph=new SCOTCHGraph(array,edgeweights); #else - throw INTERP_KERNEL::Exception("SCOTCH Graph is not available. Check your products, please."); + throw INTERP_KERNEL::Exception("MeshCollection::createPartition : SCOTCH is not available. Check your products, please."); #endif break; } @@ -1468,9 +1479,7 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nb std::cout << "building new topology" << std::endl; //cellGraph is a shared pointer Topology *topology=0; -#ifdef HAVE_MPI2 topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); -#endif //cleaning delete [] edgeweights; delete cellGraph; @@ -1497,15 +1506,12 @@ MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(const { domains.insert(partition[i]); } - int nbdomain=domains.size(); - cellGraph=new UserGraph(array, partition, _topology->nbCells()); //cellGraph is a shared pointer Topology *topology=0; -#ifdef HAVE_MPI2 + int nbdomain=domains.size(); topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); -#endif // if (array!=0) delete array; delete cellGraph; return topology; @@ -1677,7 +1683,7 @@ void MEDPARTITIONER::MeshCollection::filterFaceOnCell() else { faceNotOnCell.push_back(iface); - if (MyGlobals::_Is0verbose) + if (MyGlobals::_Is0verbose>300) std::cout << "face NOT on cell " << iface << " " << faceOnCell.size()-1 << std::endl; } } diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx index 4ac1a4cb2..2406505c9 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx @@ -157,7 +157,6 @@ int MeshCollectionMedXmlDriver::read(const char* filename, ParaDomainSelector* d throw INTERP_KERNEL::Exception("I/O error reading parallel MED file"); } - ParallelTopology* aPT = new ParallelTopology(_collection->getMesh()); //creation of topology from mesh and connect zones if ( _collection->isParallelMode() ) diff --git a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx index 490081d62..54e336b6f 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx @@ -168,7 +168,20 @@ void METISGraph::partGraph(int ndomain, throw INTERP_KERNEL::Exception("Problem in ParMETIS_PartKway"); } #else - throw INTERP_KERNEL::Exception("ParMETIS is not available. Check your products, please."); + +#ifdef MED_ENABLE_METIS + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph METIS_PartGraph Recursive/Kway" << std::endl; + if (options_string != "k") + METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, + &base, &nparts, options, &edgecut, partition); + else + METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, + &base, &nparts, options, &edgecut, partition); +#else + throw INTERP_KERNEL::Exception("ParMETIS or METIS is not available. Check your products, please."); +#endif + #endif } else diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx index a492f3ca9..665f7b20e 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx @@ -125,10 +125,12 @@ void MEDPARTITIONER::ParaDomainSelector::gatherNbOf(const std::vectorgetNumberOfNodes(); } // receive nb of elems from other procs - std::vector all_nb_elems( nb_domains*2 ); #ifdef HAVE_MPI2 + std::vector all_nb_elems( nb_domains*2 ); MPI_Allreduce((void*)&nb_elems[0], (void*)&all_nb_elems[0], nb_domains*2, MPI_INT, MPI_SUM, MPI_COMM_WORLD); +#else + std::vector all_nb_elems=nb_elems; #endif int total_nb_cells=0, total_nb_nodes=0; for (int i=0; i& loc_ids_here ) const { int* loc_ids_dist = new int[ loc_ids_here.size()]; +#ifdef HAVE_MPI2 int dest = getProcessorID( dist_domain ); int tag = 2002 + jointId( loc_domain, dist_domain ); -#ifdef HAVE_MPI2 MPI_Status status; MPI_Sendrecv((void*)&loc_ids_here[0], loc_ids_here.size(), MPI_INT, dest, tag, (void*) loc_ids_dist, loc_ids_here.size(), MPI_INT, dest, tag, @@ -502,6 +504,9 @@ double MEDPARTITIONER::ParaDomainSelector::getPassedTime() const void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingUMesh& mesh, int target) const { +#ifndef HAVE_MPI2 + throw INTERP_KERNEL::Exception("ParaDomainSelector::sendMesh : incoherent call in non_MPI mode"); +#else if (MyGlobals::_Verbose>600) std::cout << "proc " << _rank << " : sendMesh '" << mesh.getName() << "' size " << mesh.getNumberOfCells() << " to " << target << std::endl; // First stage : sending sizes @@ -513,11 +518,9 @@ void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingU //the transmitted mesh. mesh.getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS); tinyInfoLocal.push_back(mesh.getNumberOfCells()); -#ifdef HAVE_MPI2 int tinySize=tinyInfoLocal.size(); MPI_Send(&tinySize, 1, MPI_INT, target, 1113, MPI_COMM_WORLD); MPI_Send(&tinyInfoLocal[0], tinyInfoLocal.size(), MPI_INT, target, 1112, MPI_COMM_WORLD); -#endif if (mesh.getNumberOfCells()>0) //no sends if empty { @@ -532,9 +535,7 @@ void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingU nbLocalElems=v1Local->getNbOfElems(); // if empty be 1! ptLocal=v1Local->getPointer(); } -#ifdef HAVE_MPI2 MPI_Send(ptLocal, nbLocalElems, MPI_INT, target, 1111, MPI_COMM_WORLD); -#endif int nbLocalElems2=0; double *ptLocal2=0; if(v2Local) //if empty be 0! @@ -542,12 +543,11 @@ void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingU nbLocalElems2=v2Local->getNbOfElems(); ptLocal2=v2Local->getPointer(); } -#ifdef HAVE_MPI2 MPI_Send(ptLocal2, nbLocalElems2, MPI_DOUBLE, target, 1110, MPI_COMM_WORLD); -#endif if(v1Local) v1Local->decrRef(); if(v2Local) v2Local->decrRef(); } +#endif } /*! Receives messages from proc \a source to fill mesh \a mesh. @@ -557,6 +557,9 @@ void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingU */ void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& mesh, int source)const { +#ifndef HAVE_MPI2 + throw INTERP_KERNEL::Exception("ParaDomainSelector::recvMesh : incoherent call in non_MPI mode"); +#else // First stage : exchanging sizes // ------------------------------ std::vector tinyInfoDistant; @@ -564,17 +567,13 @@ void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& std::vector tinyInfoDistantD(1); //Getting tiny info of local mesh to allow the distant proc to initialize and allocate //the transmitted mesh. -#ifdef HAVE_MPI2 MPI_Status status; int tinyVecSize; MPI_Recv(&tinyVecSize, 1, MPI_INT, source, 1113, MPI_COMM_WORLD, &status); tinyInfoDistant.resize(tinyVecSize); -#endif std::fill(tinyInfoDistant.begin(),tinyInfoDistant.end(),0); -#ifdef HAVE_MPI2 MPI_Recv(&tinyInfoDistant[0], tinyVecSize, MPI_INT,source,1112,MPI_COMM_WORLD, &status); -#endif //there was tinyInfoLocal.push_back(mesh.getNumberOfCells()); int NumberOfCells=tinyInfoDistant[tinyVecSize-1]; if (NumberOfCells>0) @@ -596,9 +595,7 @@ void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& nbDistElem=v1Distant->getNbOfElems(); ptDist=v1Distant->getPointer(); } -#ifdef HAVE_MPI2 MPI_Recv(ptDist, nbDistElem, MPI_INT, source,1111, MPI_COMM_WORLD, &status); -#endif double *ptDist2=0; nbDistElem=0; if(v2Distant) @@ -606,9 +603,7 @@ void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& nbDistElem=v2Distant->getNbOfElems(); ptDist2=v2Distant->getPointer(); } -#ifdef HAVE_MPI2 MPI_Recv(ptDist2, nbDistElem, MPI_DOUBLE,source, 1110, MPI_COMM_WORLD, &status); -#endif //finish unserialization mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); if(v1Distant) v1Distant->decrRef(); @@ -620,6 +615,7 @@ void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& } if (MyGlobals::_Verbose>600) std::cout << "proc " << _rank << " : recvMesh '" << mesh->getName() << "' size " << mesh->getNumberOfCells() << " from " << source << std::endl; +#endif } #ifndef WIN32 diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx index 1b165b5c4..94395d75d 100644 --- a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx +++ b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx @@ -106,7 +106,9 @@ void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSe std::cout << "c" << idomain << "|" << i << "|" << global << " "; } } - if (MyGlobals::_Verbose>500) MPI_Barrier(MPI_COMM_WORLD); +#ifdef HAVE_MPI2 + if (MyGlobals::_Verbose>500) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace +#endif if (MyGlobals::_Is0verbose>500) std::cout << std::endl; if (MyGlobals::_Is0verbose>500) std::cout << "(n)idomain|ilocalNode|iglobalNode" << std::endl; @@ -123,7 +125,9 @@ void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSe std::cout << "n" << idomain << "|" << i << "|" << global << " "; } } - if (MyGlobals::_Verbose>500) MPI_Barrier(MPI_COMM_WORLD); +#ifdef HAVE_MPI2 + if (MyGlobals::_Verbose>500) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace +#endif if (MyGlobals::_Is0verbose>500) std::cout << std::endl; _nb_total_cells=domainSelector->getNbTotalCells(); diff --git a/src/MEDPartitioner/Makefile.am b/src/MEDPartitioner/Makefile.am index 5a3168d91..278c7e56d 100644 --- a/src/MEDPartitioner/Makefile.am +++ b/src/MEDPartitioner/Makefile.am @@ -34,13 +34,14 @@ MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx \ MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx \ MEDPARTITIONER_ParallelTopology.hxx \ MEDPARTITIONER_JointFinder.hxx \ -MEDPARTITIONER_Graph.hxx\ +MEDPARTITIONER_Graph.hxx \ MEDPARTITIONER_UserGraph.hxx\ MEDPARTITIONER_Utils.hxx \ MEDPARTITIONER.hxx \ MEDPARTITIONER_ParaDomainSelector.hxx \ MEDPARTITIONER_ConnectZone.hxx \ -MEDPARTITIONER_SkyLineArray.hxx +MEDPARTITIONER_SkyLineArray.hxx + if MED_ENABLE_PARMETIS salomeinclude_HEADERS += MEDPARTITIONER_MetisGraph.hxx @@ -57,11 +58,13 @@ MEDPARTITIONER_MeshCollection.cxx \ MEDPARTITIONER_MeshCollectionDriver.cxx \ MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx \ MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx \ +MEDPARTITIONER_ParallelTopology.cxx \ MEDPARTITIONER_Graph.cxx\ MEDPARTITIONER_UserGraph.cxx\ -MEDPARTITIONER_SkyLineArray.cxx \ +MEDPARTITIONER_Utils.cxx \ +MEDPARTITIONER_ParaDomainSelector.cxx \ MEDPARTITIONER_ConnectZone.cxx \ -MEDPARTITIONER_Utils.cxx +MEDPARTITIONER_SkyLineArray.cxx libmedpartitioner_la_CPPFLAGS = $(MPI_INCLUDES) $(MED3_INCLUDES) $(HDF5_INCLUDES) \ $(LIBXML_INCLUDES) -I$(srcdir)/../INTERP_KERNEL/Bases -I$(srcdir)/../MEDCoupling \ @@ -70,9 +73,7 @@ libmedpartitioner_la_CPPFLAGS = $(MPI_INCLUDES) $(MED3_INCLUDES) $(HDF5_INCLUDES libmedpartitioner_la_LDFLAGS = if MPI_IS_OK - dist_libmedpartitioner_la_SOURCES += MEDPARTITIONER_ParaDomainSelector.cxx \ - MEDPARTITIONER_UtilsPara.cxx \ - MEDPARTITIONER_ParallelTopology.cxx \ + dist_libmedpartitioner_la_SOURCES += MEDPARTITIONER_UtilsPara.cxx \ MEDPARTITIONER_JointFinder.cxx if MED_ENABLE_PARMETIS @@ -111,7 +112,15 @@ else !MPI_IS_OK bin_PROGRAMS = medpartitioner dist_medpartitioner_SOURCES = medpartitioner.cxx medpartitioner_CPPFLAGS = -I$(srcdir)/../INTERP_KERNEL/Bases -I$(srcdir)/../MEDCoupling \ - -I$(srcdir)/../MEDLoader -I$(srcdir)/../INTERP_KERNEL $(METIS_CPPFLAGS) $(SCOTCH_CPPFLAGS) + -I$(srcdir)/../MEDLoader -I$(srcdir)/../INTERP_KERNEL + +if MED_ENABLE_METIS + medpartitioner_CPPFLAGS += $(METIS_CPPFLAGS) +endif +if MED_ENABLE_SCOTCH + medpartitioner_CPPFLAGS += $(SCOTCH_CPPFLAGS) +endif + medpartitioner_LDADD = libmedpartitioner.la endif diff --git a/src/MEDPartitioner/medpartitioner.cxx b/src/MEDPartitioner/medpartitioner.cxx index f23552f3f..8469d70a3 100644 --- a/src/MEDPartitioner/medpartitioner.cxx +++ b/src/MEDPartitioner/medpartitioner.cxx @@ -1,36 +1,42 @@ -// Copyright (C) 2007-2011 CEA/DEN, EDF R&D +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// MED medsplitter : tool to split n MED files into p separate -// MED files with a partitioning specified -// by an external tool -// File : medsplitter.cxx -// Author : Vincent BERGEAUD (CEA-DEN/DANS/DM2S/SFME/LGLS) -// Module : MED +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +/* + examples of launch + export verb=1 + medpartitioner --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb + medpartitioner --input-file=medpartitioner_blade.xml --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb + medpartitioner --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --dump-cpu-memory --verbose=$verb +*/ + +/* #include "MEDPARTITIONER_Graph.hxx" #include "MEDPARTITIONER_Topology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" #include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_Utils.hxx" +*/ -#ifdef BOOST_PROGRAM_OPTIONS_LIB -#include -#endif +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" #include #include @@ -38,297 +44,262 @@ #include #include -#ifdef BOOST_PROGRAM_OPTIONS_LIB -namespace po=boost::program_options; -#endif +using namespace std; +using namespace MEDPARTITIONER; int main(int argc, char** argv) { -#ifndef ENABLE_METIS -#ifndef ENABLE_SCOTCH +#if !defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) std::cout << "Sorry, no one split method is available. Please, compile with METIS or SCOTCH." << std::endl; return 1; -#endif -#endif +#else // Defining options // by parsing the command line - bool mesh_only = false; - bool is_sequential = true; - bool xml_output_master=true; - bool creates_boundary_faces=false; - bool split_families=false; + + bool split_family=false; bool empty_groups=false; + bool mesure_memory=false; + bool filter_face=true; - std::string input; - std::string output; - std::string meshname; - std::string library; + string input; + string output; + string meshname; + string library="metis"; //default int ndomains; + int help=0; + + //sequential : no MPI + MyGlobals::_World_Size=1; + MyGlobals::_Rank=0; -#ifdef BOOST_PROGRAM_OPTIONS_LIB - // Use boost::program_options for command-line options parsing - po::options_description desc("Available options of medpartitioner V1.0"); - desc.add_options() - ("help","produces this help message") - ("mesh-only","prevents the splitter from creating the fields contained in the original file(s)") - ("distributed","specifies that the input file is distributed") - ("input-file",po::value(),"name of the input MED file") - ("output-file",po::value(),"name of the resulting file") - ("meshname",po::value(),"name of the input mesh") -#ifdef ENABLE_METIS -#ifdef ENABLE_SCOTCH - ("split-method",po::value(&library)->default_value("metis"),"name of the splitting library (metis,scotch)") -#endif + // Primitive parsing of command-line options + string desc ("Available options of medpartitioner V1.0:\n" + "\t--help : produces this help message\n" + "\t--verbose : echoes arguments\n" + "\t--input-file= : name of the input .med file or .xml master file\n" + "\t--output-file= : name of the resulting file (without extension)\n" + "\t--ndomains= : number of subdomains in the output file, default is 1\n" +#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) + //user can choose! + "\t--split-method= : name of the splitting library (metis/scotch), default is metis\n" #endif - ("ndomains",po::value(&ndomains)->default_value(1),"number of subdomains in the output file") - ("plain-master","creates a plain masterfile instead of an XML file") - ("creates-boundary-faces","creates the necessary faces so that faces joints are created in the output files") - ("family-splitting","preserves the family names instead of focusing on the groups") - ("empty-groups","creates empty groups in zones that do not contain a group from the original domain"); - - po::variables_map vm; - po::store(po::parse_command_line(argc,argv,desc),vm); - po::notify(vm); +// "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" + "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" + ); - if (vm.count("help")) + if (argc<=1) help=1; + string value; + for (int i = 1; i < argc; i++) { - std::cout << desc << "\n"; - return 1; + if (strlen(argv[i]) < 3) + { + cerr << "bad argument : "<< argv[i] << endl; + return 1; + } + + if (TestArg(argv[i],"--verbose",value)) + { + MyGlobals::_Verbose=1; + if (value!="") MyGlobals::_Verbose = atoi(value.c_str()); + } + else if (TestArg(argv[i],"--help",value)) help=1; +// else if (TestArg(argv[i],"--test",value)) test=1; + else if (TestArg(argv[i],"--input-file",value)) input=value; + else if (TestArg(argv[i],"--output-file",value)) output=value; + else if (TestArg(argv[i],"--split-method",value)) library=value; + else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); +// else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; + else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; + else + { + cerr << "unknown argument : "<< argv[i] << endl; + return 1; + } } - if (!vm.count("ndomains")) + MyGlobals::_Is0verbose=MyGlobals::_Verbose; + +//no choice +#if defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) + library = "metis"; +#endif +#if !defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) + library = "scotch"; +#endif +//user choice +#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) + if ((library!="metis") && (library!="scotch")) { - std::cout << "ndomains must be specified !"<< std::endl; + cerr << "split-method only available : metis, scotch" << endl; return 1; } - - ndomains = vm["ndomains"].as(); - if (!vm.count("input-file") || !vm.count("output-file")) +#endif + + if (help==1) { - std::cout << "input-file and output-file names must be specified" << std::endl; - return 1; + cout<(); - output = vm["output-file"].as(); - - if (vm.count("mesh-only")) - mesh_only=true; - - if (vm.count("distributed")) - is_sequential=false; - - if (is_sequential) - meshname = vm["meshname"].as(); - - if (vm.count("plain-master")) - xml_output_master=false; - - if (vm.count("creates-boundary-faces")) - creates_boundary_faces=true; - - if (vm.count("split-families")) - split_families=true; - - if (vm.count("empty-groups")) - empty_groups=true; - -#else // BOOST_PROGRAM_OPTIONS_LIB - - // Primitive parsing of command-line options - - std::string desc ("Available options of medpartitioner V1.0:\n" - "\t--help : produces this help message\n" - "\t--mesh-only : do not create the fields contained in the original file(s)\n" - "\t--distributed : specifies that the input file is distributed\n" - "\t--input-file= : name of the input MED file\n" - "\t--output-file= : name of the resulting file\n" - "\t--meshname= : name of the input mesh (not used with --distributed option)\n" - "\t--ndomains= : number of subdomains in the output file, default is 1\n" -#ifdef ENABLE_METIS -#ifdef ENABLE_SCOTCH - "\t--split-method=: name of the splitting library (metis/scotch), default is metis\n" -#endif -#endif - "\t--plain-master : creates a plain masterfile instead of an XML file\n" - "\t--creates-boundary-faces: creates the necessary faces so that faces joints are created in the output files\n" - "\t--family-splitting : preserves the family names instead of focusing on the groups\n" - "\t--empty-groups : creates empty groups in zones that do not contain a group from the original domain" - ); - - if (argc < 4) + //testing whether it is possible to write a file at the specified location + if (MyGlobals::_Rank==0) { - std::cout << desc.c_str() << std::endl; - return 1; + string outputtest = output + ".testioms."; + ofstream testfile (outputtest.c_str()); + if (testfile.fail()) + { + cerr << "output-file directory does not exist or is in read-only access" << endl; + return 1; + } + //deletes test file + remove(outputtest.c_str()); } + + // Beginning of the computation - for (int i = 1; i < argc; i++) + // Loading the mesh collection + if (MyGlobals::_Is0verbose) cout << "Reading input files "<setGlobalNumerotationDefault(collection.getParaDomainSelector()); + //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains + //to have unique valid fields names/pointers/descriptions for partitionning + collection.prepareFieldDescriptions(); + //int nbfields=collection.getFieldDescriptions().size(); //on all domains + //cout<setGlobalNumerotationDefault(collection.getParaDomainSelector()); + //to have unique valid fields names/pointers/descriptions for partitionning + collection.prepareFieldDescriptions(); - if (strncmp(argv[i],"--m",3) == 0) + //MEDPARTITIONER::MeshCollection collection(input); + + //Creating the graph and partitioning it + if (MyGlobals::_Is0verbose) cout << "Computing partition with " << library << endl; + + auto_ptr< MEDPARTITIONER::Topology > new_topo; + if (library == "metis") + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); + else + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); + parallelizer.evaluateMemory(); + + //Creating a new mesh collection from the partitioning + if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl; + MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); + + if (filter_face) new_collection.filterFaceOnCell(); + + //to get infos on all procs + + //see meshName + vector finalInformations; + vector r1,r2; + //r1=AllgathervVectorOfString(MyGlobals::_General_Informations); + r1=MyGlobals::_General_Informations; + //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"< 13) - { // "--input-file=" - input = (argv[i] + 13); - std::cout << "\tinput-file = " << input << std::endl; // tmp - } - } - else if (strncmp(argv[i],"--o",3) == 0) - { - if (strlen(argv[i]) > 14) - { // "--output-file=" - output = (argv[i] + 14); - std::cout << "\toutput-file = " << output << std::endl; // tmp - } - } - else if (strncmp(argv[i],"--s",3) == 0) - { - if (strlen(argv[i]) > 15) - { // "--split-method=" - library = (argv[i] + 15); - std::cout << "\tsplit-method = " << library << std::endl; // tmp - } - } - else if (strncmp(argv[i],"--f",3) == 0) - { //"--family-splitting" - split_families=true; - std::cout << "\tfamily-splitting true" << std::endl; // tmp - } - else if (strncmp(argv[i],"--n",3) == 0) - { - if (strlen(argv[i]) > 11) - { // "--ndomains=" - ndomains = atoi(argv[i] + 11); - std::cout << "\tndomains = " << ndomains << std::endl; // tmp - } - } - else if (strncmp(argv[i],"--p",3) == 0) - { // "--plain-master" - xml_output_master = false; - std::cout << "\txml_output_master = " << xml_output_master << std::endl; // tmp - } - else if (strncmp(argv[i],"--c",3) == 0) - { // "--creates-boundary-faces" - creates_boundary_faces = true; - std::cout << "\tcreates_boundary_faces = " << creates_boundary_faces << std::endl; // tmp - } - else if (strncmp(argv[i],"--e",3) == 0) - { // "--empty-groups" - empty_groups = true; - std::cout << "\tempty_groups = true" << std::endl; // tmp - } - else - { - std::cout << desc.c_str() << std::endl; - return 1; - } - } + + //see field info nbComponents & componentInfo (if fields present) + r2=SelectTagsInVectorOfString(r1,"fieldName="); + r2=SelectTagsInVectorOfString(r2,"nbComponents="); + //may be yes? or not? + for (std::size_t i=0; i0) cout<<"OK END"<< endl; + return 0; + } + catch(const char *mess) { - std::cout << "Mesh name must be given for sequential(not distributed) input file." << std::endl; - std::cout << desc << std::endl; + cerr<createPartition(ndomains,MEDPARTITIONER::Graph::METIS); - else - new_topo = collection->createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH); - - std::cout << "MEDPARTITIONER : creating new meshes"<< std::endl; - - // Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(*collection, new_topo, split_families, empty_groups); - if (mesh_only) + } + catch(std::exception& e) { - delete collection; - collection=0; + cerr<<"std_Exception : "< : name of the input .med file or .xml master file\n" - "\t--output-file= : name of the resulting file (without exension)\n" + "\t--output-file= : name of the resulting file (without extension)\n" "\t--ndomains= : number of subdomains in the output file, default is 1\n" -#ifdef MED_MED_ENABLE_PARMETIS -#ifdef MED_MED_ENABLE_SCOTCH +#if defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) + //user can choose! "\t--split-method= : name of the splitting library (metis/scotch), default is metis\n" -#endif #endif "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" //"\t--randomize= : random seed for other partitionning (only on one proc)\n" - //"\t--atomize : do the opposite of a good partitionner (only on one proc)\n" + //"\t--atomize : do the opposite of a good partitionner (only on one proc)\n" ); if (argc<=1) help=1; @@ -147,14 +144,22 @@ int main(int argc, char** argv) if (MyGlobals::_Rank==0) cerr << "randomize only available on 1 proc (mpirun -np 1)" << endl; MyGlobals::_Randomize=0; } - -#ifdef MED_ENABLE_PARMETIS -#ifndef MED_ENABLE_SCOTCH + +//no choice +#if defined(MED_ENABLE_PARMETIS) && !defined(MED_ENABLE_SCOTCH) library = "metis"; #endif -#else +#if !defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) library = "scotch"; #endif +//user choice +#if defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) + if ((library!="metis") && (library!="scotch")) + { + if (MyGlobals::_Rank==0) cerr << "split-method only available : metis, scotch" << endl; + MPI_Finalize(); return 1; + } +#endif if (help==1) { @@ -215,7 +220,7 @@ int main(int argc, char** argv) try { MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); //cvwat01 + MEDPARTITIONER::MeshCollection collection(input,parallelizer); MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains @@ -229,25 +234,25 @@ int main(int argc, char** argv) cout<<"fileNames :"< new_topo; - if (library == "metis") //cvwat06 + if (library == "metis") new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); else new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); parallelizer.evaluateMemory(); - // Creating a new mesh collection from the partitioning - if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<