Zoltan2
Zoltan2_XpetraTraits.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
45 
50 #ifndef _ZOLTAN2_XPETRATRAITS_HPP_
51 #define _ZOLTAN2_XPETRATRAITS_HPP_
52 
53 #include <Zoltan2_InputTraits.hpp>
54 #include <Zoltan2_Standards.hpp>
55 
56 #include <Xpetra_TpetraCrsMatrix.hpp>
57 #include <Xpetra_TpetraRowMatrix.hpp>
58 #include <Xpetra_TpetraVector.hpp>
59 #include <Tpetra_Vector.hpp>
60 
61 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
62 #include <Xpetra_EpetraCrsMatrix.hpp>
63 #include <Xpetra_EpetraVector.hpp>
64 #include <Xpetra_EpetraUtils.hpp>
65 #endif
66 
67 namespace Zoltan2 {
68 
70 // Extra traits needed only for Xpetra matrices and graphs
71 
94 template <typename User>
96 {
99  static inline RCP<User> convertToXpetra(const RCP<User> &a)
100  {
101  return a;
102  }
103 
107 
111 
117  static RCP<User> doMigration(const User &from,
118  size_t numLocalRows, const gno_t *myNewRows)
119  {
120  return Teuchos::null;
121  }
122 };
123 
124 #ifndef DOXYGEN_SHOULD_SKIP_THIS
125 
127 // Tpetra::CrsMatrix
128 template <typename scalar_t,
129  typename lno_t,
130  typename gno_t,
131  typename node_t>
132 struct XpetraTraits<Tpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> >
133 {
134  typedef typename Xpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t>
135  xmatrix_t;
136  typedef typename Xpetra::TpetraCrsMatrix<scalar_t,lno_t,gno_t,node_t>
137  xtmatrix_t;
138  typedef typename Tpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t>
139  tmatrix_t;
140 
141  static inline RCP<xmatrix_t> convertToXpetra(const RCP<tmatrix_t> &a)
142  {
143  return rcp(new xtmatrix_t(a));
144  }
145 
146  static RCP<tmatrix_t> doMigration(const tmatrix_t &from,
147  size_t numLocalRows, const gno_t *myNewRows)
148  {
149  typedef Tpetra::Map<lno_t, gno_t, node_t> map_t;
150  lno_t base = 0;
151 
152  // source map
153  const RCP<const map_t> &smap = from.getRowMap();
154  int oldNumElts = smap->getNodeNumElements();
155  gno_t numGlobalRows = smap->getGlobalNumElements();
156 
157  // target map
158  ArrayView<const gno_t> rowList(myNewRows, numLocalRows);
159  const RCP<const Teuchos::Comm<int> > &comm = from.getComm();
160  RCP<const map_t> tmap = rcp(
161  new map_t(numGlobalRows, rowList, base, comm));
162  int newNumElts = numLocalRows;
163 
164  // importer
165  Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap);
166 
167  // number of non zeros in my new rows
168  typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> vector_t;
169  vector_t numOld(smap); // TODO These vectors should have scalar = size_t,
170  vector_t numNew(tmap); // but explicit instantiation does not yet support that.
171  for (int lid=0; lid < oldNumElts; lid++){
172  numOld.replaceGlobalValue(smap->getGlobalElement(lid),
173  scalar_t(from.getNumEntriesInLocalRow(lid)));
174  }
175  numNew.doImport(numOld, importer, Tpetra::INSERT);
176 
177  // TODO Could skip this copy if could declare vector with scalar = size_t.
178  ArrayRCP<size_t> nnz(newNumElts);
179  if (newNumElts > 0){
180  ArrayRCP<scalar_t> ptr = numNew.getDataNonConst(0);
181  for (int lid=0; lid < newNumElts; lid++){
182  nnz[lid] = static_cast<size_t>(ptr[lid]);
183  }
184  }
185 
186  // target matrix
187  RCP<tmatrix_t> M = rcp(new tmatrix_t(tmap, nnz, Tpetra::StaticProfile));
188  M->doImport(from, importer, Tpetra::INSERT);
189  M->fillComplete();
190 
191  return M;
192  }
193 };
194 
196 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
197 // Epetra_CrsMatrix
198 template <>
199 struct XpetraTraits<Epetra_CrsMatrix>
200 {
205 
206  static inline RCP<Xpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> >
207  convertToXpetra(const RCP<Epetra_CrsMatrix> &a)
208  {
209  return rcp(new Xpetra::EpetraCrsMatrixT<gno_t, node_t>(a));
210  }
211 
212 
213  static RCP<Epetra_CrsMatrix> doMigration(const Epetra_CrsMatrix &from,
214  size_t numLocalRows, const gno_t *myNewRows)
215  {
216  lno_t base = 0;
217 
218  // source map
219  const Epetra_Map &smap = from.RowMap();
220  int oldNumElts = smap.NumMyElements();
221  gno_t numGlobalRows = smap.NumGlobalElements();
222 
223  // target map
224  const Epetra_Comm &comm = from.Comm();
225  Epetra_Map tmap(numGlobalRows, numLocalRows, myNewRows, base, comm);
226  int newNumElts = numLocalRows;
227 
228  // importer
229  Epetra_Import importer(tmap, smap);
230 
231  // number of non zeros in my new rows
232  Epetra_Vector numOld(smap);
233  Epetra_Vector numNew(tmap);
234 
235  for (int lid=0; lid < oldNumElts; lid++){
236  numOld[lid] = from.NumMyEntries(lid);
237  }
238  numNew.Import(numOld, importer, Insert);
239 
240  Array<int> nnz(newNumElts);
241  for (int lid=0; lid < newNumElts; lid++){
242  nnz[lid] = static_cast<int>(numNew[lid]);
243  }
244 
245  // target matrix
246  RCP<Epetra_CrsMatrix> M = rcp(new Epetra_CrsMatrix(::Copy, tmap, nnz.getRawPtr(), true));
247  M->Import(from, importer, Insert);
248  M->FillComplete();
249 
250  return M;
251  }
252 };
253 #endif
254 
256 // Xpetra::CrsMatrix
257 // KDDKDD: Do we need specializations for Xpetra::EpetraCrsMatrix and
258 // KDDKDD: Xpetra::TpetraCrsMatrix
259 template <typename scalar_t,
260  typename lno_t,
261  typename gno_t,
262  typename node_t>
263 struct XpetraTraits<Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> >
264 {
265  typedef Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> x_matrix_t;
266  typedef Xpetra::TpetraCrsMatrix<scalar_t, lno_t, gno_t, node_t> xt_matrix_t;
267  typedef Tpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> t_matrix_t;
268 
269  static inline RCP<x_matrix_t> convertToXpetra(const RCP<x_matrix_t > &a)
270  {
271  return a;
272  }
273 
274  static RCP<x_matrix_t> doMigration(const x_matrix_t &from,
275  size_t numLocalRows, const gno_t *myNewRows)
276  {
277  Xpetra::UnderlyingLib lib = from.getRowMap()->lib();
278 
279  if (lib == Xpetra::UseEpetra){
280  throw std::logic_error("compiler should have used specialization");
281  } else{
282  // Do the import with the Tpetra::CrsMatrix traits object
283  const xt_matrix_t *xtm = dynamic_cast<const xt_matrix_t *>(&from);
284  RCP<const t_matrix_t> tm = xtm->getTpetra_CrsMatrix();
285 
286  RCP<t_matrix_t> tmnew = XpetraTraits<t_matrix_t>::doMigration(
287  *tm, numLocalRows, myNewRows);
288 
289  RCP<x_matrix_t> xmnew = XpetraTraits<t_matrix_t>::convertToXpetra(tmnew);
290 
291  return xmnew;
292  }
293  }
294 };
295 
297 // Xpetra::CrsMatrix specialization
298 
299 template <typename node_t>
300 struct XpetraTraits<Xpetra::CrsMatrix<double, int, int, node_t> >
301 {
302  typedef double scalar_t;
303  typedef int lno_t;
304  typedef int gno_t;
305  typedef Xpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t> x_matrix_t;
306  typedef Xpetra::TpetraCrsMatrix<scalar_t, lno_t, gno_t, node_t> xt_matrix_t;
307  typedef Tpetra::CrsMatrix<scalar_t,lno_t,gno_t,node_t> t_matrix_t;
308 
309  static inline RCP<x_matrix_t> convertToXpetra(const RCP<x_matrix_t > &a)
310  {
311  return a;
312  }
313 
314  static RCP<x_matrix_t> doMigration(const x_matrix_t &from,
315  size_t numLocalRows, const gno_t *myNewRows)
316  {
317  Xpetra::UnderlyingLib lib = from.getRowMap()->lib();
318 
319  if (lib == Xpetra::UseEpetra){
320 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
321  typedef Epetra_CrsMatrix e_matrix_t;
322  typedef Xpetra::EpetraCrsMatrixT<gno_t,node_t> xe_matrix_t;
323  // Do the import with the Epetra_CrsMatrix traits object
324  const xe_matrix_t *xem = dynamic_cast<const xe_matrix_t *>(&from);
325  RCP<const e_matrix_t> em = xem->getEpetra_CrsMatrix();
326 
327  RCP<e_matrix_t> emnew = XpetraTraits<e_matrix_t>::doMigration(
328  *em, numLocalRows, myNewRows);
329 
330  RCP<x_matrix_t> xmnew = XpetraTraits<e_matrix_t>::convertToXpetra(emnew);
331 
332  return xmnew;
333 #else
334  throw std::runtime_error("Xpetra with Epetra requested, but "
335  "Trilinos is not built with Epetra");
336 #endif
337  } else{
338  // Do the import with the Tpetra::CrsMatrix traits object
339  const xt_matrix_t *xtm = dynamic_cast<const xt_matrix_t *>(&from);
340  RCP<const t_matrix_t> tm = xtm->getTpetra_CrsMatrix();
341 
342  RCP<t_matrix_t> tmnew = XpetraTraits<t_matrix_t>::doMigration(
343  *tm, numLocalRows, myNewRows);
344 
345  RCP<x_matrix_t> xmnew = XpetraTraits<t_matrix_t>::convertToXpetra(tmnew);
346 
347  return xmnew;
348  }
349  }
350 };
351 
352 
354 // Tpetra::CrsGraph
355 template <typename lno_t,
356  typename gno_t,
357  typename node_t>
358 struct XpetraTraits<Tpetra::CrsGraph<lno_t, gno_t, node_t> >
359 {
360  typedef typename Xpetra::CrsGraph<lno_t, gno_t, node_t> xgraph_t;
361  typedef typename Xpetra::TpetraCrsGraph<lno_t, gno_t, node_t> xtgraph_t;
362  typedef typename Tpetra::CrsGraph<lno_t, gno_t, node_t> tgraph_t;
363 
364  static inline RCP<xgraph_t> convertToXpetra(const RCP<tgraph_t> &a)
365  {
366  return rcp(new xtgraph_t(a));
367  }
368 
369  static RCP<tgraph_t> doMigration(const tgraph_t &from,
370  size_t numLocalRows, const gno_t *myNewRows)
371  {
372  typedef Tpetra::Map<lno_t, gno_t, node_t> map_t;
373  lno_t base = 0;
374 
375  // source map
376  const RCP<const map_t> &smap = from.getRowMap();
377  int oldNumElts = smap->getNodeNumElements();
378  gno_t numGlobalRows = smap->getGlobalNumElements();
379 
380  // target map
381  ArrayView<const gno_t> rowList(myNewRows, numLocalRows);
382  const RCP<const Teuchos::Comm<int> > &comm = from.getComm();
383  RCP<const map_t> tmap = rcp(
384  new map_t(numGlobalRows, rowList, base, comm));
385 
386  // importer
387  Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap);
388 
389  // number of entries in my new rows
390  typedef Tpetra::Vector<gno_t, lno_t, gno_t, node_t> vector_t;
391  vector_t numOld(smap);
392  vector_t numNew(tmap);
393  for (int lid=0; lid < oldNumElts; lid++){
394  numOld.replaceGlobalValue(smap->getGlobalElement(lid),
395  from.getNumEntriesInLocalRow(lid));
396  }
397  numNew.doImport(numOld, importer, Tpetra::INSERT);
398 
399  size_t numElts = tmap->getNodeNumElements();
400  ArrayRCP<const gno_t> nnz;
401  if (numElts > 0)
402  nnz = numNew.getData(0); // hangs if vector len == 0
403 
404  ArrayRCP<const size_t> nnz_size_t;
405 
406  if (numElts && sizeof(gno_t) != sizeof(size_t)){
407  size_t *vals = new size_t [numElts];
408  nnz_size_t = arcp(vals, 0, numElts, true);
409  for (size_t i=0; i < numElts; i++){
410  vals[i] = static_cast<size_t>(nnz[i]);
411  }
412  }
413  else{
414  nnz_size_t = arcp_reinterpret_cast<const size_t>(nnz);
415  }
416 
417  // target graph
418  RCP<tgraph_t> G = rcp(new tgraph_t(tmap, nnz_size_t, Tpetra::StaticProfile));
419 
420  G->doImport(from, importer, Tpetra::INSERT);
421  G->fillComplete();
422 
423  return G;
424  }
425 
426 };
427 
429 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
430 // Epetra_CrsGraph
431 template < >
432 struct XpetraTraits<Epetra_CrsGraph>
433 {
437  static inline RCP<Xpetra::CrsGraph<lno_t,gno_t,node_t> >
438  convertToXpetra(const RCP<Epetra_CrsGraph> &a)
439  {
440  return rcp(new Xpetra::EpetraCrsGraphT<gno_t,node_t>(a));
441  }
442 
443  static RCP<Epetra_CrsGraph> doMigration(const Epetra_CrsGraph &from,
444  size_t numLocalRows, const gno_t *myNewRows)
445  {
446  lno_t base = 0;
447 
448  // source map
449  const Epetra_BlockMap &smap = from.RowMap();
450  gno_t numGlobalRows = smap.NumGlobalElements();
451  lno_t oldNumElts = smap.NumMyElements();
452 
453  // target map
454  const Epetra_Comm &comm = from.Comm();
455  Epetra_BlockMap tmap(numGlobalRows, numLocalRows,
456  myNewRows, 1, base, comm);
457  lno_t newNumElts = tmap.NumMyElements();
458 
459  // importer
460  Epetra_Import importer(tmap, smap);
461 
462  // number of non zeros in my new rows
463  Epetra_Vector numOld(smap);
464  Epetra_Vector numNew(tmap);
465 
466  for (int lid=0; lid < oldNumElts; lid++){
467  numOld[lid] = from.NumMyIndices(lid);
468  }
469  numNew.Import(numOld, importer, Insert);
470 
471  Array<int> nnz(newNumElts);
472  for (int lid=0; lid < newNumElts; lid++){
473  nnz[lid] = static_cast<int>(numNew[lid]);
474  }
475 
476  // target graph
477  RCP<Epetra_CrsGraph> G = rcp(new Epetra_CrsGraph(::Copy, tmap, nnz.getRawPtr(), true));
478  G->Import(from, importer, Insert);
479  G->FillComplete();
480 
481  return G;
482  }
483 
484 };
485 #endif
486 
488 // Xpetra::CrsGraph
489 // KDDKDD Do we need specializations for Xpetra::TpetraCrsGraph and
490 // KDDKDD Xpetra::EpetraCrsGraph?
491 template <typename lno_t,
492  typename gno_t,
493  typename node_t>
494 struct XpetraTraits<Xpetra::CrsGraph<lno_t, gno_t, node_t> >
495 {
496  typedef Xpetra::CrsGraph<lno_t, gno_t, node_t> x_graph_t;
497  typedef Xpetra::TpetraCrsGraph<lno_t, gno_t, node_t> xt_graph_t;
498  typedef Tpetra::CrsGraph<lno_t,gno_t,node_t> t_graph_t;
499 
500  static inline RCP<x_graph_t> convertToXpetra(const RCP<x_graph_t> &a)
501  {
502  return a;
503  }
504 
505  static RCP<x_graph_t> doMigration(const x_graph_t &from,
506  size_t numLocalRows, const gno_t *myNewRows)
507  {
508  Xpetra::UnderlyingLib lib = from.getRowMap()->lib();
509 
510  if (lib == Xpetra::UseEpetra){
511  throw std::logic_error("compiler should have used specialization");
512  } else{
513  // Do the import with the Tpetra::CrsGraph traits object
514  const xt_graph_t *xtg = dynamic_cast<const xt_graph_t *>(&from);
515  RCP<const t_graph_t> tg = xtg->getTpetra_CrsGraph();
516 
517  RCP<t_graph_t> tgnew = XpetraTraits<t_graph_t>::doMigration(
518  *tg, numLocalRows, myNewRows);
519 
520  RCP<x_graph_t> xgnew = XpetraTraits<t_graph_t>::convertToXpetra(tgnew);
521  return xgnew;
522  }
523  }
524 };
525 
526 
527 
529 // Xpetra::RowMatrix
530 template <typename scalar_t,
531  typename lno_t,
532  typename gno_t,
533  typename node_t>
534 struct XpetraTraits<Xpetra::RowMatrix<scalar_t, lno_t, gno_t, node_t> >
535 {
536  typedef Xpetra::RowMatrix<scalar_t, lno_t, gno_t, node_t> x_matrix_t;
537  typedef Xpetra::TpetraRowMatrix<scalar_t, lno_t, gno_t, node_t> xt_matrix_t;
538  typedef Tpetra::RowMatrix<scalar_t,lno_t,gno_t,node_t> t_matrix_t;
539 
540  static inline RCP<x_matrix_t> convertToXpetra(const RCP<x_matrix_t > &a)
541  {
542  return a;
543  }
544 
545  static RCP<x_matrix_t> doMigration(const x_matrix_t &from,
546  size_t numLocalRows, const gno_t *myNewRows)
547  {
548  Xpetra::UnderlyingLib lib = from.getRowMap()->lib();
549 
550  if (lib == Xpetra::UseEpetra){
551  throw std::logic_error("compiler should have used specialization");
552  } else{
553  // Do the import with the Tpetra::CrsMatrix traits object
554  const xt_matrix_t *xtm = dynamic_cast<const xt_matrix_t *>(&from);
555  RCP<const t_matrix_t> tm = xtm->getTpetra_CrsMatrix();
556 
557  RCP<t_matrix_t> tmnew = XpetraTraits<t_matrix_t>::doMigration(
558  *tm, numLocalRows, myNewRows);
559 
560  RCP<x_matrix_t> xmnew = XpetraTraits<t_matrix_t>::convertToXpetra(tmnew);
561 
562  return xmnew;
563  }
564  }
565 };
566 
568 // Xpetra::CrsGraph specialization
569 template < typename node_t>
570 struct XpetraTraits<Xpetra::CrsGraph<int, int, node_t> >
571 {
572  typedef int lno_t;
573  typedef int gno_t;
574  typedef Xpetra::CrsGraph<lno_t, gno_t, node_t> x_graph_t;
575  typedef Xpetra::TpetraCrsGraph<lno_t, gno_t, node_t> xt_graph_t;
576  typedef Tpetra::CrsGraph<lno_t,gno_t,node_t> t_graph_t;
577 
578  static inline RCP<x_graph_t> convertToXpetra(const RCP<x_graph_t> &a)
579  {
580  return a;
581  }
582 
583  static RCP<x_graph_t> doMigration(const x_graph_t &from,
584  size_t numLocalRows, const gno_t *myNewRows)
585  {
586  Xpetra::UnderlyingLib lib = from.getRowMap()->lib();
587 
588  if (lib == Xpetra::UseEpetra){
589 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
590  typedef Xpetra::EpetraCrsGraphT<gno_t,node_t> xe_graph_t;
591  typedef Epetra_CrsGraph e_graph_t;
592  // Do the import with the Epetra_CrsGraph traits object
593  const xe_graph_t *xeg = dynamic_cast<const xe_graph_t *>(&from);
594  RCP<const e_graph_t> eg = xeg->getEpetra_CrsGraph();
595 
596  RCP<e_graph_t> egnew = XpetraTraits<e_graph_t>::doMigration(
597  *eg, numLocalRows, myNewRows);
598 
599  RCP<x_graph_t> xgnew = XpetraTraits<e_graph_t>::convertToXpetra(egnew);
600 
601  return xgnew;
602 #else
603  throw std::runtime_error("Xpetra with Epetra requested, but "
604  "Trilinos is not built with Epetra");
605 #endif
606  } else{
607  // Do the import with the Tpetra::CrsGraph traits object
608  const xt_graph_t *xtg = dynamic_cast<const xt_graph_t *>(&from);
609  RCP<const t_graph_t> tg = xtg->getTpetra_CrsGraph();
610 
611  RCP<t_graph_t> tgnew = XpetraTraits<t_graph_t>::doMigration(
612  *tg, numLocalRows, myNewRows);
613 
614  RCP<x_graph_t> xgnew = XpetraTraits<t_graph_t>::convertToXpetra(tgnew);
615 
616  return xgnew;
617  }
618  }
619 };
620 
622 // Tpetra::Vector
623 template <typename scalar_t,
624  typename lno_t,
625  typename gno_t,
626  typename node_t>
627 struct XpetraTraits<Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> >
628 {
629  typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> t_vector_t;
630  typedef Xpetra::TpetraVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t;
631  typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t;
632 
633  static inline RCP<x_vector_t> convertToXpetra(const RCP<t_vector_t> &a)
634  {
635  return rcp(new xt_vector_t(a));
636  }
637 
638  static RCP<t_vector_t> doMigration(const t_vector_t &from,
639  size_t numLocalElts, const gno_t *myNewElts)
640  {
641  lno_t base = 0;
642  typedef Tpetra::Map<lno_t, gno_t, node_t> map_t;
643 
644  // source map
645  const RCP<const map_t> &smap = from.getMap();
646  gno_t numGlobalElts = smap->getGlobalNumElements();
647 
648  // target map
649  ArrayView<const gno_t> eltList(myNewElts, numLocalElts);
650  const RCP<const Teuchos::Comm<int> > comm = from.getMap()->getComm();
651  RCP<const map_t> tmap = rcp(
652  new map_t(numGlobalElts, eltList, base, comm));
653 
654  // importer
655  Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap);
656 
657  // target vector
658  RCP<t_vector_t> V =
659  Tpetra::createVector<scalar_t,lno_t,gno_t,node_t>(tmap);
660  V->doImport(from, importer, Tpetra::INSERT);
661 
662  return V;
663  }
664 };
665 
667 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
668 // Epetra_Vector
669 template < >
670 struct XpetraTraits<Epetra_Vector>
671 {
674  typedef InputTraits<Epetra_Vector>::node_t node_t;
675  typedef InputTraits<Epetra_Vector>::scalar_t scalar_t;
676 
677  typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t;
678 
679  static inline RCP<x_vector_t> convertToXpetra(const RCP<Epetra_Vector> &a)
680  {
681  RCP<Xpetra::EpetraVectorT<gno_t,node_t> > xev = rcp(new Xpetra::EpetraVectorT<gno_t,node_t>(a));
682  return rcp_implicit_cast<x_vector_t>(xev);
683  }
684 
685  static RCP<Epetra_Vector> doMigration(const Epetra_Vector &from,
686  size_t numLocalElts, const gno_t *myNewElts)
687  {
688  lno_t base = 0;
689  // source map
690  const Epetra_BlockMap &smap = from.Map();
691  gno_t numGlobalElts = smap.NumGlobalElements();
692 
693  // target map
694  const Epetra_Comm &comm = from.Comm();
695  const Epetra_BlockMap tmap(numGlobalElts, numLocalElts, myNewElts,
696  1, base, comm);
697 
698  // importer
699  Epetra_Import importer(tmap, smap);
700 
701  // target vector
702  RCP<Epetra_Vector> V = rcp(new Epetra_Vector(tmap, true));
703  Epetra_CombineMode c = Insert;
704  V->Import(from, importer, c);
705 
706  return V;
707  }
708 };
709 #endif
710 
712 // Xpetra::Vector
713 template <typename scalar_t,
714  typename lno_t,
715  typename gno_t,
716  typename node_t>
717 struct XpetraTraits<Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> >
718 {
719  typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t;
720  typedef Xpetra::TpetraVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t;
721  typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> t_vector_t;
722 
723  static inline RCP<x_vector_t> convertToXpetra(const RCP<x_vector_t> &a)
724  {
725  return a;
726  }
727 
728  static RCP<x_vector_t> doMigration(const x_vector_t &from,
729  size_t numLocalRows, const gno_t *myNewRows)
730  {
731  Xpetra::UnderlyingLib lib = from.getMap()->lib();
732 
733  if (lib == Xpetra::UseEpetra){
734  throw std::logic_error("compiler should have used specialization");
735  } else{
736  // Do the import with the Tpetra::Vector traits object
737  const xt_vector_t *xtv = dynamic_cast<const xt_vector_t *>(&from);
738  RCP<const t_vector_t> tv = xtv->getTpetra_Vector();
739 
740  RCP<t_vector_t> tvnew = XpetraTraits<t_vector_t>::doMigration(
741  *tv, numLocalRows, myNewRows);
742 
743  RCP<x_vector_t> xvnew = XpetraTraits<t_vector_t>::convertToXpetra(tvnew);
744 
745  return xvnew;
746  }
747  }
748 };
749 
751 // Xpetra::Vector specialization
752 template <typename node_t>
753 struct XpetraTraits<Xpetra::Vector<double, int, int, node_t> >
754 {
755  typedef double scalar_t;
756  typedef int lno_t;
757  typedef int gno_t;
758  typedef Xpetra::Vector<scalar_t, lno_t, gno_t, node_t> x_vector_t;
759  typedef Xpetra::TpetraVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t;
760  typedef Tpetra::Vector<scalar_t, lno_t, gno_t, node_t> t_vector_t;
761 
762  static inline RCP<x_vector_t> convertToXpetra(const RCP<x_vector_t> &a)
763  {
764  return a;
765  }
766 
767  static RCP<x_vector_t> doMigration(const x_vector_t &from,
768  size_t numLocalRows, const gno_t *myNewRows)
769  {
770  Xpetra::UnderlyingLib lib = from.getMap()->lib();
771 
772  if (lib == Xpetra::UseEpetra){
773 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
774  typedef Epetra_Vector e_vector_t;
775  typedef Xpetra::EpetraVectorT<gno_t,node_t> xe_vector_t;
776  // Do the import with the Epetra_Vector traits object
777  const xe_vector_t *xev = dynamic_cast<const xe_vector_t *>(&from);
778  RCP<const e_vector_t> ev = rcp(xev->getEpetra_Vector());
779 
780  RCP<e_vector_t> evnew = XpetraTraits<e_vector_t>::doMigration(
781  *ev, numLocalRows, myNewRows);
782 
783  RCP<x_vector_t> xvnew = XpetraTraits<e_vector_t>::convertToXpetra(evnew);
784 
785  return xvnew;
786 #else
787  throw std::runtime_error("Xpetra with Epetra requested, but "
788  "Trilinos is not built with Epetra");
789 #endif
790  } else{
791  // Do the import with the Tpetra::Vector traits object
792  const xt_vector_t *xtv = dynamic_cast<const xt_vector_t *>(&from);
793  RCP<t_vector_t> tv = xtv->getTpetra_Vector();
794 
795  RCP<t_vector_t> tvnew = XpetraTraits<t_vector_t>::doMigration(
796  *tv, numLocalRows, myNewRows);
797 
798  RCP<x_vector_t> xvnew = XpetraTraits<t_vector_t>::convertToXpetra(tvnew);
799 
800  return xvnew;
801  }
802  }
803 };
804 
806 // Tpetra::MultiVector
807 template <typename scalar_t,
808  typename lno_t,
809  typename gno_t,
810  typename node_t>
811 struct XpetraTraits<Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> >
812 {
813  typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> t_vector_t;
814  typedef Xpetra::TpetraMultiVector<scalar_t, lno_t, gno_t, node_t> xt_vector_t;
815  typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_vector_t;
816 
817  static inline RCP<x_vector_t> convertToXpetra(const RCP<t_vector_t> &a)
818  {
819  return rcp(new xt_vector_t(a));
820  }
821 
822  static RCP<t_vector_t> doMigration(const t_vector_t &from,
823  size_t numLocalElts, const gno_t *myNewElts)
824  {
825  typedef Tpetra::Map<lno_t, gno_t, node_t> map_t;
826  lno_t base = 0;
827 
828  // source map
829  const RCP<const map_t> &smap = from.getMap();
830  gno_t numGlobalElts = smap->getGlobalNumElements();
831 
832  // target map
833  ArrayView<const gno_t> eltList(myNewElts, numLocalElts);
834  const RCP<const Teuchos::Comm<int> > comm = from.getMap()->getComm();
835  RCP<const map_t> tmap = rcp(
836  new map_t(numGlobalElts, eltList, base, comm));
837 
838  // importer
839  Tpetra::Import<lno_t, gno_t, node_t> importer(smap, tmap);
840 
841  // target vector
842  RCP<t_vector_t> MV = rcp(
843  new t_vector_t(tmap, from.getNumVectors(), true));
844  MV->doImport(from, importer, Tpetra::INSERT);
845 
846  return MV;
847  }
848 };
849 
851 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
852 // Epetra_MultiVector
853 template < >
854 struct XpetraTraits<Epetra_MultiVector>
855 {
860  typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t;
861 
862  static inline RCP<x_mvector_t> convertToXpetra(
863  const RCP<Epetra_MultiVector> &a)
864  {
865  RCP<Xpetra::EpetraMultiVectorT<gno_t,node_t> > xemv = rcp(new Xpetra::EpetraMultiVectorT<gno_t,node_t>(a));
866  return rcp_implicit_cast<x_mvector_t>(xemv);
867  }
868 
869  static RCP<Epetra_MultiVector> doMigration(const Epetra_MultiVector &from,
870  size_t numLocalElts, const gno_t *myNewElts)
871  {
872  lno_t base = 0;
873  // source map
874  const Epetra_BlockMap &smap = from.Map();
875  gno_t numGlobalElts = smap.NumGlobalElements();
876 
877  // target map
878  const Epetra_Comm &comm = from.Comm();
879  const Epetra_BlockMap tmap(numGlobalElts, numLocalElts, myNewElts,
880  1, base, comm);
881 
882  // importer
883  Epetra_Import importer(tmap, smap);
884 
885  // target vector
886  RCP<Epetra_MultiVector> MV = rcp(
887  new Epetra_MultiVector(tmap, from.NumVectors(), true));
888  Epetra_CombineMode c = Insert;
889  MV->Import(from, importer, c);
890 
891  return MV;
892  }
893 };
894 #endif
895 
897 // Xpetra::MultiVector
898 template <typename scalar_t,
899  typename lno_t,
900  typename gno_t,
901  typename node_t>
902 struct XpetraTraits<Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> >
903 {
904  typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t;
905  typedef Xpetra::TpetraMultiVector<scalar_t, lno_t, gno_t, node_t> xt_mvector_t;
906  typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> t_mvector_t;
907 
908  static inline RCP<x_mvector_t> convertToXpetra(const RCP<x_mvector_t> &a)
909  {
910  return a;
911  }
912 
913  static RCP<x_mvector_t> doMigration(const x_mvector_t &from,
914  size_t numLocalRows, const gno_t *myNewRows)
915  {
916  Xpetra::UnderlyingLib lib = from.getMap()->lib();
917 
918  if (lib == Xpetra::UseEpetra){
919  throw std::logic_error("compiler should have used specialization");
920  } else{
921  // Do the import with the Tpetra::MultiVector traits object
922  const xt_mvector_t *xtv = dynamic_cast<const xt_mvector_t *>(&from);
923  RCP<t_mvector_t> tv = xtv->getTpetra_MultiVector();
924 
925  RCP<t_mvector_t> tvnew = XpetraTraits<t_mvector_t>::doMigration(
926  *tv, numLocalRows, myNewRows);
927 
928  RCP<x_mvector_t> xvnew = XpetraTraits<t_mvector_t>::convertToXpetra(tvnew);
929 
930  return xvnew;
931  }
932  }
933 };
934 
936 // Xpetra::MultiVector specialization
937 template <typename node_t>
938 struct XpetraTraits<Xpetra::MultiVector<double, int, int, node_t> >
939 {
940  typedef double scalar_t;
941  typedef int lno_t;
942  typedef int gno_t;
943  typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t;
944  typedef Xpetra::TpetraMultiVector<scalar_t, lno_t, gno_t, node_t> xt_mvector_t;
945  typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> t_mvector_t;
946 
947  static inline RCP<x_mvector_t> convertToXpetra(const RCP<x_mvector_t> &a)
948  {
949  return a;
950  }
951 
952  static RCP<x_mvector_t> doMigration(const x_mvector_t &from,
953  size_t numLocalRows, const gno_t *myNewRows)
954  {
955  Xpetra::UnderlyingLib lib = from.getMap()->lib();
956 
957  if (lib == Xpetra::UseEpetra){
958 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
959  typedef Epetra_MultiVector e_mvector_t;
960  typedef Xpetra::EpetraMultiVectorT<gno_t,node_t> xe_mvector_t;
961  // Do the import with the Epetra_MultiVector traits object
962  const xe_mvector_t *xev = dynamic_cast<const xe_mvector_t *>(&from);
963  RCP<e_mvector_t> ev = xev->getEpetra_MultiVector();
964 
965  RCP<e_mvector_t> evnew = XpetraTraits<e_mvector_t>::doMigration(
966  *ev, numLocalRows, myNewRows);
967 
968  RCP<x_mvector_t> xvnew = XpetraTraits<e_mvector_t>::convertToXpetra(evnew);
969 
970  return xvnew;
971 #else
972  throw std::runtime_error("Xpetra with Epetra requested, but "
973  "Trilinos is not built with Epetra");
974 #endif
975  } else{
976  // Do the import with the Tpetra::MultiVector traits object
977  const xt_mvector_t *xtv = dynamic_cast<const xt_mvector_t *>(&from);
978  RCP<t_mvector_t> tv = xtv->getTpetra_MultiVector();
979 
980  RCP<t_mvector_t> tvnew = XpetraTraits<t_mvector_t>::doMigration(
981  *tv, numLocalRows, myNewRows);
982 
983  RCP<x_mvector_t> xvnew = XpetraTraits<t_mvector_t>::convertToXpetra(tvnew);
984 
985  return xvnew;
986  }
987  }
988 };
989 
990 #endif // DOXYGEN_SHOULD_SKIP_THIS
991 
992 } //namespace Zoltan2
993 
994 #endif // _ZOLTAN2_XPETRATRAITS_HPP_
Defines the traits required for Tpetra, Eptra and Xpetra objects.
default_gno_t gno_t
The objects global ordinal data type.
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > tmatrix_t
Xpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > xmatrix_t
static RCP< User > doMigration(const User &from, size_t numLocalRows, const gno_t *myNewRows)
Migrate the object Given a user object and a new row distribution, create and return a new user objec...
Xpetra::CrsGraph< zlno_t, zgno_t, znode_t > xgraph_t
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.
dictionary vals
Definition: xml2dox.py:186
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices...
Traits for application input objects.
default_gno_t gno_t
The ordinal type (e.g., int, long, int64_t) that can represent global counts and identifiers.
default_node_t node_t
The Kokkos node type. This is only meaningful for users of Tpetra objects.
default_lno_t lno_t
The objects local ordinal data type.
Tpetra::Vector< z2TestScalar, z2TestLO, z2TestGO > Vector
Gathering definitions used in software development.
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tgraph_t
default_scalar_t scalar_t
The data type for weights and coordinates.