Kokkos Node API and Local Linear Algebra Kernels Version of the Day
CrsMatrix_Scale.cpp
00001 // ************************************************************************
00002 // 
00003 //          Kokkos: A Fast Kernel Package
00004 //              Copyright (2004) Sandia Corporation
00005 // 
00006 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00007 // license for use of this work by or on behalf of the U.S. Government.
00008 // 
00009 // This library is free software; you can redistribute it and/or modify
00010 // it under the terms of the GNU Lesser General Public License as
00011 // published by the Free Software Foundation; either version 2.1 of the
00012 // License, or (at your option) any later version.
00013 //  
00014 // This library is distributed in the hope that it will be useful, but
00015 // WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 //  
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // USA
00022 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00023 // 
00024 // ************************************************************************
00025 //@HEADER
00026 
00027 #include <Teuchos_UnitTestHarness.hpp>
00028 #include <Teuchos_TimeMonitor.hpp>
00029 #include <Teuchos_Time.hpp>
00030 #include <Teuchos_TypeNameTraits.hpp>
00031 #include <Teuchos_ScalarTraits.hpp>
00032 
00033 #include "Kokkos_ConfigDefs.hpp"
00034 #include "Kokkos_DefaultArithmetic.hpp"
00035 #include "Kokkos_DefaultKernels.hpp"
00036 #include "Kokkos_Version.hpp"
00037 
00038 #include "Kokkos_SerialNode.hpp"
00039 #ifdef HAVE_KOKKOS_TBB
00040 #include "Kokkos_TBBNode.hpp"
00041 #endif
00042 #ifdef HAVE_KOKKOS_THREADPOOL
00043 #include "Kokkos_TPINode.hpp"
00044 #endif
00045 #ifdef HAVE_KOKKOS_THRUST
00046 #include "Kokkos_ThrustGPUNode.hpp"
00047 #endif
00048 
00049 namespace {
00050 
00051   using Kokkos::MultiVector;
00052   using Kokkos::CrsMatrix;
00053   using Kokkos::CrsGraph;
00054   using Kokkos::DefaultArithmetic;
00055   using Kokkos::DefaultKernels;
00056   using Kokkos::SerialNode;
00057   using Teuchos::ArrayRCP;
00058   using Teuchos::RCP;
00059   using Teuchos::rcp;
00060   using Teuchos::null;
00061   using std::endl;
00062 
00063   RCP<SerialNode> snode;
00064 #ifdef HAVE_KOKKOS_TBB
00065   using Kokkos::TBBNode;
00066   RCP<TBBNode> tbbnode;
00067 #endif
00068 #ifdef HAVE_KOKKOS_THREADPOOL
00069   using Kokkos::TPINode;
00070   RCP<TPINode> tpinode;
00071 #endif
00072 #ifdef HAVE_KOKKOS_THRUST
00073   using Kokkos::ThrustGPUNode;
00074   RCP<ThrustGPUNode> thrustnode;
00075 #endif
00076 
00077   int N = 1000;
00078 
00079   TEUCHOS_STATIC_SETUP()
00080   {
00081     Teuchos::CommandLineProcessor &clp = Teuchos::UnitTestRepository::getCLP();
00082     clp.addOutputSetupOptions(true);
00083     clp.setOption("test-size",&N,"Vector length for tests.");
00084   }
00085 
00086   template <class Node>
00087   RCP<Node> getNode() {
00088     assert(false);
00089   }
00090 
00091   template <>
00092   RCP<SerialNode> getNode<SerialNode>() {
00093     if (snode == null) {
00094       Teuchos::ParameterList pl;
00095       snode = rcp(new SerialNode(pl));
00096     }
00097     return snode;
00098   }
00099 
00100 #ifdef HAVE_KOKKOS_TBB
00101   template <>
00102   RCP<TBBNode> getNode<TBBNode>() {
00103     if (tbbnode == null) {
00104       Teuchos::ParameterList pl;
00105       pl.set<int>("Num Threads",0);
00106       tbbnode = rcp(new TBBNode(pl));
00107     }
00108     return tbbnode;
00109   }
00110 #endif
00111 
00112 #ifdef HAVE_KOKKOS_THREADPOOL
00113   template <>
00114   RCP<TPINode> getNode<TPINode>() {
00115     if (tpinode == null) {
00116       Teuchos::ParameterList pl;
00117       pl.set<int>("Num Threads",0);
00118       tpinode = rcp(new TPINode(pl));
00119     }
00120     return tpinode;
00121   }
00122 #endif
00123 
00124 #ifdef HAVE_KOKKOS_THRUST
00125   template <>
00126   RCP<ThrustGPUNode> getNode<ThrustGPUNode>() {
00127     if (thrustnode == null) {
00128       Teuchos::ParameterList pl;
00129       pl.set<int>("Num Threads",0);
00130       pl.set<int>("Verbose",1);
00131       thrustnode = rcp(new ThrustGPUNode(pl));
00132     }
00133     return thrustnode;
00134   }
00135 #endif
00136 
00137   //
00138   // UNIT TESTS
00139   // 
00140 
00141   TEUCHOS_UNIT_TEST_TEMPLATE_3_DECL( CrsMatrix, Scale, Ordinal, Scalar, Node )
00142   {
00143     RCP<Node> node = getNode<Node>();
00144     typedef typename DefaultKernels<Scalar,Ordinal,Node>::SparseOps DSM;
00145     typedef CrsGraph<Ordinal,Node,DSM>                             GRPH;
00146     typedef CrsMatrix<Scalar,Ordinal,Node,DSM>                      MAT;
00147     typedef MultiVector<Scalar,Node>                                 MV;
00148     typedef Teuchos::ScalarTraits<Scalar>                            ST;
00149     const Scalar ONE = ST::one(),
00150                 ZERO = ST::zero();
00151     // generate tridiagonal matrix:
00152     // [ 2 -1                   ]
00153     // [-1  3  -1               ]
00154     // [   -1   3  -1           ]
00155     // [                        ]
00156     // [                -1  3 -1]
00157     // [                   -1  2]
00158     if (N<2) return;
00159     GRPH G(N,node);
00160     MAT  A(G);
00161     // allocate buffers for offsets, indices and values
00162     const size_t totalNNZ = 3*N - 2;
00163     ArrayRCP<size_t> offsets(N+1);
00164     ArrayRCP<Ordinal>   inds(totalNNZ);
00165     ArrayRCP<Scalar>    vals(totalNNZ);
00166     // fill the buffers on the host
00167     {
00168       size_t NNZsofar = 0;
00169       offsets[0] = NNZsofar;
00170       inds[NNZsofar] = 0; inds[NNZsofar+1] =  1;
00171       vals[NNZsofar] = 2; vals[NNZsofar+1] = -1;
00172       NNZsofar += 2;
00173       for (int i=1; i != N-1; ++i) {
00174         offsets[i] = NNZsofar;
00175         inds[NNZsofar] = i-1; inds[NNZsofar+1] = i; inds[NNZsofar+2] = i+1;
00176         vals[NNZsofar] =  -1; vals[NNZsofar+1] = 3; vals[NNZsofar+2] =  -1;
00177         NNZsofar += 3;
00178       }
00179       offsets[N-1] = NNZsofar;
00180       inds[NNZsofar] = N-2; inds[NNZsofar+1] = N-1;
00181       vals[NNZsofar] =  -1; vals[NNZsofar+1] = 2;
00182       NNZsofar += 2;
00183       offsets[N]   = NNZsofar;
00184       TEST_FOR_EXCEPT(NNZsofar != totalNNZ);
00185     }
00186     G.set1DStructure(inds, offsets, offsets.persistingView(1,N));
00187     offsets = Teuchos::null;
00188     inds    = Teuchos::null;
00189     A.set1DValues(vals);
00190     vals    = Teuchos::null;
00191     A.finalize(true);
00192     typename DSM::template rebind<Scalar>::other dsm(node);
00193     out << "Testing with sparse ops: " << Teuchos::typeName(dsm) << std::endl;
00194     dsm.initializeStructure(G);
00195     dsm.initializeValues(A);
00196 
00197     ArrayRCP<Scalar> xdat, axdat;
00198     xdat  = node->template allocBuffer<Scalar>(N);
00199     axdat = node->template allocBuffer<Scalar>(N);
00200     MV X(node), AX(node);
00201     X.initializeValues( N,1, xdat,N);
00202     AX.initializeValues(N,1,axdat,N);
00203 
00204     // Scale by x, unscale by x and test the multiply.
00205     DefaultArithmetic<MV>::Init( X,2);
00206     dsm.leftScale(X);
00207     DefaultArithmetic<MV>::Init( X,0.5);
00208     dsm.leftScale(X);
00209 
00210     DefaultArithmetic<MV>::Init( X,1.0);
00211     dsm.multiply(Teuchos::NO_TRANS,ONE,X,AX);
00212 
00213     // AX should be all ones
00214     {
00215       ArrayRCP<const Scalar> axview = node->template viewBuffer<Scalar>(N,axdat);
00216       Scalar err = ZERO;
00217       for (int i=0; i<N; ++i) {
00218         err += ST::magnitude(ONE - axview[i]);
00219       }
00220       TEST_EQUALITY_CONST(err, ZERO);
00221     }
00222 
00223     xdat = null;
00224     axdat = null;
00225   }
00226 
00227 #include "CrsMatrix_DefaultMultiplyTests.hpp"
00228 
00229 #define ALL_UNIT_TESTS_ORDINAL_SCALAR_NODE( ORDINAL, SCALAR, NODE ) \
00230       TEUCHOS_UNIT_TEST_TEMPLATE_3_INSTANT( CrsMatrix,        Scale, ORDINAL, SCALAR, NODE ) 
00231 
00232 #define UNIT_TEST_SERIALNODE(ORDINAL, SCALAR) \
00233       ALL_UNIT_TESTS_ORDINAL_SCALAR_NODE( ORDINAL, SCALAR, SerialNode )
00234 
00235 #ifdef HAVE_KOKKOS_TBB
00236 #define UNIT_TEST_TBBNODE(ORDINAL, SCALAR) \
00237       ALL_UNIT_TESTS_ORDINAL_SCALAR_NODE( ORDINAL, SCALAR, TBBNode )
00238 #else
00239 #define UNIT_TEST_TBBNODE(ORDINAL, SCALAR)
00240 #endif
00241 
00242 #ifdef HAVE_KOKKOS_THREADPOOL
00243 #define UNIT_TEST_TPINODE(ORDINAL, SCALAR) \
00244       ALL_UNIT_TESTS_ORDINAL_SCALAR_NODE( ORDINAL, SCALAR, TPINode )
00245 #else
00246 #define UNIT_TEST_TPINODE(ORDINAL, SCALAR)
00247 #endif
00248 
00249 #ifdef HAVE_KOKKOS_THRUST
00250 #define UNIT_TEST_THRUSTGPUNODE(ORDINAL, SCALAR) \
00251       ALL_UNIT_TESTS_ORDINAL_SCALAR_NODE( ORDINAL, SCALAR, ThrustGPUNode )
00252 #else
00253 #define UNIT_TEST_THRUSTGPUNODE(ORDINAL, SCALAR)
00254 #endif
00255 
00256 #define UNIT_TEST_GROUP_ORDINAL_SCALAR( ORDINAL, SCALAR ) \
00257         UNIT_TEST_SERIALNODE( ORDINAL, SCALAR ) \
00258         UNIT_TEST_TBBNODE( ORDINAL, SCALAR ) \
00259         UNIT_TEST_TPINODE( ORDINAL, SCALAR ) \
00260 
00261 #define UNIT_TEST_GROUP_ORDINAL( ORDINAL ) \
00262         UNIT_TEST_GROUP_ORDINAL_SCALAR(ORDINAL, float)
00263 
00264      UNIT_TEST_GROUP_ORDINAL(int)
00265      typedef short int ShortInt; UNIT_TEST_GROUP_ORDINAL(ShortInt)
00266 
00267 }
00268 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends