Teuchos - Trilinos Tools Package Version of the Day
Teuchos_MpiReductionOpSetter.cpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_MpiReductionOpSetter.hpp"
00043 #include "Teuchos_OpaqueWrapper.hpp"
00044 #include "Teuchos_GlobalMPISession.hpp"
00045 
00046 #ifdef MPIAPI
00047 #define CALL_API MPIAPI
00048 #else
00049 #define CALL_API 
00050 #endif
00051 
00052 //
00053 // This implementation of handling the reduction operator
00054 // will work just fine in a single threaded program.
00055 // For multi-threaded program this has to be reworked!
00056 //
00057 
00058 //
00059 // The callback that an MPI implementation will actually call
00060 //
00061 
00062 extern "C" {
00063 void CALL_API Teuchos_MPI_reduction_op(
00064   void              *invec
00065   ,void             *inoutvec
00066   ,int              *len
00067   ,MPI_Datatype     *datatype
00068   );
00069 
00070 void Teuchos_MPI_Op_free( MPI_Op *op )
00071 {
00072   //if(Teuchos::GlobalMPISession::mpiIsInitialized())
00073   //  MPI_Op_free(op);
00074   //else
00075   //  *op = MPI_OP_NULL;
00076   //
00077   // RAB: I have commented this out because this is getting called after
00078   // MPI_Finalize() is called when the Teuchos::GlobalMPISession class is not
00079   // being used..  On some systems, like MPICH, this was not problem.
00080   // However, there are some systems that complain when you do this.
00081   // Therefore, since I don't really know how to fix this problem, I am just
00082   // going to punt and just not delete this MPI_Op object.  I suspect that
00083   // many people do not clean up their MPI objects correctly so I would guess
00084   // that almost every MPI implementation allows you to not free objects and
00085   // end just fine.
00086 }
00087 
00088 } // extern "C"
00089 
00090 //
00091 // Manage the reduction operation as static data.  I have used access
00092 // functions here to allow more insulation for other implementations other
00093 // other than just single threaded programs.
00094 //
00095 
00096 namespace {
00097 
00098 Teuchos::RCP<const Teuchos::MpiReductionOpBase> the_reduct_op = Teuchos::null;
00099 
00100 Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Op> > the_mpi_op = Teuchos::null;
00101 
00102 Teuchos::RCP<const Teuchos::MpiReductionOpBase> get_reduct_op()
00103 {
00104   return the_reduct_op;
00105 }
00106 
00107 void set_reduct_op( const Teuchos::RCP<const Teuchos::MpiReductionOpBase>& reduct_op )
00108 {
00109   using Teuchos::null;
00110 #ifdef TEUCHOS_DEBUG
00111   TEUCHOS_TEST_FOR_EXCEPT( get_reduct_op() != null && reduct_op != null  );
00112 #endif
00113   if(!the_mpi_op.get()) {
00114     MPI_Op mpi_op = MPI_OP_NULL;
00115     TEUCHOS_TEST_FOR_EXCEPT(
00116       0!=MPI_Op_create( &Teuchos_MPI_reduction_op ,1 ,&mpi_op ) // Assume op is commutative?
00117       );
00118     the_mpi_op = Teuchos::opaqueWrapper(mpi_op,Teuchos_MPI_Op_free);
00119   }
00120   the_reduct_op = reduct_op;
00121 }
00122 
00123 } // namespace
00124 
00125 extern "C" {
00126 void CALL_API Teuchos_MPI_reduction_op(
00127   void              *invec
00128   ,void             *inoutvec
00129   ,int              *len
00130   ,MPI_Datatype     *datatype
00131   )
00132 {
00133   get_reduct_op()->reduce(invec,inoutvec,len,datatype);
00134 }
00135 
00136 } // extern "C"
00137 
00138 namespace Teuchos {
00139 
00140 MpiReductionOpSetter::MpiReductionOpSetter(
00141   const Teuchos::RCP<const MpiReductionOpBase>& reduct_op
00142   )
00143 {
00144 #ifdef TEUCHOS_DEBUG
00145   TEUCHOS_TEST_FOR_EXCEPT(!reduct_op.get())
00146 #endif
00147   set_reduct_op(reduct_op);
00148 }
00149 
00150 MpiReductionOpSetter::~MpiReductionOpSetter()
00151 {
00152   set_reduct_op( null );
00153 }
00154 
00155 MPI_Op MpiReductionOpSetter::mpi_op() const
00156 {
00157   return (*the_mpi_op)();
00158 }
00159 
00160 } // namespace Teuchos
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines