Kokkos Node API and Local Linear Algebra Kernels Version of the Day
Kokkos_CrsMatrix.hpp
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //          Kokkos: Node API and Parallel Node Kernels
00005 //              Copyright (2008) Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 // 
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00038 // 
00039 // ************************************************************************
00040 //@HEADER
00041 
00042 #ifndef KOKKOS_CRSMATRIX_HPP
00043 #define KOKKOS_CRSMATRIX_HPP
00044 
00045 #include <Teuchos_RCP.hpp>
00046 #include <Teuchos_TypeNameTraits.hpp>
00047 #include <Teuchos_Assert.hpp>
00048 #include <Teuchos_ArrayRCP.hpp>
00049 
00050 #include "Kokkos_ConfigDefs.hpp"
00051 #include "Kokkos_DefaultNode.hpp"
00052 #include "Kokkos_CrsGraph.hpp"
00053 
00054 namespace Kokkos {
00055 
00056   //=========================================================================================================================
00057   // 
00058   // A host-resident CrsMatrix
00059   // 
00060   //=========================================================================================================================
00061 
00065   template <class Scalar, 
00066             class Ordinal, 
00067             class Node,
00068             class LocalMatOps>
00069   class CrsMatrixHostCompute {
00070   public:
00071 
00072     typedef Scalar                ScalarType;
00073     typedef Ordinal               OrdinalType;
00074     typedef Node                  NodeType;
00075     typedef LocalMatOps           LocalMatOpsType;
00076 
00078 
00079 
00081     CrsMatrixHostCompute();
00082 
00084     CrsMatrixHostCompute(CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &graph);
00085 
00087     CrsMatrixHostCompute(const CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &graph);
00088 
00090     virtual ~CrsMatrixHostCompute();
00091 
00093 
00095 
00096 
00098     void setOwnedGraph(CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &graph);
00099 
00101     void setStaticGraph(const CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &graph);
00102     
00104 
00106 
00107 
00109     RCP<Node> getNode() const;
00110 
00112     size_t getNumRows() const;
00113 
00115     size_t getNumEntries() const;
00116 
00118     bool isEmpty() const;
00119 
00121     bool isFinalized() const;
00122 
00125     bool is1DStructure() const;
00126 
00129     bool is2DStructure() const;
00130 
00132     bool isOptimized() const;
00133 
00135 
00138     void set1DValues(ArrayRCP<Scalar> vals);
00139 
00141 
00144     void set2DValues(ArrayRCP<ArrayRCP<Scalar> > vals);
00145 
00147 
00151     void get1DValues(ArrayRCP<Scalar> &vals);
00152 
00154 
00158     void get2DValues(ArrayRCP<ArrayRCP<Scalar> > &inds);
00159 
00161 
00167     void finalize(bool OptimizeStorage);
00168 
00170     virtual void clear();
00171 
00173 
00174   protected:
00176     CrsMatrixHostCompute(const CrsMatrixHostCompute& sources);
00177 
00178     CrsGraphHostCompute<Ordinal,Node,LocalMatOps> *myGraph_;
00179     const CrsGraphHostCompute<Ordinal,Node,LocalMatOps> *staticGraph_;
00180     bool isFinalized_;
00181 
00182     // 2D storage
00183     ArrayRCP<ArrayRCP<Scalar> >  values2D_;
00184     // 1D storage
00185     ArrayRCP<Scalar>             values1D_;
00186   };
00187 
00188 
00189   //==============================================================================
00190   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00191   CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::CrsMatrixHostCompute()
00192   {
00193     myGraph_ = NULL;
00194     staticGraph_ = NULL;
00195     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::clear();
00196   }
00197 
00198   //==============================================================================
00199   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00200   CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::CrsMatrixHostCompute(const CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &graph)
00201   {
00202     setStaticGraph(graph);
00203     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::clear();
00204   }
00205 
00206   //==============================================================================
00207   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00208   CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::CrsMatrixHostCompute(CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &graph)
00209   {
00210     setOwnedGraph(graph);
00211     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::clear();
00212   }
00213 
00214   //==============================================================================
00215   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00216   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setStaticGraph(const CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &hgraph)
00217   {
00218     myGraph_ = NULL;
00219     staticGraph_ = &hgraph;
00220     TEUCHOS_TEST_FOR_EXCEPTION( staticGraph_->isFinalized() == false, std::runtime_error, 
00221         Teuchos::typeName(*this) << ": construction with static graph requires that the graph is already finalized.");
00222   }
00223 
00224   //==============================================================================
00225   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00226   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setOwnedGraph(CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &hgraph)
00227   {
00228     myGraph_ = &hgraph;
00229     staticGraph_ = &hgraph;
00230     TEUCHOS_TEST_FOR_EXCEPTION( myGraph_->isFinalized() == true, std::runtime_error,
00231         Teuchos::typeName(*this) << ": construction with matrix-owned graph requires that the graph is not yet finalized.");
00232   }
00233 
00234   //==============================================================================
00235   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00236   CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::~CrsMatrixHostCompute() {
00237   }
00238 
00239   // ======= clear ===========
00240   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00241   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::clear() {
00242     isFinalized_   = false;
00243     values1D_      = null;
00244     values2D_      = null;
00245   }
00246 
00247   // ======= node ===========
00248   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00249   RCP<Node> CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::getNode() const {
00250     return staticGraph_->getNode();
00251   }
00252 
00253   // ======= numrows ===========
00254   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00255   size_t CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::getNumRows() const {
00256     return staticGraph_->getNumRows();
00257   }
00258 
00259   // ======= numentries ===========
00260   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00261   size_t CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::getNumEntries() const {
00262     return staticGraph_->getNumEntries();
00263   }
00264 
00265   // ======= isempty ===========
00266   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00267   bool CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::isEmpty() const {
00268     return staticGraph_->isEmpty();
00269   }
00270 
00271   // ======= isfinalized ===========
00272   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00273   bool CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::isFinalized() const {
00274     return isFinalized_;
00275   }
00276 
00277   // ======= is1d ===========
00278   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00279   bool CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::is1DStructure() const {
00280     return staticGraph_->is1DStructure();
00281   }
00282 
00283   // ======= is2d ===========
00284   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00285   bool CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::is2DStructure() const {
00286     return staticGraph_->is2DStructure();
00287   }
00288 
00289   // ======= isopt ===========
00290   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00291   bool CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::isOptimized() const {
00292     return staticGraph_->isOptimized();
00293   }
00294 
00295   // ======= get 1d ===========
00296   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00297   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::get1DValues(ArrayRCP<Scalar> &vals)
00298   {
00299     vals = values1D_;
00300   }
00301 
00302   // ======= get 2d ===========
00303   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00304   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::get2DValues(ArrayRCP<ArrayRCP<Scalar> > &vals)
00305   {
00306     vals = values2D_;
00307   }
00308 
00309   // ======= set 1d ===========
00310   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00311   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::set1DValues(ArrayRCP<Scalar> vals)
00312   {
00313     this->clear();
00314     TEUCHOS_TEST_FOR_EXCEPTION( is1DStructure() == false, std::runtime_error, 
00315         Teuchos::typeName(*this) << "::set1DValues(vals): graph must have 1D structure and must be set before matrix.");
00316     values1D_ = vals;
00317     TEUCHOS_TEST_FOR_EXCEPTION( (size_t)values1D_.size() < getNumEntries(), std::runtime_error,
00318         Teuchos::typeName(*this) << "::set1DValues(vals): inds must have as many entries as the number of entries in the associated graph, and the graph entries must be set first.");
00319   }
00320 
00321   // ======= set 2d ===========
00322   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00323   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::set2DValues(ArrayRCP<ArrayRCP<Scalar> > vals)
00324   {
00325     TEUCHOS_TEST_FOR_EXCEPTION( is2DStructure() == false, std::runtime_error, 
00326         Teuchos::typeName(*this) << "::set2DValues(vals): graph must have 2D structure and must be set before matrix.");
00327     TEUCHOS_TEST_FOR_EXCEPTION( (size_t)vals.size() != getNumRows(), std::runtime_error,
00328         Teuchos::typeName(*this) << "::set2DValues(inds): vals must have as many entries as the number of rows in the associated graph.");
00329     this->clear();
00330     values2D_  = vals;
00331   }
00332 
00333 
00334   // ======= finalize ===========
00335   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00336   void CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::finalize(bool OptimizeStorage)
00337   {
00338     if (isFinalized_ && !(OptimizeStorage == true && staticGraph_->isOptimized() == false)) return;
00339     // we only have something to do if we have a matrix-owned graph
00340     if (myGraph_ != NULL) {
00341       myGraph_->template finalize<Scalar>(OptimizeStorage, values2D_, values1D_);
00342     }
00343     else {
00344       TEUCHOS_TEST_FOR_EXCEPTION(OptimizeStorage == true && staticGraph_->isOptimized() == false, std::runtime_error, 
00345           Teuchos::typeName(*this) << "::finalize(OptimizeStorage == true): underlying static graph is not optimized and cannot be optimized.");
00346     }
00347     isFinalized_ = true;
00348   }
00349 
00350 
00351   //=========================================================================================================================
00352   // 
00353   // A device-resident CrsMatrix
00354   // 
00355   //=========================================================================================================================
00356 
00357 
00365   template <class Scalar,
00366             class Ordinal, 
00367             class Node,
00368             class LocalMatOps>
00369   class CrsMatrixDeviceCompute : public CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps> {
00370   public:
00371 
00373 
00374 
00376     CrsMatrixDeviceCompute();
00377 
00379     CrsMatrixDeviceCompute(CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &graph);
00380 
00382     CrsMatrixDeviceCompute(const CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &graph);
00383 
00385     ~CrsMatrixDeviceCompute();
00386 
00388 
00390 
00391 
00393     void setOwnedGraph(CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &graph);
00394 
00396     void setStaticGraph(const CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &graph);
00397     
00399 
00403     void finalize(bool OptimizeStorage);
00404 
00406     void getDeviceBuffer(ArrayRCP<Scalar> &d_vals) const;
00407 
00409     virtual void clear();
00410 
00412 
00413   protected:
00415     CrsMatrixDeviceCompute(const CrsMatrixDeviceCompute& sources);
00416 
00417     // pointers to device-based graph
00418     CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> *myDeviceGraph_;
00419     const CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> *staticDeviceGraph_;
00420     // device storage (always 1D packed)
00421     ArrayRCP<Scalar> pbuf_values_;
00422   };
00423 
00424   //==============================================================================
00425   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00426   CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::CrsMatrixDeviceCompute()
00427   : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>()
00428   , myDeviceGraph_(NULL)
00429   , staticDeviceGraph_(NULL)
00430   {}
00431 
00432   //==============================================================================
00433   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00434   CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::CrsMatrixDeviceCompute(const CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &graph)
00435   : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>(graph)
00436   , myDeviceGraph_(NULL)
00437   , staticDeviceGraph_(&graph)
00438   {}
00439 
00440   //==============================================================================
00441   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00442   CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::CrsMatrixDeviceCompute(CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &graph)
00443   : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>(graph)
00444   , myDeviceGraph_(&graph)
00445   , staticDeviceGraph_(&graph)
00446   {}
00447 
00448   //===== destructor =====
00449   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00450   CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::~CrsMatrixDeviceCompute() 
00451   {}
00452 
00453   //===== clear =====
00454   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00455   void CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::clear() { 
00456     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::clear();
00457     pbuf_values_ = null;
00458   }
00459 
00460   // ======= get device ===========
00461   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00462   void CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::getDeviceBuffer(ArrayRCP<Scalar> &vals) const
00463   {
00464     vals = pbuf_values_;
00465   }
00466 
00467   //==============================================================================
00468   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00469   void CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::setStaticGraph(const CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &dgraph)
00470   {
00471     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setStaticGraph(dgraph);
00472     myDeviceGraph_     = NULL;
00473     staticDeviceGraph_ = &dgraph;
00474   }
00475 
00476   //==============================================================================
00477   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00478   void CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::setOwnedGraph(CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> &dgraph)
00479   {
00480     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setOwnedGraph(dgraph);
00481     myDeviceGraph_     = &dgraph;
00482     staticDeviceGraph_ = &dgraph;
00483   }
00484 
00485   //==============================================================================
00486   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00487   void CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps>::finalize(bool OptimizeStorage)
00488   {
00489     if (this->isFinalized() && !(OptimizeStorage == true && staticDeviceGraph_->isOptimized() == false)) return;
00490     if (myDeviceGraph_ != NULL) {
00491       // this will finalize both classes and copy data to the device
00492       myDeviceGraph_->template finalize<Scalar>(OptimizeStorage, this->values2D_, this->values1D_, pbuf_values_);
00493     }
00494     else {
00495       TEUCHOS_TEST_FOR_EXCEPTION(OptimizeStorage == true && this->staticGraph_->isOptimized() == false, std::runtime_error, 
00496           Teuchos::typeName(*this) << "::finalize(OptimizeStorage == true): underlying static graph is not optimized and cannot be optimized.");
00497       // static graph. no changes, but need to copy values to device.
00498       if (this->isEmpty()) {
00499         pbuf_values_  = null;
00500       }
00501       else {
00502         // allocate space on the device and copy data there, in a packed format
00503         pbuf_values_ = this->getNode()->template allocBuffer<Scalar>(this->getNumEntries());
00504         ArrayRCP<size_t> rowBegs, rowEnds, numEntriesPerRow;
00505         if (this->is1DStructure()) {
00506           ArrayRCP<Ordinal> inds;
00507           const_cast<CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> *>(staticDeviceGraph_)->get1DStructure(inds, rowBegs, rowEnds);
00508         }
00509         else {
00510           ArrayRCP<ArrayRCP<Ordinal> > inds;
00511           const_cast<CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps> *>(staticDeviceGraph_)->get2DStructure(inds, numEntriesPerRow);
00512         }
00513         if (this->isOptimized()) {
00514           // should be packed now; single copy should do, and offsets are rowBegs_
00515           this->getNode()->template copyToBuffer<Scalar >(this->getNumEntries(), this->values1D_(0,this->getNumEntries()), pbuf_values_);
00516         }
00517         else {
00518           // need to get graph structure from graph
00519           ArrayRCP<Scalar> view_values = this->getNode()->template viewBufferNonConst<Scalar >(WriteOnly, pbuf_values_.size(), pbuf_values_);
00520           typename ArrayRCP<Scalar >::iterator oldvals, newvals;
00521           newvals = view_values.begin();
00522           size_t curnuminds;
00523           for (size_t i=0; i < this->getNumRows(); ++i) {
00524             if (this->is1DStructure()) {
00525               curnuminds = rowEnds[i] - rowBegs[i];
00526               oldvals = this->values1D_.begin() + rowBegs[i];
00527             }
00528             else {
00529               curnuminds = numEntriesPerRow[i];
00530               oldvals = this->values2D_[i].begin();
00531             }
00532             std::copy(oldvals, oldvals+curnuminds, newvals);
00533             newvals += curnuminds;
00534           }
00535           view_values  = null;
00536         }
00537       }
00538     }
00539     this->isFinalized_ = true;
00540   }
00541 
00542 
00543   //=========================================================================================================================
00544   // 
00545   // A first-touch allocation host-resident CrsMatrix
00546   // 
00547   //=========================================================================================================================
00548 
00552   template <class Scalar, 
00553             class Ordinal, 
00554             class Node,
00555             class LocalMatOps>
00556   class FirstTouchHostCrsMatrix : public CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps> {
00557   public:
00558 
00559     typedef typename CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::ScalarType        ScalarType;
00560     typedef typename CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::OrdinalType       OrdinalType;
00561     typedef typename CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::NodeType          NodeType;
00562     typedef typename CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::LocalMatOpsType   LocalMatOpsType;
00563 
00565 
00566 
00568     FirstTouchHostCrsMatrix();
00569 
00571     FirstTouchHostCrsMatrix(FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &graph);
00572 
00574     FirstTouchHostCrsMatrix(const FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &graph);
00575 
00577     virtual ~FirstTouchHostCrsMatrix();
00578 
00580 
00582 
00583 
00585     void setOwnedGraph(FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &graph);
00586 
00588     void setStaticGraph(const FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &graph);
00589     
00591 
00593 
00594 
00596 
00602     void finalize(bool OptimizeStorage);
00603 
00605 
00606   protected:
00608     FirstTouchHostCrsMatrix(const FirstTouchHostCrsMatrix& sources);
00609     // pointers to first-touch graphs
00610     FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps>           *myFTGraph_;
00611     const FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> *staticFTGraph_;
00612   };
00613 
00614 
00615   //==============================================================================
00616   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00617   FirstTouchHostCrsMatrix<Scalar,Ordinal,Node,LocalMatOps>::FirstTouchHostCrsMatrix()
00618   : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>() 
00619   , myFTGraph_(NULL)
00620   , staticFTGraph_(NULL)
00621   {}
00622 
00623   //==============================================================================
00624   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00625   FirstTouchHostCrsMatrix<Scalar,Ordinal,Node,LocalMatOps>::FirstTouchHostCrsMatrix(const FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &graph)
00626   : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>(graph) 
00627   , myFTGraph_(NULL)
00628   , staticFTGraph_(&graph)
00629   {}
00630 
00631   //==============================================================================
00632   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00633   FirstTouchHostCrsMatrix<Scalar,Ordinal,Node,LocalMatOps>::FirstTouchHostCrsMatrix(FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &graph)
00634   : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>(graph) 
00635   , myFTGraph_(&graph)
00636   , staticFTGraph_(&graph)
00637   {}
00638 
00639   //==============================================================================
00640   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00641   FirstTouchHostCrsMatrix<Scalar,Ordinal,Node,LocalMatOps>::~FirstTouchHostCrsMatrix() {
00642   }
00643 
00644   //==============================================================================
00645   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00646   void FirstTouchHostCrsMatrix<Scalar,Ordinal,Node,LocalMatOps>::setStaticGraph(const FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &dgraph)
00647   {
00648     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setStaticGraph(dgraph);
00649     myFTGraph_     = NULL;
00650     staticFTGraph_ = &dgraph;
00651   }
00652 
00653   //==============================================================================
00654   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00655   void FirstTouchHostCrsMatrix<Scalar,Ordinal,Node,LocalMatOps>::setOwnedGraph(FirstTouchHostCrsGraph<Ordinal,Node,LocalMatOps> &dgraph)
00656   {
00657     CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setOwnedGraph(dgraph);
00658     myFTGraph_     = &dgraph;
00659     staticFTGraph_ = &dgraph;
00660   }
00661 
00662   // ======= finalize ===========
00663   template <class Scalar, class Ordinal, class Node, class LocalMatOps>
00664   void FirstTouchHostCrsMatrix<Scalar,Ordinal,Node,LocalMatOps>::finalize(bool OptimizeStorage)
00665   {
00666     if (this->isFinalized_ == false || 
00667        (OptimizeStorage == true && staticFTGraph_->isOptimized() == false))
00668     {
00669       if (this->myFTGraph_ != NULL) {
00670         // call graph finalize to finalize/first-touch graph and matrix at the same time
00671         myFTGraph_->template finalize<Scalar>(OptimizeStorage, this->values2D_, this->values1D_);
00672       }
00673       else {
00674         TEUCHOS_TEST_FOR_EXCEPTION(OptimizeStorage == true && staticFTGraph_->isOptimized() == false, std::runtime_error, 
00675             Teuchos::typeName(*this) << "::finalize(OptimizeStorage == true): underlying static graph is not already optimized and cannot be optimized.");
00676       }
00677       this->isFinalized_ = true;
00678     }
00679 #ifdef HAVE_KOKKOS_DEBUG
00680     TEUCHOS_TEST_FOR_EXCEPTION(this->isFinalized_ == false || staticFTGraph_->isFinalized() == false, std::logic_error,
00681         Teuchos::typeName(*this) << "::finalize(): logic error. Post-condition violated. Please contact Tpetra team.");
00682     TEUCHOS_TEST_FOR_EXCEPTION(OptimizeStorage == true && (staticFTGraph_->isOptimized() == false && staticFTGraph_->isEmpty() == false), std::logic_error,
00683         Teuchos::typeName(*this) << "::finalize(): logic error. Post-condition violated. Please contact Tpetra team.");
00684 #endif
00685   }
00686 
00687 
00688   //=========================================================================================================================
00689   // 
00690   // Specializations
00691   // 
00692   //=========================================================================================================================
00693   // C++0x: it would be nice if these were template aliases
00694 
00700   template <class Scalar,
00701             class Ordinal, 
00702             class Node,
00703             class LocalMatOps>
00704   class CrsMatrix : public CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps> {
00705   public:
00706     CrsMatrix() : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>() {}
00707     CrsMatrix(CrsGraph<Ordinal,Node,LocalMatOps> &graph) : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>(graph) {}
00708     CrsMatrix(const CrsGraph<Ordinal,Node,LocalMatOps> &graph) : CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>(graph) {}
00709     void setStaticGraph(const CrsGraph<Ordinal,Node,LocalMatOps> &graph) {
00710       const CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &hgraph = dynamic_cast<const CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &>(graph);
00711       CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setStaticGraph(hgraph);
00712     }
00713     void setOwnedGraph(CrsGraph<Ordinal,Node,LocalMatOps> &graph) {
00714       CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &hgraph = dynamic_cast<CrsGraphHostCompute<Ordinal,Node,LocalMatOps> &>(graph);
00715       CrsMatrixHostCompute<Scalar,Ordinal,Node,LocalMatOps>::setOwnedGraph(hgraph);
00716     }
00717   private:
00718     CrsMatrix(const CrsMatrix<Scalar,Ordinal,Node,LocalMatOps> &mat); // not implemented
00719   };
00720 
00721 #ifndef HAVE_KOKKOS_NO_FIRST_TOUCH_MATVEC_ALLOCATION
00722 #ifdef HAVE_KOKKOS_TBB
00723 
00728   class TBBNode;
00729   template <class Scalar,
00730             class Ordinal, 
00731             class LocalMatOps>
00732   class CrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps> : public FirstTouchHostCrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps> {
00733   public:
00734     CrsMatrix() : FirstTouchHostCrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps>() {}
00735     CrsMatrix(CrsGraph<Ordinal,TBBNode,LocalMatOps> &graph) : FirstTouchHostCrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps>(graph) {}
00736     CrsMatrix(const CrsGraph<Ordinal,TBBNode,LocalMatOps> &graph) : FirstTouchHostCrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps>(graph) {}
00737     void setStaticGraph(const CrsGraph<Ordinal,TBBNode,LocalMatOps> &graph) {
00738       const FirstTouchHostCrsGraph<Ordinal,TBBNode,LocalMatOps> &hgraph = dynamic_cast<const FirstTouchHostCrsGraph<Ordinal,TBBNode,LocalMatOps> &>(graph);
00739       FirstTouchHostCrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps>::setStaticGraph(hgraph);
00740     }
00741     void setOwnedGraph(CrsGraph<Ordinal,TBBNode,LocalMatOps> &graph) {
00742       FirstTouchHostCrsGraph<Ordinal,TBBNode,LocalMatOps> &hgraph = dynamic_cast<FirstTouchHostCrsGraph<Ordinal,TBBNode,LocalMatOps> &>(graph);
00743       FirstTouchHostCrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps>::setOwnedGraph(hgraph);
00744     }
00745   private:
00746     CrsMatrix(const CrsMatrix<Scalar,Ordinal,TBBNode,LocalMatOps> &mat); // not implemented
00747   };
00748 #endif
00749 #ifdef HAVE_KOKKOS_THREADPOOL
00750   class TPINode;
00756   template <class Scalar,
00757             class Ordinal, 
00758             class LocalMatOps>
00759   class CrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps> : public FirstTouchHostCrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps> {
00760   public:
00761     CrsMatrix() : FirstTouchHostCrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps>() {}
00762     CrsMatrix(CrsGraph<Ordinal,TPINode,LocalMatOps> &graph) : FirstTouchHostCrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps>(graph) {}
00763     CrsMatrix(const CrsGraph<Ordinal,TPINode,LocalMatOps> &graph) : FirstTouchHostCrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps>(graph) {}
00764     void setStaticGraph(const CrsGraph<Ordinal,TPINode,LocalMatOps> &graph) {
00765       const FirstTouchHostCrsGraph<Ordinal,TPINode,LocalMatOps> &hgraph = dynamic_cast<const FirstTouchHostCrsGraph<Ordinal,TPINode,LocalMatOps> &>(graph);
00766       FirstTouchHostCrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps>::setStaticGraph(hgraph);
00767     }
00768     void setOwnedGraph(CrsGraph<Ordinal,TPINode,LocalMatOps> &graph) {
00769       FirstTouchHostCrsGraph<Ordinal,TPINode,LocalMatOps> &hgraph = dynamic_cast<FirstTouchHostCrsGraph<Ordinal,TPINode,LocalMatOps> &>(graph);
00770       FirstTouchHostCrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps>::setOwnedGraph(hgraph);
00771     }
00772   private:
00773     CrsMatrix(const CrsMatrix<Scalar,Ordinal,TPINode,LocalMatOps> &mat); // not implemented
00774   };
00775 #endif
00776 #endif
00777 
00783   template <class S, class O, class N> class DefaultDeviceSparseOps;
00784   template <class Scalar,
00785             class Ordinal,
00786             class Node>
00787   class CrsMatrix<Scalar,Ordinal,Node,DefaultDeviceSparseOps<void,Ordinal,Node> > : public CrsMatrixDeviceCompute<Scalar,Ordinal,Node,DefaultDeviceSparseOps<void,Ordinal,Node> > {
00788   public:
00789     typedef DefaultDeviceSparseOps<void,Ordinal,Node> LocalMatOps;
00790     CrsMatrix() : CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps >() {}
00791     CrsMatrix(CrsGraph<Ordinal,Node,LocalMatOps > &graph) : CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps >(graph) {}
00792     CrsMatrix(const CrsGraph<Ordinal,Node,LocalMatOps > &graph) : CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps >(graph) {}
00793     void setStaticGraph(const CrsGraph<Ordinal,Node,LocalMatOps > &graph) {
00794       const CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps > &dgraph = dynamic_cast<const CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps > &>(graph);
00795       CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps >::setStaticGraph(dgraph);
00796     }
00797     void setOwnedGraph(CrsGraph<Ordinal,Node,LocalMatOps > &graph) {
00798       CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps > &dgraph = dynamic_cast<CrsGraphDeviceCompute<Ordinal,Node,LocalMatOps > &>(graph);
00799       CrsMatrixDeviceCompute<Scalar,Ordinal,Node,LocalMatOps >::setOwnedGraph(dgraph);
00800     }
00801   private:
00802     CrsMatrix(const CrsMatrix<Scalar,Ordinal,Node,LocalMatOps > &mat); // not implemented
00803   };
00804 
00805 } // namespace Kokkos
00806 
00807 #endif /* KOKKOS_CRSMATRIX_HPP */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends