std::string VisitorBuild::build(ElementComplexe* elementComplexe) { std::string result; result+="<"; string name(elementComplexe->getElementName()->second); result+=name; //Récupérer la liste des attributs AttList *attList = elementComplexe->getAttList(); //Parcours de la liste et affichage des attributs for(AttList::iterator it = attList->begin(); it != attList->end(); ++it) { result+=" " + (*it)->first+" = \""+ (*it)->second+"\""; } result+=">"; //récupérer les fils list<Element*> *elementList(elementComplexe->getElements()); for(list<Element*> ::iterator it = elementList->begin(); it != elementList->end(); ++it) { result+=(*it)->build(this); } //Fermer la balise de l'élément result+="</"+name+">"; return result; }
void CoordinatesTransferFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Build(Level & fineLevel, Level &coarseLevel) const { FactoryMonitor m(*this, "Build", coarseLevel); GetOStream(Runtime0, 0) << "Transferring coordinates" << std::endl; const ParameterList & pL = GetParameterList(); int writeStart = pL.get< int >("write start"); int writeEnd = pL.get< int >("write end"); RCP<Aggregates> aggregates = Get< RCP<Aggregates> > (fineLevel, "Aggregates"); RCP<MultiVector> fineCoords = Get< RCP<MultiVector> >(fineLevel, "Coordinates"); RCP<const Map> coarseMap = Get< RCP<const Map> > (fineLevel, "CoarseMap"); // coarseMap is being used to set up the domain map of tentative P, and therefore, the row map of Ac // Therefore, if we amalgamate coarseMap, logical nodes in the coordinates vector would correspond to // logical blocks in the matrix ArrayView<const GO> elementAList = coarseMap->getNodeElementList(); LO blkSize = 1; if (rcp_dynamic_cast<const StridedMap>(coarseMap) != Teuchos::null) blkSize = rcp_dynamic_cast<const StridedMap>(coarseMap)->getFixedBlockSize(); GO indexBase = coarseMap->getIndexBase(); size_t numElements = elementAList.size() / blkSize; Array<GO> elementList(numElements); // Amalgamate the map for (LO i = 0; i < Teuchos::as<LO>(numElements); i++) elementList[i] = (elementAList[i*blkSize]-indexBase)/blkSize + indexBase; RCP<const Map> coarseCoordMap = MapFactory ::Build(coarseMap->lib(), Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), elementList, indexBase, coarseMap->getComm()); RCP<MultiVector> coarseCoords = MultiVectorFactory::Build(coarseCoordMap, fineCoords->getNumVectors()); // Maps RCP<const Map> uniqueMap = fineCoords->getMap(); RCP<const Map> nonUniqueMap = aggregates->GetMap(); // Create overlapped fine coordinates to reduce global communication RCP<const Import> importer = ImportFactory ::Build(uniqueMap, nonUniqueMap); RCP<MultiVector> ghostedCoords = MultiVectorFactory::Build(nonUniqueMap, fineCoords->getNumVectors()); ghostedCoords->doImport(*fineCoords, *importer, Xpetra::INSERT); // Get some info about aggregates int myPID = uniqueMap->getComm()->getRank(); LO numAggs = aggregates->GetNumAggregates(); ArrayRCP<LO> aggSizes = aggregates->ComputeAggregateSizes(); const ArrayRCP<const LO> vertex2AggID = aggregates->GetVertex2AggId()->getData(0); const ArrayRCP<const LO> procWinner = aggregates->GetProcWinner()->getData(0); // Fill in coarse coordinates for (size_t j = 0; j < fineCoords->getNumVectors(); j++) { ArrayRCP<const Scalar> fineCoordsData = ghostedCoords->getData(j); ArrayRCP<Scalar> coarseCoordsData = coarseCoords->getDataNonConst(j); for (LO lnode = 0; lnode < vertex2AggID.size(); lnode++) if (procWinner[lnode] == myPID) coarseCoordsData[vertex2AggID[lnode]] += fineCoordsData[lnode]; for (LO agg = 0; agg < numAggs; agg++) coarseCoordsData[agg] /= aggSizes[agg]; } Set<RCP<MultiVector> >(coarseLevel, "Coordinates", coarseCoords); if (writeStart == 0 && fineLevel.GetLevelID() == 0 && writeStart <= writeEnd) { std::ostringstream buf; buf << fineLevel.GetLevelID(); std::string fileName = "coordinates_before_rebalance_level_" + buf.str() + ".m"; Utils::Write(fileName,*fineCoords); } if (writeStart <= coarseLevel.GetLevelID() && coarseLevel.GetLevelID() <= writeEnd) { std::ostringstream buf; buf << coarseLevel.GetLevelID(); std::string fileName = "coordinates_before_rebalance_level_" + buf.str() + ".m"; Utils::Write(fileName,*coarseCoords); } } // Build
Zoltan_CrsGraph::NewTypeRef Zoltan_CrsGraph:: operator()( OriginalTypeRef orig ) { origObj_ = &orig; int err; //Setup Load Balance Object float version; char * dummy = 0; Zoltan::LoadBalance LB( 0, &dummy, &version ); err = LB.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() ); if( err == ZOLTAN_OK ) err = LB.Set_Param( "LB_METHOD", "GRAPH" ); #ifdef HAVE_LIBPARMETIS if( err == ZOLTAN_OK ) err = LB.Set_Param( "GRAPH_PACKAGE", "PARMETIS" ); if( err == ZOLTAN_OK ) err = LB.Set_Param( "PARMETIS_METHOD", partitionMethod_ ); #endif //Setup Query Object CrsGraph_Transpose transposeTransform; Epetra_CrsGraph & TransGraph = transposeTransform( orig ); ZoltanQuery Query( orig, &TransGraph ); if( err == ZOLTAN_OK ) err = LB.Set_QueryObject( &Query ); if( err != ZOLTAN_OK ) { cout << "Setup of Zoltan Load Balancing Objects FAILED!\n"; exit(0); } //Generate Load Balance int changes; int num_gid_entries, num_lid_entries; int num_import; ZOLTAN_ID_PTR import_global_ids, import_local_ids; int * import_procs; int num_export; ZOLTAN_ID_PTR export_global_ids, export_local_ids; int * export_procs; orig.Comm().Barrier(); err = LB.Balance( &changes, &num_gid_entries, &num_lid_entries, &num_import, &import_global_ids, &import_local_ids, &import_procs, &num_export, &export_global_ids, &export_local_ids, &export_procs ); LB.Evaluate( 1, 0, 0, 0, 0, 0, 0 ); orig.Comm().Barrier(); //Generate New Element List int numMyElements = orig.RowMap().NumMyElements(); vector<int> elementList( numMyElements ); orig.RowMap().MyGlobalElements( &elementList[0] ); int newNumMyElements = numMyElements - num_export + num_import; vector<int> newElementList( newNumMyElements ); set<int> gidSet; for( int i = 0; i < num_export; ++i ) gidSet.insert( export_global_ids[i] ); //Add unmoved indices to new list int loc = 0; for( int i = 0; i < numMyElements; ++i ) if( !gidSet.count( elementList[i] ) ) newElementList[loc++] = elementList[i]; //Add imports to end of list for( int i = 0; i < num_import; ++i ) newElementList[loc+i] = import_global_ids[i]; //Free Zoltan Data if( err == ZOLTAN_OK ) err = LB.Free_Data( &import_global_ids, &import_local_ids, &import_procs, &export_global_ids, &export_local_ids, &export_procs ); //Create Import Map NewRowMap_ = new Epetra_Map( orig.RowMap().NumGlobalElements(), newNumMyElements, &newElementList[0], orig.RowMap().IndexBase(), orig.RowMap().Comm() ); //Create Importer Epetra_Import Importer( *NewRowMap_, orig.RowMap() ); //Create New Graph Epetra_CrsGraph * NewGraph = new Epetra_CrsGraph( Copy, *NewRowMap_, 0 ); NewGraph->Import( orig, Importer, Insert ); NewGraph->FillComplete(); Zoltan::LoadBalance LB2( 0, &dummy, &version ); err = LB2.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() ); if( err == ZOLTAN_OK ) err = LB2.Set_Param( "LB_METHOD", "GRAPH" ); #ifdef HAVE_LIBPARMETIS if( err == ZOLTAN_OK ) err = LB2.Set_Param( "GRAPH_PACKAGE", "PARMETIS" ); if( err == ZOLTAN_OK ) err = LB2.Set_Param( "PARMETIS_METHOD", partitionMethod_ ); #endif CrsGraph_Transpose transTrans; Epetra_CrsGraph & trans2 = transTrans( *NewGraph ); ZoltanQuery query( *NewGraph, &trans2 ); if( err == ZOLTAN_OK ) err = LB2.Set_QueryObject( &query ); //err = LB2.Balance( &changes, // &num_gid_entries, &num_lid_entries, // &num_import, &import_global_ids, &import_local_ids, &import_procs, // &num_export, &export_global_ids, &export_local_ids, &export_procs ); LB2.Evaluate( 1, 0, 0, 0, 0, 0, 0 ); newObj_ = NewGraph; return *NewGraph; }