Tpetra parallel linear algebra  Version of the Day
Tpetra_Import_Util.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_IMPORT_UTIL_HPP
43 #define TPETRA_IMPORT_UTIL_HPP
44 
50 
51 #include "Tpetra_ConfigDefs.hpp"
52 #include "Tpetra_Import.hpp"
53 #include "Tpetra_HashTable.hpp"
54 #include "Tpetra_Map.hpp"
55 #include "Tpetra_Util.hpp"
56 #include "Tpetra_Distributor.hpp"
57 #include <Teuchos_Array.hpp>
58 #include <utility>
59 
60 namespace Tpetra {
61  namespace Import_Util {
68  template <typename LocalOrdinal, typename GlobalOrdinal, typename Node>
69  void
71  Teuchos::Array< std::pair<int,GlobalOrdinal> >& gpids,
72  bool use_minus_one_for_local);
73 
75  template <typename LocalOrdinal, typename GlobalOrdinal, typename Node>
76  void
78  Teuchos::Array<int>& pids,
79  bool use_minus_one_for_local);
80 
83  template <typename LocalOrdinal, typename GlobalOrdinal, typename Node>
84  void
86  Teuchos::Array<int>& RemotePIDs);
87  } // namespace Import_Util
88 } // namespace Tpetra
89 
90 namespace Tpetra {
91 namespace Import_Util {
92 
93 template <typename LocalOrdinal, typename GlobalOrdinal, typename Node>
94 void
96  Teuchos::Array< std::pair<int,GlobalOrdinal> >& gpids,
97  bool use_minus_one_for_local)
98 {
99  // Put the (PID,GID) pair in member of Importer.TargetMap() in
100  // gpids. If use_minus_one_for_local==true, put in -1 instead of
101  // MyPID.
102  const Tpetra::Distributor& D = Importer.getDistributor();
103 
104  LocalOrdinal ii;
105  size_t i,j,k;
106  int mypid = Importer.getTargetMap()->getComm()->getRank();
107  size_t N = Importer.getTargetMap()->getNodeNumElements();
108 
109  // Get the importer's data
110  Teuchos::ArrayView<const LocalOrdinal> RemoteLIDs = Importer.getRemoteLIDs();
111 
112  // Get the distributor's data
113  size_t NumReceives = D.getNumReceives();
114  Teuchos::ArrayView<const int> ProcsFrom = D.getImagesFrom();
115  Teuchos::ArrayView<const size_t> LengthsFrom = D.getLengthsFrom();
116 
117  // Resize the outgoing data structure
118  gpids.resize(N);
119 
120  // Start by claiming that I own all the data
121  LocalOrdinal lzero = Teuchos::ScalarTraits<LocalOrdinal>::zero();
122  if(use_minus_one_for_local)
123  for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) gpids[ii]=std::make_pair(-1,Importer.getTargetMap()->getGlobalElement(ii));
124  else
125  for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) gpids[ii]=std::make_pair(mypid,Importer.getTargetMap()->getGlobalElement(ii));
126 
127  // Now, for each remote ID, record who actually owns it. This loop follows the operation order in the
128  // MpiDistributor so it ought to duplicate that effect.
129  for(i=0,j=0; i<NumReceives; i++){
130  int pid=ProcsFrom[i];
131  for(k=0; k<LengthsFrom[i]; k++){
132  if(pid!=mypid) gpids[RemoteLIDs[j]].first=pid;
133  j++;
134  }
135  }
136 }
137 
138 template <typename LocalOrdinal, typename GlobalOrdinal, typename Node>
139 void
141  Teuchos::Array<int>& pids,
142  bool use_minus_one_for_local)
143 {
144  const Tpetra::Distributor & D=Importer.getDistributor();
145 
146  LocalOrdinal ii;
147  size_t i,j,k;
148  int mypid = Importer.getTargetMap()->getComm()->getRank();
149  size_t N = Importer.getTargetMap()->getNodeNumElements();
150 
151  // Get the importer's data
152  Teuchos::ArrayView<const LocalOrdinal> RemoteLIDs = Importer.getRemoteLIDs();
153 
154  // Get the distributor's data
155  size_t NumReceives = D.getNumReceives();
156  Teuchos::ArrayView<const int> ProcsFrom = D.getImagesFrom();
157  Teuchos::ArrayView<const size_t> LengthsFrom = D.getLengthsFrom();
158 
159  // Resize the outgoing data structure
160  pids.resize(N);
161 
162  // Start by claiming that I own all the data
163  LocalOrdinal lzero = Teuchos::ScalarTraits<LocalOrdinal>::zero();
164  if(use_minus_one_for_local)
165  for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) pids[ii]=-1;
166  else
167  for(ii=lzero; Teuchos::as<size_t>(ii)<N; ii++) pids[ii]=mypid;
168 
169  // Now, for each remote ID, record who actually owns it. This loop follows the operation order in the
170  // MpiDistributor so it ought to duplicate that effect.
171  for(i=0,j=0; i<NumReceives; i++){
172  int pid=ProcsFrom[i];
173  for(k=0; k<LengthsFrom[i]; k++){
174  if(pid!=mypid) pids[RemoteLIDs[j]]=pid;
175  j++;
176  }
177  }
178 }
179 
180 template <typename LocalOrdinal, typename GlobalOrdinal, typename Node>
181 void
183  Teuchos::Array<int>& RemotePIDs)
184 {
185  const Tpetra::Distributor& D = Importer.getDistributor();
186 
187  // Get the importer's data
188  Teuchos::ArrayView<const LocalOrdinal> RemoteLIDs = Importer.getRemoteLIDs();
189 
190  // Get the distributor's data
191  size_t NumReceives = D.getNumReceives();
192  Teuchos::ArrayView<const int> ProcsFrom = D.getImagesFrom();
193  Teuchos::ArrayView<const size_t> LengthsFrom = D.getLengthsFrom();
194 
195  // Resize the outgoing data structure
196  RemotePIDs.resize(Importer.getNumRemoteIDs());
197 
198  // Now, for each remote ID, record who actually owns it. This loop
199  // follows the operation order in the MpiDistributor so it ought to
200  // duplicate that effect.
201  size_t i,j,k;
202  for (i = 0, j = 0; i < NumReceives; ++i) {
203  const int pid = ProcsFrom[i];
204  for (k = 0; k < LengthsFrom[i]; ++k) {
205  RemotePIDs[j] = pid;
206  j++;
207  }
208  }
209 }
210 
211 } // namespace Import_Util
212 } // namespace Tpetra
213 
214 #endif // TPETRA_IMPORT_UTIL_HPP
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
size_t getNumReceives() const
The number of processes from which we will receive data.
ArrayView< const size_t > getLengthsFrom() const
Number of values this process will receive from each process.
void getRemotePIDs(const Tpetra::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 getPidGidPairs(const Tpetra::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.
Sets up and executes a communication plan for a Tpetra DistObject.
Stand-alone utility functions and macros.
ArrayView< const int > getImagesFrom() const
Ranks of the processes sending values to this process.
Distributor & getDistributor() const
The Distributor that this Import object uses to move data.
size_t getNumRemoteIDs() const
Number of entries not on the calling process.
void getPids(const Tpetra::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.
Teuchos::RCP< const map_type > getTargetMap() const
The Target Map used to construct this Import object.