Thyra Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TestThyraDebugHang.cpp
Go to the documentation of this file.
1 #include "Teuchos_RCP.hpp"
4 #include "Epetra_MpiComm.h"
5 #include "Epetra_Map.h"
6 #include "Thyra_VectorSpaceFactoryBase.hpp"
8 #include "Thyra_DefaultSpmdVectorSpace_decl.hpp"
9 #include "Thyra_DefaultSpmdVector_decl.hpp"
10 #include "Thyra_MultiVectorBase_decl.hpp"
11 #include "Thyra_ScalarProdVectorSpaceBase_decl.hpp"
12 #include "Thyra_DefaultSpmdMultiVector_decl.hpp"
13 
15 
16 #include <iostream> // std::cerr, std::endl
17 #include <sstream>
18 #include <string>
19 
20 // If Thyra is compiled with TEUCHOS_DEBUG defined then the following
21 // wil hang in a collective MPI communication when run on four
22 // processors.
23 TEUCHOS_UNIT_TEST( ThyraEpetraMultiVector, HangingInParallelDebug )
24 {
25  using Teuchos::outArg;
26  using Teuchos::RCP;
27  using Teuchos::rcp;
28  using Teuchos::rcp_dynamic_cast;
29  using Teuchos::REDUCE_MIN;
30  using Teuchos::reduceAll;
31  using std::cerr;
32  using std::endl;
33  int lclSuccess = 1; // to be revised below
34  int gblSuccess = 1; // to be revised below
35  int myRank = 0;
36  int numProcs = 1;
37 #ifdef HAVE_MPI
38  (void) MPI_Comm_rank (MPI_COMM_WORLD, &myRank);
39  (void) MPI_Comm_size (MPI_COMM_WORLD, &numProcs);
40 #endif // HAVE_MPI
41 
42  std::string prefix;
43  {
44  std::ostringstream os;
45  os << "(Process " << myRank << ") ";
46  prefix = os.str ();
47  }
48 
49  {
50  std::ostringstream os;
51  os << prefix << "Creating Epetra_Comm" << endl;
52  cerr << os.str ();
53  }
54 #ifdef HAVE_MPI
55  const Epetra_MpiComm epetra_comm (MPI_COMM_WORLD);
56 #else
57  const Epetra_SerialComm epetra_comm ();
58 #endif
59  {
60  std::ostringstream os;
61  os << prefix << "Creating Teuchos::Comm" << endl;
62  cerr << os.str ();
63  }
64  RCP<const Teuchos::Comm<Teuchos_Ordinal> > comm =
66  // Make sure that everything is OK on all processes.
67  TEST_ASSERT( ! comm.is_null () );
68  lclSuccess = success ? 1 : 0;
69  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
70  TEST_EQUALITY( gblSuccess, 1 );
71  if (gblSuccess != 1) {
72  out << "FAILED; some process(es) have a null Teuchos::Comm" << endl;
73  return;
74  }
75 
76  // Some processors have to have data and some not.
77  const int localDim = myRank % 2;
78  const int globalDim = numProcs / 2;
79  RCP<const Epetra_Map> epetra_map;
80  {
81  std::ostringstream os;
82  os << prefix << "Creating Epetra_Map: localDim=" << localDim << ", globalDim=" << globalDim << endl;
83  cerr << os.str ();
84  }
85  epetra_map = rcp (new Epetra_Map (globalDim, localDim, 0, epetra_comm));
86  // Make sure that everything is OK on all processes.
87  TEST_ASSERT( ! epetra_map.is_null () );
88  lclSuccess = success ? 1 : 0;
89  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
90  TEST_EQUALITY( gblSuccess, 1 );
91  if (gblSuccess != 1) {
92  out << "FAILED; some process(es) have a null Epetra_Map" << endl;
93  return;
94  }
95 
96  {
97  std::ostringstream os;
98  os << prefix << "Creating Thyra::DefaultSpmdVectorSpace" << endl;
99  cerr << os.str ();
100  }
101  RCP<Thyra::DefaultSpmdVectorSpace<double> > SPMD =
102  Thyra::DefaultSpmdVectorSpace<double>::create();
103 
104  // Make sure that everything is OK on all processes.
105  TEST_ASSERT( ! epetra_map.is_null () );
106  lclSuccess = success ? 1 : 0;
107  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
108  TEST_EQUALITY( gblSuccess, 1 );
109  if (gblSuccess != 1) {
110  out << "FAILED; some process(es) have a null SPMD" << endl;
111  return;
112  }
113 
114  SPMD->initialize(comm, localDim, globalDim);
115 
116  {
117  std::ostringstream os;
118  os << prefix << "Creating Thyra::MultiVectorBase" << endl;
119  cerr << os.str ();
120  }
121  RCP<const Thyra::MultiVectorBase<double> > spmd =
122  rcp (new Thyra::DefaultSpmdMultiVector<double> (
123  SPMD,
124  rcp_dynamic_cast<const Thyra::ScalarProdVectorSpaceBase<double> > (
125  SPMD->smallVecSpcFcty()->createVecSpc(1),true)
126  )
127  );
128  // Make sure that everything is OK on all processes.
129  TEST_ASSERT( ! spmd.is_null () );
130  lclSuccess = success ? 1 : 0;
131  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
132  TEST_EQUALITY( gblSuccess, 1 );
133  if (gblSuccess != 1) {
134  out << "FAILED; some process(es) have a null Thyra::MultiVectorBase"
135  << endl;
136  return;
137  }
138 
139  {
140  std::ostringstream os;
141  os << prefix << "Calling Thyra::get_Epetra_MultiVector "
142  "(const overload; see #1941)" << endl;
143  cerr << os.str ();
144  }
145  // Make sure that we invoke the const overload.
146  RCP<const Epetra_MultiVector> mv_c =
147  Thyra::get_Epetra_MultiVector (*epetra_map,
148  const_cast<const Thyra::MultiVectorBase<double>& > (*spmd));
149  // Make sure that everything is OK on all processes.
150  TEST_ASSERT( ! mv_c.is_null () );
151  lclSuccess = success ? 1 : 0;
152  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
153  TEST_EQUALITY( gblSuccess, 1 );
154  if (gblSuccess != 1) {
155  out << "FAILED; some process(es) have a null const Epetra_MultiVector"
156  << endl;
157  return;
158  }
159 
160  {
161  std::ostringstream os;
162  os << prefix << "Calling Thyra::get_Epetra_MultiVector "
163  "(nonconst overload; see #2061)" << endl;
164  cerr << os.str ();
165  }
166  // Make sure that we invoke the nonconst overload.
167  RCP<Epetra_MultiVector> mv_nc =
168  Thyra::get_Epetra_MultiVector (*epetra_map,
169  const_cast<Thyra::MultiVectorBase<double>& > (*spmd));
170  // Make sure that everything is OK on all processes.
171  TEST_ASSERT( ! mv_nc.is_null () );
172  lclSuccess = success ? 1 : 0;
173  reduceAll (*comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
174  TEST_EQUALITY( gblSuccess, 1 );
175  if (gblSuccess != 1) {
176  out << "FAILED; some process(es) have a null nonconst Epetra_MultiVector"
177  << endl;
178  return;
179  }
180 
181  {
182  std::ostringstream os;
183  os << prefix << "Done with test on this process" << endl;
184  cerr << os.str ();
185  }
186 }
187 
RCP< Epetra_MultiVector > get_Epetra_MultiVector(const Epetra_Map &map, const RCP< MultiVectorBase< double > > &mv)
Get a non-const Epetra_MultiVector view from a non-const MultiVectorBase object if possible...
#define TEST_ASSERT(v1)
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
TEUCHOS_UNIT_TEST(EpetraOperatorWrapper, basic)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
#define TEST_EQUALITY(v1, v2)