Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Details_checkView.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef TPETRA_DETAILS_CHECKVIEW_HPP
11 #define TPETRA_DETAILS_CHECKVIEW_HPP
12 
19 
21 #include "Tpetra_Details_WrappedDualView.hpp"
22 #include "Kokkos_DualView.hpp"
23 #include "Teuchos_TypeNameTraits.hpp"
24 #include "Teuchos_Comm.hpp"
25 #include "Teuchos_CommHelpers.hpp"
26 #include <sstream>
27 
28 namespace Tpetra {
29 namespace Details {
30 
31 std::string memorySpaceName (const void* ptr);
32 
53 template<class DataType, class ... Properties>
54 bool
56  (std::ostream* lclErrStrm,
57  const int myMpiProcessRank,
58  const Kokkos::View<DataType, Properties...>& view)
59 {
60  using Teuchos::TypeNameTraits;
61  using std::endl;
62  using view_type = Kokkos::View<DataType, Properties...>;
63 
64  if (view.size () == 0) {
65  // Kokkos::View can be zero size with a nonnull pointer.
66  // Even std::vector can have this behavior.
67  return true;
68  }
69  else { // nonzero size
70  auto ptr = view.data ();
71 
72  if (ptr == nullptr) {
73  if (lclErrStrm != nullptr) {
74  const std::string viewName = TypeNameTraits<view_type>::name ();
75  *lclErrStrm << "Proc " << myMpiProcessRank << ": Kokkos::View "
76  "of type " << viewName << " has nonzero size " << view.size ()
77  << " but a null pointer." << endl;
78  }
79  return false;
80  }
81  else
82  return true;
83  }
84 }
85 
89 template<class DataType ,
90  class... Args>
91 bool
93  (std::ostream* const lclErrStrm,
94  const int myMpiProcessRank,
95  const Kokkos::DualView<DataType, Args...>& dv)
96 {
97  const bool dev_good =
98  checkLocalViewValidity (lclErrStrm, myMpiProcessRank,
99  dv.view_device ());
100  const bool host_good =
101  checkLocalViewValidity (lclErrStrm, myMpiProcessRank,
102  dv.view_host ());
103  const bool good = dev_good && host_good;
104  if (! good && lclErrStrm != nullptr) {
105  using Teuchos::TypeNameTraits;
106  using std::endl;
107  using dv_type =
108  Kokkos::DualView<DataType, Args...>;
109 
110  const std::string dvName = TypeNameTraits<dv_type>::name ();
111  *lclErrStrm << "Proc " << myMpiProcessRank << ": Kokkos::DualView "
112  "of type " << dvName << " has one or more invalid Views. See "
113  "above error messages from this MPI process for details." << endl;
114  }
115  return good;
116 }
117 
118 template<class DataType ,
119  class... Args>
120 bool
121 checkGlobalDualViewValidity
122 (std::ostream* const gblErrStrm,
123  const Kokkos::DualView<DataType, Args...>& dv,
124  const bool verbose,
125  const Teuchos::Comm<int>* const comm)
126 {
127  using std::endl;
128  const int myRank = comm == nullptr ? 0 : comm->getRank ();
129  std::ostringstream lclErrStrm;
130  int lclSuccess = 1;
131 
132  try {
133  const bool lclValid =
134  checkLocalDualViewValidity (&lclErrStrm, myRank, dv);
135  lclSuccess = lclValid ? 1 : 0;
136  }
137  catch (std::exception& e) {
138  lclErrStrm << "Proc " << myRank << ": checkLocalDualViewValidity "
139  "threw an exception: " << e.what () << endl;
140  lclSuccess = 0;
141  }
142  catch (...) {
143  lclErrStrm << "Proc " << myRank << ": checkLocalDualViewValidity "
144  "threw an exception not a subclass of std::exception." << endl;
145  lclSuccess = 0;
146  }
147 
148  int gblSuccess = 0; // output argument
149  if (comm == nullptr) {
150  gblSuccess = lclSuccess;
151  }
152  else {
153  using Teuchos::outArg;
154  using Teuchos::REDUCE_MIN;
155  using Teuchos::reduceAll;
156  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
157  }
158 
159  if (gblSuccess != 1 && gblErrStrm != nullptr) {
160  *gblErrStrm << "On at least one (MPI) process, the "
161  "Kokkos::DualView has "
162  "either the device or host pointer in the "
163  "DualView equal to null, but the DualView has a nonzero number of "
164  "rows. For more detailed information, please rerun with the "
165  "TPETRA_VERBOSE environment variable set to 1. ";
166  if (verbose) {
167  *gblErrStrm << " Here are error messages from all "
168  "processes:" << endl;
169  if (comm == nullptr) {
170  *gblErrStrm << lclErrStrm.str ();
171  }
172  else {
174  gathervPrint (*gblErrStrm, lclErrStrm.str (), *comm);
175  }
176  }
177  *gblErrStrm << endl;
178  }
179  return gblSuccess == 1;
180 }
181 
182 
186 template<class DataType ,
187  class... Args>
188 bool
190  (std::ostream* const lclErrStrm,
191  const int myMpiProcessRank,
192  const Tpetra::Details::WrappedDualView<Kokkos::DualView<DataType, Args...> >& dv)
193 {
194  const bool dev_good = dv.is_valid_device();
195  const bool host_good = dv. is_valid_host();
196  const bool good = dev_good && host_good;
197  if (! good && lclErrStrm != nullptr) {
198  using Teuchos::TypeNameTraits;
199  using std::endl;
200  using dv_type =
201  Tpetra::Details::WrappedDualView<Kokkos::DualView<DataType, Args...> >;
202 
203  const std::string dvName = TypeNameTraits<dv_type>::name ();
204  *lclErrStrm << "Proc " << myMpiProcessRank << ": Tpetra::WrappedDualView "
205  "of type " << dvName << " has one or more invalid Views. See "
206  "above error messages from this MPI process for details." << endl;
207  }
208  return good;
209 }
210 
211 template<class DataType ,
212  class... Args>
213 bool
214 checkGlobalWrappedDualViewValidity
215 (std::ostream* const gblErrStrm,
216  const Tpetra::Details::WrappedDualView<Kokkos::DualView<DataType, Args...> >& dv,
217  const bool verbose,
218  const Teuchos::Comm<int>* const comm)
219 {
220  using std::endl;
221  const int myRank = comm == nullptr ? 0 : comm->getRank ();
222  std::ostringstream lclErrStrm;
223  int lclSuccess = 1;
224 
225  try {
226  const bool lclValid =
227  checkLocalWrappedDualViewValidity (&lclErrStrm, myRank, dv);
228  lclSuccess = lclValid ? 1 : 0;
229  }
230  catch (std::exception& e) {
231  lclErrStrm << "Proc " << myRank << ": checkLocalDualViewValidity "
232  "threw an exception: " << e.what () << endl;
233  lclSuccess = 0;
234  }
235  catch (...) {
236  lclErrStrm << "Proc " << myRank << ": checkLocalDualViewValidity "
237  "threw an exception not a subclass of std::exception." << endl;
238  lclSuccess = 0;
239  }
240 
241  int gblSuccess = 0; // output argument
242  if (comm == nullptr) {
243  gblSuccess = lclSuccess;
244  }
245  else {
246  using Teuchos::outArg;
247  using Teuchos::REDUCE_MIN;
248  using Teuchos::reduceAll;
249  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
250  }
251 
252  if (gblSuccess != 1 && gblErrStrm != nullptr) {
253  *gblErrStrm << "On at least one (MPI) process, the "
254  "Kokkos::DualView has "
255  "either the device or host pointer in the "
256  "DualView equal to null, but the DualView has a nonzero number of "
257  "rows. For more detailed information, please rerun with the "
258  "TPETRA_VERBOSE environment variable set to 1. ";
259  if (verbose) {
260  *gblErrStrm << " Here are error messages from all "
261  "processes:" << endl;
262  if (comm == nullptr) {
263  *gblErrStrm << lclErrStrm.str ();
264  }
265  else {
267  gathervPrint (*gblErrStrm, lclErrStrm.str (), *comm);
268  }
269  }
270  *gblErrStrm << endl;
271  }
272  return gblSuccess == 1;
273 }
274 
275 
276 } // namespace Details
277 } // namespace Tpetra
278 
279 #endif // TPETRA_DETAILS_CHECKVIEW_HPP
Declaration of a function that prints strings from each process.
A wrapper around Kokkos::DualView to safely manage data that might be replicated between host and dev...
bool checkLocalWrappedDualViewValidity(std::ostream *const lclErrStrm, const int myMpiProcessRank, const Tpetra::Details::WrappedDualView< Kokkos::DualView< DataType, Args...> > &dv)
Is the given Tpetra::WrappedDualView valid?
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.
bool checkLocalViewValidity(std::ostream *lclErrStrm, const int myMpiProcessRank, const Kokkos::View< DataType, Properties...> &view)
Is the given View valid?
bool checkLocalDualViewValidity(std::ostream *const lclErrStrm, const int myMpiProcessRank, const Kokkos::DualView< DataType, Args...> &dv)
Is the given Kokkos::DualView valid?