Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
reduce.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
45#ifdef HAVE_TEUCHOS_MPI
47#endif // HAVE_TEUCHOS_MPI
49
50
51template<class PacketType>
52bool
53testReduceSum (bool& success, std::ostream& out,
54 const int root, const Teuchos::Comm<int>& comm)
55{
56 using Teuchos::reduce;
58 using std::endl;
59 typedef PacketType packet_type;
60
61 // Teuchos constructs the output stream such that it only prints on
62 // Process 0 anyway.
63 out << "Testing Teuchos::reduce<int, " << TypeNameTraits<packet_type>::name ()
64 << "> with reductType = REDUCE_SUM and root = " << root << endl;
65
66 const packet_type ZERO = Teuchos::ScalarTraits<packet_type>::zero ();
67 const packet_type ONE = Teuchos::ScalarTraits<packet_type>::one ();
68 const int count = 10;
69 packet_type sendBuf[10];
70 packet_type recvBuf[10];
71 for (int i = 0; i < count; ++i) {
72 sendBuf[i] = ONE;
73 recvBuf[i] = ZERO;
74 }
75 const Teuchos::EReductionType reductType = Teuchos::REDUCE_SUM;
76 reduce<int, packet_type> (sendBuf, recvBuf, count, reductType, root, comm);
77
78 // Don't trust that any other Teuchos communicator wrapper functions
79 // work here. Instead, if building with MPI, use raw MPI. If not
80 // building with MPI, first test that comm has only one process,
81 // then assume this in the test.
82
83#ifdef HAVE_TEUCHOS_MPI
84 using Teuchos::MpiComm;
85 int err = MPI_SUCCESS;
86
87 const MpiComm<int>* mpiComm = dynamic_cast<const MpiComm<int>* > (&comm);
89 (mpiComm == NULL, std::logic_error, "Building with MPI, but default "
90 "communicator is not a Teuchos::MpiComm!");
91 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
92
93 // Use a barrier to make sure that every process got this far.
94 err = MPI_Barrier (rawMpiComm);
96 (err != MPI_SUCCESS, std::logic_error, "MPI_Barrier failed!");
97
98 // Recompute using MPI. Use an all-reduce to simplify the test.
99 packet_type sendBuf2[10];
100 packet_type recvBuf2[10];
101 for (int i = 0; i < count; ++i) {
102 sendBuf2[i] = ONE;
103 recvBuf2[i] = ZERO;
104 }
105 // FIXME (14 Jul 2015) Need to get the MPI_Datatype right for PacketType.
106 MPI_Datatype rawMpiType;
107 if (typeid (packet_type) == typeid (short)) {
108 rawMpiType = MPI_SHORT;
109 } else if (typeid (packet_type) == typeid (unsigned short)) {
110 rawMpiType = MPI_UNSIGNED_SHORT;
111 } else if (typeid (packet_type) == typeid (int)) {
112 rawMpiType = MPI_INT;
113 } else if (typeid (packet_type) == typeid (unsigned int)) {
114 rawMpiType = MPI_UNSIGNED;
115 } else if (typeid (packet_type) == typeid (long)) {
116 rawMpiType = MPI_LONG;
117 } else if (typeid (packet_type) == typeid (unsigned long)) {
118 rawMpiType = MPI_UNSIGNED_LONG;
119 } else if (typeid (packet_type) == typeid (long long)) {
120 rawMpiType = MPI_LONG_LONG;
121 } else if (typeid (packet_type) == typeid (unsigned long long)) {
122 rawMpiType = MPI_UNSIGNED_LONG_LONG;
123 } else if (typeid (packet_type) == typeid (float)) {
124 rawMpiType = MPI_FLOAT;
125 } else if (typeid (packet_type) == typeid (double)) {
126 rawMpiType = MPI_DOUBLE;
127 } else {
129 (true, std::logic_error, "Unimplemented conversion from PacketType = "
130 << TypeNameTraits<packet_type>::name () << " to MPI_Datatype.");
131 }
132
133 err = MPI_Allreduce (sendBuf2, recvBuf2, count, rawMpiType, MPI_SUM, rawMpiComm);
135 (err != MPI_SUCCESS, std::logic_error, "MPI_Allreduce failed!");
136 if (root == comm.getRank ()) {
137 for (int i = 0; i < count; ++i) {
138 TEST_EQUALITY( recvBuf2[i], recvBuf[i] );
139 }
140 }
141
142 int lclSuccess = success ? 1 : 0;
143 int gblSuccess = lclSuccess;
144 err = MPI_Allreduce (&lclSuccess, &gblSuccess, 1, MPI_INT, MPI_MIN, rawMpiComm);
146 (err != MPI_SUCCESS, std::logic_error, "MPI_Allreduce failed!");
147 success = gblSuccess == 1 ? true : false;
148
149#else // HAVE_TEUCHOS_MPI
151 (comm.getSize () != 1, std::logic_error, "Not building with MPI, but "
152 "communicator has size = " << comm.getSize () << " != 1. We don't know "
153 "how to test this case.");
154 for (int i = 0; i < count; ++i) {
155 TEST_EQUALITY( sendBuf[i], recvBuf[i] );
156 TEST_EQUALITY( recvBuf[i], ONE );
157 }
158#endif // HAVE_TEUCHOS_MPI
159
160 return success;
161}
162
163
164TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( Comm, ReduceSum, PacketType )
165{
166 using Teuchos::Comm;
167 using Teuchos::RCP;
168 using Teuchos::reduce;
169 typedef PacketType packet_type;
170
171 RCP<const Comm<int> > comm = Teuchos::DefaultComm<int>::getComm ();
172 const int numProcs = comm->getSize ();
173
174 // Make sure that it works for all possible root processes in the
175 // communicator, not just Process 0.
176 for (int root = 0; root < numProcs; ++root) {
177 const bool curSuccess = testReduceSum<packet_type> (success, out, root, *comm);
178 TEST_EQUALITY_CONST( curSuccess, true );
179 success = success && curSuccess;
180 }
181}
182
183//
184// mfh 14 Jul 2015: We only need to test int for now. See Bug 6375.
185//
186TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( Comm, ReduceSum, int )
Teuchos header file which uses auto-configuration information to include necessary C++ headers.
Implementation of Teuchos wrappers for MPI.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
Unit testing support.
#define TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(TEST_GROUP, TEST_NAME, TYPE)
Macro for defining a templated unit test with one template parameter.
#define TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT(TEST_GROUP, TEST_NAME, TYPE)
Instantiate a templated unit test with one template parameter.
Abstract interface for distributed-memory communication.
virtual int getSize() const =0
Returns the number of processes that make up this communicator.
virtual int getRank() const =0
Returns the rank of this process.
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
Smart reference counting pointer class for automatic garbage collection.
Default traits class that just returns typeid(T).name().
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool testReduceSum(bool &success, std::ostream &out, const int root, const Teuchos::Comm< int > &comm)
Definition: reduce.cpp:53
static T one()
Returns representation of one for this scalar type.
static T zero()
Returns representation of zero for this scalar type.