|
Tpetra Matrix/Vector Services Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Tpetra: Templated Linear Algebra Services Package 00006 // Copyright (2008) Sandia Corporation 00007 // 00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00009 // the U.S. Government retains certain rights in this software. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // ************************************************************************ 00041 // @HEADER 00042 */ 00043 00044 #ifndef MULTIPREC_DRIVER_HPP 00045 #define MULTIPREC_DRIVER_HPP 00046 00047 #include <Teuchos_TypeNameTraits.hpp> 00048 #include <Teuchos_TimeMonitor.hpp> 00049 #include <Teuchos_ParameterList.hpp> 00050 #include <Teuchos_FancyOStream.hpp> 00051 00052 #include <Tpetra_Version.hpp> 00053 #include <Tpetra_MatrixIO.hpp> 00054 #include <Tpetra_RTI.hpp> 00055 #include <Tpetra_CrsMatrix.hpp> 00056 #include <Tpetra_Vector.hpp> 00057 00058 #include "MultiPrecCG.hpp" 00059 00060 template <class MPStack> 00061 class MultiPrecDriver { 00062 public: 00063 // input 00064 Teuchos::RCP<Teuchos::FancyOStream> out; 00065 Teuchos::RCP<Teuchos::ParameterList> params; 00066 std::string matrixFile; 00067 bool unfusedTest; 00068 // output 00069 bool testPassed; 00070 00071 template <class Node> 00072 void run(Teuchos::ParameterList &myMachPL, const Teuchos::RCP<const Teuchos::Comm<int> > &comm, const Teuchos::RCP<Node> &node) 00073 { 00074 using std::pair; 00075 using std::make_pair; 00076 using std::plus; 00077 using std::endl; 00078 using Teuchos::RCP; 00079 using Teuchos::ParameterList; 00080 using TpetraExamples::make_pair_op; 00081 using Tpetra::RTI::reductionGlob; 00082 using Tpetra::RTI::ZeroOp; 00083 using Tpetra::RTI::binary_pre_transform_reduce; 00084 using Tpetra::RTI::binary_transform; 00085 00086 // Static types 00087 typedef typename MPStack::type S; 00088 typedef int LO; 00089 typedef int GO; 00090 typedef Tpetra::CrsMatrix<S,LO,GO,Node> CrsMatrix; 00091 typedef Tpetra::Vector<S,LO,GO,Node> Vector; 00092 00093 *out << "Running test with Node==" << Teuchos::typeName(*node) << " on rank " << comm->getRank() << "/" << comm->getSize() << std::endl; 00094 00095 // read the matrix 00096 RCP<CrsMatrix> A; 00097 Tpetra::Utils::readHBMatrix(matrixFile,comm,node,A); 00098 00099 // init the solver stack 00100 TpetraExamples::RFPCGInit<S,LO,GO,Node> init(A); 00101 RCP<ParameterList> db = Tpetra::Ext::initStackDB<MPStack>(*params,init); 00102 00103 testPassed = true; 00104 00105 // choose a solution, compute a right-hand-side 00106 auto x = Tpetra::createVector<S>(A->getRowMap()), 00107 b = Tpetra::createVector<S>(A->getRowMap()); 00108 x->randomize(); 00109 A->apply(*x,*b); 00110 { 00111 // init the rhs 00112 auto bx = db->get<RCP<Vector>>("bx"); 00113 binary_transform( *bx, *b, [](S, S bi) {return bi;}); // bx = b 00114 } 00115 00116 // call the solve 00117 TpetraExamples::recursiveFPCG<MPStack,LO,GO,Node>(out,*db); 00118 00119 // check that residual is as requested 00120 { 00121 auto xhat = db->get<RCP<Vector>>("bx"), 00122 bhat = Tpetra::createVector<S>(A->getRowMap()); 00123 A->apply(*xhat,*bhat); 00124 // compute bhat-b, while simultaneously computing |bhat-b|^2 and |b|^2 00125 auto nrms = binary_pre_transform_reduce(*bhat, *b, 00126 reductionGlob<ZeroOp<pair<S,S>>>( 00127 [](S bhati, S bi){ return bi-bhati;}, // bhati = bi-bhat 00128 [](S bhati, S bi){ return make_pair(bhati*bhati, bi*bi); }, 00129 make_pair_op<S,S>(plus<S>())) ); 00130 const S enrm = Teuchos::ScalarTraits<S>::squareroot(nrms.first), 00131 bnrm = Teuchos::ScalarTraits<S>::squareroot(nrms.second); 00132 // check that residual is as requested 00133 *out << "|b - A*x|/|b|: " << enrm / bnrm << endl; 00134 const double tolerance = db->get<double>("tolerance"); 00135 if (MPStack::bottom) { 00136 // give a little slack 00137 if (enrm / bnrm > 5*tolerance) testPassed = false; 00138 } 00139 else { 00140 if (enrm / bnrm > tolerance) testPassed = false; 00141 } 00142 } 00143 00144 // 00145 // solve again, with the unfused version, just for timings purposes 00146 if (unfusedTest) 00147 { 00148 // init the rhs 00149 auto bx = db->get<RCP<Vector>>("bx"); 00150 binary_transform( *bx, *b, [](S, S bi) {return bi;}); // bx = b 00151 // call the solve 00152 TpetraExamples::recursiveFPCGUnfused<MPStack,LO,GO,Node>(out,*db); 00153 // 00154 // test the result 00155 auto xhat = db->get<RCP<Vector>>("bx"), 00156 bhat = Tpetra::createVector<S>(A->getRowMap()); 00157 A->apply(*xhat,*bhat); 00158 // compute bhat-b, while simultaneously computing |bhat-b|^2 and |b|^2 00159 auto nrms = binary_pre_transform_reduce(*bhat, *b, 00160 reductionGlob<ZeroOp<pair<S,S>>>( 00161 [](S bhati, S bi){ return bi-bhati;}, // bhati = bi-bhat 00162 [](S bhati, S bi){ return make_pair(bhati*bhati, bi*bi); }, 00163 make_pair_op<S,S>(plus<S>())) ); 00164 const S enrm = Teuchos::ScalarTraits<S>::squareroot(nrms.first), 00165 bnrm = Teuchos::ScalarTraits<S>::squareroot(nrms.second); 00166 // check that residual is as requested 00167 *out << "|b - A*x|/|b|: " << enrm / bnrm << endl; 00168 const double tolerance = db->get<double>("tolerance"); 00169 if (MPStack::bottom) { 00170 // give a little slack 00171 if (enrm / bnrm > 5*tolerance) testPassed = false; 00172 } 00173 else { 00174 if (enrm / bnrm > tolerance) testPassed = false; 00175 } 00176 } 00177 00178 00179 // print timings 00180 Teuchos::TimeMonitor::summarize( *out ); 00181 } 00182 }; 00183 00184 #endif // MULTIPREC_DRIVER_HPP
1.7.4