Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Xpetra_ImportUtils.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Xpetra: A linear algebra interface package
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
39 // Jonathan Hu (jhu@sandia.gov)
40 // Ray Tuminaro (rstumin@sandia.gov)
41 // Chris Siefert (csiefer@sandia.gov)
42 // Luc Berger-Vergoat (lberge@sandia.gov)
43 //
44 // ***********************************************************************
45 //
46 // @HEADER
47 #ifndef PACKAGES_XPETRA_IMPORT_UTILS_HPP_
48 #define PACKAGES_XPETRA_IMPORT_UTILS_HPP_
49 
50 #include "Xpetra_ConfigDefs.hpp"
51 #include "Xpetra_Exceptions.hpp"
52 #include "Xpetra_Map.hpp" // definition of UnderlyingLib
53 #include "Xpetra_Import.hpp"
54 #include "Teuchos_Array.hpp"
55 #include "Teuchos_ArrayView.hpp"
56 
57 #include <utility>
58 
59 #ifdef HAVE_XPETRA_EPETRA
60 #include "Epetra_Util.h"
61 #include "Xpetra_EpetraImport.hpp"
62 #endif
63 
64 #ifdef HAVE_XPETRA_TPETRA
65 #include "Xpetra_TpetraImport.hpp"
66 #include "Tpetra_Import_Util.hpp"
67 #endif
68 
69 namespace Xpetra {
70 
78 template <class LocalOrdinal,
79  class GlobalOrdinal,
80  class Node = Tpetra::KokkosClassic::DefaultNode::DefaultNodeType>
81 class ImportUtils {
82 #undef XPETRA_IMPORTUTILS_SHORT
83 
84  public:
91  void
93  Teuchos::Array<std::pair<int, GlobalOrdinal> >& gpids,
94  bool use_minus_one_for_local) {
95  UnderlyingLib lib = Importer.getSourceMap()->lib();
96  if (lib == Xpetra::UseEpetra) {
97 #if defined(HAVE_XPETRA_EPETRA)
98  throw(Xpetra::Exceptions::RuntimeError("Xpetra::ImportUtils only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
99 #endif // HAVE_XPETRA_EPETRA
100  } else if (lib == Xpetra::UseTpetra) {
101 #ifdef HAVE_XPETRA_TPETRA
102  Tpetra::Import_Util::getPidGidPairs(Xpetra::toTpetra(Importer), gpids, use_minus_one_for_local);
103 #endif // HAVE_XPETRA_TPETRA
104  }
105  }
106 
108  void
110  Teuchos::Array<int>& pids,
111  bool use_minus_one_for_local) {
112  UnderlyingLib lib = Importer.getSourceMap()->lib();
113  if (lib == Xpetra::UseEpetra) {
114 #if defined(HAVE_XPETRA_EPETRA)
115  throw(Xpetra::Exceptions::RuntimeError("Xpetra::ImportUtils only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
116 #endif // HAVE_XPETRA_EPETRA
117  } else if (lib == Xpetra::UseTpetra) {
118 #ifdef HAVE_XPETRA_TPETRA
119  Tpetra::Import_Util::getPids(Xpetra::toTpetra(Importer), pids, use_minus_one_for_local);
120 #endif // HAVE_XPETRA_TPETRA
121  }
122  }
123 
125  // Like the above, but without the resize
126  void
128  Teuchos::ArrayView<int>& pids,
129  bool use_minus_one_for_local) {
130  UnderlyingLib lib = Importer.getSourceMap()->lib();
131  if (lib == Xpetra::UseEpetra) {
132 #if defined(HAVE_XPETRA_EPETRA)
133  throw(Xpetra::Exceptions::RuntimeError("Xpetra::ImportUtils only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
134 #endif // HAVE_XPETRA_EPETRA
135  } else if (lib == Xpetra::UseTpetra) {
136 #ifdef HAVE_XPETRA_TPETRA
137  Tpetra::Import_Util::getPids(Xpetra::toTpetra(Importer), pids, use_minus_one_for_local);
138 #endif // HAVE_XPETRA_TPETRA
139  }
140  }
141 
144  void
146  Teuchos::Array<int>& RemotePIDs) {
147  UnderlyingLib lib = Importer.getSourceMap()->lib();
148  if (lib == Xpetra::UseEpetra) {
149 #if defined(HAVE_XPETRA_EPETRA)
150  throw(Xpetra::Exceptions::RuntimeError("Xpetra::ImportUtils only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
151 #endif // HAVE_XPETRA_EPETRA
152  } else if (lib == Xpetra::UseTpetra) {
153 #ifdef HAVE_XPETRA_TPETRA
154  Tpetra::Import_Util::getRemotePIDs(Xpetra::toTpetra(Importer), RemotePIDs);
155 #endif // HAVE_XPETRA_TPETRA
156  }
157  }
158 
159 }; // end class ImportUtils
160 
161 #ifdef HAVE_XPETRA_EPETRA
162 // Specialization for int, int, EpetraNode
163 template <>
164 class ImportUtils<int, int, EpetraNode> {
165  typedef int LocalOrdinal;
166  typedef int GlobalOrdinal;
167  typedef EpetraNode Node;
168 #undef XPETRA_IMPORTUTILS_SHORT
169 
170  public:
171  void
173  Teuchos::Array<std::pair<int, GlobalOrdinal> >& gpids,
174  bool use_minus_one_for_local) {
175  UnderlyingLib lib = Importer.getSourceMap()->lib();
176  if (lib == Xpetra::UseEpetra) {
177  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
178  std::vector<std::pair<int, GlobalOrdinal> > gpids_v(gpids.size());
179  Epetra_Util::GetPidGidPairs(*e_Importer, gpids_v, use_minus_one_for_local);
180  std::copy(gpids_v.begin(), gpids_v.end(), gpids.begin());
181  } else if (lib == Xpetra::UseTpetra) {
182 #ifdef HAVE_XPETRA_TPETRA
183  Tpetra::Import_Util::getPidGidPairs(Xpetra::toTpetra(Importer), gpids, use_minus_one_for_local);
184 #endif // HAVE_XPETRA_TPETRA
185  }
186  }
187 
189  void
191  Teuchos::Array<int>& pids,
192  bool use_minus_one_for_local) {
193  UnderlyingLib lib = Importer.getSourceMap()->lib();
194  if (lib == Xpetra::UseEpetra) {
195  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
196  std::vector<int> pids_v(pids.size());
197  Epetra_Util::GetPids(*e_Importer, pids_v, use_minus_one_for_local);
198  std::copy(pids_v.begin(), pids_v.end(), pids.begin());
199  } else if (lib == Xpetra::UseTpetra) {
200 #ifdef HAVE_XPETRA_TPETRA
201  Tpetra::Import_Util::getPids(Xpetra::toTpetra(Importer), pids, use_minus_one_for_local);
202 #endif // HAVE_XPETRA_TPETRA
203  }
204  }
205 
207  // Like the above, but without the resize
208  void
210  Teuchos::ArrayView<int>& pids,
211  bool use_minus_one_for_local) {
212  UnderlyingLib lib = Importer.getSourceMap()->lib();
213  if (lib == Xpetra::UseEpetra) {
214  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
215  std::vector<int> pids_v(pids.begin(), pids.end());
216  Epetra_Util::GetPids(*e_Importer, pids_v, use_minus_one_for_local);
217  } else if (lib == Xpetra::UseTpetra) {
218 #ifdef HAVE_XPETRA_TPETRA
219  Tpetra::Import_Util::getPids(Xpetra::toTpetra(Importer), pids, use_minus_one_for_local);
220 #endif // HAVE_XPETRA_TPETRA
221  }
222  }
223 
226  void
228  Teuchos::Array<int>& RemotePIDs) {
229  UnderlyingLib lib = Importer.getSourceMap()->lib();
230  if (lib == Xpetra::UseEpetra) {
231  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
232  std::vector<int> pids_v(RemotePIDs.size());
233  Epetra_Util::GetRemotePIDs(*e_Importer, pids_v);
234  std::copy(pids_v.begin(), pids_v.end(), RemotePIDs.begin());
235  } else if (lib == Xpetra::UseTpetra) {
236 #ifdef HAVE_XPETRA_TPETRA
237  Tpetra::Import_Util::getRemotePIDs(Xpetra::toTpetra(Importer), RemotePIDs);
238 #endif // HAVE_XPETRA_TPETRA
239  }
240  }
241 
242 }; // end class ImportUtils
243 
244 // Specialization for double, int, long long, EpetraNode
245 template <>
246 class ImportUtils<int, long long, EpetraNode> {
247  typedef int LocalOrdinal;
248  typedef long long GlobalOrdinal;
249  typedef EpetraNode Node;
250 #undef XPETRA_IMPORTUTILS_SHORT
251 
252  public:
253  void
255  Teuchos::Array<std::pair<int, GlobalOrdinal> >& gpids,
256  bool use_minus_one_for_local) {
257  UnderlyingLib lib = Importer.getSourceMap()->lib();
258  if (lib == Xpetra::UseEpetra) {
259  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
260  std::vector<std::pair<int, GlobalOrdinal> > gpids_v(gpids.size());
261  Epetra_Util::GetPidGidPairs(*e_Importer, gpids_v, use_minus_one_for_local);
262  std::copy(gpids_v.begin(), gpids_v.end(), gpids.begin());
263 
264  } else if (lib == Xpetra::UseTpetra) {
265 #ifdef HAVE_XPETRA_TPETRA
266  Tpetra::Import_Util::getPidGidPairs(Xpetra::toTpetra(Importer), gpids, use_minus_one_for_local);
267 #endif // HAVE_XPETRA_TPETRA
268  }
269  }
270 
272  void
274  Teuchos::Array<int>& pids,
275  bool use_minus_one_for_local) {
276  UnderlyingLib lib = Importer.getSourceMap()->lib();
277  if (lib == Xpetra::UseEpetra) {
278  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
279  std::vector<int> pids_v(pids.size());
280  Epetra_Util::GetPids(*e_Importer, pids_v, use_minus_one_for_local);
281  std::copy(pids_v.begin(), pids_v.end(), pids.begin());
282  } else if (lib == Xpetra::UseTpetra) {
283 #ifdef HAVE_XPETRA_TPETRA
284  Tpetra::Import_Util::getPids(Xpetra::toTpetra(Importer), pids, use_minus_one_for_local);
285 #endif // HAVE_XPETRA_TPETRA
286  }
287  }
288 
290  // Like the above, but without the resize
291  void
293  Teuchos::ArrayView<int>& pids,
294  bool use_minus_one_for_local) {
295  UnderlyingLib lib = Importer.getSourceMap()->lib();
296  if (lib == Xpetra::UseEpetra) {
297  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
298  std::vector<int> pids_v(pids.size());
299  Epetra_Util::GetPids(*e_Importer, pids_v, use_minus_one_for_local);
300  std::copy(pids_v.begin(), pids_v.end(), pids.begin());
301  } else if (lib == Xpetra::UseTpetra) {
302 #ifdef HAVE_XPETRA_TPETRA
303  Tpetra::Import_Util::getPids(Xpetra::toTpetra(Importer), pids, use_minus_one_for_local);
304 #endif // HAVE_XPETRA_TPETRA
305  }
306  }
307 
310  void
312  Teuchos::Array<int>& RemotePIDs) {
313  UnderlyingLib lib = Importer.getSourceMap()->lib();
314  if (lib == Xpetra::UseEpetra) {
315  RCP<const Epetra_Import> e_Importer = dynamic_cast<const EpetraImportT<GlobalOrdinal, Node>*>(&Importer)->getEpetra_Import();
316  std::vector<int> pids_v(RemotePIDs.size());
317  Epetra_Util::GetRemotePIDs(*e_Importer, pids_v);
318  std::copy(pids_v.begin(), pids_v.end(), RemotePIDs.begin());
319  } else if (lib == Xpetra::UseTpetra) {
320 #ifdef HAVE_XPETRA_TPETRA
321  Tpetra::Import_Util::getRemotePIDs(Xpetra::toTpetra(Importer), RemotePIDs);
322 #endif // HAVE_XPETRA_TPETRA
323  }
324  }
325 
326 }; // end class ImportUtils
327 #endif // HAVE_XPETRA_EPETRA for Epetra scpecialization
328 
329 } // end namespace Xpetra
330 
331 #define XPETRA_IMPORTUTILS_SHORT
332 
333 #endif // PACKAGES_XPETRA_IMPORT_UTILS_HPP_
void getPidGidPairs(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< std::pair< int, GlobalOrdinal > > &gpids, bool use_minus_one_for_local)
For each GID in the TargetMap, find who owns the GID in the SourceMap.
void getPidGidPairs(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< std::pair< int, GlobalOrdinal > > &gpids, bool use_minus_one_for_local)
void getRemotePIDs(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &RemotePIDs)
Get a list of remote PIDs from an importer in the order corresponding to the remote LIDs...
void getPids(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &pids, bool use_minus_one_for_local)
Like getPidGidPairs, but just gets the PIDs, ordered by the column Map.
Exception throws to report errors in the internal logical of the program.
void getPids(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::ArrayView< int > &pids, bool use_minus_one_for_local)
Like getPidGidPairs, but just gets the PIDs, ordered by the column Map.
void getPids(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::ArrayView< int > &pids, bool use_minus_one_for_local)
Like getPidGidPairs, but just gets the PIDs, ordered by the column Map.
void getRemotePIDs(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &RemotePIDs)
Get a list of remote PIDs from an importer in the order corresponding to the remote LIDs...
void getPids(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &pids, bool use_minus_one_for_local)
Like getPidGidPairs, but just gets the PIDs, ordered by the column Map.
RCP< const Tpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > toTpetra(const RCP< const CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > &graph)
void getPids(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::ArrayView< int > &pids, bool use_minus_one_for_local)
Like getPidGidPairs, but just gets the PIDs, ordered by the column Map.
Tpetra::KokkosCompat::KokkosSerialWrapperNode EpetraNode
void getRemotePIDs(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &RemotePIDs)
Get a list of remote PIDs from an importer in the order corresponding to the remote LIDs...
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getSourceMap() const =0
The Source Map used to construct this Import object.
Xpetra utility class for Import-related routines.
void getPids(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< int > &pids, bool use_minus_one_for_local)
Like getPidGidPairs, but just gets the PIDs, ordered by the column Map.
void getPidGidPairs(const Import< LocalOrdinal, GlobalOrdinal, Node > &Importer, Teuchos::Array< std::pair< int, GlobalOrdinal > > &gpids, bool use_minus_one_for_local)