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 #ifndef TEUCHOS_MPI_REDUCTION_OP_SETTER_HPP
43 #define TEUCHOS_MPI_REDUCTION_OP_SETTER_HPP
44 
45 /// \file Teuchos_MpiReductionOpSetter.hpp
46 /// \brief Implementation detail of Teuchos' MPI wrapper.
47 ///
48 /// \warning Everything in this file is an implementation detail of
49 ///   Teuchos.  Do not use it and do not depend on it.
50 ///
51 /// This file only contains meaningful content if building with MPI.
52 
53 #include <Teuchos_ConfigDefs.hpp>
54 
55 #ifdef HAVE_MPI
56 #include "Teuchos_ReductionOp.hpp"
57 #include <mpi.h>
58 
59 namespace Teuchos {
60 namespace Details {
61 
62 /// \brief Base class for an MPI-compatible reduction operator.
63 ///
64 /// This class exists as an intermediate wrapper between
65 /// ValueTypeReductionOp and MPI_Op.  Its pure virtual method reduce()
66 /// takes the same arguments as an MPI_Op reduction / scan operator.
67 ///
68 /// \note This class only exists if building with MPI enabled.
69 class TEUCHOSCOMM_LIB_DLL_EXPORT MpiReductionOpBase :
70     virtual public Describable {
71 public:
72   virtual void
73   reduce (void* invec, void* inoutvec,
74           int* len, MPI_Datatype* datatype) const = 0;
75 };
76 
77 /// \brief Subclass of MpiReductionOpBase that implements reduce()
78 ///   using a ValueTypeReductionOp instance.
79 ///
80 /// \note This class only views the ValueTypeReductionOp instance; it
81 ///   does not own it.  The ValueTypeReductionOp must be in scope;
82 ///   otherwise this class' behavior is undefined.
83 template<typename OrdinalType>
84 class MpiReductionOp : public MpiReductionOpBase {
85 public:
MpiReductionOp(const ValueTypeReductionOp<OrdinalType,char> & reductOp)86   MpiReductionOp (const ValueTypeReductionOp<OrdinalType,char>& reductOp)
87     : reductOp_ (reductOp)
88   {}
89 
90   void
reduce(void * invec,void * inoutvec,int * len,MPI_Datatype * datatype) const91   reduce (void* invec, void* inoutvec, int* len, MPI_Datatype* datatype) const
92   {
93 #ifdef TEUCHOS_DEBUG
94     TEUCHOS_TEST_FOR_EXCEPT(!len);
95     TEUCHOS_TEST_FOR_EXCEPT(!datatype);
96 #endif
97     // mfh 23 Nov 2014: Ross made the unfortunate decision initially
98     // to mash everything into MPI_CHAR.  This means that we have to
99     // do a lot of type casting here.  Of course, most implementations
100     // of ValueTypeReductionOp will immediately cast back from char*
101     // to the actual type of interest.
102     int sz;
103     MPI_Type_size (*datatype, &sz);
104     (void) datatype;
105     reductOp_.reduce ((*len) * sz, reinterpret_cast<char*> (invec),
106                       reinterpret_cast<char*> (inoutvec));
107   }
108 
109 private:
110   const ValueTypeReductionOp<OrdinalType, char>& reductOp_;
111   // Not defined and not to be called
112   MpiReductionOp ();
113   MpiReductionOp (const MpiReductionOp&);
114   MpiReductionOp& operator= (const MpiReductionOp&);
115 };
116 
117 /// \brief Set the current reduction or scan operation for MpiComm.
118 ///   Get the resulting MPI_Op to pass into MPI functions.
119 ///
120 /// \return Global singleton MPI_Op to pass into MPI functions.
121 ///   This is valid only before MPI_Finalize has been called.
122 ///
123 /// \warning This is an implementation detail of Teuchos.
124 ///   Users should never call this function directly.
125 MPI_Op setMpiReductionOp (const MpiReductionOpBase& reductOp);
126 
127 } // namespace Details
128 } // namespace Teuchos
129 
130 #endif // HAVE_MPI
131 
132 #endif // TEUCHOS_MPI_REDUCTION_OP_SETTER_HPP
133