TEUCHOS_UNIT_TEST(RAPFactory, ImplicitTranspose) { out << "version: " << MueLu::Version() << std::endl; RCP<const Teuchos::Comm<int> > comm = Parameters::getDefaultComm(); if (comm->getSize() > 1 && TestHelpers::Parameters::getLib() == Xpetra::UseEpetra ) { out << "Skipping ImplicitTranspose test for Epetra and #proc>1" << std::endl; return; } // build test-specific default factory manager RCP<FactoryManager> defManager = rcp(new FactoryManager()); defManager->SetFactory("A", rcp(MueLu::NoFactory::get(),false)); // dummy factory for A defManager->SetFactory("Nullspace", rcp(new NullspaceFactory())); // real null space factory for Ptent defManager->SetFactory("Graph", rcp(new CoalesceDropFactory())); // real graph factory for Ptent defManager->SetFactory("Aggregates", rcp(new CoupledAggregationFactory())); // real aggregation factory for Ptent Level fineLevel, coarseLevel; TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::createTwoLevelHierarchy(fineLevel, coarseLevel); // overwrite default factory manager fineLevel.SetFactoryManager(defManager); coarseLevel.SetFactoryManager(defManager); RCP<Matrix> Op = TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::Build1DPoisson(19*comm->getSize()); fineLevel.Set("A",Op); TentativePFactory tentpFactory; SaPFactory sapFactory; sapFactory.SetFactory("P",rcpFromRef(tentpFactory)); TransPFactory transPFactory; transPFactory.SetFactory("P", rcpFromRef(sapFactory)); coarseLevel.Request("P", &sapFactory); coarseLevel.Request("R", &transPFactory); coarseLevel.Request(sapFactory); coarseLevel.Request(transPFactory); sapFactory.Build(fineLevel, coarseLevel); transPFactory.Build(fineLevel,coarseLevel); RAPFactory rap; ParameterList rapList = *(rap.GetValidParameterList()); rapList.set("transpose: use implicit", true); rap.SetParameterList(rapList); rap.SetFactory("P", rcpFromRef(sapFactory)); rap.SetFactory("R", rcpFromRef(transPFactory)); coarseLevel.Request("A", &rap); coarseLevel.Request(rap); rap.Build(fineLevel,coarseLevel); RCP<Matrix> A = fineLevel.Get< RCP<Matrix> >("A"); RCP<Matrix> P = coarseLevel.Get< RCP<Matrix> >("P", &sapFactory); RCP<Matrix> R = coarseLevel.Get< RCP<Matrix> >("R", &transPFactory); //std::string filename = "A.dat"; //Utils::Write(filename,Op); //filename = "P.dat"; //Utils::Write(filename,P); RCP<MultiVector> workVec1 = MultiVectorFactory::Build(P->getRangeMap(),1); RCP<MultiVector> workVec2 = MultiVectorFactory::Build(Op->getRangeMap(),1); RCP<MultiVector> result1 = MultiVectorFactory::Build(P->getDomainMap(),1); RCP<MultiVector> X = MultiVectorFactory::Build(P->getDomainMap(),1); X->randomize(); //out.precision(12); //out.setOutputToRootOnly(-1); //X->describe(out,Teuchos::VERB_EXTREME); //Calculate result1 = P^T*(A*(P*X)) P->apply(*X,*workVec1,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Op->apply(*workVec1,*workVec2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); P->apply(*workVec2,*result1,Teuchos::TRANS,(SC)1.0,(SC)0.0); RCP<Matrix> coarseOp = coarseLevel.Get< RCP<Matrix> >("A", &rap); //Calculate result2 = (R*A*P)*X RCP<MultiVector> result2 = MultiVectorFactory::Build(P->getDomainMap(),1); coarseOp->apply(*X,*result2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Teuchos::Array<Teuchos::ScalarTraits<SC>::magnitudeType> normX(1), normResult1(1),normResult2(1); X->norm2(normX); out << "This test checks the correctness of the Galerkin triple " << "matrix product by comparing (RAP)*X to R(A(P*X)), where R is the implicit transpose of P." << std::endl; out << "||X||_2 = " << normX << std::endl; result1->norm2(normResult1); result2->norm2(normResult2); TEST_FLOATING_EQUALITY(normResult1[0], normResult2[0], 1e-12); } // Correctness test
TEUCHOS_UNIT_TEST(RAPFactory, Correctness) { out << "version: " << MueLu::Version() << std::endl; RCP<const Teuchos::Comm<int> > comm = Parameters::getDefaultComm(); Level fineLevel, coarseLevel; TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::createTwoLevelHierarchy(fineLevel, coarseLevel); RCP<Matrix> Op = TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::Build1DPoisson(27*comm->getSize()); fineLevel.Set("A",Op); TentativePFactory tentpFactory; SaPFactory sapFactory; sapFactory.SetFactory("P",rcpFromRef(tentpFactory)); TransPFactory transPFactory; transPFactory.SetFactory("P", rcpFromRef(sapFactory)); //todo:rcpFromRef coarseLevel.Request("P",&sapFactory); coarseLevel.Request("R",&transPFactory); coarseLevel.Request(sapFactory); coarseLevel.Request(transPFactory); sapFactory.Build(fineLevel,coarseLevel); transPFactory.Build(fineLevel,coarseLevel); RAPFactory rap; rap.SetFactory("P", rcpFromRef(sapFactory)); rap.SetFactory("R", rcpFromRef(transPFactory)); coarseLevel.Request(rap); coarseLevel.Request("A",&rap); rap.Build(fineLevel,coarseLevel); RCP<Matrix> A = fineLevel.Get< RCP<Matrix> >("A"); RCP<Matrix> P = coarseLevel.Get< RCP<Matrix> >("P", &sapFactory); RCP<Matrix> R = coarseLevel.Get< RCP<Matrix> >("R", &transPFactory); RCP<MultiVector> workVec1 = MultiVectorFactory::Build(P->getRangeMap(),1); RCP<MultiVector> workVec2 = MultiVectorFactory::Build(Op->getRangeMap(),1); RCP<MultiVector> result1 = MultiVectorFactory::Build(R->getRangeMap(),1); RCP<MultiVector> X = MultiVectorFactory::Build(P->getDomainMap(),1); X->randomize(); //Calculate result1 = R*(A*(P*X)) P->apply(*X,*workVec1,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Op->apply(*workVec1,*workVec2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); R->apply(*workVec2,*result1,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); RCP<Matrix> coarseOp = coarseLevel.Get< RCP<Matrix> >("A", &rap); //Calculate result2 = (R*A*P)*X RCP<MultiVector> result2 = MultiVectorFactory::Build(R->getRangeMap(),1); coarseOp->apply(*X,*result2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Teuchos::Array<Teuchos::ScalarTraits<SC>::magnitudeType> normX(1), normResult1(1),normResult2(1); X->norm2(normX); out << "This test checks the correctness of the Galerkin triple " << "matrix product by comparing (RAP)*X to R(A(P*X))." << std::endl; out << "||X||_2 = " << normX << std::endl; result1->norm2(normResult1); result2->norm2(normResult2); TEST_FLOATING_EQUALITY(normResult1[0], normResult2[0], 1e-12); } // Correctness test
int main(int argc, char *argv[]) { #include <MueLu_UseShortNames.hpp> using Teuchos::RCP; using Teuchos::rcp; using Teuchos::Time; using Teuchos::TimeMonitor; // // MPI initialization using Teuchos // Teuchos::GlobalMPISession mpiSession(&argc, &argv, NULL); RCP< const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm(); // // Parameters // Teuchos::CommandLineProcessor clp(false); GO nx, ny, nz; nx=50; ny=50; nz=50; Galeri::Xpetra::Parameters<GO> matrixParameters(clp, nx, ny, nz, "Laplace2D"); // manage parameters of the test case Xpetra::Parameters xpetraParameters(clp); // manage parameters of Xpetra int optNraps = 5; clp.setOption("nraps", &optNraps, "number of RAPS to perform"); bool optTimings = true; clp.setOption("timings", "notimings", &optTimings, "print timings to screen"); switch (clp.parse(argc, argv)) { case Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED: return EXIT_SUCCESS; break; case Teuchos::CommandLineProcessor::PARSE_ERROR: case Teuchos::CommandLineProcessor::PARSE_UNRECOGNIZED_OPTION: return EXIT_FAILURE; break; case Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL: break; } if (comm->getRank() == 0) { std::cout << "========================================================" << std::endl << xpetraParameters << matrixParameters; } // // Construct the problem // { TimeMonitor globalTimeMonitor(*TimeMonitor::getNewTimer("RAPScalingTest: S - Global Time")); RCP<Matrix> A; RCP<MultiVector> coordinates; { TimeMonitor tm(*TimeMonitor::getNewTimer("RAPScalingTest: 1 - Matrix creation")); RCP<const Map> map; // Retrieve matrix parameters (they may have been changed on the command line), and pass them to Galeri. // Galeri will attempt to create a square-as-possible distribution of subdomains di, e.g., // d1 d2 d3 // d4 d5 d6 // d7 d8 d9 // d10 d11 d12 // A perfect distribution is only possible when the #processors is a perfect square. // This *will* result in "strip" distribution if the #processors is a prime number or if the factors are very different in // size. For example, np=14 will give a 7-by-2 distribution. // If you don't want Galeri to do this, specify mx or my on the galeriList. Teuchos::ParameterList pl = matrixParameters.GetParameterList(); Teuchos::ParameterList galeriList; galeriList.set("nx", pl.get("nx", nx)); galeriList.set("ny", pl.get("ny", ny)); galeriList.set("nz", pl.get("nz", nz)); if (matrixParameters.GetMatrixType() == "Laplace1D") { map = MapFactory::Build(xpetraParameters.GetLib(), matrixParameters.GetNumGlobalElements(), 0, comm); coordinates = Galeri::Xpetra::Utils::CreateCartesianCoordinates<SC, LO, GO, Map, MultiVector>("1D", map, matrixParameters.GetParameterList()); } else if (matrixParameters.GetMatrixType() == "Laplace2D" || matrixParameters.GetMatrixType() == "Star2D") { map = Galeri::Xpetra::CreateMap<LO, GO, Node>(xpetraParameters.GetLib(), "Cartesian2D", comm, galeriList); coordinates = Galeri::Xpetra::Utils::CreateCartesianCoordinates<SC, LO, GO, Map, MultiVector>("2D", map, matrixParameters.GetParameterList()); } else if (matrixParameters.GetMatrixType() == "Laplace3D") { map = Galeri::Xpetra::CreateMap<LO, GO, Node>(xpetraParameters.GetLib(), "Cartesian3D", comm, galeriList); coordinates = Galeri::Xpetra::Utils::CreateCartesianCoordinates<SC, LO, GO, Map, MultiVector>("3D", map, matrixParameters.GetParameterList()); } //FIXME if (comm->getRank() == 0) { GO mx = galeriList.get("mx", -1); GO my = galeriList.get("my", -1); std::cout << "Processor subdomains in x direction: " << mx << std::endl << "Processor subdomains in y direction: " << my << std::endl << "========================================================" << std::endl; } Teuchos::RCP<Galeri::Xpetra::Problem<Map,CrsMatrixWrap,MultiVector> > Pr = Galeri::Xpetra::BuildProblem<SC,LO,GO,Map,CrsMatrixWrap,MultiVector>(matrixParameters.GetMatrixType(), map, matrixParameters.GetParameterList()); A = Pr->BuildMatrix(); } Level fineLevel, coarseLevel; RAPFactory AcFact; AcFact.DisableMultipleCallCheck(); RCP<SaPFactory> PFact; // Setup P { TimeMonitor tm(*TimeMonitor::getNewTimer("RAPScalingTest: 2 - P Setup")); MueLuTests::TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::createTwoLevelHierarchy(fineLevel, coarseLevel); // set a default FactoryManager fineLevel.Set("A", A); PFact = rcp(new SaPFactory()); coarseLevel.Request("P", PFact.get()); PFact->Build(fineLevel, coarseLevel); AcFact.SetFactory("P", PFact); } // Setup R, repeatedly RCP<Time> RKernelTimer = TimeMonitor::getNewTimer("RAPScalingTest: 3 - R Setup"); // re-use the same timer in the loop RCP<TransPFactory> RFact = rcp(new TransPFactory()); RFact->SetFactory("P", PFact); for (int i=0; i<optNraps; ++i) { coarseLevel.Request("R", RFact.get()); { TimeMonitor tm(*RKernelTimer); RFact->Build(fineLevel, coarseLevel); } coarseLevel.Release("R", RFact.get()); } } // end of globalTimeMonitor if (optTimings) { Teuchos::TableFormat &format = TimeMonitor::format(); format.setPrecision(25); TimeMonitor::summarize(); } } //main