Tpetra parallel linear algebra  Version of the Day
Tpetra_Details_Transfer_def.hpp
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_DETAILS_TRANSFER_DEF_HPP
43 #define TPETRA_DETAILS_TRANSFER_DEF_HPP
44 
45 #include "Tpetra_Details_Transfer_decl.hpp"
46 #include "Tpetra_Details_gathervPrint.hpp"
47 #include "Tpetra_Distributor.hpp"
48 #include "Tpetra_Map.hpp"
49 #include "Teuchos_CommHelpers.hpp"
50 #include "Teuchos_TypeNameTraits.hpp"
51 #include <sstream>
52 
53 namespace Tpetra {
54 namespace Details {
55 
56 template <class LO, class GO, class NT>
57 void
59 describe (Teuchos::FancyOStream& out,
60  const Teuchos::EVerbosityLevel verbLevel) const
61 {
62  this->describeImpl (out, "Tpetra::Details::Transfer", verbLevel);
63 }
64 
65 template<class LO, class GO, class NT>
66 void
68 describeImpl (Teuchos::FancyOStream& out,
69  const std::string& className,
70  const Teuchos::EVerbosityLevel verbLevel) const
71 {
72  using Teuchos::TypeNameTraits;
73  using Teuchos::VERB_DEFAULT;
74  using Teuchos::VERB_NONE;
75  using Teuchos::VERB_LOW;
76  using std::endl;
77  const Teuchos::EVerbosityLevel vl =
78  (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
79 
80  if (vl == VERB_NONE) {
81  return; // don't print anything
82  }
83  // If this Transfer's source Map or Comm is null, then the Transfer
84  // does not participate in collective operations with the other
85  // processes. In that case, it is not even legal to call this
86  // method. The reasonable thing to do in that case is nothing.
87  auto srcMap = this->getSourceMap ();
88  if (srcMap.is_null ()) {
89  return;
90  }
91  auto comm = srcMap->getComm ();
92  if (comm.is_null ()) {
93  return;
94  }
95  if (this->getTargetMap ().is_null () ||
96  this->getTargetMap ()->getComm ().is_null ()) {
97  return;
98  }
99 
100  const int myRank = comm->getRank ();
101  const int numProcs = comm->getSize ();
102 
103  // Only Process 0 should touch the output stream, but this method in
104  // general may need to do communication. Thus, we may need to
105  // preserve the current tab level across multiple "if (myRank == 0)
106  // { ... }" inner scopes. This is why we sometimes create OSTab
107  // instances by pointer, instead of by value.
108  Teuchos::RCP<Teuchos::OSTab> tab0, tab1;
109 
110  if (myRank == 0) {
111  // At every verbosity level but VERB_NONE, Process 0 prints.
112  // By convention, describe() always begins with a tab before
113  // printing.
114  tab0 = Teuchos::rcp (new Teuchos::OSTab (out));
115 
116  out << "\"" << className << "\":" << endl;
117  tab1 = Teuchos::rcp (new Teuchos::OSTab (out));
118 
119  {
120  out << "Template parameters:" << endl;
121  Teuchos::OSTab tab2 (out);
122  out << "LocalOrdinal: " << TypeNameTraits<LO>::name () << endl
123  << "GlobalOrdinal: " << TypeNameTraits<GO>::name () << endl
124  << "Node: " << TypeNameTraits<NT>::name () << endl;
125  }
126 
127  const std::string label = this->getObjectLabel ();
128  if (label != "") {
129  out << "Label: " << label << endl;
130  }
131  out << "Number of processes: " << numProcs << endl;
132  }
133 
134  if (vl > VERB_LOW) {
135  // At higher verbosity levels, describe() is allowed to
136  // communicate in order to print information from other
137  // processes in the object's communicator.
138  this->globalDescribe (out, vl);
139  }
140 
141  // It's illegal to call describe() on a process where either Map is
142  // null. (That implies the process in question is not participating
143  // in collective operations with either Map, and describe is
144  // collective over the Maps' communicator.) Thus, we don't have to
145  // define behavior when either Map is NULL on any process. Thus,
146  // it's OK that the code below isn't quite right (that is, won't
147  // print anything) if either Map is NULL on Process 0.
148 
149  if (myRank == 0) {
150  out << "Source Map:" << endl;
151  }
152  // This is collective over the Map's communicator.
153  this->getSourceMap ()->describe (out, vl);
154 
155  if (myRank == 0) {
156  out << "Target Map:" << endl;
157  }
158  // This is collective over the Map's communicator.
159  this->getTargetMap ()->describe (out, vl);
160 
161  if (myRank == 0) {
162  out << "Distributor:" << endl;
163  }
164  this->getDistributor ().describe (out, vl);
165 }
166 
167 template<class LO, class GO, class NT>
168 void
170 globalDescribe (Teuchos::FancyOStream& out,
171  const Teuchos::EVerbosityLevel vl) const
172 {
173  using Teuchos::Comm;
174  using Teuchos::OSTab;
175  using Teuchos::RCP;
176  using Teuchos::toString;
177  using std::endl;
178 
179  // If this Transfer's source Map or Comm is null, then the Transfer
180  // does not participate in collective operations with the other
181  // processes. In that case, it is not even legal to call this
182  // method. The reasonable thing to do in that case is nothing.
183  auto srcMap = this->getSourceMap ();
184  if (srcMap.is_null ()) {
185  return;
186  }
187  RCP<const Teuchos::Comm<int> > comm = srcMap->getComm ();
188  if (comm.is_null ()) {
189  return;
190  }
191 
192  const std::string myStr = localDescribeToString (vl);
193  Tpetra::Details::gathervPrint (out, myStr, *comm);
194 }
195 
196 template<class LO, class GO, class NT>
197 std::string
198 Transfer<LO, GO, NT>::
199 localDescribeToString (const Teuchos::EVerbosityLevel vl) const
200 {
201  using Teuchos::OSTab;
202  using Teuchos::RCP;
203  using std::endl;
204 
205  RCP<std::ostringstream> outString (new std::ostringstream);
206  RCP<Teuchos::FancyOStream> outp = Teuchos::getFancyOStream (outString);
207  Teuchos::FancyOStream& out = *outp; // only valid during this scope
208 
209  RCP<const Teuchos::Comm<int> > comm = this->getSourceMap ()->getComm ();
210  if (this->getSourceMap ().is_null () ||
211  this->getSourceMap ()->getComm ().is_null ()) {
212  // If this Transfer does not participate in the communicator,
213  // it's not even legal to call this method. However, we need to
214  // do something in this case. The reasonable thing to do is not
215  // to print anything.
216  return std::string ("");
217  }
218  else {
219  const int myRank = comm->getRank ();
220  const int numProcs = comm->getSize ();
221 
222  out << "Process " << myRank << " of " << numProcs << ":" << endl;
223  OSTab tab1 (out);
224 
225  out << "numSameIDs: " << getNumSameIDs () << endl;
226  out << "numPermuteIDs: " << getNumPermuteIDs () << endl;
227  out << "numRemoteIDs: " << getNumRemoteIDs () << endl;
228  out << "numExportIDs: " << getNumExportIDs () << endl;
229 
230  // Only print the actual contents of these arrays at the two
231  // highest verbosity levels. Otherwise, just print their counts.
232  if (vl <= Teuchos::VERB_MEDIUM) {
233  out << "permuteFromLIDs count: " << getPermuteFromLIDs ().size () << endl
234  << "permuteToLIDs count: " << getPermuteToLIDs ().size () << endl
235  << "remoteLIDs count: " << getRemoteLIDs ().size () << endl
236  << "exportLIDs count: " << getExportLIDs ().size () << endl
237  << "exportPIDs count: " << getExportPIDs () << endl;
238  }
239  else { // vl = VERB_HIGH or VERB_EXTREME
240  out << "permuteFromLIDs: " << toString (getPermuteFromLIDs ()) << endl
241  << "permuteToLIDs: " << toString (getPermuteToLIDs ()) << endl
242  << "remoteLIDs: " << toString (getRemoteLIDs ()) << endl
243  << "exportLIDs: " << toString (getExportLIDs ()) << endl
244  << "exportPIDs: " << toString (getExportPIDs ()) << endl;
245  }
246 
247  out.flush (); // make sure the ostringstream got everything
248  return outString->str ();
249  }
250 }
251 
252 } // namespace Details
253 } // namespace Tpetra
254 
255 #endif // TPETRA_DETAILS_TRANSFER_DEF_HPP
void describeImpl(Teuchos::FancyOStream &out, const std::string &className, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of describe() for subclasses (Tpetra::Import and Tpetra::Export).
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Common base class of Import and Export.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Describe this object in a human-readable way to the given output stream.
Implementation details of Tpetra.
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator, in rank order.