Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
reduceAllInPlace.cpp
Go to the documentation of this file.
1// @HEADER
2// ***********************************************************************
3//
4// Teuchos: Common Tools Package
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
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// Test that Teuchos::reduceAll allows aliasing input and output
43// buffers, if the communicator is not an intercomm. Motivation:
44// https://github.com/trilinos/Trilinos/issues/1389
45
48#ifdef HAVE_TEUCHOS_MPI
49# include "mpi.h"
51#endif // HAVE_TEUCHOS_MPI
53
54namespace { // (anonymous)
55
56#ifdef HAVE_TEUCHOS_MPI
57MPI_Comm
58getRawMpiCommFromTeuchosComm (const ::Teuchos::Comm<int>& comm)
59{
60 using ::Teuchos::Comm;
61 using ::Teuchos::MpiComm;
62 using ::Teuchos::RCP;
63
64 const Comm<int>* commPtr = &comm;
65 const MpiComm<int>* mpiCommPtr = dynamic_cast<const MpiComm<int>* > (commPtr);
66 if (mpiCommPtr == NULL) {
67 return MPI_COMM_SELF;
68 }
69 else {
70 using ::Teuchos::OpaqueWrapper;
71 using ::Teuchos::RCP;
72 RCP<const OpaqueWrapper<MPI_Comm> > wrapper = mpiCommPtr->getRawMpiComm ();
73 if (wrapper.is_null ()) {
74 return MPI_COMM_SELF;
75 }
76 else {
77 return *wrapper;
78 }
79 }
80}
81#endif // HAVE_TEUCHOS_MPI
82
83TEUCHOS_UNIT_TEST( Comm, ReduceAllInPlace )
84{
85 using Teuchos::Comm;
86 using Teuchos::outArg;
87 using Teuchos::reduceAll;
89 using Teuchos::RCP;
90 using std::endl;
91
92 out << "Test Teuchos::reduceAll with both intracomms and intercomms" << endl;
93 Teuchos::OSTab tab1 (out);
94
95 RCP<const Comm<int> > comm = Teuchos::DefaultComm<int>::getComm ();
96 const int numProcs = comm->getSize ();
97 TEST_ASSERT( numProcs > 1 );
98 if (numProcs > 1) {
99 out << "This test requires > 1 processes in the input communicator "
100 "in order to be meaningful." << endl;
101 return;
102 }
103
104 typedef int reduce_type; // type of reductions' input & output, for this test
105 reduce_type inputVal = 3;
106 reduce_type outputVal = 0; // output of reduceAll
107 const reduce_type expectedOutputVal = inputVal * numProcs;
108
109 // Sanity check for reduceAll.
110 reduceAll<int, reduce_type> (*comm, REDUCE_SUM, inputVal, outArg (outputVal));
111 TEST_EQUALITY( outputVal, expectedOutputVal );
112
113#ifdef HAVE_TEUCHOS_MPI
114 MPI_Comm rawMpiComm = getRawMpiCommFromTeuchosComm (*comm);
115 int isInter = 0;
116 // This is a "local routine" (MPI 3.1, Section 6.6.1, p. 259).
117 (void) MPI_Comm_test_inter (rawMpiComm, &isInter);
118 if (isInter != 0) { // input communicator is an intercomm.
119 out << "Input communicator is an intercomm; "
120 "no point in continuing (not safe to exercise MPI_IN_PLACE)." << endl;
121 }
122 else { // input communicator is NOT an intercomm (is an intracomm)
123 out << "Input communicator is NOT an intercomm; "
124 "we may safely exercise MPI_IN_PLACE." << endl;
125
126 // We hide use of MPI_IN_PLACE, by letting users alias the input
127 // and output buffers.
128 inputVal = 3;
129 reduceAll<int, reduce_type> (*comm, REDUCE_SUM, inputVal, outArg (inputVal));
130 TEST_EQUALITY( inputVal, expectedOutputVal );
131 }
132
133 // Test whether we succeeded on all processes. This is particularly
134 // important when exercising MPI_IN_PLACE, since incorrect use of
135 // aliasing may cause only some processes to have incorrect results.
136 int lclSuccess = success ? 1 : 0;
137 int gblSuccess = 0; // output argument
138 const int err = MPI_Allreduce (&lclSuccess, &gblSuccess, 1, MPI_INT, MPI_MIN, rawMpiComm);
140 (err != MPI_SUCCESS, std::logic_error, "MPI_Allreduce failed!");
141 success = (gblSuccess == 1);
142 TEST_ASSERT( gblSuccess == 1 );
143#endif // HAVE_TEUCHOS_MPI
144}
145
146} // namespace (anonymous)
Implementation of Teuchos wrappers for MPI.
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
Unit testing support.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Abstract interface for distributed-memory communication.
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
Smart reference counting pointer class for automatic garbage collection.
Concrete serial communicator subclass.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.