Tpetra parallel linear algebra  Version of the Day
Tpetra_Details_checkView.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 // ************************************************************************
38 // @HEADER
39 
40 #ifndef TPETRA_DETAILS_CHECKVIEW_HPP
41 #define TPETRA_DETAILS_CHECKVIEW_HPP
42 
49 
51 #include "Kokkos_DualView.hpp"
52 #include "Teuchos_TypeNameTraits.hpp"
53 #include "Teuchos_Comm.hpp"
54 #include "Teuchos_CommHelpers.hpp"
55 #include <sstream>
56 
57 namespace Tpetra {
58 namespace Details {
59 
60 std::string memorySpaceName (const void* ptr);
61 
82 template<class DataType, class ... Properties>
83 bool
85  (std::ostream* lclErrStrm,
86  const int myMpiProcessRank,
87  const Kokkos::View<DataType, Properties...>& view)
88 {
89  using Teuchos::TypeNameTraits;
90  using std::endl;
91  using view_type = Kokkos::View<DataType, Properties...>;
92 
93  if (view.size () == 0) {
94  // Kokkos::View can be zero size with a nonnull pointer.
95  // Even std::vector can have this behavior.
96  return true;
97  }
98  else { // nonzero size
99  auto ptr = view.data ();
100 
101  if (ptr == nullptr) {
102  if (lclErrStrm != nullptr) {
103  const std::string viewName = TypeNameTraits<view_type>::name ();
104  *lclErrStrm << "Proc " << myMpiProcessRank << ": Kokkos::View "
105  "of type " << viewName << " has nonzero size " << view.size ()
106  << " but a null pointer." << endl;
107  }
108  return false;
109  }
110  else
111  return true;
112  }
113 }
114 
118 template<class DataType ,
119  class Arg1Type = void ,
120  class Arg2Type = void ,
121  class Arg3Type = void>
122 bool
124  (std::ostream* const lclErrStrm,
125  const int myMpiProcessRank,
126  const Kokkos::DualView<DataType, Arg1Type, Arg2Type, Arg3Type>& dv)
127 {
128  const bool dev_good =
129  checkLocalViewValidity (lclErrStrm, myMpiProcessRank,
130  dv.view_device ());
131  const bool host_good =
132  checkLocalViewValidity (lclErrStrm, myMpiProcessRank,
133  dv.view_host ());
134  const bool good = dev_good && host_good;
135  if (! good && lclErrStrm != nullptr) {
136  using Teuchos::TypeNameTraits;
137  using std::endl;
138  using dv_type =
139  Kokkos::DualView<DataType, Arg1Type, Arg2Type, Arg3Type>;
140 
141  const std::string dvName = TypeNameTraits<dv_type>::name ();
142  *lclErrStrm << "Proc " << myMpiProcessRank << ": Kokkos::DualView "
143  "of type " << dvName << " has one or more invalid Views. See "
144  "above error messages from this MPI process for details." << endl;
145  }
146  return good;
147 }
148 
149 template<class DataType ,
150  class Arg1Type = void ,
151  class Arg2Type = void ,
152  class Arg3Type = void>
153 bool
154 checkGlobalDualViewValidity
155 (std::ostream* const gblErrStrm,
156  const Kokkos::DualView<DataType, Arg1Type, Arg2Type, Arg3Type>& dv,
157  const bool verbose,
158  const Teuchos::Comm<int>* const comm)
159 {
160  using std::endl;
161  const int myRank = comm == nullptr ? 0 : comm->getRank ();
162  std::ostringstream lclErrStrm;
163  int lclSuccess = 1;
164 
165  try {
166  const bool lclValid =
167  checkLocalDualViewValidity (&lclErrStrm, myRank, dv);
168  lclSuccess = lclValid ? 1 : 0;
169  }
170  catch (std::exception& e) {
171  lclErrStrm << "Proc " << myRank << ": checkLocalDualViewValidity "
172  "threw an exception: " << e.what () << endl;
173  lclSuccess = 0;
174  }
175  catch (...) {
176  lclErrStrm << "Proc " << myRank << ": checkLocalDualViewValidity "
177  "threw an exception not a subclass of std::exception." << endl;
178  lclSuccess = 0;
179  }
180 
181  int gblSuccess = 0; // output argument
182  if (comm == nullptr) {
183  gblSuccess = lclSuccess;
184  }
185  else {
186  using Teuchos::outArg;
187  using Teuchos::REDUCE_MIN;
188  using Teuchos::reduceAll;
189  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
190  }
191 
192  if (gblSuccess != 1 && gblErrStrm != nullptr) {
193  *gblErrStrm << "On at least one (MPI) process, the "
194  "Kokkos::DualView has "
195  "either the device or host pointer in the "
196  "DualView equal to null, but the DualView has a nonzero number of "
197  "rows. For more detailed information, please rerun with the "
198  "TPETRA_VERBOSE environment variable set to 1. ";
199  if (verbose) {
200  *gblErrStrm << " Here are error messages from all "
201  "processes:" << endl;
202  if (comm == nullptr) {
203  *gblErrStrm << lclErrStrm.str ();
204  }
205  else {
207  gathervPrint (*gblErrStrm, lclErrStrm.str (), *comm);
208  }
209  }
210  *gblErrStrm << endl;
211  }
212  return gblSuccess == 1;
213 }
214 
215 } // namespace Details
216 } // namespace Tpetra
217 
218 #endif // TPETRA_DETAILS_CHECKVIEW_HPP
Declaration of a function that prints strings from each process.
Implementation details of Tpetra.
bool checkLocalDualViewValidity(std::ostream *const lclErrStrm, const int myMpiProcessRank, const Kokkos::DualView< DataType, Arg1Type, Arg2Type, Arg3Type > &dv)
Is the given Kokkos::DualView valid?
bool checkLocalViewValidity(std::ostream *lclErrStrm, const int myMpiProcessRank, const Kokkos::View< DataType, Properties... > &view)
Is the given View 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,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.