|
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_XPETRATRAITS_HPP_ 00051 #define _ZOLTAN2_XPETRATRAITS_HPP_ 00052 00053 #include <Zoltan2_InputTraits.hpp> 00054 #include <Zoltan2_Standards.hpp> 00055 00056 #include <Xpetra_EpetraCrsMatrix.hpp> 00057 #include <Xpetra_TpetraCrsMatrix.hpp> 00058 #include <Xpetra_TpetraRowMatrix.hpp> 00059 #include <Xpetra_EpetraVector.hpp> 00060 #include <Xpetra_TpetraVector.hpp> 00061 #include <Xpetra_EpetraUtils.hpp> 00062 #include <Tpetra_Vector.hpp> 00063 00064 namespace Zoltan2 { 00065 00067 // Extra traits needed only for Xpetra matrices and graphs 00068 00091 template <typename User> 00092 struct XpetraTraits 00093 { 00096 static inline RCP<const User> convertToXpetra(const RCP<const User> &a) 00097 { 00098 return a; 00099 } 00100 00103 typedef long gno_t; 00104 00107 typedef int lno_t; 00108 00114 static RCP<const User> doMigration(const RCP<const User> &from, 00115 size_t numLocalRows, const gno_t *myNewRows) 00116 { 00117 return from; 00118 } 00119 }; 00120 00121 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00122 00124 // Tpetra::CrsMatrix 00125 template <typename scalar_t, 00126 typename lno_t, 00127 typename gno_t, 00128 typename node_t> 00129 struct XpetraTraits<Tpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> > 00130 { 00131 typedef typename Xpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> 00132 xmatrix_t; 00133 typedef typename Xpetra::TpetraCrsMatrix<scalar_t,lno_t,gno_t,node_t> 00134 xtmatrix_t; 00135 typedef typename Tpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> 00136 tmatrix_t; 00137 00138 static inline RCP<const xmatrix_t> convertToXpetra( 00139 const RCP<const tmatrix_t> &a) 00140 { 00141 return rcp(new xtmatrix_t(rcp_const_cast<tmatrix_t>(a))); 00142 } 00143 00144 static RCP<const tmatrix_t> doMigration(const RCP<const tmatrix_t> &from, 00145 size_t numLocalRows, const gno_t *myNewRows) 00146 { 00147 typedef Tpetra::Map<lno_t, gno_t, node_t> map_t; 00148 lno_t base = 0; 00149 00150 // source map 00151 const RCP<const map_t> &smap = from->getRowMap(); 00152 int oldNumElts = smap->getNodeNumElements(); 00153 gno_t numGlobalRows = smap->getGlobalNumElements(); 00154 00155 // target map 00156 ArrayView<const gno_t> rowList(myNewRows, numLocalRows); 00157 const RCP<const Teuchos::Comm<int> > &comm = from->getComm(); 00158 RCP<const map_t> tmap = rcp( 00159 new map_t(numGlobalRows, rowList, base, comm)); 00160 int newNumElts = numLocalRows; 00161 00162 // importer 00163 Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap); 00164 00165 // number of non zeros in my new rows 00166 typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> vector_t; 00167 vector_t numOld(smap); // TODO These vectors should have scalar = size_t, 00168 vector_t numNew(tmap); // but explicit instantiation does not yet support that. 00169 for (int lid=0; lid < oldNumElts; lid++){ 00170 numOld.replaceGlobalValue(smap->getGlobalElement(lid), 00171 scalar_t(from->getNumEntriesInLocalRow(lid))); 00172 } 00173 numNew.doImport(numOld, importer, Tpetra::INSERT); 00174 00175 // TODO Could skip this copy if could declare vector with scalar = size_t. 00176 ArrayRCP<size_t> nnz(newNumElts); 00177 if (newNumElts > 0){ 00178 ArrayRCP<scalar_t> ptr = numNew.getDataNonConst(0); 00179 for (int lid=0; lid < newNumElts; lid++){ 00180 nnz[lid] = static_cast<size_t>(ptr[lid]); 00181 } 00182 } 00183 00184 // target matrix 00185 RCP<tmatrix_t> M = rcp(new tmatrix_t(tmap, nnz, Tpetra::StaticProfile)); 00186 M->doImport(*from, importer, Tpetra::INSERT); 00187 M->fillComplete(); 00188 00189 return rcp_const_cast<const tmatrix_t>(M); 00190 } 00191 }; 00192 00194 // Epetra_CrsMatrix 00195 00196 template <> 00197 struct XpetraTraits<Epetra_CrsMatrix> 00198 { 00199 typedef InputTraits<Epetra_CrsMatrix>::scalar_t scalar_t; 00200 typedef InputTraits<Epetra_CrsMatrix>::lno_t lno_t; 00201 typedef InputTraits<Epetra_CrsMatrix>::gno_t gno_t; 00202 typedef InputTraits<Epetra_CrsMatrix>::node_t node_t; 00203 00204 static inline RCP<const Xpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> > 00205 convertToXpetra(const RCP<const Epetra_CrsMatrix> &a) 00206 { 00207 return rcp(new Xpetra::EpetraCrsMatrix( 00208 rcp_const_cast<Epetra_CrsMatrix>(a))); 00209 } 00210 00211 00212 static RCP<Epetra_CrsMatrix> doMigration( 00213 const RCP<const Epetra_CrsMatrix> &from, 00214 size_t numLocalRows, const gno_t *myNewRows) 00215 { 00216 lno_t base = 0; 00217 00218 // source map 00219 const Epetra_Map &smap = from->RowMap(); 00220 int oldNumElts = smap.NumMyElements(); 00221 gno_t numGlobalRows = smap.NumGlobalElements(); 00222 00223 // target map 00224 const Epetra_Comm &comm = from->Comm(); 00225 Epetra_Map tmap(numGlobalRows, numLocalRows, myNewRows, base, comm); 00226 int newNumElts = numLocalRows; 00227 00228 // importer 00229 Epetra_Import importer(tmap, smap); 00230 00231 // number of non zeros in my new rows 00232 Epetra_Vector numOld(smap); 00233 Epetra_Vector numNew(tmap); 00234 00235 for (int lid=0; lid < oldNumElts; lid++){ 00236 numOld[lid] = from->NumMyEntries(lid); 00237 } 00238 numNew.Import(numOld, importer, Insert); 00239 00240 Array<int> nnz(newNumElts); 00241 for (int lid=0; lid < newNumElts; lid++){ 00242 nnz[lid] = static_cast<int>(numNew[lid]); 00243 } 00244 00245 // target matrix 00246 RCP<Epetra_CrsMatrix> M = rcp(new Epetra_CrsMatrix(::Copy, tmap, nnz.getRawPtr(), true)); 00247 M->Import(*from, importer, Insert); 00248 M->FillComplete(); 00249 00250 return M; 00251 } 00252 }; 00253 00255 // Xpetra::CrsMatrix 00256 // KDDKDD: Do we need specializations for Xpetra::EpetraCrsMatrix and 00257 // KDDKDD: Xpetra::TpetraCrsMatrix 00258 template <typename scalar_t, 00259 typename lno_t, 00260 typename gno_t, 00261 typename node_t> 00262 struct XpetraTraits<Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> > 00263 { 00264 typedef Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> x_matrix_t; 00265 typedef Xpetra::TpetraCrsMatrix<scalar_t, lno_t, gno_t, node_t> xt_matrix_t; 00266 typedef Tpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> t_matrix_t; 00267 00268 static inline RCP<const x_matrix_t> 00269 convertToXpetra( const RCP<const x_matrix_t > &a) 00270 { 00271 return a; 00272 } 00273 00274 static RCP<const x_matrix_t> doMigration(const RCP<const x_matrix_t> &from, 00275 size_t numLocalRows, const gno_t *myNewRows) 00276 { 00277 Xpetra::UnderlyingLib lib = from->getRowMap()->lib(); 00278 00279 if (lib == Xpetra::UseEpetra){ 00280 throw std::logic_error("compiler should have used specialization"); 00281 } else{ 00282 // Do the import with the Tpetra::CrsMatrix traits object 00283 const x_matrix_t *xm = from.get(); 00284 const xt_matrix_t *xtm = dynamic_cast<const xt_matrix_t *>(xm); 00285 RCP<const t_matrix_t> tm = xtm->getTpetra_CrsMatrix(); 00286 00287 RCP<const t_matrix_t> tmnew = XpetraTraits<t_matrix_t>::doMigration( 00288 tm, numLocalRows, myNewRows); 00289 00290 RCP<const x_matrix_t> xmnew = 00291 XpetraTraits<t_matrix_t>::convertToXpetra(tmnew); 00292 00293 return xmnew; 00294 } 00295 } 00296 }; 00297 00299 // Xpetra::CrsMatrix specialization 00300 00301 template <typename node_t> 00302 struct XpetraTraits<Xpetra::CrsMatrix<double, int, int, node_t> > 00303 { 00304 typedef double scalar_t; 00305 typedef int lno_t; 00306 typedef int gno_t; 00307 typedef Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> x_matrix_t; 00308 typedef Xpetra::TpetraCrsMatrix<scalar_t, lno_t, gno_t, node_t> xt_matrix_t; 00309 typedef Tpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> t_matrix_t; 00310 typedef Xpetra::EpetraCrsMatrix xe_matrix_t; 00311 typedef Epetra_CrsMatrix e_matrix_t; 00312 00313 static inline RCP<const x_matrix_t> 00314 convertToXpetra( const RCP<const x_matrix_t > &a) 00315 { 00316 return a; 00317 } 00318 00319 static RCP<const x_matrix_t> doMigration(const RCP<const x_matrix_t> &from, 00320 size_t numLocalRows, const gno_t *myNewRows) 00321 { 00322 Xpetra::UnderlyingLib lib = from->getRowMap()->lib(); 00323 const x_matrix_t *xm = from.get(); 00324 00325 if (lib == Xpetra::UseEpetra){ 00326 // Do the import with the Epetra_CrsMatrix traits object 00327 const xe_matrix_t *xem = dynamic_cast<const xe_matrix_t *>(xm); 00328 RCP<const e_matrix_t> em = xem->getEpetra_CrsMatrix(); 00329 00330 RCP<const e_matrix_t> emnew = XpetraTraits<e_matrix_t>::doMigration( 00331 em, numLocalRows, myNewRows); 00332 00333 RCP<const x_matrix_t> xmnew = 00334 XpetraTraits<e_matrix_t>::convertToXpetra(emnew); 00335 00336 return xmnew; 00337 } else{ 00338 // Do the import with the Tpetra::CrsMatrix traits object 00339 const xt_matrix_t *xtm = dynamic_cast<const xt_matrix_t *>(xm); 00340 RCP<const t_matrix_t> tm = xtm->getTpetra_CrsMatrix(); 00341 00342 RCP<const t_matrix_t> tmnew = XpetraTraits<t_matrix_t>::doMigration( 00343 tm, numLocalRows, myNewRows); 00344 00345 RCP<const x_matrix_t> xmnew = 00346 XpetraTraits<t_matrix_t>::convertToXpetra(tmnew); 00347 00348 return xmnew; 00349 } 00350 } 00351 }; 00352 00353 00355 // Tpetra::CrsGraph 00356 template <typename lno_t, 00357 typename gno_t, 00358 typename node_t> 00359 struct XpetraTraits<Tpetra::CrsGraph<lno_t, gno_t, node_t> > 00360 { 00361 typedef typename Xpetra::CrsGraph<lno_t, gno_t, node_t> xgraph_t; 00362 typedef typename Xpetra::TpetraCrsGraph<lno_t, gno_t, node_t> xtgraph_t; 00363 typedef typename Tpetra::CrsGraph<lno_t, gno_t, node_t> tgraph_t; 00364 00365 static inline RCP<const xgraph_t> convertToXpetra( 00366 const RCP<const tgraph_t> &a) 00367 { 00368 return rcp(new xtgraph_t(rcp_const_cast<tgraph_t>(a))); 00369 } 00370 00371 static RCP<const tgraph_t> doMigration(const RCP<const tgraph_t> &from, 00372 size_t numLocalRows, const gno_t *myNewRows) 00373 { 00374 typedef Tpetra::Map<lno_t, gno_t, node_t> map_t; 00375 lno_t base = 0; 00376 00377 // source map 00378 const RCP<const map_t> &smap = from->getRowMap(); 00379 int oldNumElts = smap->getNodeNumElements(); 00380 gno_t numGlobalRows = smap->getGlobalNumElements(); 00381 00382 // target map 00383 ArrayView<const gno_t> rowList(myNewRows, numLocalRows); 00384 const RCP<const Teuchos::Comm<int> > &comm = from->getComm(); 00385 RCP<const map_t> tmap = rcp( 00386 new map_t(numGlobalRows, rowList, base, comm)); 00387 00388 // importer 00389 Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap); 00390 00391 // number of entries in my new rows 00392 typedef Tpetra::Vector<gno_t, lno_t, gno_t, node_t> vector_t; 00393 vector_t numOld(smap); 00394 vector_t numNew(tmap); 00395 for (int lid=0; lid < oldNumElts; lid++){ 00396 numOld.replaceGlobalValue(smap->getGlobalElement(lid), 00397 from->getNumEntriesInLocalRow(lid)); 00398 } 00399 numNew.doImport(numOld, importer, Tpetra::INSERT); 00400 00401 size_t numElts = tmap->getNodeNumElements(); 00402 ArrayRCP<const gno_t> nnz; 00403 if (numElts > 0) 00404 nnz = numNew.getData(0); // hangs if vector len == 0 00405 00406 ArrayRCP<const size_t> nnz_size_t; 00407 00408 if (numElts && sizeof(gno_t) != sizeof(size_t)){ 00409 size_t *vals = new size_t [numElts]; 00410 nnz_size_t = arcp(vals, 0, numElts, true); 00411 for (size_t i=0; i < numElts; i++){ 00412 vals[i] = static_cast<size_t>(nnz[i]); 00413 } 00414 } 00415 else{ 00416 nnz_size_t = arcp_reinterpret_cast<const size_t>(nnz); 00417 } 00418 00419 // target graph 00420 RCP<tgraph_t> G = rcp(new tgraph_t(tmap, nnz_size_t, Tpetra::StaticProfile)); 00421 00422 G->doImport(*from, importer, Tpetra::INSERT); 00423 G->fillComplete(); 00424 00425 return G; 00426 } 00427 00428 }; 00429 00431 // Epetra_CrsGraph 00432 template < > 00433 struct XpetraTraits<Epetra_CrsGraph> 00434 { 00435 typedef InputTraits<Epetra_CrsGraph>::lno_t lno_t; 00436 typedef InputTraits<Epetra_CrsGraph>::gno_t gno_t; 00437 typedef InputTraits<Epetra_CrsGraph>::node_t node_t; 00438 static inline RCP<const Xpetra::CrsGraph<lno_t,gno_t,node_t> > 00439 convertToXpetra(const RCP<const Epetra_CrsGraph> &a) 00440 { 00441 return rcp(new Xpetra::EpetraCrsGraph( 00442 rcp_const_cast<Epetra_CrsGraph>(a))); 00443 } 00444 00445 static RCP<const Epetra_CrsGraph> doMigration( 00446 const RCP<const Epetra_CrsGraph> &from, 00447 size_t numLocalRows, const gno_t *myNewRows) 00448 { 00449 lno_t base = 0; 00450 00451 // source map 00452 const Epetra_BlockMap &smap = from->RowMap(); 00453 gno_t numGlobalRows = smap.NumGlobalElements(); 00454 lno_t oldNumElts = smap.NumMyElements(); 00455 00456 // target map 00457 const Epetra_Comm &comm = from->Comm(); 00458 Epetra_BlockMap tmap(numGlobalRows, numLocalRows, 00459 myNewRows, 1, base, comm); 00460 lno_t newNumElts = tmap.NumMyElements(); 00461 00462 // importer 00463 Epetra_Import importer(tmap, smap); 00464 00465 // number of non zeros in my new rows 00466 Epetra_Vector numOld(smap); 00467 Epetra_Vector numNew(tmap); 00468 00469 for (int lid=0; lid < oldNumElts; lid++){ 00470 numOld[lid] = from->NumMyIndices(lid); 00471 } 00472 numNew.Import(numOld, importer, Insert); 00473 00474 Array<int> nnz(newNumElts); 00475 for (int lid=0; lid < newNumElts; lid++){ 00476 nnz[lid] = static_cast<int>(numNew[lid]); 00477 } 00478 00479 // target graph 00480 RCP<Epetra_CrsGraph> G = rcp(new Epetra_CrsGraph(::Copy, tmap, nnz.getRawPtr(), true)); 00481 G->Import(*from, importer, Insert); 00482 G->FillComplete(); 00483 00484 return G; 00485 } 00486 00487 }; 00488 00490 // Xpetra::CrsGraph 00491 // KDDKDD Do we need specializations for Xpetra::TpetraCrsGraph and 00492 // KDDKDD Xpetra::EpetraCrsGraph? 00493 template <typename lno_t, 00494 typename gno_t, 00495 typename node_t> 00496 struct XpetraTraits<Xpetra::CrsGraph<lno_t, gno_t, node_t> > 00497 { 00498 typedef Xpetra::CrsGraph<lno_t, gno_t, node_t> x_graph_t; 00499 typedef Xpetra::TpetraCrsGraph<lno_t, gno_t, node_t> xt_graph_t; 00500 typedef Tpetra::CrsGraph<lno_t,gno_t,node_t> t_graph_t; 00501 00502 static inline RCP<const x_graph_t> 00503 convertToXpetra(const RCP<const x_graph_t> &a) 00504 { 00505 return a; 00506 } 00507 00508 static RCP<const x_graph_t> doMigration(const RCP<const x_graph_t> &from, 00509 size_t numLocalRows, const gno_t *myNewRows) 00510 { 00511 Xpetra::UnderlyingLib lib = from->getRowMap()->lib(); 00512 00513 if (lib == Xpetra::UseEpetra){ 00514 throw std::logic_error("compiler should have used specialization"); 00515 } else{ 00516 // Do the import with the Tpetra::CrsGraph traits object 00517 const x_graph_t *xg = from.get(); 00518 const xt_graph_t *xtg = dynamic_cast<const xt_graph_t *>(xg); 00519 RCP<const t_graph_t> tg = xtg->getTpetra_CrsGraph(); 00520 00521 RCP<const t_graph_t> tgnew = XpetraTraits<t_graph_t>::doMigration( 00522 tg, numLocalRows, myNewRows); 00523 00524 RCP<const x_graph_t> xgnew = 00525 XpetraTraits<t_graph_t>::convertToXpetra(tgnew); 00526 return xgnew; 00527 } 00528 } 00529 }; 00530 00531 00532 00534 // Xpetra::RowMatrix 00535 template <typename scalar_t, 00536 typename lno_t, 00537 typename gno_t, 00538 typename node_t> 00539 struct XpetraTraits<Xpetra::RowMatrix<scalar_t, lno_t, gno_t, node_t> > 00540 { 00541 typedef Xpetra::RowMatrix<scalar_t, lno_t, gno_t, node_t> x_matrix_t; 00542 typedef Xpetra::TpetraRowMatrix<scalar_t, lno_t, gno_t, node_t> xt_matrix_t; 00543 typedef Tpetra::RowMatrix<scalar_t,lno_t,gno_t,node_t> t_matrix_t; 00544 00545 static inline RCP<const x_matrix_t> 00546 convertToXpetra( const RCP<const x_matrix_t > &a) 00547 { 00548 return a; 00549 } 00550 00551 static RCP<const x_matrix_t> doMigration(const RCP<const x_matrix_t> &from, 00552 size_t numLocalRows, const gno_t *myNewRows) 00553 { 00554 Xpetra::UnderlyingLib lib = from->getRowMap()->lib(); 00555 00556 if (lib == Xpetra::UseEpetra){ 00557 throw std::logic_error("compiler should have used specialization"); 00558 } else{ 00559 // Do the import with the Tpetra::CrsMatrix traits object 00560 const x_matrix_t *xm = from.get(); 00561 const xt_matrix_t *xtm = dynamic_cast<const xt_matrix_t *>(xm); 00562 RCP<const t_matrix_t> tm = xtm->getTpetra_CrsMatrix(); 00563 00564 RCP<const t_matrix_t> tmnew = XpetraTraits<t_matrix_t>::doMigration( 00565 tm, numLocalRows, myNewRows); 00566 00567 RCP<const x_matrix_t> xmnew = 00568 XpetraTraits<t_matrix_t>::convertToXpetra(tmnew); 00569 00570 return xmnew; 00571 } 00572 } 00573 }; 00574 00576 // Xpetra::CrsGraph specialization 00577 template < typename node_t> 00578 struct XpetraTraits<Xpetra::CrsGraph<int, int, node_t> > 00579 { 00580 typedef int lno_t; 00581 typedef int gno_t; 00582 typedef Xpetra::CrsGraph<lno_t, gno_t, node_t> x_graph_t; 00583 typedef Xpetra::TpetraCrsGraph<lno_t, gno_t, node_t> xt_graph_t; 00584 typedef Tpetra::CrsGraph<lno_t,gno_t,node_t> t_graph_t; 00585 typedef Xpetra::EpetraCrsGraph xe_graph_t; 00586 typedef Epetra_CrsGraph e_graph_t; 00587 00588 static inline RCP<const x_graph_t> 00589 convertToXpetra(const RCP<const x_graph_t> &a) 00590 { 00591 return a; 00592 } 00593 00594 static RCP<const x_graph_t> doMigration(const RCP<const x_graph_t> &from, 00595 size_t numLocalRows, const gno_t *myNewRows) 00596 { 00597 Xpetra::UnderlyingLib lib = from->getRowMap()->lib(); 00598 const x_graph_t *xg = from.get(); 00599 00600 if (lib == Xpetra::UseEpetra){ 00601 // Do the import with the Epetra_CrsGraph traits object 00602 const xe_graph_t *xeg = dynamic_cast<const xe_graph_t *>(xg); 00603 RCP<const e_graph_t> eg = xeg->getEpetra_CrsGraph(); 00604 00605 RCP<const e_graph_t> egnew = XpetraTraits<e_graph_t>::doMigration( 00606 eg, numLocalRows, myNewRows); 00607 00608 RCP<const x_graph_t> xgnew = 00609 XpetraTraits<e_graph_t>::convertToXpetra(egnew); 00610 00611 return xgnew; 00612 } else{ 00613 // Do the import with the Tpetra::CrsGraph traits object 00614 const xt_graph_t *xtg = dynamic_cast<const xt_graph_t *>(xg); 00615 RCP<const t_graph_t> tg = xtg->getTpetra_CrsGraph(); 00616 00617 RCP<const t_graph_t> tgnew = XpetraTraits<t_graph_t>::doMigration( 00618 tg, numLocalRows, myNewRows); 00619 00620 RCP<const x_graph_t> xgnew = 00621 XpetraTraits<t_graph_t>::convertToXpetra(tgnew); 00622 00623 return xgnew; 00624 } 00625 } 00626 }; 00627 00629 // Tpetra::Vector 00630 template <typename scalar_t, 00631 typename lno_t, 00632 typename gno_t, 00633 typename node_t> 00634 struct XpetraTraits<Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> > 00635 { 00636 typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> t_vector_t; 00637 typedef Xpetra::TpetraVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t; 00638 typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t; 00639 00640 static inline RCP<const x_vector_t> 00641 convertToXpetra(const RCP<const t_vector_t> &a) 00642 { 00643 return rcp(new xt_vector_t(rcp_const_cast<t_vector_t>(a))); 00644 } 00645 00646 static RCP<const t_vector_t> doMigration(const RCP<const t_vector_t> &from, 00647 size_t numLocalElts, const gno_t *myNewElts) 00648 { 00649 lno_t base = 0; 00650 typedef Tpetra::Map<lno_t, gno_t, node_t> map_t; 00651 00652 // source map 00653 const RCP<const map_t> &smap = from->getMap(); 00654 gno_t numGlobalElts = smap->getGlobalNumElements(); 00655 00656 // target map 00657 ArrayView<const gno_t> eltList(myNewElts, numLocalElts); 00658 const RCP<const Teuchos::Comm<int> > comm = from->getMap()->getComm(); 00659 RCP<const map_t> tmap = rcp( 00660 new map_t(numGlobalElts, eltList, base, comm)); 00661 00662 // importer 00663 Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap); 00664 00665 // target vector 00666 RCP<t_vector_t> V = 00667 Tpetra::createVector<scalar_t,lno_t,gno_t,node_t>(tmap); 00668 V->doImport(*from, importer, Tpetra::INSERT); 00669 00670 return V; 00671 } 00672 }; 00673 00675 // Epetra_Vector 00676 template < > 00677 struct XpetraTraits<Epetra_Vector> 00678 { 00679 typedef InputTraits<Epetra_Vector>::lno_t lno_t; 00680 typedef InputTraits<Epetra_Vector>::gno_t gno_t; 00681 typedef InputTraits<Epetra_Vector>::node_t node_t; 00682 typedef InputTraits<Epetra_Vector>::scalar_t scalar_t; 00683 00684 typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t; 00685 00686 static inline RCP<const x_vector_t> 00687 convertToXpetra(const RCP<const Epetra_Vector> &a) 00688 { 00689 RCP<Xpetra::EpetraVector> xev = rcp( 00690 new Xpetra::EpetraVector(rcp_const_cast<Epetra_Vector>(a))); 00691 return rcp_implicit_cast<x_vector_t>(xev); 00692 } 00693 00694 static RCP<Epetra_Vector> doMigration(const RCP<const Epetra_Vector> &from, 00695 size_t numLocalElts, const gno_t *myNewElts) 00696 { 00697 lno_t base = 0; 00698 // source map 00699 const Epetra_BlockMap &smap = from->Map(); 00700 gno_t numGlobalElts = smap.NumGlobalElements(); 00701 00702 // target map 00703 const Epetra_Comm &comm = from->Comm(); 00704 const Epetra_BlockMap tmap(numGlobalElts, numLocalElts, myNewElts, 00705 1, base, comm); 00706 00707 // importer 00708 Epetra_Import importer(tmap, smap); 00709 00710 // target vector 00711 RCP<Epetra_Vector> V = rcp(new Epetra_Vector(tmap, true)); 00712 Epetra_CombineMode c = Insert; 00713 V->Import(*from, importer, c); 00714 00715 return V; 00716 } 00717 }; 00718 00720 // Xpetra::Vector 00721 template <typename scalar_t, 00722 typename lno_t, 00723 typename gno_t, 00724 typename node_t> 00725 struct XpetraTraits<Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> > 00726 { 00727 typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t; 00728 typedef Xpetra::TpetraVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t; 00729 typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> t_vector_t; 00730 00731 static inline RCP<const x_vector_t> 00732 convertToXpetra(const RCP<const x_vector_t> &a) 00733 { 00734 return a; 00735 } 00736 00737 static RCP<const x_vector_t> doMigration(const RCP<const x_vector_t> &from, 00738 size_t numLocalRows, const gno_t *myNewRows) 00739 { 00740 Xpetra::UnderlyingLib lib = from->getMap()->lib(); 00741 00742 if (lib == Xpetra::UseEpetra){ 00743 throw std::logic_error("compiler should have used specialization"); 00744 } else{ 00745 // Do the import with the Tpetra::Vector traits object 00746 const x_vector_t *xv = from.get(); 00747 const xt_vector_t *xtv = dynamic_cast<const xt_vector_t *>(xv); 00748 RCP<const t_vector_t> tv = xtv->getTpetra_Vector(); 00749 00750 RCP<const t_vector_t> tvnew = XpetraTraits<t_vector_t>::doMigration( 00751 tv, numLocalRows, myNewRows); 00752 00753 RCP<const x_vector_t> xvnew = 00754 XpetraTraits<t_vector_t>::convertToXpetra(tvnew); 00755 00756 return xvnew; 00757 } 00758 } 00759 }; 00760 00762 // Xpetra::Vector specialization 00763 template <typename node_t> 00764 struct XpetraTraits<Xpetra::Vector<double, int, int, node_t> > 00765 { 00766 typedef double scalar_t; 00767 typedef int lno_t; 00768 typedef int gno_t; 00769 typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t; 00770 typedef Xpetra::TpetraVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t; 00771 typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> t_vector_t; 00772 typedef Xpetra::EpetraVector xe_vector_t; 00773 typedef Epetra_Vector e_vector_t; 00774 00775 static inline RCP<const x_vector_t> 00776 convertToXpetra(const RCP<const x_vector_t> &a) 00777 { 00778 return a; 00779 } 00780 00781 static RCP<const x_vector_t> doMigration(const RCP<const x_vector_t> &from, 00782 size_t numLocalRows, const gno_t *myNewRows) 00783 { 00784 Xpetra::UnderlyingLib lib = from->getMap()->lib(); 00785 const x_vector_t *vec = from.get(); 00786 00787 if (lib == Xpetra::UseEpetra){ 00788 // Do the import with the Epetra_Vector traits object 00789 const xe_vector_t *xev = dynamic_cast<const xe_vector_t *>(vec); 00790 RCP<const e_vector_t> ev = rcp(xev->getEpetra_Vector()); 00791 00792 RCP<const e_vector_t> evnew = XpetraTraits<e_vector_t>::doMigration( 00793 ev, numLocalRows, myNewRows); 00794 00795 RCP<const x_vector_t> xvnew = 00796 XpetraTraits<e_vector_t>::convertToXpetra(evnew); 00797 00798 return xvnew; 00799 } else{ 00800 // Do the import with the Tpetra::Vector traits object 00801 const xt_vector_t *xtv = dynamic_cast<const xt_vector_t *>(vec); 00802 RCP<t_vector_t> tv = xtv->getTpetra_Vector(); 00803 RCP<const t_vector_t> ctv = rcp_const_cast<const t_vector_t>(tv); 00804 00805 RCP<const t_vector_t> tvnew = XpetraTraits<t_vector_t>::doMigration( 00806 ctv, numLocalRows, myNewRows); 00807 00808 RCP<const x_vector_t> xvnew = 00809 XpetraTraits<t_vector_t>::convertToXpetra(tvnew); 00810 00811 return xvnew; 00812 } 00813 } 00814 }; 00815 00817 // Tpetra::MultiVector 00818 template <typename scalar_t, 00819 typename lno_t, 00820 typename gno_t, 00821 typename node_t> 00822 struct XpetraTraits<Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> > 00823 { 00824 typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> t_vector_t; 00825 typedef Xpetra::TpetraMultiVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t; 00826 typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_vector_t; 00827 00828 static inline RCP<const x_vector_t> 00829 convertToXpetra(const RCP<const t_vector_t> &a) 00830 { 00831 return rcp(new xt_vector_t(rcp_const_cast<t_vector_t>(a))); 00832 } 00833 00834 static RCP<const t_vector_t> doMigration(const RCP<const t_vector_t> &from, 00835 size_t numLocalElts, const gno_t *myNewElts) 00836 { 00837 typedef Tpetra::Map<lno_t, gno_t, node_t> map_t; 00838 lno_t base = 0; 00839 00840 // source map 00841 const RCP<const map_t> &smap = from->getMap(); 00842 gno_t numGlobalElts = smap->getGlobalNumElements(); 00843 00844 // target map 00845 ArrayView<const gno_t> eltList(myNewElts, numLocalElts); 00846 const RCP<const Teuchos::Comm<int> > comm = from->getMap()->getComm(); 00847 RCP<const map_t> tmap = rcp( 00848 new map_t(numGlobalElts, eltList, base, comm)); 00849 00850 // importer 00851 Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap); 00852 00853 // target vector 00854 RCP<t_vector_t> MV = rcp( 00855 new t_vector_t(tmap, from->getNumVectors(), true)); 00856 MV->doImport(*from, importer, Tpetra::INSERT); 00857 00858 return MV; 00859 } 00860 }; 00861 00863 // Epetra_MultiVector 00864 template < > 00865 struct XpetraTraits<Epetra_MultiVector> 00866 { 00867 typedef InputTraits<Epetra_MultiVector>::lno_t lno_t; 00868 typedef InputTraits<Epetra_MultiVector>::gno_t gno_t; 00869 typedef InputTraits<Epetra_MultiVector>::node_t node_t; 00870 typedef InputTraits<Epetra_MultiVector>::scalar_t scalar_t; 00871 typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t; 00872 00873 static inline RCP<const x_mvector_t> 00874 convertToXpetra(const RCP<const Epetra_MultiVector> &a) 00875 { 00876 RCP<Xpetra::EpetraMultiVector> xemv = rcp( 00877 new Xpetra::EpetraMultiVector( 00878 rcp_const_cast<Epetra_MultiVector>(a))); 00879 return rcp_implicit_cast<x_mvector_t>(xemv); 00880 } 00881 00882 static RCP<Epetra_MultiVector> doMigration( 00883 const RCP<const Epetra_MultiVector> &from, 00884 size_t numLocalElts, const gno_t *myNewElts) 00885 { 00886 lno_t base = 0; 00887 // source map 00888 const Epetra_BlockMap &smap = from->Map(); 00889 gno_t numGlobalElts = smap.NumGlobalElements(); 00890 00891 // target map 00892 const Epetra_Comm &comm = from->Comm(); 00893 const Epetra_BlockMap tmap(numGlobalElts, numLocalElts, myNewElts, 00894 1, base, comm); 00895 00896 // importer 00897 Epetra_Import importer(tmap, smap); 00898 00899 // target vector 00900 RCP<Epetra_MultiVector> MV = rcp( 00901 new Epetra_MultiVector(tmap, from->NumVectors(), true)); 00902 Epetra_CombineMode c = Insert; 00903 MV->Import(*from, importer, c); 00904 00905 return MV; 00906 } 00907 }; 00908 00910 // Xpetra::MultiVector 00911 template <typename scalar_t, 00912 typename lno_t, 00913 typename gno_t, 00914 typename node_t> 00915 struct XpetraTraits<Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> > 00916 { 00917 typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t; 00918 typedef Xpetra::TpetraMultiVector<scalar_t, lno_t, gno_t, node_t> xt_mvector_t; 00919 typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> t_mvector_t; 00920 00921 static inline RCP<const x_mvector_t> 00922 convertToXpetra(const RCP<const x_mvector_t> &a) 00923 { 00924 return a; 00925 } 00926 00927 static RCP<const x_mvector_t> doMigration(const RCP<const x_mvector_t> &from, 00928 size_t numLocalRows, const gno_t *myNewRows) 00929 { 00930 Xpetra::UnderlyingLib lib = from->getMap()->lib(); 00931 00932 if (lib == Xpetra::UseEpetra){ 00933 throw std::logic_error("compiler should have used specialization"); 00934 } else{ 00935 // Do the import with the Tpetra::MultiVector traits object 00936 const x_mvector_t *xmv = from.get(); 00937 const xt_mvector_t *xtv = dynamic_cast<const xt_mvector_t *>(xmv); 00938 RCP<t_mvector_t> tv = xtv->getTpetra_MultiVector(); 00939 RCP<const t_mvector_t> ctv = rcp_const_cast<const t_mvector_t>(tv); 00940 00941 RCP<const t_mvector_t> tvnew = XpetraTraits<t_mvector_t>::doMigration( 00942 ctv, numLocalRows, myNewRows); 00943 00944 RCP<const x_mvector_t> xvnew = 00945 XpetraTraits<t_mvector_t>::convertToXpetra(tvnew); 00946 00947 return xvnew; 00948 } 00949 } 00950 }; 00951 00953 // Xpetra::MultiVector specialization 00954 template <typename node_t> 00955 struct XpetraTraits<Xpetra::MultiVector<double, int, int, node_t> > 00956 { 00957 typedef double scalar_t; 00958 typedef int lno_t; 00959 typedef int gno_t; 00960 typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t; 00961 typedef Xpetra::TpetraMultiVector<scalar_t, lno_t, gno_t, node_t> xt_mvector_t; 00962 typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> t_mvector_t; 00963 typedef Xpetra::EpetraMultiVector xe_mvector_t; 00964 typedef Epetra_MultiVector e_mvector_t; 00965 00966 static inline RCP<const x_mvector_t> 00967 convertToXpetra(const RCP<const x_mvector_t> &a) 00968 { 00969 return a; 00970 } 00971 00972 static RCP<const x_mvector_t> doMigration(const RCP<const x_mvector_t> &from, 00973 size_t numLocalRows, const gno_t *myNewRows) 00974 { 00975 Xpetra::UnderlyingLib lib = from->getMap()->lib(); 00976 const x_mvector_t *xmv = from.get(); 00977 00978 if (lib == Xpetra::UseEpetra){ 00979 // Do the import with the Epetra_MultiVector traits object 00980 const xe_mvector_t *xev = dynamic_cast<const xe_mvector_t *>(xmv); 00981 RCP<e_mvector_t> ev = xev->getEpetra_MultiVector(); 00982 RCP<const e_mvector_t> cev = rcp_const_cast<const e_mvector_t>(ev); 00983 00984 RCP<const e_mvector_t> evnew = XpetraTraits<e_mvector_t>::doMigration( 00985 cev, numLocalRows, myNewRows); 00986 00987 RCP<const x_mvector_t> xvnew = 00988 XpetraTraits<e_mvector_t>::convertToXpetra(evnew); 00989 00990 return xvnew; 00991 00992 } else{ 00993 // Do the import with the Tpetra::MultiVector traits object 00994 const xt_mvector_t *xtv = dynamic_cast<const xt_mvector_t *>(xmv); 00995 RCP<t_mvector_t> tv = xtv->getTpetra_MultiVector(); 00996 RCP<const t_mvector_t> ctv = rcp_const_cast<const t_mvector_t>(tv); 00997 00998 RCP<const t_mvector_t> tvnew = XpetraTraits<t_mvector_t>::doMigration( 00999 ctv, numLocalRows, myNewRows); 01000 01001 RCP<const x_mvector_t> xvnew = 01002 XpetraTraits<t_mvector_t>::convertToXpetra(tvnew); 01003 01004 return xvnew; 01005 } 01006 } 01007 }; 01008 01009 #endif // DOXYGEN_SHOULD_SKIP_THIS 01010 01011 } //namespace Zoltan2 01012 01013 #endif // _ZOLTAN2_XPETRATRAITS_HPP_
1.7.6.1