|
Zoltan2
|
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_Adapter.hpp> 00055 #include <Zoltan2_StridedData.hpp> 00056 00057 namespace Zoltan2 { 00058 00069 template <typename Adapter> 00070 class IdentifierModel : public Model<Adapter> 00071 { 00072 public: 00073 00074 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00075 typedef typename Adapter::scalar_t scalar_t; 00076 typedef typename Adapter::gno_t gno_t; 00077 typedef typename Adapter::lno_t lno_t; 00078 typedef typename Adapter::zgid_t zgid_t; 00079 typedef IdentifierMap<typename Adapter::user_t> idmap_t; 00080 typedef StridedData<lno_t, scalar_t> input_t; 00081 #endif 00082 00090 IdentifierModel(const Adapter *ia, const RCP<const Environment> &env, 00091 const RCP<const Comm<int> > &comm, modelFlag_t &modelFlags); 00092 00095 inline size_t getLocalNumIdentifiers() const { return gids_.size(); } 00096 00099 inline global_size_t getGlobalNumIdentifiers() const { 00100 return numGlobalIdentifiers_; 00101 } 00102 00111 inline size_t getIdentifierList(ArrayView<const gno_t> &Ids, 00112 ArrayView<input_t> &wgts) const 00113 { 00114 Ids = ArrayView<const gno_t>(); 00115 wgts = weights_.view(0, nUserWeights_); 00116 size_t n = getLocalNumIdentifiers(); 00117 if (n){ 00118 if (gnosAreGids_) 00119 Ids = ArrayView<const gno_t>( 00120 reinterpret_cast<const gno_t*>(gids_.getRawPtr()), n); 00121 else 00122 Ids = gnosConst_(0, n); 00123 } 00124 return n; 00125 } 00126 00128 // The Model interface. 00130 00131 inline size_t getLocalNumObjects() const {return getLocalNumIdentifiers();} 00132 00133 inline size_t getGlobalNumObjects() const {return getGlobalNumIdentifiers();} 00134 00135 private: 00136 00137 bool gnosAreGids_; 00138 gno_t numGlobalIdentifiers_; 00139 const RCP<const Environment> env_; 00140 const RCP<const Comm<int> > comm_; 00141 ArrayRCP<const zgid_t> gids_; 00142 int nUserWeights_; 00143 ArrayRCP<input_t> weights_; 00144 ArrayRCP<gno_t> gnos_; 00145 ArrayRCP<const gno_t> gnosConst_; 00146 }; 00147 00149 template <typename Adapter> 00150 IdentifierModel<Adapter>::IdentifierModel( 00151 const Adapter *ia, 00152 const RCP<const Environment> &env, 00153 const RCP<const Comm<int> > &comm, 00154 modelFlag_t &modelFlags): 00155 gnosAreGids_(false), numGlobalIdentifiers_(), env_(env), comm_(comm), 00156 gids_(), nUserWeights_(0), weights_(), gnos_(), gnosConst_() 00157 { 00158 // Get the local and global problem size 00159 size_t nLocalIds = ia->getLocalNumIDs(); 00160 gno_t lsum = nLocalIds; 00161 reduceAll<int, gno_t>(*comm_, Teuchos::REDUCE_SUM, 1, &lsum, 00162 &numGlobalIdentifiers_); 00163 00164 // Get the number of weights 00165 // Use max number of weights over all processes as nUserWeights_ 00166 int tmp = ia->getNumWeightsPerID(); 00167 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, 1, 00168 &tmp, &nUserWeights_); 00169 00170 // Prepare to store views from input adapter 00171 // TODO: Do we have to store these views, or can we get them on an 00172 // TODO: as-needed basis? 00173 Array<const scalar_t *> wgts(nUserWeights_, (const scalar_t *)NULL); 00174 Array<int> wgtStrides(nUserWeights_, 0); 00175 00176 if (nUserWeights_ > 0){ 00177 input_t *w = new input_t [nUserWeights_]; 00178 weights_ = arcp<input_t>(w, 0, nUserWeights_); 00179 } 00180 00181 const zgid_t *gids=NULL; 00182 00183 // Get the input adapter's views 00184 try{ 00185 ia->getIDsView(gids); 00186 for (int idx=0; idx < nUserWeights_; idx++) 00187 ia->getWeightsView(wgts[idx], wgtStrides[idx], idx); 00188 } 00189 Z2_FORWARD_EXCEPTIONS; 00190 00191 if (nLocalIds){ 00192 gids_ = arcp(gids, 0, nLocalIds, false); 00193 00194 if (nUserWeights_ > 0){ 00195 for (int idx=0; idx < nUserWeights_; idx++){ 00196 ArrayRCP<const scalar_t> wgtArray(wgts[idx], 0, 00197 nLocalIds*wgtStrides[idx], false); 00198 weights_[idx] = input_t(wgtArray, wgtStrides[idx]); 00199 } 00200 } 00201 } 00202 00203 00204 // TODO: Why does an IdentifierModel need an IdentifierMap? 00205 // TODO: Currently is useful only if zgid_t is not Teuchos::Ordinal 00206 RCP<const idmap_t> idMap; 00207 try{ 00208 if (modelFlags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE)) 00209 idMap = rcp(new idmap_t(env_, comm_, gids_, true)); 00210 else 00211 idMap = rcp(new idmap_t(env_, comm_, gids_, false)); 00212 } 00213 Z2_FORWARD_EXCEPTIONS; 00214 00215 gnosAreGids_ = idMap->gnosAreGids(); 00216 00217 this->setIdentifierMap(idMap); 00218 00219 if (!gnosAreGids_ && nLocalIds>0){ 00220 gno_t *tmpGno = new gno_t [nLocalIds]; 00221 env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno); 00222 gnos_ = arcp(tmpGno, 0, nLocalIds); 00223 00224 try{ 00225 ArrayRCP<zgid_t> gidsNonConst = arcp_const_cast<zgid_t>(gids_); 00226 idMap->gidTranslate( gidsNonConst(0,nLocalIds), gnos_(0,nLocalIds), 00227 TRANSLATE_APP_TO_LIB); 00228 } 00229 Z2_FORWARD_EXCEPTIONS; 00230 } 00231 00232 gnosConst_ = arcp_const_cast<const gno_t>(gnos_); 00233 00234 env_->memory("After construction of identifier model"); 00235 } 00236 00237 } // namespace Zoltan2 00238 00239 #endif
1.7.6.1