Kokkos Node API and Local Linear Algebra Kernels Version of the Day
NodeTest.hpp
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 // 
00005 //          Kokkos: Node API and Parallel Node Kernels
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 NODE_TEST_HPP_
00045 #define NODE_TEST_HPP_ 
00046 
00047 #include <Teuchos_UnitTestHarness.hpp>
00048 #include <Teuchos_TimeMonitor.hpp>
00049 #include <Teuchos_Time.hpp>
00050 #include <Teuchos_Tuple.hpp>
00051 #include <Teuchos_ParameterList.hpp>
00052 
00053 #include <functional>
00054 #include <algorithm>
00055 
00056 #include "Kokkos_ConfigDefs.hpp"
00057 #include "Kokkos_DefaultSparseOps.hpp"
00058 #include "Kokkos_FirstTouchSparseOps.hpp"
00059 
00060 namespace NodeTest {
00061   extern int N;
00062   extern int numIters;
00063   extern int numThreads;
00064   extern int verbose;
00065 }
00066 
00067 namespace {
00068 
00069   using Teuchos::Array;
00070   using Teuchos::ArrayRCP;
00071   using Teuchos::Time;
00072   using Teuchos::RCP;
00073   using Teuchos::rcp;
00074   using Teuchos::null;
00075   using Teuchos::TimeMonitor;
00076   using Teuchos::ParameterList;
00077   using Kokkos::MultiVector;
00078   using Kokkos::DefaultArithmetic;
00079   using Kokkos::DefaultHostSparseOps;
00080   using Kokkos::FirstTouchSparseOps;
00081 
00082   template <class NODE>
00083   RCP<NODE> getNode() {
00084     TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Node type not defined.");
00085   }
00086 
00087   template <class NODE>
00088   void initNode() {
00089     TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Node type not defined.");
00090   }
00091 
00092   //
00093   // UNIT TESTS
00094   // 
00095 
00096   TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( AAAAA_Is_First, InitNode, NODE )
00097   {
00098     out << "Initializing " << Teuchos::TypeNameTraits<NODE>::name() << std::endl;
00099     initNode<NODE>();
00100     TEST_EQUALITY(0,0);
00101   }
00102 
00105   //  tests
00106   TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( CrsMatrix, TimingTest, BaseOPS )
00107   {
00108     typedef double                             Scalar;
00109     typedef typename BaseOPS::ordinal_type     Ordinal;
00110     typedef typename BaseOPS::node_type        Node;
00111     typedef typename BaseOPS::template bind_scalar<Scalar>::other_type       OPS;
00112     typedef typename OPS::template matrix<Scalar,Ordinal,Node>::matrix_type  MAT;
00113     typedef typename OPS::template graph<Ordinal,Node>::graph_type          GRPH;
00114     typedef MultiVector<Scalar,Node>                                          MV;
00115     typedef Teuchos::ScalarTraits<Scalar>                                     ST;
00116     const Scalar ONE = ST::one();
00117     RCP<Node> node = getNode<Node>();
00118     // generate tridiagonal matrix:
00119     // [ 2 -1                   ]
00120     // [-1  3  -1               ]
00121     // [   -1   3  -1           ]
00122     // [                        ]
00123     // [                -1  3 -1]
00124     // [                   -1  2]
00125     const int N = NodeTest::N;
00126     if (N<2) return;
00127     RCP<GRPH> G = rcp(new GRPH (N,node,null) );
00128     RCP<MAT>  A = rcp(new MAT  (G,null) );
00129     // allocate data for ptrs, indices and values
00130     const size_t totalNNZ = 3*N - 2;
00131     ArrayRCP<size_t> ptrs(N+1);
00132     ArrayRCP<Ordinal>   inds(totalNNZ);
00133     ArrayRCP<Scalar>    vals(totalNNZ);
00134     // fill the data
00135     {
00136       size_t NNZsofar = 0;
00137       ptrs[0] = NNZsofar;
00138       inds[NNZsofar] = 0; inds[NNZsofar+1] =  1;
00139       vals[NNZsofar] = 2; vals[NNZsofar+1] = -1;
00140       NNZsofar += 2;
00141       for (int i=1; i != N-1; ++i) {
00142         ptrs[i] = NNZsofar;
00143         inds[NNZsofar] = i-1; inds[NNZsofar+1] = i; inds[NNZsofar+2] = i+1;
00144         vals[NNZsofar] =  -1; vals[NNZsofar+1] = 3; vals[NNZsofar+2] =  -1;
00145         NNZsofar += 3;
00146       }
00147       ptrs[N-1] = NNZsofar;
00148       inds[NNZsofar] = N-2; inds[NNZsofar+1] = N-1;
00149       vals[NNZsofar] =  -1; vals[NNZsofar+1] = 2;
00150       NNZsofar += 2;
00151       ptrs[N]   = NNZsofar;
00152       TEUCHOS_TEST_FOR_EXCEPT(NNZsofar != totalNNZ);
00153     }
00154     G->setStructure(ptrs, inds);
00155     ptrs = Teuchos::null;
00156     inds = Teuchos::null;
00157     A->setValues(vals);
00158     vals = Teuchos::null;
00159     OPS::finalizeGraphAndMatrix(Teuchos::UNDEF_TRI,Teuchos::NON_UNIT_DIAG,*G,*A,null);
00160     Teuchos::EDiag diag;
00161     Teuchos::EUplo uplo;
00162     G->getMatDesc(uplo,diag);
00163     OPS dsm(node);
00164     out << "Testing with sparse ops: " << Teuchos::typeName(dsm) << std::endl;
00165     TEST_NOTHROW( dsm.setGraphAndMatrix(G,A) )
00166 
00167     ArrayRCP<Scalar> xdat, axdat;
00168     xdat  = node->template allocBuffer<Scalar>(N);
00169     axdat = node->template allocBuffer<Scalar>(N);
00170     MV X(node), Y(node);
00171     X.initializeValues( N,1, xdat,N);
00172     Y.initializeValues(N,1,axdat,N);
00173     DefaultArithmetic<MV>::Init( X,1);
00174     Teuchos::RCP<Teuchos::Time> matvectime = Teuchos::TimeMonitor::getNewTimer("LocalTimer");
00175     {
00176       Teuchos::TimeMonitor lcltimer(*matvectime);
00177       for (int i=0; i<NodeTest::numIters; ++i) {
00178         // Y = A*X
00179         dsm.multiply(Teuchos::NO_TRANS,ONE,X,Y);
00180       }
00181     }
00182     out << "Time is " << matvectime->totalElapsedTime() << std::endl;
00183   }
00184 
00185 
00186   // 
00187   // INSTANTIATIONS
00188   //
00189 
00190   #define TEST_NODE( NODE ) \
00191     TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( AAAAA_Is_First, InitNode, NODE ) \
00192     typedef DefaultHostSparseOps<void,int,NODE> NoFirstTouch; \
00193     typedef FirstTouchSparseOps<void,int,NODE>  YesFirstTouch; \
00194     TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( CrsMatrix, TimingTest, NoFirstTouch) \
00195     TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( CrsMatrix, TimingTest, YesFirstTouch)
00196 
00197 }
00198 
00199 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends