Tpetra Matrix/Vector Services Version of the Day
IRTRDriver.hpp
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 IRTR_DRIVER_HPP
00045 #define IRTR_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 "IRTR_solvers.hpp"
00059 
00060 
00061 #define XFORM_REDUCE TPETRA_BINARY_PRETRANSFORM_REDUCE
00062 
00063   namespace IRTRdetails {
00064 
00065     struct trivial_fpu_fix {
00066       void fix() {}
00067       void unfix() {}
00068     };
00069 #ifdef HAVE_TPETRA_QD
00070     struct nontrivial_fpu_fix {
00071       unsigned int old_cw;
00072       void fix()   {fpu_fix_start(&old_cw);}
00073       void unfix() {fpu_fix_end(&old_cw);}
00074     };
00075 #endif
00076     // implementations
00077     template <class T> struct fpu_fix : trivial_fpu_fix {};
00078 #ifdef HAVE_TPETRA_QD
00079     template <> struct fpu_fix<qd_real> : nontrivial_fpu_fix {};
00080     template <> struct fpu_fix<dd_real> : nontrivial_fpu_fix {};
00081 #endif
00082 
00083   }
00084 
00085 
00086 template <class S, class Sinner = S>
00087 class IRTR_Driver {
00088   public:
00089   // input
00090   Teuchos::RCP<Teuchos::FancyOStream>     out; 
00091   Teuchos::RCP<Teuchos::ParameterList> params;
00092   std::string                      matrixFile;
00093   // output
00094   bool                             testPassed;
00095 
00096   template <class Node> 
00097   void run(Teuchos::ParameterList &myMachPL, const Teuchos::RCP<const Teuchos::Comm<int> > &comm, const Teuchos::RCP<Node> &node) 
00098   {
00099     using std::plus;
00100     using std::endl;
00101     using Teuchos::null;
00102     using Teuchos::RCP;
00103     using Teuchos::ParameterList;
00104     using Teuchos::parameterList;
00105     using Tpetra::RTI::ZeroOp;
00106 
00107     // Static types
00108     typedef int                     LO;
00109     typedef int                     GO;
00110     typedef Tpetra::Map<LO,GO,Node>               Map;
00111     typedef Tpetra::CrsMatrix<S,LO,GO,Node> CrsMatrix;
00112     typedef Tpetra::Vector<S,LO,GO,Node>       Vector;
00113     typedef Teuchos::ScalarTraits<S> ST;
00114 
00115     IRTRdetails::fpu_fix<S> ff; ff.fix();
00116 
00117     *out << "Running test with Node==" << Teuchos::typeName(*node) << " on rank " << comm->getRank() << "/" << comm->getSize() << std::endl;
00118 
00119     // read the matrix
00120     RCP<CrsMatrix> A;
00121     RCP<const Map> rowMap = null;
00122     RCP<ParameterList> fillParams = parameterList();
00123     // must preserve the local graph in order to do convert() calls later
00124     if (Teuchos::TypeTraits::is_same<S,Sinner>::value) {
00125       fillParams->set("Preserve Local Graph",false);
00126     }
00127     else {
00128       fillParams->set("Preserve Local Graph",true);
00129     }
00130     Tpetra::Utils::readHBMatrix(matrixFile,comm,node,A,rowMap,fillParams);
00131     rowMap = A->getRowMap();
00132 
00133     testPassed = true;
00134 
00135     // compute an inital vector
00136     auto x = Tpetra::createVector<S>(rowMap);
00137     x->randomize();
00138 
00139     // call the solve
00140     S lambda = TpetraExamples::IRTR<Sinner,S,LO,GO,Node>(out,*params,A,x);
00141 
00142     // check that residual is as requested
00143     {
00144       auto r = Tpetra::createVector<S>(rowMap);
00145       A->apply(*x,*r);
00146       // compute A*x - x*lambda, while simultaneously computing |A*x - x*lambda|
00147       const S r_r = XFORM_REDUCE(r, x,                          // fused: 
00148                                  r - x*lambda,                  //      : r = r - x*lambda = A*x - x*lambda
00149                                  r*r, ZeroOp<S>, plus<S>() );   //      : sum r'*r
00150       const S rnrm = Teuchos::ScalarTraits<S>::squareroot(r_r);
00151       // check that residual is as requested
00152       *out << "|A*x - x*lambda|/|lambda|: " << rnrm / ST::magnitude(lambda) << endl;
00153       const double tolerance = params->get<double>("tolerance");
00154       if (rnrm / lambda > tolerance) testPassed = false;
00155     }
00156 
00157     ff.unfix();
00158 
00159     // print timings
00160     Teuchos::TimeMonitor::summarize( *out );
00161   }
00162 };
00163 
00164 #endif // IRTR_DRIVER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines