Zoltan 2 Version 0.5
Zoltan2_IdentifierModel.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_IDENTIFIERMODEL_HPP_
00051 #define _ZOLTAN2_IDENTIFIERMODEL_HPP_
00052 
00053 #include <Zoltan2_Model.hpp>
00054 #include <Zoltan2_MatrixInput.hpp>
00055 #include <Zoltan2_VectorInput.hpp>
00056 #include <Zoltan2_GraphInput.hpp>
00057 #include <Zoltan2_IdentifierInput.hpp>
00058 #include <Zoltan2_CoordinateInput.hpp>
00059 #include <Zoltan2_StridedData.hpp>
00060 
00061 namespace Zoltan2 {
00062 
00081 template <typename Adapter>
00082 class IdentifierModel : public Model<Adapter> 
00083 {
00084 private:
00085 
00086 public:
00087 
00088 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00089   typedef typename Adapter::scalar_t  scalar_t;
00090   typedef typename Adapter::gno_t     gno_t;
00091   typedef typename Adapter::lno_t     lno_t;
00092   typedef StridedData<lno_t, scalar_t> input_t;
00093 #endif
00094   
00095   IdentifierModel(){
00096     throw std::logic_error("a specific instantiation should be used");
00097   }
00098 
00100   // The IdentifierModel interface.
00102 
00105   size_t getLocalNumIdentifiers() const { return 0; }
00106 
00109   global_size_t getGlobalNumIdentifiers() const { return 0; }
00110 
00113   int getIdentifierWeightDim() const { return 0; }
00114 
00126   size_t getIdentifierList(ArrayView<const gno_t>  &Ids,
00127     ArrayView<input_t> &wgts) const {return 0;}
00128 
00130   // The Model interface.
00132 
00133   size_t getLocalNumObjects() const
00134   {
00135     return getLocalNumIdentifiers();
00136   }
00137 
00138   size_t getGlobalNumObjects() const
00139   {
00140     return getGlobalNumIdentifiers();
00141   }
00142 
00143   void getGlobalObjectIds(ArrayView<const gno_t> &gnos) const { return ; }
00144 };
00145 
00146 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00147 
00149 // Identifier model derived from IdentifierInput.
00151 
00152 template <typename User>
00153 class IdentifierModel<IdentifierInput<User> > : public Model<IdentifierInput<User> >
00154 {
00155 public:
00156 
00157   typedef typename IdentifierInput<User>::scalar_t  scalar_t;
00158   typedef typename IdentifierInput<User>::gno_t     gno_t;
00159   typedef typename IdentifierInput<User>::lno_t     lno_t;
00160   typedef typename IdentifierInput<User>::gid_t     gid_t;
00161   typedef IdentifierMap<User> idmap_t;
00162   typedef StridedData<lno_t, scalar_t> input_t;
00163 
00172   IdentifierModel( const IdentifierInput<User> *ia, 
00173     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00174     modelFlag_t &modelFlags);
00175 
00178   size_t getLocalNumIdentifiers() const { return gids_.size(); }
00179 
00182   global_size_t getGlobalNumIdentifiers() const {return numGlobalIdentifiers_;}
00183 
00186   int getIdentifierWeightDim() const { return this->getNumWeights(); }
00187 
00198   size_t getIdentifierList(ArrayView<const gno_t>  &Ids,
00199     ArrayView<input_t> &wgts) const 
00200   {
00201     Ids = ArrayView<const gno_t>();
00202     wgts = weights_.view(0, userWeightDim_);
00203 
00204     size_t n = getLocalNumIdentifiers();
00205     if (n){
00206       if (gnosAreGids_)
00207         Ids = gids_(0, n);
00208       else
00209         Ids = gnosConst_(0, n);
00210     }
00211 
00212     return n;
00213   }
00214 
00216   // The Model interface.
00218 
00219   size_t getLocalNumObjects() const
00220   {
00221     return getLocalNumIdentifiers();
00222   }
00223 
00224   size_t getGlobalNumObjects() const
00225   {
00226     return getGlobalNumIdentifiers();
00227   }
00228 
00229   void getGlobalObjectIds(ArrayView<const gno_t> &gnos) const 
00230   { 
00231     ArrayView<input_t> weights;
00232     getIdentifierList(gnos, weights);
00233   }
00234 
00235 private:
00236 
00237   bool gnosAreGids_;
00238   gno_t numGlobalIdentifiers_;
00239   const RCP<const Environment> env_;
00240   const RCP<const Comm<int> > comm_;
00241   ArrayRCP<const gid_t> gids_;
00242   int userWeightDim_;
00243   ArrayRCP<input_t> weights_;
00244   ArrayRCP<gno_t> gnos_;
00245   ArrayRCP<const gno_t> gnosConst_;
00246 };
00247 
00248 template <typename User>
00249   IdentifierModel<IdentifierInput<User> >::IdentifierModel( 
00250     const IdentifierInput<User> *ia,
00251     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm,
00252     modelFlag_t &modelFlags):
00253       gnosAreGids_(false), numGlobalIdentifiers_(), env_(env), comm_(comm),
00254       gids_(), userWeightDim_(0), weights_(), gnos_(), gnosConst_()
00255 {
00256   userWeightDim_ = ia->getNumberOfWeights();
00257   size_t nLocalIds = ia->getLocalNumberOfIdentifiers();
00258 
00259   Model<IdentifierInput<User> >::maxCount(*comm, userWeightDim_);
00260 
00261   Array<const scalar_t *> wgts(userWeightDim_, (const scalar_t *)NULL);
00262   Array<int> wgtStrides(userWeightDim_, 0);
00263   Array<lno_t> weightArrayLengths(userWeightDim_, 0);
00264 
00265   if (userWeightDim_ > 0){
00266     input_t *w = new input_t [userWeightDim_];
00267     weights_ = arcp<input_t>(w, 0, userWeightDim_);
00268   }
00269 
00270   const gid_t *gids=NULL;
00271 
00272   try{
00273     ia->getIdentifierList(gids);
00274     for (int dim=0; dim < userWeightDim_; dim++)
00275       ia->getIdentifierWeights(dim, wgts[dim], wgtStrides[dim]);
00276   }
00277   Z2_FORWARD_EXCEPTIONS;
00278 
00279   if (nLocalIds){
00280     gids_ = arcp(gids, 0, nLocalIds, false);
00281 
00282     if (userWeightDim_ > 0){
00283       for (int i=0; i < userWeightDim_; i++){
00284         if (wgts[i] != NULL){
00285           ArrayRCP<const scalar_t> wgtArray(
00286             wgts[i], 0, nLocalIds*wgtStrides[i], false);
00287           weights_[i] = input_t(wgtArray, wgtStrides[i]);
00288           weightArrayLengths[i] = nLocalIds;
00289         }
00290       }
00291     }
00292   }
00293 
00294   this->setWeightArrayLengths(weightArrayLengths, *comm_);
00295 
00296   RCP<const idmap_t> idMap;
00297 
00298   try{
00299     if (modelFlags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE))
00300       idMap = rcp(new idmap_t(env_, comm_, gids_, true));
00301     else
00302       idMap = rcp(new idmap_t(env_, comm_, gids_, false));
00303   }
00304   Z2_FORWARD_EXCEPTIONS;
00305 
00306   gnosAreGids_ = idMap->gnosAreGids();
00307 
00308   this->setIdentifierMap(idMap);
00309 
00310   gno_t lsum = nLocalIds;
00311   reduceAll<int, gno_t>(*comm_, Teuchos::REDUCE_SUM, 1, &lsum,
00312     &numGlobalIdentifiers_);
00313 
00314   if (!gnosAreGids_ && nLocalIds>0){
00315     gno_t *tmpGno = new gno_t [nLocalIds];
00316     env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno);
00317     gnos_ = arcp(tmpGno, 0, nLocalIds);
00318 
00319     try{
00320       ArrayRCP<gid_t> gidsNonConst = arcp_const_cast<gid_t>(gids_);
00321       idMap->gidTranslate( gidsNonConst(0,nLocalIds),  gnos_(0,nLocalIds),
00322         TRANSLATE_APP_TO_LIB);
00323     }
00324     Z2_FORWARD_EXCEPTIONS;
00325   }
00326 
00327   gnosConst_ = arcp_const_cast<const gno_t>(gnos_);
00328 
00329   env_->memory("After construction of identifier model");
00330 }
00331 
00333 // Identifier model derived from CoordinateInput.
00335 
00336 template <typename User>
00337   class IdentifierModel<CoordinateInput<User> > : 
00338     public Model<CoordinateInput<User> >
00339 {
00340 public:
00341 
00342   typedef typename CoordinateInput<User>::scalar_t  scalar_t;
00343   typedef typename CoordinateInput<User>::gno_t     gno_t;
00344   typedef typename CoordinateInput<User>::lno_t     lno_t;
00345   typedef typename CoordinateInput<User>::gid_t     gid_t;
00346   typedef IdentifierMap<User> idmap_t;
00347   typedef StridedData<lno_t, scalar_t> input_t;
00348   
00349   IdentifierModel( const CoordinateInput<User> *ia, 
00350     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00351     modelFlag_t &modelFlags);
00352 
00355   size_t getLocalNumIdentifiers() const { return gids_.size(); }
00356 
00359   global_size_t getGlobalNumIdentifiers() const {return numGlobalIdentifiers_;}
00360 
00363   int getIdentifierWeightDim() const { return this->getNumWeights();}
00364 
00375   size_t getIdentifierList(ArrayView<const gno_t>  &Ids,
00376     ArrayView<input_t> &wgts) const            
00377   {
00378     Ids = ArrayView<const gno_t>();
00379     wgts = weights_.view(0, userWeightDim_);
00380 
00381     size_t n = getLocalNumIdentifiers();
00382     if (n){
00383       if (gnosAreGids_)
00384         Ids = gids_(0, n);
00385       else
00386         Ids = gnosConst_(0, n);
00387     }
00388 
00389     return n;
00390   }
00391 
00393   // The Model interface.
00395 
00396   size_t getLocalNumObjects() const
00397   {
00398     return getLocalNumIdentifiers();
00399   }
00400 
00401   size_t getGlobalNumObjects() const
00402   {
00403     return getGlobalNumIdentifiers();
00404   }
00405 
00406   void getGlobalObjectIds(ArrayView<const gno_t> &gnos) const 
00407   { 
00408     ArrayView<input_t> weights;
00409     getIdentifierList(gnos, weights);
00410   }
00411 
00412 private:
00413 
00414   bool gnosAreGids_;
00415   gno_t numGlobalIdentifiers_;
00416   const RCP<const Environment> env_;
00417   const RCP<const Comm<int> > comm_;
00418   ArrayRCP<const gid_t> gids_;
00419   int userWeightDim_;
00420   ArrayRCP<input_t> weights_;
00421   ArrayRCP<gno_t> gnos_;
00422   ArrayRCP<const gno_t> gnosConst_;
00423 };
00424 
00425 template <typename User>
00426   IdentifierModel<CoordinateInput<User> >::IdentifierModel( 
00427     const CoordinateInput<User> *ia, 
00428     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00429     modelFlag_t &modelFlags):
00430       gnosAreGids_(false), numGlobalIdentifiers_(), env_(env), comm_(comm),
00431       gids_(), userWeightDim_(0), weights_(), gnos_(), gnosConst_()
00432 {
00434   // Get global IDs.
00435 
00436   size_t nLocalIds = ia->getLocalNumberOfCoordinates();
00437   const gid_t *gids=NULL;
00438 
00439   if (nLocalIds > 0){
00440     try{
00441       size_t coordListSize; 
00442       const scalar_t *coords;
00443       int stride;
00444       coordListSize = ia->getCoordinates(0, gids, coords, stride);
00445     }
00446     Z2_FORWARD_EXCEPTIONS;
00447 
00448     gids_ = arcp(gids, 0, nLocalIds, false);
00449   }
00450 
00451   RCP<const idmap_t> idMap;
00452 
00453   try{
00454     if (modelFlags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE) )
00455       idMap = rcp(new idmap_t(env_, comm_, gids_, true));
00456     else
00457       idMap = rcp(new idmap_t(env_, comm_, gids_, false));
00458   }
00459   Z2_FORWARD_EXCEPTIONS;
00460 
00461   numGlobalIdentifiers_ = idMap->getGlobalNumberOfIds();
00462   gnosAreGids_ = idMap->gnosAreGids();
00463   this->setIdentifierMap(idMap);   // Base Model method
00464 
00466   // Get weights.
00467 
00468   userWeightDim_ = ia->getNumberOfWeights();
00469   Array<lno_t> weightListSizes(userWeightDim_, 0);
00470 
00471   Model<CoordinateInput<User> >::maxCount(*comm, userWeightDim_);
00472 
00473   if (userWeightDim_ > 0){
00474     input_t *weightObj = new input_t [userWeightDim_];
00475     weights_ = arcp(weightObj, 0, userWeightDim_);
00476 
00477     if (nLocalIds > 0){
00478       const scalar_t *wgts=NULL;
00479       int stride = 0;
00480       size_t wgtListSize;
00481 
00482       for (int wdim=0; wdim < userWeightDim_; wdim++){
00483         wgtListSize = ia->getCoordinateWeights(wdim, wgts, stride);
00484 
00485         if (wgtListSize > 0){  // non-uniform weights
00486           ArrayRCP<const scalar_t> wgtArray(wgts, 0, wgtListSize, false);
00487           weightObj[wdim] = StridedData<lno_t, scalar_t>(wgtArray, stride);
00488           weightListSizes[wdim] = wgtListSize;
00489         }
00490       }
00491     }
00492   }
00493 
00494   this->setWeightArrayLengths(weightListSizes, *comm_);
00495 
00497   // Get internal global numbers if necessary.
00498 
00499   if (!gnosAreGids_ && nLocalIds>0){
00500     gno_t *tmpGno = new gno_t [nLocalIds];
00501     env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno);
00502     gnos_ = arcp(tmpGno, 0, gids_.size());
00503 
00504     try{
00505      ArrayRCP<gid_t> gidsNonConst = arcp_const_cast<gid_t>(gids_);
00506      idMap->gidTranslate(gidsNonConst(0, nLocalIds), gnos_(0, nLocalIds), 
00507        TRANSLATE_APP_TO_LIB);
00508     }
00509     Z2_FORWARD_EXCEPTIONS;
00510   }
00511 
00512   gnosConst_ = arcp_const_cast<const gno_t>(gnos_);
00513   env_->memory("After construction of identifier model");
00514 }
00515 
00516 
00518 // Identifier model derived from MatrixInput.
00520 
00521 template <typename User>
00522 class IdentifierModel<MatrixInput<User> > : public Model<MatrixInput<User> >
00523 {
00524 public:
00525 
00526   typedef typename MatrixInput<User>::scalar_t  scalar_t;
00527   typedef typename MatrixInput<User>::gno_t     gno_t;
00528   typedef typename MatrixInput<User>::lno_t     lno_t;
00529   typedef typename MatrixInput<User>::gid_t     gid_t;
00530   typedef IdentifierMap<User> idmap_t;
00531   typedef StridedData<lno_t, scalar_t> input_t;
00532   
00533   IdentifierModel( const MatrixInput<User> *ia, 
00534     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00535     modelFlag_t &modelFlags);
00536 
00539   size_t getLocalNumIdentifiers() const { return gids_.size(); }
00540 
00543   global_size_t getGlobalNumIdentifiers() const {return numGlobalIdentifiers_;}
00544 
00548   int getIdentifierWeightDim() const { return 0; }
00549 
00560   size_t getIdentifierList(ArrayView<const gno_t>  &Ids,
00561     ArrayView<input_t> &wgts) const            
00562   {
00563     Ids = ArrayView<const gno_t>();
00564     wgts = weights_.view(0, userWeightDim_);
00565 
00566     size_t n = getLocalNumIdentifiers();
00567     if (n){
00568       if (gnosAreGids_)
00569         Ids = gids_(0, n);
00570       else
00571         Ids = gnosConst_(0, n);
00572     }
00573 
00574     return n;
00575   }
00576 
00578   // The Model interface.
00580 
00581   size_t getLocalNumObjects() const
00582   {
00583     return getLocalNumIdentifiers();
00584   }
00585 
00586   size_t getGlobalNumObjects() const
00587   {
00588     return getGlobalNumIdentifiers();
00589   }
00590 
00591   void getGlobalObjectIds(ArrayView<const gno_t> &gnos) const 
00592   { 
00593     ArrayView<input_t> weights;
00594     getIdentifierList(gnos, weights);
00595   }
00596 
00597 private:
00598 
00599   bool gnosAreGids_;
00600   gno_t numGlobalIdentifiers_;
00601   const RCP<const Environment> env_;
00602   const RCP<const Comm<int> > comm_;
00603   ArrayRCP<const gid_t> gids_;
00604   int userWeightDim_;
00605   ArrayRCP<input_t> weights_;
00606   ArrayRCP<gno_t> gnos_;
00607   ArrayRCP<const gno_t> gnosConst_;
00608 };
00609 
00610   
00611 template <typename User>
00612   IdentifierModel<MatrixInput<User> >::IdentifierModel( 
00613     const MatrixInput<User> *ia, 
00614     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00615     modelFlag_t &modelFlags):
00616       gnosAreGids_(false), numGlobalIdentifiers_(), env_(env), comm_(comm),
00617       gids_(), userWeightDim_(0), weights_(), gnos_(), gnosConst_()
00618 {
00619   size_t nLocalIds;
00620   const gid_t *gids;
00621   const gid_t *colIds;
00622   const lno_t *offsets;
00623 
00624   try{
00625     nLocalIds = ia->getRowListView(gids, offsets, colIds);
00626   }
00627   Z2_FORWARD_EXCEPTIONS;
00628 
00629   if (nLocalIds){
00630     gids_ = arcp(gids, 0, nLocalIds, false);
00631   }
00632 
00633   RCP<const idmap_t> idMap;
00634 
00635   try{
00636     if (modelFlags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE) )
00637       idMap = rcp(new idmap_t(env_, comm_, gids_, true));
00638     else
00639       idMap = rcp(new idmap_t(env_, comm_, gids_, false));
00640   }
00641   Z2_FORWARD_EXCEPTIONS;
00642 
00643   numGlobalIdentifiers_ = idMap->getGlobalNumberOfIds();
00644   gnosAreGids_ = idMap->gnosAreGids();
00645 
00646   this->setIdentifierMap(idMap);   // Base Model methods
00647   Array<lno_t> weightListSizes;
00648   this->setWeightArrayLengths(weightListSizes, *comm_);
00649 
00650   if (!gnosAreGids_ && nLocalIds>0){
00651     gno_t *tmpGno = new gno_t [nLocalIds];
00652     env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno);
00653     gnos_ = arcp(tmpGno, 0, gids_.size());
00654 
00655     try{
00656      ArrayRCP<gid_t> gidsNonConst = arcp_const_cast<gid_t>(gids_);
00657       idMap->gidTranslate(gidsNonConst(0, nLocalIds),
00658         gnos_(0, nLocalIds), TRANSLATE_APP_TO_LIB);
00659     }
00660     Z2_FORWARD_EXCEPTIONS;
00661   }
00662 
00663   gnosConst_ = arcp_const_cast<const gno_t>(gnos_);
00664   env_->memory("After construction of identifier model");
00665 }
00666 
00668 // Identifier model derived from VectorInput.
00670 
00671 template <typename User>
00672 class IdentifierModel<VectorInput<User> > : public Model<VectorInput<User> >
00673 {
00674 public:
00675 
00676   typedef typename VectorInput<User>::scalar_t  scalar_t;
00677   typedef typename VectorInput<User>::gno_t     gno_t;
00678   typedef typename VectorInput<User>::lno_t     lno_t;
00679   typedef typename VectorInput<User>::gid_t     gid_t;
00680   typedef IdentifierMap<User> idmap_t;
00681   typedef StridedData<lno_t, scalar_t> input_t;
00682   
00683   IdentifierModel( const VectorInput<User> *ia, 
00684     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00685     modelFlag_t &modelFlags);
00686 
00689   size_t getLocalNumIdentifiers() const { return gids_.size(); }
00690 
00693   global_size_t getGlobalNumIdentifiers() const {return numGlobalIdentifiers_;}
00694 
00698   int getIdentifierWeightDim() const { return 0; }
00699 
00710   size_t getIdentifierList(ArrayView<const gno_t>  &Ids,
00711     ArrayView<input_t> &wgts) const            
00712   {
00713     Ids = ArrayView<const gno_t>();
00714     wgts = weights_.view(0, userWeightDim_);
00715 
00716     size_t n = getLocalNumIdentifiers();
00717     if (n){
00718       if (gnosAreGids_)
00719         Ids = gids_(0, n);
00720       else
00721         Ids = gnosConst_(0, n);
00722     }
00723 
00724     return n;
00725   }
00726 
00728   // The Model interface.
00730 
00731   size_t getLocalNumObjects() const
00732   {
00733     return getLocalNumIdentifiers();
00734   }
00735 
00736   size_t getGlobalNumObjects() const
00737   {
00738     return getGlobalNumIdentifiers();
00739   }
00740 
00741   void getGlobalObjectIds(ArrayView<const gno_t> &gnos) const 
00742   { 
00743     ArrayView<input_t> weights;
00744     getIdentifierList(gnos, weights);
00745   }
00746 
00747 private:
00748 
00749   bool gnosAreGids_;
00750   gno_t numGlobalIdentifiers_;
00751   const RCP<const Environment> env_;
00752   const RCP<const Comm<int> > comm_;
00753   ArrayRCP<const gid_t> gids_;
00754   int userWeightDim_;
00755   ArrayRCP<input_t> weights_;
00756   ArrayRCP<gno_t> gnos_;
00757   ArrayRCP<const gno_t> gnosConst_;
00758 };
00759 
00760   
00761 template <typename User>
00762   IdentifierModel<VectorInput<User> >::IdentifierModel( 
00763     const VectorInput<User> *ia, 
00764     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00765     modelFlag_t &modelFlags):
00766       gnosAreGids_(false), numGlobalIdentifiers_(), env_(env), comm_(comm),
00767       gids_(), userWeightDim_(0), weights_(), gnos_(), gnosConst_()
00768 {
00769   size_t nLocalIds;
00770   const gid_t *gids;
00771   const scalar_t *elements;
00772   int stride;
00773 
00774   try{
00775     nLocalIds = ia->getVector(gids, elements, stride);
00776   }
00777   Z2_FORWARD_EXCEPTIONS;
00778 
00779   if (nLocalIds){
00780     gids_ = arcp(gids, 0, nLocalIds, false);
00781   }
00782 
00783   RCP<const idmap_t> idMap;
00784 
00785   try{
00786     if (modelFlags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE) )
00787       idMap = rcp(new idmap_t(env_, comm_, gids_, true));
00788     else
00789       idMap = rcp(new idmap_t(env_, comm_, gids_, false));
00790   }
00791   Z2_FORWARD_EXCEPTIONS;
00792 
00793   numGlobalIdentifiers_ = idMap->getGlobalNumberOfIds();
00794   gnosAreGids_ = idMap->gnosAreGids();
00795 
00796   this->setIdentifierMap(idMap);   // Base Model methods
00797   Array<lno_t> weightListSizes;
00798   this->setWeightArrayLengths(weightListSizes, *comm_);
00799 
00800   if (!gnosAreGids_ && nLocalIds>0){
00801     gno_t *tmpGno = new gno_t [nLocalIds];
00802     env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno);
00803     gnos_ = arcp(tmpGno, 0, gids_.size());
00804 
00805     try{
00806      ArrayRCP<gid_t> gidsNonConst = arcp_const_cast<gid_t>(gids_);
00807       idMap->gidTranslate(gidsNonConst(0, nLocalIds),
00808         gnos_(0, nLocalIds), TRANSLATE_APP_TO_LIB);
00809     }
00810     Z2_FORWARD_EXCEPTIONS;
00811   }
00812 
00813   gnosConst_ = arcp_const_cast<const gno_t>(gnos_);
00814   env_->memory("After construction of identifier model");
00815 }
00816 
00818 // Identifier model derived from GraphInput.
00820 
00821 template <typename User>
00822 class IdentifierModel<GraphInput<User> > : public Model<GraphInput<User> >
00823 {
00824 public:
00825 
00826   typedef typename GraphInput<User>::scalar_t  scalar_t;
00827   typedef typename GraphInput<User>::gno_t     gno_t;
00828   typedef typename GraphInput<User>::lno_t     lno_t;
00829   typedef typename GraphInput<User>::gid_t     gid_t;
00830   typedef IdentifierMap<User> idmap_t;
00831   typedef StridedData<lno_t, scalar_t> input_t;
00832 
00841   IdentifierModel( const GraphInput<User> *ia, 
00842     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, 
00843     modelFlag_t &modelFlags);
00844 
00847   size_t getLocalNumIdentifiers() const { return gids_.size(); }
00848 
00851   global_size_t getGlobalNumIdentifiers() const {return numGlobalIdentifiers_;}
00852 
00855   int getIdentifierWeightDim() const { return this->getNumWeights(); }
00856 
00867   size_t getIdentifierList(ArrayView<const gno_t>  &Ids,
00868     ArrayView<input_t> &wgts) const 
00869   {
00870     Ids = ArrayView<const gno_t>();
00871     wgts = weights_.view(0, userWeightDim_);
00872 
00873     size_t n = getLocalNumIdentifiers();
00874     if (n){
00875       if (gnosAreGids_)
00876         Ids = gids_(0, n);
00877       else
00878         Ids = gnosConst_(0, n);
00879     }
00880 
00881     return n;
00882   }
00883 
00885   // The Model interface.
00887 
00888   size_t getLocalNumObjects() const
00889   {
00890     return getLocalNumIdentifiers();
00891   }
00892 
00893   size_t getGlobalNumObjects() const
00894   {
00895     return getGlobalNumIdentifiers();
00896   }
00897 
00898   void getGlobalObjectIds(ArrayView<const gno_t> &gnos) const 
00899   { 
00900     ArrayView<input_t> weights;
00901     getIdentifierList(gnos, weights);
00902   }
00903 
00904 private:
00905 
00906   bool gnosAreGids_;
00907   gno_t numGlobalIdentifiers_;
00908   const RCP<const Environment> env_;
00909   const RCP<const Comm<int> > comm_;
00910   ArrayRCP<const gid_t> gids_;
00911   int userWeightDim_;
00912   ArrayRCP<input_t> weights_;
00913   ArrayRCP<gno_t> gnos_;
00914   ArrayRCP<const gno_t> gnosConst_;
00915 };
00916 
00917 template <typename User>
00918   IdentifierModel<GraphInput<User> >::IdentifierModel( 
00919     const GraphInput<User> *ia,
00920     const RCP<const Environment> &env, const RCP<const Comm<int> > &comm,
00921     modelFlag_t &modelFlags):
00922       gnosAreGids_(false), numGlobalIdentifiers_(), env_(env), comm_(comm),
00923       gids_(), userWeightDim_(0), weights_(), gnos_(), gnosConst_()
00924 {
00925   userWeightDim_ = ia->getVertexWeightDimension();
00926   size_t nLocalIds = ia->getLocalNumberOfVertices();
00927 
00928   Model<GraphInput<User> >::maxCount(*comm, userWeightDim_);
00929 
00930   Array<const scalar_t *> wgts(userWeightDim_, NULL);
00931   Array<int> wgtStrides(userWeightDim_, 0);
00932   Array<lno_t> weightArrayLengths(userWeightDim_, 0);
00933 
00934   if (userWeightDim_ > 0){
00935     input_t *w = new input_t [userWeightDim_];
00936     weights_ = arcp<input_t>(w, 0, userWeightDim_);
00937   }
00938 
00939   const gid_t *gids=NULL;
00940 
00941   try{
00942     const lno_t *offsets;
00943     const gid_t *nbors;
00944     ia->getVertexListView(gids, offsets, nbors);
00945     for (int dim=0; dim < userWeightDim_; dim++)
00946       ia->getVertexWeights(dim, wgts[dim], wgtStrides[dim]);
00947   }
00948   Z2_FORWARD_EXCEPTIONS;
00949 
00950   if (nLocalIds){
00951     gids_ = arcp(gids, 0, nLocalIds, false);
00952 
00953     if (userWeightDim_ > 0){
00954       for (int i=0; i < userWeightDim_; i++){
00955         if (wgts[i] != NULL){
00956           ArrayRCP<const scalar_t> wgtArray(
00957             wgts[i], 0, nLocalIds*wgtStrides[i], false);
00958           weights_[i] = input_t(wgtArray, wgtStrides[i]);
00959           weightArrayLengths[i] = nLocalIds;
00960         }
00961       }
00962     }
00963   }
00964 
00965   this->setWeightArrayLengths(weightArrayLengths, *comm_);
00966 
00967   RCP<const idmap_t> idMap;
00968 
00969   try{
00970     if (modelFlags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE))
00971       idMap = rcp(new idmap_t(env_, comm_, gids_, true));
00972     else
00973       idMap = rcp(new idmap_t(env_, comm_, gids_, false));
00974   }
00975   Z2_FORWARD_EXCEPTIONS;
00976 
00977   gnosAreGids_ = idMap->gnosAreGids();
00978 
00979   this->setIdentifierMap(idMap);
00980 
00981   gno_t lsum = nLocalIds;
00982   reduceAll<int, gno_t>(*comm_, Teuchos::REDUCE_SUM, 1, &lsum,
00983     &numGlobalIdentifiers_);
00984 
00985   if (!gnosAreGids_ && nLocalIds>0){
00986     gno_t *tmpGno = new gno_t [nLocalIds];
00987     env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno);
00988     gnos_ = arcp(tmpGno, 0, nLocalIds);
00989 
00990     try{
00991       ArrayRCP<gid_t> gidsNonConst = arcp_const_cast<gid_t>(gids_);
00992       idMap->gidTranslate( gidsNonConst(0,nLocalIds),  gnos_(0,nLocalIds),
00993         TRANSLATE_APP_TO_LIB);
00994     }
00995     Z2_FORWARD_EXCEPTIONS;
00996   }
00997 
00998   gnosConst_ = arcp_const_cast<const gno_t>(gnos_);
00999 
01000   env_->memory("After construction of identifier model");
01001 }
01002 
01003 #endif // DOXYGEN_SHOULD_SKIP_THIS
01004 
01005 }  // namespace Zoltan2
01006 
01007 #endif