THYRA_DEPRECATED void uninitializePrec( const PreconditionerFactoryBase<Scalar> &precFactory, PreconditionerBase<Scalar> *prec, Teuchos::RCP<const LinearOpBase<Scalar> > *fwdOp = NULL, ESupportSolveUse *supportSolveUse = NULL ) { using Teuchos::ptr; uninitializePrec<Scalar>(precFactory, ptr(prec), ptr(fwdOp), ptr(supportSolveUse)); }
THYRA_DEPRECATED SolveStatus<Scalar> solve( const LinearOpWithSolveBase<Scalar> &A, const EOpTransp A_trans, const MultiVectorBase<Scalar> &B, MultiVectorBase<Scalar> *X, const SolveCriteria<Scalar> *solveCriteria = NULL ) { using Teuchos::ptr; return A.solve(A_trans, B, ptr(X), ptr(solveCriteria)); }
THYRA_DEPRECATED void uninitializeOp( const LinearOpWithSolveFactoryBase<Scalar> &lowsFactory, LinearOpWithSolveBase<Scalar> *Op, RCP<const LinearOpBase<Scalar> > *fwdOp = NULL, RCP<const PreconditionerBase<Scalar> > *prec = NULL, RCP<const LinearOpBase<Scalar> > *approxFwdOp = NULL, ESupportSolveUse *supportSolveUse = NULL ) { using Teuchos::ptr; uninitializeOp<Scalar>(lowsFactory, ptr(Op), ptr(fwdOp), ptr(prec), ptr(approxFwdOp), ptr(supportSolveUse)); }
int main (int argc, char *argv[]) { using Teuchos::Array; using Teuchos::as; using Teuchos::Comm; using Teuchos::CommandLineProcessor; using Teuchos::ParameterList; using Teuchos::ptr; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::REDUCE_MAX; using Teuchos::REDUCE_MIN; using Teuchos::reduceAll; using std::cerr; using std::cout; using std::endl; typedef double scalar_type; typedef int local_ordinal_type; typedef int global_ordinal_type; typedef Kokkos::SerialNode node_type; Teuchos::GlobalMPISession mpiSession (&argc, &argv, &cout); RCP<const Comm<int> > comm = Tpetra::DefaultPlatform::getDefaultPlatform().getComm(); const int myRank = comm->getRank(); const int numProcs = comm->getSize(); std::string inputFilename; // Matrix Market file to read std::string temporaryFilename; // Matrix Market file to write (if applicable) std::string outputFilename; // Matrix Market file to write (if applicable) // Number of a specific test to run. If nonzero, only run that // test. We always run Test #1 since its result is needed for // subsequent tests. int testToRun = 0; // FIXME (mfh 07 Feb 2012) Currently, all tests with a different // index base FAIL. Reading in the multivector appears to be // correct, but writing it results in a multivector of all zeros (on // _all_ processes). bool testDifferentIndexBase = false; bool testContiguousInputMap = true; bool testNoncontiguousInputMap = false; bool testWrite = true; // Test Matrix Market output? bool tolerant = false; // Parse the file tolerantly? bool echo = false; // Echo the read-in matrix back? bool verbose = false; // Verbosity of output bool debug = false; // Print debugging info? // If true, stop after a single test failure. Intended for // interactive use, so that you can examine a test's output file. // Not intended for batch or ctest use. bool stopAfterFailure = false; CommandLineProcessor cmdp (false, true); cmdp.setOption ("inputFilename", &inputFilename, "Name of the Matrix Market dense matrix file to read."); cmdp.setOption ("temporaryFilename", &temporaryFilename, "If --testWrite is true, then use this file as temporary " "storage on (MPI) Proc 0. Otherwise, this argument is " "ignored."); cmdp.setOption ("outputFilename", &outputFilename, "If --testWrite is true, then write the read-in matrix to " "this file in Matrix Market format on (MPI) Proc 0. " "Otherwise, this argument is ignored. Note that the output " "file may not be identical to the input file."); cmdp.setOption ("testToRun", &testToRun, "Number of a specific test to run. " "If nonzero, only run that test. We always run Test #1 since" " its result is needed for subsequent tests."); cmdp.setOption ("testDifferentIndexBase", "dontTestDifferentIndexBase", &testDifferentIndexBase, "Whether to test input and output " "for Maps with different index bases."); cmdp.setOption ("testContiguousInputMap", "dontTestContiguousInputMap", &testContiguousInputMap, "Whether to test input and output for nonnull contiguous " "input Maps."); cmdp.setOption ("testNoncontiguousInputMap", "dontTestNoncontiguousInputMap", &testNoncontiguousInputMap, "Whether to test input and output for nonnull noncontiguous " "input Maps."); cmdp.setOption ("testWrite", "noTestWrite", &testWrite, "Whether to test Matrix Market file output. Ignored if no " "--outputFilename value is given."); cmdp.setOption ("tolerant", "strict", &tolerant, "Whether to parse the input Matrix Market file tolerantly."); cmdp.setOption ("echo", "noecho", &echo, "Whether to echo the read-in matrix back to stdout on Rank 0 " "in Matrix Market format. Note that the echoed matrix may " "not be identical to the input file."); cmdp.setOption ("verbose", "quiet", &verbose, "Print messages and results."); cmdp.setOption ("debug", "nodebug", &debug, "Print debugging information."); cmdp.setOption ("stopAfterFailure", "dontStopAfterFailure", &stopAfterFailure, "Whether to stop after a single test failure."); // Parse the command-line arguments. { const CommandLineProcessor::EParseCommandLineReturn parseResult = cmdp.parse (argc,argv); // If the caller asks us to print the documentation, or does not // explicitly say to run the benchmark, we let this "test" pass // trivially. if (parseResult == CommandLineProcessor::PARSE_HELP_PRINTED) { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } TEUCHOS_TEST_FOR_EXCEPTION(parseResult != CommandLineProcessor::PARSE_SUCCESSFUL, std::invalid_argument, "Failed to parse command-line arguments."); } // Get a Kokkos Node instance for the particular Node type. RCP<node_type> node = getNode<node_type>(); // List of numbers of failed tests. std::vector<int> failedTests; // Current test number. Increment before starting each test. If a // test is only run conditionally, increment before evaluating the // condition. This ensures that each test has the same number each // time, whether or not a particular test is run. int testNum = 0; // Run all the tests. If no input filename was specified, we don't // invoke the test and we report a "TEST PASSED" message. if (inputFilename != "") { // Convenient abbreviations typedef scalar_type ST; typedef local_ordinal_type LO; typedef global_ordinal_type GO; typedef node_type NT; typedef Tpetra::MultiVector<ST, LO, GO, NT> MV; typedef Tpetra::Map<LO, GO, NT> MT; // If not testing writes, don't do the sanity check that tests // input by comparing against output. std::string outFilename = testWrite ? outputFilename : ""; std::string tmpFilename = testWrite ? temporaryFilename : ""; // Test 1: null input Map. ++testNum; if (verbose && myRank == 0) { cout << "Test " << testNum << ": Null Map on input to readDenseFile()" << endl; } RCP<MV> X; try { X = testReadDenseFile<MV> (inputFilename, tmpFilename, comm, node, tolerant, verbose, debug); if (outFilename != "") { testWriteDenseFile<MV> (outFilename, X, echo, verbose, debug); } } catch (std::exception& e) { failedTests.push_back (testNum); // If Test 1 fails, the other tests shouldn't even run, since // they depend on the result of Test 1 (the multivector X). throw e; } // Test 2: nonnull contiguous input Map with the same index base // as X's Map. This Map may or may not necessarily be the same as // (in the sense of isSameAs()) or even compatible with X's Map. ++testNum; if ((testToRun == 0 && testContiguousInputMap) || (testToRun != 0 && testToRun == testNum)) { if (verbose && myRank == 0) { cout << "Test " << testNum << ": Nonnull contiguous Map (same index " "base) on input to readDenseFile()" << endl; } const Tpetra::global_size_t globalNumRows = X->getMap()->getGlobalNumElements(); const GO indexBase = X->getMap()->getIndexBase(); // Create the Map. RCP<const MT> map = rcp (new Tpetra::Map<LO, GO, NT> (globalNumRows, indexBase, comm, Tpetra::GloballyDistributed, node)); try { RCP<MV> X2 = testReadDenseFileWithInputMap<MV> (inputFilename, tmpFilename, map, tolerant, verbose, debug); if (outFilename != "") { testWriteDenseFile<MV> (outFilename, X2, echo, verbose, debug); } } catch (std::exception& e) { failedTests.push_back (testNum); if (myRank == 0) { cerr << "Test " << testNum << " failed: " << e.what() << endl; } if (stopAfterFailure) { if (failedTests.size() > 0) { if (myRank == 0) { cout << "End Result: TEST FAILED" << endl; } return EXIT_FAILURE; } else { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } } // if stop after failure } } // Test 3: nonnull contiguous input Map, with a different index // base than X's Map. In this case, the index base is X's Map's // index base plus a small number (3). For sufficiently long // vectors, this tests the case where the GID sets overlap. ++testNum; if ((testToRun == 0 && testContiguousInputMap && testDifferentIndexBase) || (testToRun != 0 && testToRun == testNum)) { if (verbose && myRank == 0) { cout << "Test " << testNum << ": Nonnull contiguous Map (different " "index base) on input to readDenseFile()" << endl; } const Tpetra::global_size_t globalNumRows = X->getMap()->getGlobalNumElements(); const GO indexBase = X->getMap()->getIndexBase() + as<GO> (3); // Make sure that the index base is the same on all processes. // It definitely should be, since the Map's getMaxAllGlobalIndex() // method should return the same value on all processes. GO minIndexBase = indexBase; reduceAll (*comm, REDUCE_MIN, indexBase, ptr (&minIndexBase)); GO maxIndexBase = indexBase; reduceAll (*comm, REDUCE_MAX, indexBase, ptr (&maxIndexBase)); TEUCHOS_TEST_FOR_EXCEPTION(minIndexBase != maxIndexBase || minIndexBase != indexBase, std::logic_error, "Index base values do not match on all processes. " "Min value is " << minIndexBase << " and max value is " << maxIndexBase << "."); // Create the Map. RCP<const MT> map = rcp (new Tpetra::Map<LO, GO, NT> (globalNumRows, indexBase, comm, Tpetra::GloballyDistributed, node)); try { RCP<MV> X3 = testReadDenseFileWithInputMap<MV> (inputFilename, tmpFilename, map, tolerant, verbose, debug); if (outFilename != "") { testWriteDenseFile<MV> (outFilename, X3, echo, verbose, debug); } } catch (std::exception& e) { failedTests.push_back (testNum); if (myRank == 0) { cerr << "Test " << testNum << " failed: " << e.what() << endl; } if (stopAfterFailure) { if (failedTests.size() > 0) { if (myRank == 0) { cout << "End Result: TEST FAILED" << endl; } return EXIT_FAILURE; } else { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } } // if stop after failure } } // Test 4: nonnull contiguous input Map, with a different index // base than X's Map. In this case, the new index base is chosen // so that the new GID set does not overlap with X's Map's GID // set. ++testNum; if ((testToRun == 0 && testContiguousInputMap && testDifferentIndexBase) || (testToRun != 0 && testToRun == testNum)) { if (verbose && myRank == 0) { cout << "Test " << testNum << ": Nonnull contiguous Map (different " "index base) on input to readDenseFile()" << endl; } const Tpetra::global_size_t globalNumRows = X->getMap()->getGlobalNumElements(); // Choose the Map's index base so that the global ordinal sets // of X->getMap() and map don't overlap. This will ensure that // we test something nontrivial. const GO indexBase = X->getMap()->getMaxAllGlobalIndex() + 1; // Make sure that the index base is the same on all processes. // It definitely should be, since the Map's getMaxAllGlobalIndex() // method should return the same value on all processes. GO minIndexBase = indexBase; reduceAll (*comm, REDUCE_MIN, indexBase, ptr (&minIndexBase)); GO maxIndexBase = indexBase; reduceAll (*comm, REDUCE_MAX, indexBase, ptr (&maxIndexBase)); TEUCHOS_TEST_FOR_EXCEPTION(minIndexBase != maxIndexBase || minIndexBase != indexBase, std::logic_error, "Index base values do not match on all processes. " "Min value is " << minIndexBase << " and max value is " << maxIndexBase << "."); // Create the Map. RCP<const MT> map = rcp (new Tpetra::Map<LO, GO, NT> (globalNumRows, indexBase, comm, Tpetra::GloballyDistributed, node)); try { RCP<MV> X3 = testReadDenseFileWithInputMap<MV> (inputFilename, tmpFilename, map, tolerant, verbose, debug); if (outFilename != "") { testWriteDenseFile<MV> (outFilename, X3, echo, verbose, debug); } } catch (std::exception& e) { failedTests.push_back (testNum); if (myRank == 0) { cerr << "Test " << testNum << " failed: " << e.what() << endl; } if (stopAfterFailure) { if (failedTests.size() > 0) { if (myRank == 0) { cout << "End Result: TEST FAILED" << endl; } return EXIT_FAILURE; } else { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } } // if stop after failure } } ++testNum; if ((testToRun == 0 && testNoncontiguousInputMap) || (testToRun != 0 && testToRun == testNum)) { // Test 5: nonnull input Map with the same index base as X's // Map, and a "noncontiguous" distribution (in the sense that // the Map is constructed using the constructor that takes an // arbitrary list of GIDs; that doesn't necessarily mean that // the GIDs themselves are noncontiguous). if (verbose && myRank == 0) { cout << "Test " << testNum << ": Nonnull noncontiguous Map (same index " "base) on input to readDenseFile()" << endl; } const GO indexBase = X->getMap()->getIndexBase(); const Tpetra::global_size_t globalNumRows = X->getMap()->getGlobalNumElements(); // Compute number of GIDs owned by each process. We're // replicating Tpetra functionality here because we want to // trick Tpetra into thinking we have a noncontiguous // distribution. This is the most general case and the most // likely to uncover bugs. const size_t quotient = globalNumRows / numProcs; const size_t remainder = globalNumRows - quotient * numProcs; const size_t localNumRows = (as<size_t> (myRank) < remainder) ? (quotient + 1) : quotient; // Build the list of GIDs owned by this process. Array<GO> elementList (localNumRows); GO myStartGID; if (as<size_t> (myRank) < remainder) { myStartGID = indexBase + as<GO> (myRank) * as<GO> (quotient + 1); } else { // This branch does _not_ assume that GO is a signed type. myStartGID = indexBase + as<GO> (remainder) * as<GO> (quotient + 1) + (as<GO> (myRank) - as<GO> (remainder)) * as<GO> (quotient); } for (GO i = 0; i < as<GO> (localNumRows); ++i) { elementList[i] = myStartGID + i; } if (debug) { for (int p = 0; p < numProcs; ++p) { if (p == myRank) { if (elementList.size() > 0) { const GO minGID = *std::min_element (elementList.begin(), elementList.end()); const GO maxGID = *std::max_element (elementList.begin(), elementList.end()); cerr << "On Proc " << p << ": min,max GID = " << minGID << "," << maxGID << endl; } else { cerr << "On Proc " << p << ": elementList is empty" << endl; } cerr << std::flush; } comm->barrier (); comm->barrier (); comm->barrier (); } } // Create the Map. using Tpetra::createNonContigMapWithNode; RCP<const MT> map = createNonContigMapWithNode<LO, GO, NT> (elementList(), comm, node); try { RCP<MV> X4 = testReadDenseFileWithInputMap<MV> (inputFilename, tmpFilename, map, tolerant, verbose, debug); if (outFilename != "") { testWriteDenseFile<MV> (outFilename, X4, echo, verbose, debug); } } catch (std::exception& e) { failedTests.push_back (testNum); if (myRank == 0) { cerr << "Test " << testNum << " failed: " << e.what() << endl; } if (stopAfterFailure) { if (failedTests.size() > 0) { if (myRank == 0) { cout << "End Result: TEST FAILED" << endl; } return EXIT_FAILURE; } else { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } } // if stop after failure } } // if test noncontiguous input Map ++testNum; if ((testToRun == 0 && testNoncontiguousInputMap && testDifferentIndexBase) || (testToRun != 0 && testToRun == testNum)) { // Test 6: nonnull input Map with a different index base than // X's Map, and a "noncontiguous" distribution (in the sense // that the Map is constructed using the constructor that takes // an arbitrary list of GIDs; that doesn't necessarily mean that // the GIDs themselves are noncontiguous). if (verbose && myRank == 0) { cout << "Test " << testNum << ": Nonnull noncontiguous Map (different " "index base) on input to readDenseFile()" << endl; } // Make sure that the global ordinal sets of X->getMap() and // map don't overlap. GO indexBase = X->getMap()->getMaxAllGlobalIndex() + 1; const Tpetra::global_size_t globalNumRows = X->getMap()->getGlobalNumElements(); // Compute number of GIDs owned by each process. We're // replicating Tpetra functionality here because we want to // trick Tpetra into thinking we have a noncontiguous // distribution. This is the most general case and the most // likely to uncover bugs. const size_t quotient = globalNumRows / numProcs; const size_t remainder = globalNumRows - quotient * numProcs; const size_t localNumRows = (as<size_t> (myRank) < remainder) ? (quotient + 1) : quotient; // Build the list of GIDs owned by this process. Array<GO> elementList (localNumRows); GO myStartGID; if (as<size_t> (myRank) < remainder) { myStartGID = indexBase + as<GO> (myRank) * as<GO> (quotient + 1); } else { // This branch does _not_ assume that GO is a signed type. myStartGID = indexBase + as<GO> (remainder) * as<GO> (quotient + 1) + (as<GO> (remainder) - as<GO> (myRank)) * as<GO> (quotient); } for (GO i = 0; i < as<GO> (localNumRows); ++i) { elementList[i] = myStartGID + i; } // Create the Map. using Tpetra::createNonContigMapWithNode; RCP<const MT> map = createNonContigMapWithNode<LO, GO, NT> (elementList(), comm, node); try { RCP<MV> X5 = testReadDenseFileWithInputMap<MV> (inputFilename, tmpFilename, map, tolerant, verbose, debug); if (outFilename != "") { testWriteDenseFile<MV> (outFilename, X5, echo, verbose, debug); } } catch (std::exception& e) { failedTests.push_back (testNum); if (myRank == 0) { cerr << "Test " << testNum << " failed: " << e.what() << endl; } if (stopAfterFailure) { if (failedTests.size() > 0) { if (myRank == 0) { cout << "End Result: TEST FAILED" << endl; } return EXIT_FAILURE; } else { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } } // if stop after failure } } // if test noncontiguous input Map ++testNum; if ((testToRun == 0 && testNoncontiguousInputMap) || (testToRun != 0 && testToRun == testNum)) { // Test 7: nonnull input Map with the same index base as X's // Map, and a "noncontiguous" distribution with GIDs that start // at 3. This lets us easily observe any missing entries after // writing X and reading it back in again. if (verbose && myRank == 0) { cout << "Test " << testNum << ": Nonnull noncontiguous Map (same index " "base, GIDs not in 0 .. N-1) on input to readDenseFile()" << endl; } const Tpetra::global_size_t globalNumRows = X->getMap()->getGlobalNumElements(); const GO globalStartGID = as<GO> (3); // Compute number of GIDs owned by each process. We're // replicating Tpetra functionality here because we want to // trick Tpetra into thinking we have a noncontiguous // distribution. This is the most general case and the most // likely to uncover bugs. const size_t quotient = globalNumRows / numProcs; const size_t remainder = globalNumRows - quotient * numProcs; const size_t localNumRows = (as<size_t> (myRank) < remainder) ? (quotient + 1) : quotient; // Build the list of GIDs owned by this process. Array<GO> elementList (localNumRows); GO myStartGID; if (as<size_t> (myRank) < remainder) { myStartGID = globalStartGID + as<GO> (myRank) * as<GO> (quotient + 1); } else { // This branch does _not_ assume that GO is a signed type. myStartGID = globalStartGID + as<GO> (remainder) * as<GO> (quotient + 1) + (as<GO> (myRank) - as<GO> (remainder)) * as<GO> (quotient); } for (GO i = 0; i < as<GO> (localNumRows); ++i) { elementList[i] = myStartGID + i; } if (debug) { for (int p = 0; p < numProcs; ++p) { if (p == myRank) { if (elementList.size() > 0) { const GO minGID = *std::min_element (elementList.begin(), elementList.end()); const GO maxGID = *std::max_element (elementList.begin(), elementList.end()); cerr << "On Proc " << p << ": min,max GID = " << minGID << "," << maxGID << endl; } else { cerr << "On Proc " << p << ": elementList is empty" << endl; } cerr << std::flush; } comm->barrier (); comm->barrier (); comm->barrier (); } } // Create the Map. using Tpetra::createNonContigMapWithNode; RCP<const MT> map = createNonContigMapWithNode<LO, GO, NT> (elementList(), comm, node); try { RCP<MV> X7 = testReadDenseFileWithInputMap<MV> (inputFilename, tmpFilename, map, tolerant, verbose, debug); if (outFilename != "") { testWriteDenseFile<MV> (outFilename, X7, echo, verbose, debug); } } catch (std::exception& e) { failedTests.push_back (testNum); if (myRank == 0) { cerr << "Test " << testNum << " failed: " << e.what() << endl; } if (stopAfterFailure) { if (failedTests.size() > 0) { if (myRank == 0) { cout << "End Result: TEST FAILED" << endl; } return EXIT_FAILURE; } else { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } } // if stop after failure } } // if test noncontiguous input Map } if (failedTests.size() > 0) { if (myRank == 0) { cout << "End Result: TEST FAILED" << endl; } return EXIT_FAILURE; } else { if (myRank == 0) { cout << "End Result: TEST PASSED" << endl; } return EXIT_SUCCESS; } }