|
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 00051 #ifndef _ZOLTAN2_COORDINATEMODEL_HPP_ 00052 #define _ZOLTAN2_COORDINATEMODEL_HPP_ 00053 00054 // disable clang warnings 00055 #ifdef __clang__ 00056 #pragma clang system_header 00057 #endif 00058 00059 #include <Zoltan2_Model.hpp> 00060 #include <Zoltan2_MeshAdapter.hpp> 00061 #include <Zoltan2_MatrixAdapter.hpp> 00062 #include <Zoltan2_GraphAdapter.hpp> 00063 #include <Zoltan2_IdentifierAdapter.hpp> 00064 #include <Zoltan2_VectorAdapter.hpp> 00065 #include <Zoltan2_StridedData.hpp> 00066 00067 namespace Zoltan2 { 00068 00075 template <typename Adapter> 00076 class CoordinateModel : public Model<Adapter> 00077 { 00078 public: 00079 00080 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00081 typedef typename Adapter::scalar_t scalar_t; 00082 typedef typename Adapter::gno_t gno_t; 00083 typedef typename Adapter::zgid_t zgid_t; 00084 typedef typename Adapter::lno_t lno_t; 00085 typedef typename Adapter::user_t user_t; 00086 typedef typename Adapter::userCoord_t userCoord_t; 00087 typedef StridedData<lno_t, scalar_t> input_t; 00088 typedef IdentifierMap<user_t> idmap_t; 00089 #endif 00090 00092 // Constructors for each Adapter type 00094 00095 // VectorAdapter 00096 CoordinateModel(const VectorAdapter<user_t> *ia, 00097 const RCP<const Environment> &env, 00098 const RCP<const Comm<int> > &comm, 00099 modelFlag_t &flags): 00100 gnosAreGids_(false), numGlobalCoordinates_(), env_(env), comm_(comm), 00101 coordinateDim_(), gids_(), xyz_(), userNumWeights_(0), weights_(), 00102 gnos_(), gnosConst_() 00103 { 00104 typedef VectorAdapter<user_t> adapterWithCoords_t; 00105 sharedConstructor<adapterWithCoords_t>(ia, env, comm, flags); 00106 } 00107 00108 // MatrixAdapter 00109 CoordinateModel(const MatrixAdapter<user_t,userCoord_t> *ia, 00110 const RCP<const Environment> &env, 00111 const RCP<const Comm<int> > &comm, 00112 modelFlag_t &flags) : 00113 gnosAreGids_(false), numGlobalCoordinates_(), 00114 env_(env), comm_(comm), 00115 coordinateDim_(), gids_(), xyz_(), 00116 userNumWeights_(0), weights_(), 00117 gnos_(), gnosConst_() 00118 { 00119 if (!(ia->coordinatesAvailable())) 00120 throw std::logic_error("No coordinate info provided to MatrixAdapter."); 00121 else { 00122 typedef VectorAdapter<userCoord_t> adapterWithCoords_t; 00123 adapterWithCoords_t *va = ia->getCoordinateInput(); 00124 sharedConstructor<adapterWithCoords_t>(va, env, comm, flags); 00125 } 00126 } 00127 00128 // GraphAdapter 00129 CoordinateModel(const GraphAdapter<user_t,userCoord_t> *ia, 00130 const RCP<const Environment> &env, 00131 const RCP<const Comm<int> > &comm, 00132 modelFlag_t &flags) : 00133 gnosAreGids_(false), numGlobalCoordinates_(), 00134 env_(env), comm_(comm), 00135 coordinateDim_(), gids_(), xyz_(), 00136 userNumWeights_(0), weights_(), 00137 gnos_(), gnosConst_() 00138 { 00139 if (!(ia->coordinatesAvailable())) 00140 throw std::logic_error("No coordinate info provided to GraphAdapter."); 00141 else { 00142 typedef VectorAdapter<userCoord_t> adapterWithCoords_t; 00143 adapterWithCoords_t *va = ia->getCoordinateInput(); 00144 sharedConstructor<adapterWithCoords_t>(va, env, comm, flags); 00145 } 00146 } 00147 00148 // MeshAdapter 00149 CoordinateModel(const MeshAdapter<user_t> *ia, 00150 const RCP<const Environment> &env, 00151 const RCP<const Comm<int> > &comm, 00152 modelFlag_t &flags) : 00153 gnosAreGids_(false), numGlobalCoordinates_(), env_(env), comm_(comm), 00154 coordinateDim_(), gids_(), xyz_(), userNumWeights_(0), weights_(), 00155 gnos_(), gnosConst_() 00156 { 00157 typedef MeshAdapter<user_t> adapterWithCoords_t; 00158 sharedConstructor<adapterWithCoords_t>(ia, env, comm, flags); 00159 } 00160 00161 // IdentifierAdapter 00162 CoordinateModel(const IdentifierAdapter<user_t> *ia, 00163 const RCP<const Environment> &env, 00164 const RCP<const Comm<int> > &comm, 00165 modelFlag_t &flags) 00166 { 00167 throw std::logic_error( 00168 "A coordinate model can not be build from an IdentifierAdapter"); 00169 } 00170 00172 // CoordinateModel interface. 00174 00177 int getCoordinateDim() const { return coordinateDim_;} 00178 00181 size_t getLocalNumCoordinates() const { return gids_.size();} 00182 00185 global_size_t getGlobalNumCoordinates() const {return numGlobalCoordinates_;} 00186 00189 int getNumWeightsPerCoordinate() const { return userNumWeights_;} 00190 00213 size_t getCoordinates(ArrayView<const gno_t> &Ids, 00214 ArrayView<input_t> &xyz, 00215 ArrayView<input_t> &wgts) const 00216 { 00217 xyz = xyz_.view(0, coordinateDim_); 00218 wgts = weights_.view(0, userNumWeights_); 00219 00220 size_t nCoord = getLocalNumCoordinates(); 00221 Ids = ArrayView<const gno_t>(); 00222 00223 if (nCoord){ 00224 if (gnosAreGids_) 00225 Ids = Teuchos::arrayView<const gno_t>( 00226 reinterpret_cast<const gno_t *>(gids_.getRawPtr()), nCoord); 00227 else 00228 Ids = gnosConst_.view(0, nCoord); 00229 } 00230 00231 return nCoord; 00232 } 00233 00235 // The Model interface. 00237 00238 size_t getLocalNumObjects() const 00239 { 00240 return getLocalNumCoordinates(); 00241 } 00242 00243 size_t getGlobalNumObjects() const 00244 { 00245 return getGlobalNumCoordinates(); 00246 } 00247 00248 private: 00249 bool gnosAreGids_; 00250 gno_t numGlobalCoordinates_; 00251 const RCP<const Environment> env_; 00252 const RCP<const Comm<int> > comm_; 00253 int coordinateDim_; 00254 ArrayRCP<const zgid_t> gids_; 00255 ArrayRCP<input_t> xyz_; 00256 int userNumWeights_; 00257 ArrayRCP<input_t> weights_; 00258 ArrayRCP<gno_t> gnos_; 00259 ArrayRCP<const gno_t> gnosConst_; 00260 00261 template <typename AdapterWithCoords> 00262 void sharedConstructor(const AdapterWithCoords *ia, 00263 const RCP<const Environment> &env, 00264 const RCP<const Comm<int> > &comm, 00265 modelFlag_t &flags); 00266 00267 }; 00268 00269 00271 00272 // sharedConstructor 00273 template <typename Adapter> 00274 template <typename AdapterWithCoords> 00275 void CoordinateModel<Adapter>::sharedConstructor( 00276 const AdapterWithCoords *ia, 00277 const RCP<const Environment> &env, 00278 const RCP<const Comm<int> > &comm, 00279 modelFlag_t &flags) 00280 { 00281 bool consecutiveIds = flags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE); 00282 00283 size_t nLocalIds = ia->getLocalNumIDs(); 00284 00285 // Get coordinates and weights (if any) 00286 00287 int tmp[2], gtmp[2]; 00288 tmp[0] = ia->getDimension(); 00289 tmp[1] = ia->getNumWeightsPerID(); 00290 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, 2, tmp, gtmp); 00291 coordinateDim_ = gtmp[0]; 00292 userNumWeights_ = gtmp[1]; 00293 00294 env_->localBugAssertion(__FILE__, __LINE__, "coordinate dimension", 00295 coordinateDim_ > 0, COMPLEX_ASSERTION); 00296 00297 input_t *coordArray = new input_t [coordinateDim_]; 00298 input_t *weightArray = NULL; 00299 if (userNumWeights_) 00300 weightArray = new input_t [userNumWeights_]; 00301 00302 env_->localMemoryAssertion(__FILE__, __LINE__, userNumWeights_+coordinateDim_, 00303 coordArray && (!userNumWeights_|| weightArray)); 00304 00305 00306 if (nLocalIds){ 00307 const zgid_t *gids=NULL; 00308 ia->getIDsView(gids); 00309 gids_ = arcp(gids, 0, nLocalIds, false); 00310 00311 for (int dim=0; dim < coordinateDim_; dim++){ 00312 int stride; 00313 const scalar_t *coords=NULL; 00314 try{ 00315 ia->getCoordinatesView(coords, stride, dim); 00316 } 00317 Z2_FORWARD_EXCEPTIONS; 00318 00319 ArrayRCP<const scalar_t> cArray(coords, 0, nLocalIds*stride, false); 00320 coordArray[dim] = input_t(cArray, stride); 00321 } 00322 00323 for (int idx=0; idx < userNumWeights_; idx++){ 00324 int stride; 00325 const scalar_t *weights; 00326 try{ 00327 ia->getWeightsView(weights, stride, idx); 00328 } 00329 Z2_FORWARD_EXCEPTIONS; 00330 00331 ArrayRCP<const scalar_t> wArray(weights, 0, nLocalIds*stride, false); 00332 weightArray[idx] = input_t(wArray, stride); 00333 } 00334 } 00335 00336 xyz_ = arcp(coordArray, 0, coordinateDim_); 00337 00338 if (userNumWeights_) 00339 weights_ = arcp(weightArray, 0, userNumWeights_); 00340 00341 // Create identifier map. 00342 // TODO: Why do coordinate models need an IdentifierMap? 00343 00344 RCP<const idmap_t> idMap; 00345 00346 try{ 00347 idMap = rcp(new idmap_t(env_, comm_, gids_, consecutiveIds)); 00348 } 00349 Z2_FORWARD_EXCEPTIONS; 00350 00351 numGlobalCoordinates_ = idMap->getGlobalNumberOfIds(); 00352 gnosAreGids_ = idMap->gnosAreGids(); 00353 00354 this->setIdentifierMap(idMap); 00355 00356 if (!gnosAreGids_ && nLocalIds>0){ 00357 gno_t *tmpGno = new gno_t [nLocalIds]; 00358 env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno); 00359 gnos_ = arcp(tmpGno, 0, nLocalIds); 00360 00361 try{ 00362 ArrayRCP<zgid_t> gidsNonConst = arcp_const_cast<zgid_t>(gids_); 00363 idMap->gidTranslate( gidsNonConst(0,nLocalIds), gnos_(0,nLocalIds), 00364 TRANSLATE_APP_TO_LIB); 00365 } 00366 Z2_FORWARD_EXCEPTIONS; 00367 } 00368 00369 gnosConst_ = arcp_const_cast<const gno_t>(gnos_); 00370 00371 env_->memory("After construction of coordinate model"); 00372 } 00373 00374 #ifdef KDDKDD_NO_LONGER_NEED_DUPLICATE_CODE 00375 // meshConstructor 00376 template <typename Adapter> 00377 void CoordinateModel<Adapter>::meshConstructor( 00378 const MeshAdapter<typename Adapter::userCoord_t> *ia, 00379 const RCP<const Environment> &env, 00380 const RCP<const Comm<int> > &comm, 00381 modelFlag_t &flags) 00382 { 00383 bool consecutiveIds = flags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE); 00384 00385 size_t nLocalIds = ia->getLocalNumIDs(); 00386 00387 // Get coordinates and weights (if any) 00388 00389 int tmp[2], gtmp[2]; 00390 tmp[0] = ia->getDimension(); 00391 tmp[1] = ia->getNumWeightsPerID(); 00392 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, 2, tmp, gtmp); 00393 coordinateDim_ = gtmp[0]; 00394 userNumWeights_ = gtmp[1]; 00395 00396 env_->localBugAssertion(__FILE__, __LINE__, "coordinate dimension", 00397 coordinateDim_ > 0, COMPLEX_ASSERTION); 00398 00399 input_t *coordArray = new input_t [coordinateDim_]; 00400 input_t *weightArray = NULL; 00401 if (userNumWeights_) 00402 weightArray = new input_t [userNumWeights_]; 00403 00404 env_->localMemoryAssertion(__FILE__, __LINE__, userNumWeights_+coordinateDim_, 00405 coordArray && (!userNumWeights_|| weightArray)); 00406 00407 00408 if (nLocalIds){ 00409 const zgid_t *gids=NULL; 00410 ia->getIDsView(gids); 00411 gids_ = arcp(gids, 0, nLocalIds, false); 00412 00413 for (int dim=0; dim < coordinateDim_; dim++){ 00414 int stride; 00415 const scalar_t *coords=NULL; 00416 try{ 00417 ia->getCoordinatesViewOf(ia->getPrimaryEntityType(), coords, stride, dim); 00418 } 00419 Z2_FORWARD_EXCEPTIONS; 00420 00421 ArrayRCP<const scalar_t> cArray(coords, 0, nLocalIds*stride, false); 00422 coordArray[dim] = input_t(cArray, stride); 00423 } 00424 00425 for (int idx=0; idx < userNumWeights_; idx++){ 00426 int stride; 00427 const scalar_t *weights; 00428 try{ 00429 ia->getWeightsView(weights, stride, idx); 00430 } 00431 Z2_FORWARD_EXCEPTIONS; 00432 00433 ArrayRCP<const scalar_t> wArray(weights, 0, nLocalIds*stride, false); 00434 weightArray[idx] = input_t(wArray, stride); 00435 } 00436 } 00437 00438 xyz_ = arcp(coordArray, 0, coordinateDim_); 00439 00440 if (userNumWeights_) 00441 weights_ = arcp(weightArray, 0, userNumWeights_); 00442 00443 // Create identifier map. 00444 // TODO: Why do coordinate models need an IdentifierMap? 00445 00446 RCP<const idmap_t> idMap; 00447 00448 try{ 00449 idMap = rcp(new idmap_t(env_, comm_, gids_, consecutiveIds)); 00450 } 00451 Z2_FORWARD_EXCEPTIONS; 00452 00453 numGlobalCoordinates_ = idMap->getGlobalNumberOfIds(); 00454 gnosAreGids_ = idMap->gnosAreGids(); 00455 00456 this->setIdentifierMap(idMap); 00457 00458 if (!gnosAreGids_ && nLocalIds>0){ 00459 gno_t *tmpGno = new gno_t [nLocalIds]; 00460 env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno); 00461 gnos_ = arcp(tmpGno, 0, nLocalIds); 00462 00463 try{ 00464 ArrayRCP<zgid_t> gidsNonConst = arcp_const_cast<zgid_t>(gids_); 00465 idMap->gidTranslate( gidsNonConst(0,nLocalIds), gnos_(0,nLocalIds), 00466 TRANSLATE_APP_TO_LIB); 00467 } 00468 Z2_FORWARD_EXCEPTIONS; 00469 } 00470 00471 gnosConst_ = arcp_const_cast<const gno_t>(gnos_); 00472 00473 env_->memory("After construction of coordinate model"); 00474 } 00475 #endif 00476 00477 } // namespace Zoltan2 00478 00479 #endif
1.7.6.1