Zoltan2 Version of the Day
Zoltan2_MatrixInput.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_InputAdapter.hpp>
00054 
00055 namespace Zoltan2 {
00056 
00057 enum MatrixEntityType {
00058   MATRIX_ROW,
00059   MATRIX_COLUMN,
00060   MATRIX_NONZERO
00061 };
00062 
00108 template <typename User>
00109   class MatrixAdapter : public BaseAdapter<User> {
00110 private:
00111   enum MatrixEntityType primaryEntityType;
00112 
00113 public:
00114 
00115 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00116   typedef typename InputTraits<User>::scalar_t    scalar_t;
00117   typedef typename InputTraits<User>::lno_t    lno_t;
00118   typedef typename InputTraits<User>::gno_t    gno_t;
00119   typedef typename InputTraits<User>::gid_t    gid_t;
00120   typedef typename InputTraits<User>::node_t   node_t;
00121   typedef User user_t;
00122 #endif
00123 
00124   enum BaseAdapterType adapterType() const {return MatrixAdapterType;}
00125 
00126   // Constructor; sets default primaryEntityType to MATRIX_ROW.
00127   MatrixAdapter() : primaryEntityType(MATRIX_ROW) {}
00128 
00131   virtual ~MatrixAdapter(){}
00132 
00135   virtual size_t getLocalNumRows() const = 0;
00136 
00139   virtual size_t getLocalNumColumns() const = 0;
00140 
00143   virtual size_t getLocalNumEntries() const = 0;
00144 
00151   virtual void getRowIDsView(const gid_t *&rowIds) const
00152   {
00153 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00154     rowIds = NULL;
00155   }
00156 
00163   virtual void getColumnIDsView(const gid_t *&colIds) const
00164   {
00165 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00166     colIds = NULL;
00167   }
00168 
00174   virtual bool CRSViewAvailable() const { return false; }
00175 
00181   virtual bool CCSViewAvailable() const { return false; }
00182 
00194   virtual void getCRSView(const lno_t *&offsets,
00195                           const gid_t *&colIds) const 
00196   {
00197     // Default implementation; no CRS view provided.
00198 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00199     offsets = NULL;
00200     colIds = NULL;
00201   }
00202 
00217   virtual void getCRSView(const lno_t *&offsets,
00218                           const gid_t *& colIds,
00219                           const scalar_t *&values) const 
00220   {
00221 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00222     // Default implementation; no CRS view provided.
00223     offsets = NULL;
00224     colIds = NULL;
00225     values = NULL;
00226   }
00227 
00239   virtual void getCCSView(const lno_t *&offsets,
00240                           const gid_t *&rowIds) const 
00241   {
00242     // Default implementation; no CCS view provided.
00243 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00244     offsets = NULL;
00245     rowIds = NULL;
00246   }
00247 
00262   virtual void getCCSView(const lno_t *&offsets,
00263                           const gid_t *&rowIds,
00264                           const scalar_t *&values) const
00265   {
00266 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00267     // Default implementation; no CCS view provided.
00268     offsets = NULL;
00269     rowIds = NULL;
00270     values = NULL;
00271   }
00272 
00276   virtual int getNumWeightsPerRow() const { return 0;}
00277 
00286   virtual void getRowWeightsView(const scalar_t *&weights, int &stride,
00287                                  int idx = 0) const
00288   {
00289 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00290     // Default implementation
00291     weights = NULL;
00292     stride = 0;
00293   }
00294 
00298   virtual bool useNumNonzerosAsRowWeight(int idx) const { return 0; }
00299 
00300 
00304   virtual int getNumWeightsPerColumn() const { return 0; }
00305 
00314   virtual void getColumnWeightsView(const scalar_t *&weights, int &stride,
00315                                     int idx = 0) const 
00316   {
00317     // Default implementation
00318 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00319     weights = NULL;
00320     stride = 0;
00321   }
00322 
00326   virtual bool useNumNonzerosAsColumnWeight(int idx) const { return 0; }
00327 
00333 // Future feature
00334 //  virtual bool symmetricStorage() const {return false;}
00335   
00336 
00344 //KDDDEC  Instead of having coordinate-based functions, 
00345 //KDDDEC  see if can have a method SetCoordinateInput that
00346 //KDDDEC  allows user to provide a coordinate input adapter,
00347 //KDDDEC  and just save it.
00348 
00349   virtual int getDimension() const { return 0; }
00350 
00365   virtual void getRowCoordinatesView(const scalar_t *&coords, int &stride,
00366                                      int dim) const 
00367   {
00368 // KDDDEC THROW AN ERROR INSTEAD OF RETURNING 0.
00369     coords = NULL;
00370     stride = 0;
00371   }
00372 
00387   virtual void getColumnCoordinatesView(const scalar_t *&coords, int &stride,
00388                                         int dim) const 
00389   {
00390     coords = NULL;
00391     stride = 0;
00392   }
00393 
00394 
00396   // Implementations of base-class methods and other methods shared by all
00397 
00401   inline enum MatrixEntityType getPrimaryEntityType() const {
00402     return this->primaryEntityType;
00403   }
00404 
00410   void setPrimaryEntityType(string typestr) {
00411     if (typestr == "row") {
00412       this->primaryEntityType = MATRIX_ROW;
00413     }
00414     else if (typestr == "column") {
00415       this->primaryEntityType = MATRIX_COLUMN;
00416     }
00417     else if (typestr == "nonzero") {
00418       this->primaryEntityType = MATRIX_NONZERO;
00419     }
00420     else {
00421       std::ostringstream emsg;
00422       emsg << __FILE__ << "," << __LINE__
00423            << " error:  Invalid MatrixEntityType " << typestr << std::endl;
00424       emsg << "Valid values are 'row', 'column' and 'nonzero'." << std::endl;
00425       throw std::runtime_error(emsg.str());
00426     }
00427   }
00428 
00429   // Functions from the BaseAdapter interface
00430   size_t getLocalNum() const {
00431     switch (getPrimaryEntityType()) {
00432     case MATRIX_ROW:
00433       return getLocalNumRows();
00434     case MATRIX_COLUMN:
00435       return getLocalNumColumns();
00436     case MATRIX_NONZERO:
00437       return getLocalNumEntries();
00438     default:   // Shouldn't reach default; just making compiler happy
00439       return 0;
00440     }
00441   }
00442 
00443   void getIDsView(const gid_t *&Ids) const {
00444     switch (getPrimaryEntityType()) {
00445     case MATRIX_ROW:
00446       getRowIDsView(Ids);
00447       break;
00448     case MATRIX_COLUMN:
00449       getColumnIDsView(Ids);
00450       break;
00451     case MATRIX_NONZERO: {
00452       // TODO:  Need getNonzeroIDsView?  What is a Nonzero ID?  
00453       // TODO:  std::pair<gid_t, gid_t>?
00454       std::ostringstream emsg;
00455       emsg << __FILE__ << "," << __LINE__
00456            << " error:  getIDsView not yet supported for matrix nonzeros." 
00457            << std::endl;
00458       throw std::runtime_error(emsg.str());
00459       break;
00460       }
00461     default:   // Shouldn't reach default; just making compiler happy
00462       break;
00463     }
00464   }
00465 
00466   int getNumWeightsPerID() const {
00467     switch (getPrimaryEntityType()) {
00468     case MATRIX_ROW:
00469       return getNumWeightsPerRow();
00470     case MATRIX_COLUMN:
00471       return getNumWeightsPerColumn();
00472     case MATRIX_NONZERO:
00473       return 0;  //TODO: weights not yet supported for nonzeros
00474     default:   // Shouldn't reach default; just making compiler happy
00475       return 0;
00476     }
00477   }
00478 
00479   void getWeightsView(const scalar_t *&wgt, int &stride, int idx = 0) const {
00480     switch (getPrimaryEntityType()) {
00481     case MATRIX_ROW:
00482       getRowWeightsView(wgt, stride, idx);
00483       break;
00484     case MATRIX_COLUMN:
00485       getColumnWeightsView(wgt, stride, idx);
00486       break;
00487     case MATRIX_NONZERO:
00488       {
00489       // TODO:  Need getNonzeroWeightsView with Nonzeros as primary object? 
00490       // TODO:  That is, get Nonzeros' weights based on some nonzero ID?
00491       std::ostringstream emsg;
00492       emsg << __FILE__ << "," << __LINE__
00493            << " error:  getWeightsView not yet supported for matrix nonzeros." 
00494            << std::endl;
00495       throw std::runtime_error(emsg.str());
00496       break;
00497       }
00498     default:   // Shouldn't reach default; just making compiler happy
00499       break;
00500     }
00501   }
00502 
00503   void getCoordinatesView(const scalar_t *&coords, int &stride, int dim) const
00504   {
00505     switch (getPrimaryEntityType()) {
00506     case MATRIX_ROW:
00507       getRowCoordinatesView(coords, stride, dim);
00508       break;
00509     case MATRIX_COLUMN:
00510       getColumnCoordinatesView(coords, stride, dim);
00511       break;
00512     case MATRIX_NONZERO: {
00513       // TODO:  Need getCoordinatesView with Nonzeros as primary object? 
00514       // TODO:  Could return (i,j), but need an ordering for nonzeros.
00515       std::ostringstream emsg;
00516       emsg << __FILE__ << "," << __LINE__
00517            << " error:  getCoordinatesView not supported for matrix nonzeros." 
00518            << std::endl;
00519       throw std::runtime_error(emsg.str());
00520       break;
00521       }
00522     default:   // Shouldn't reach default; just making compiler happy
00523       break;
00524     }
00525   }
00526 };
00527   
00528 }  //namespace Zoltan2
00529   
00530 #endif