Zoltan2
Zoltan2_MatrixAdapter.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //   Zoltan2: A package of combinatorial algorithms for scientific computing
00006 //                  Copyright 2012 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 Karen Devine      (kddevin@sandia.gov)
00039 //                    Erik Boman        (egboman@sandia.gov)
00040 //                    Siva Rajamanickam (srajama@sandia.gov)
00041 //
00042 // ***********************************************************************
00043 //
00044 // @HEADER
00045 
00050 #ifndef _ZOLTAN2_MATRIXADAPTER_HPP_
00051 #define _ZOLTAN2_MATRIXADAPTER_HPP_
00052 
00053 #include <Zoltan2_Adapter.hpp>
00054 #include <Zoltan2_VectorAdapter.hpp>
00055 
00056 namespace Zoltan2 {
00057 
00058 enum MatrixEntityType {
00059   MATRIX_ROW,
00060   MATRIX_COLUMN,
00061   MATRIX_NONZERO
00062 };
00063 
00109 template <typename User, typename UserCoord=User>
00110   class MatrixAdapter : public BaseAdapter<User> {
00111 private:
00112   enum MatrixEntityType primaryEntityType_;
00113   VectorAdapter<UserCoord> *coordinateInput_;
00114   bool haveCoordinateInput_;
00115 
00116 public:
00117 
00118 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00119   typedef typename InputTraits<User>::scalar_t    scalar_t;
00120   typedef typename InputTraits<User>::lno_t    lno_t;
00121   typedef typename InputTraits<User>::gno_t    gno_t;
00122   typedef typename InputTraits<User>::zgid_t    zgid_t;
00123   typedef typename InputTraits<User>::part_t   part_t;
00124   typedef typename InputTraits<User>::node_t   node_t;
00125   typedef User user_t;
00126   typedef UserCoord userCoord_t;
00127 #endif
00128 
00129   enum BaseAdapterType adapterType() const {return MatrixAdapterType;}
00130 
00131   // Constructor; sets default primaryEntityType to MATRIX_ROW.
00132   MatrixAdapter() : primaryEntityType_(MATRIX_ROW),
00133                     coordinateInput_(),
00134                     haveCoordinateInput_(false) {}
00135 
00138   virtual ~MatrixAdapter(){}
00139 
00142   virtual size_t getLocalNumRows() const = 0;
00143 
00146   virtual size_t getLocalNumColumns() const = 0;
00147 
00150   virtual size_t getLocalNumEntries() const = 0;
00151 
00152 
00153 
00159   virtual bool CRSViewAvailable() const { return false; }
00160 
00164   virtual void getRowIDsView(const zgid_t *&rowIds) const
00165   {
00166     rowIds = NULL;
00167     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00168   }
00169 
00181   virtual void getCRSView(const lno_t *&offsets,
00182                           const zgid_t *&colIds) const
00183   {
00184     // Default implementation; no CRS view provided.
00185     offsets = NULL;
00186     colIds = NULL;
00187     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00188   }
00189 
00204   virtual void getCRSView(const lno_t *&offsets,
00205                           const zgid_t *& colIds,
00206                           const scalar_t *&values) const
00207   {
00208     // Default implementation; no CRS view provided.
00209     offsets = NULL;
00210     colIds = NULL;
00211     values = NULL;
00212     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00213   }
00214 
00218   virtual int getNumWeightsPerRow() const { return 0;}
00219 
00226   virtual void getRowWeightsView(const scalar_t *&weights, int &stride,
00227                                  int idx = 0) const
00228   {
00229     // Default implementation
00230     weights = NULL;
00231     stride = 0;
00232     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00233   }
00234 
00238   virtual bool useNumNonzerosAsRowWeight(int idx) const
00239   {
00240     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00241   }
00242 
00248   virtual bool CCSViewAvailable() const { return false; }
00249 
00253   virtual void getColumnIDsView(const zgid_t *&colIds) const
00254   {
00255     colIds = NULL;
00256     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00257   }
00258 
00270   virtual void getCCSView(const lno_t *&offsets,
00271                           const zgid_t *&rowIds) const
00272   {
00273     // Default implementation; no CCS view provided.
00274     offsets = NULL;
00275     rowIds = NULL;
00276     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00277   }
00278 
00293   virtual void getCCSView(const lno_t *&offsets,
00294                           const zgid_t *&rowIds,
00295                           const scalar_t *&values) const
00296   {
00297     // Default implementation; no CCS view provided.
00298     offsets = NULL;
00299     rowIds = NULL;
00300     values = NULL;
00301     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00302   }
00303 
00307   virtual int getNumWeightsPerColumn() const { return 0; }
00308 
00315   virtual void getColumnWeightsView(const scalar_t *&weights, int &stride,
00316                                     int idx = 0) const
00317   {
00318     // Default implementation
00319     weights = NULL;
00320     stride = 0;
00321     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00322   }
00323 
00327   virtual bool useNumNonzerosAsColumnWeight(int idx) const { return 0; }
00328 
00329 #ifdef FUTURE_FEATURE
00330 
00334   virtual bool symmetricStorage() const {return false;}
00335 #endif
00336 
00345   void setCoordinateInput(VectorAdapter<UserCoord> *coordData)
00346   {
00347     coordinateInput_ = coordData;
00348     haveCoordinateInput_ = true;
00349   }
00350 
00354   bool coordinatesAvailable() const { return haveCoordinateInput_; }
00355 
00359   VectorAdapter<UserCoord> *getCoordinateInput() const
00360   {
00361     return coordinateInput_;
00362   }
00363 
00365   // Implementations of base-class methods and other methods shared by all
00366 
00370   inline enum MatrixEntityType getPrimaryEntityType() const
00371   {
00372     return this->primaryEntityType_;
00373   }
00374 
00380   void setPrimaryEntityType(std::string typestr)
00381   {
00382     if (typestr == "row") {
00383       this->primaryEntityType = MATRIX_ROW;
00384     }
00385     else if (typestr == "column") {
00386       this->primaryEntityType = MATRIX_COLUMN;
00387     }
00388     else if (typestr == "nonzero") {
00389       this->primaryEntityType = MATRIX_NONZERO;
00390     }
00391     else {
00392       std::ostringstream emsg;
00393       emsg << __FILE__ << "," << __LINE__
00394            << " error:  Invalid MatrixEntityType " << typestr << std::endl;
00395       emsg << "Valid values are 'row', 'column' and 'nonzero'." << std::endl;
00396       throw std::runtime_error(emsg.str());
00397     }
00398   }
00399 
00400   // Functions from the BaseAdapter interface
00401   size_t getLocalNumIDs() const
00402   {
00403     switch (getPrimaryEntityType()) {
00404     case MATRIX_ROW:
00405       return getLocalNumRows();
00406     case MATRIX_COLUMN:
00407       return getLocalNumColumns();
00408     case MATRIX_NONZERO:
00409       return getLocalNumEntries();
00410     default:   // Shouldn't reach default; just making compiler happy
00411       return 0;
00412     }
00413   }
00414 
00415   void getIDsView(const zgid_t *&Ids) const
00416   {
00417     switch (getPrimaryEntityType()) {
00418     case MATRIX_ROW:
00419       getRowIDsView(Ids);
00420       break;
00421     case MATRIX_COLUMN:
00422       getColumnIDsView(Ids);
00423       break;
00424     case MATRIX_NONZERO: {
00425       // TODO:  Need getNonzeroIDsView?  What is a Nonzero ID?
00426       // TODO:  std::pair<zgid_t, zgid_t>?
00427       std::ostringstream emsg;
00428       emsg << __FILE__ << "," << __LINE__
00429            << " error:  getIDsView not yet supported for matrix nonzeros."
00430            << std::endl;
00431       throw std::runtime_error(emsg.str());
00432       break;
00433       }
00434     default:   // Shouldn't reach default; just making compiler happy
00435       break;
00436     }
00437   }
00438 
00439   int getNumWeightsPerID() const
00440   {
00441     switch (getPrimaryEntityType()) {
00442     case MATRIX_ROW:
00443       return getNumWeightsPerRow();
00444     case MATRIX_COLUMN:
00445       return getNumWeightsPerColumn();
00446     case MATRIX_NONZERO:
00447       return 0;  //TODO: weights not yet supported for nonzeros
00448     default:   // Shouldn't reach default; just making compiler happy
00449       return 0;
00450     }
00451   }
00452 
00453   void getWeightsView(const scalar_t *&wgt, int &stride, int idx = 0) const
00454   {
00455     switch (getPrimaryEntityType()) {
00456     case MATRIX_ROW:
00457       getRowWeightsView(wgt, stride, idx);
00458       break;
00459     case MATRIX_COLUMN:
00460       getColumnWeightsView(wgt, stride, idx);
00461       break;
00462     case MATRIX_NONZERO:
00463       {
00464       // TODO:  Need getNonzeroWeightsView with Nonzeros as primary object?
00465       // TODO:  That is, get Nonzeros' weights based on some nonzero ID?
00466       std::ostringstream emsg;
00467       emsg << __FILE__ << "," << __LINE__
00468            << " error:  getWeightsView not yet supported for matrix nonzeros."
00469            << std::endl;
00470       throw std::runtime_error(emsg.str());
00471       break;
00472       }
00473     default:   // Shouldn't reach default; just making compiler happy
00474       break;
00475     }
00476   }
00477 
00478   bool useDegreeAsWeight(int idx) const
00479   {
00480     if (this->getPrimaryEntityType() == MATRIX_ROW)
00481       return useNumNonzerosAsRowWeight(idx);
00482     else {
00483       std::ostringstream emsg;
00484       emsg << __FILE__ << "," << __LINE__
00485            << " error:  useDegreeAsWeight is currently supported only for rows"
00486            << std::endl;
00487       throw std::runtime_error(emsg.str());
00488     }
00489   }
00490 };
00491 
00492 }  //namespace Zoltan2
00493 
00494 #endif