Tpetra Matrix/Vector Services Version of the Day
Tpetra_HybridPlatform.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2008) Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
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 #ifndef TPETRA_HYBRIDPLATFORM_HPP
00043 #define TPETRA_HYBRIDPLATFORM_HPP
00044 
00045 #include <Tpetra_ConfigDefs.hpp>
00046 #include <Teuchos_Describable.hpp>
00047 #include <Teuchos_ParameterList.hpp>
00048 
00049 #include <Kokkos_SerialNode.hpp>
00050 #ifdef HAVE_KOKKOSCLASSIC_TBB
00051 #include <Kokkos_TBBNode.hpp>
00052 #endif
00053 #ifdef HAVE_KOKKOSCLASSIC_THREADPOOL
00054 #include <Kokkos_TPINode.hpp>
00055 #endif
00056 #ifdef HAVE_KOKKOSCLASSIC_OPENMP
00057 #include <Kokkos_OpenMPNode.hpp>
00058 #endif
00059 #ifdef HAVE_KOKKOSCLASSIC_THRUST
00060 #include <Kokkos_ThrustGPUNode.hpp>
00061 #endif
00062 
00063 // This macro is only for use by Tpetra developers.
00064 // It should only be invoked in the Tpetra namespace,
00065 // outside of the HybridPlatform class declaration.
00066 #define TPETRA_HYBRIDPLATFORM_ADD_NODE_SUPPORT_DECL(N) \
00067   template <> bool HybridPlatform::isNodeSupported<N> ();
00068 
00069 namespace Tpetra {
00070 
00072   class HybridPlatform : public Teuchos::Describable {
00073   public:
00075 
00076 
00078     HybridPlatform (const Teuchos::RCP<const Teuchos::Comm<int> >& comm, 
00079         Teuchos::ParameterList& pl);
00080 
00082     ~HybridPlatform ();
00083 
00085 
00086 
00087 
00089     Teuchos::RCP<const Teuchos::Comm<int> > getComm () const;
00090 
00092     static Teuchos::RCP<Teuchos::ParameterList> listSupportedNodes ();
00093 
00095     template <class Node>
00096     static bool isNodeSupported ();
00097 
00116     template <template <class Node> class UserCode> 
00117     void runUserCode ();
00118 
00134     template <class UserCode> 
00135     void runUserCode (UserCode &code);
00136 
00138 
00139   protected:
00140     void createNode ();
00141 
00142   private:
00143     HybridPlatform(const HybridPlatform &platform); // not supported
00144     const Teuchos::RCP<const Teuchos::Comm<int> > comm_;
00145     Teuchos::ParameterList instList_;
00146     Teuchos::RCP<KokkosClassic::SerialNode>    serialNode_;
00147     bool nodeCreated_;
00148 #ifdef HAVE_KOKKOSCLASSIC_TBB
00149     Teuchos::RCP<KokkosClassic::TBBNode>       tbbNode_;
00150 #endif
00151 #ifdef HAVE_KOKKOSCLASSIC_THREADPOOL
00152     Teuchos::RCP<KokkosClassic::TPINode>       tpiNode_;
00153 #endif
00154 #ifdef HAVE_KOKKOSCLASSIC_OPENMP
00155     Teuchos::RCP<KokkosClassic::OpenMPNode>    ompNode_;
00156 #endif
00157 #ifdef HAVE_KOKKOSCLASSIC_THRUST
00158     Teuchos::RCP<KokkosClassic::ThrustGPUNode> thrustNode_;
00159 #endif
00160 
00161     enum NodeType {
00162       SERIALNODE
00163 #ifdef HAVE_KOKKOSCLASSIC_TBB
00164       , TBBNODE
00165 #endif        
00166 #ifdef HAVE_KOKKOSCLASSIC_THREADPOOL
00167       , TPINODE
00168 #endif        
00169 #ifdef HAVE_KOKKOSCLASSIC_OPENMP
00170       , OMPNODE
00171 #endif        
00172 #ifdef HAVE_KOKKOSCLASSIC_THRUST
00173       , THRUSTGPUNODE
00174 #endif        
00175     } nodeType_;
00176   };
00177 
00178   template <class Node>
00179   bool HybridPlatform::isNodeSupported ()
00180   {
00181     return false;
00182   }
00183   
00184   template <class UserCode>
00185   void HybridPlatform::runUserCode (UserCode& codeobj) {
00186     createNode();
00187     switch (nodeType_) {
00188       case SERIALNODE:
00189         codeobj.template run<KokkosClassic::SerialNode>(instList_,comm_, serialNode_);
00190         break;
00191 #ifdef HAVE_KOKKOSCLASSIC_TBB
00192       case TBBNODE:
00193         codeobj.template run<KokkosClassic::TBBNode>(instList_,comm_, tbbNode_);
00194         break;
00195 #endif        
00196 #ifdef HAVE_KOKKOSCLASSIC_OPENMP
00197       case OMPNODE:
00198         codeobj.template run<KokkosClassic::OpenMPNode>(instList_,comm_, ompNode_);
00199         break;
00200 #endif        
00201 #ifdef HAVE_KOKKOSCLASSIC_THREADPOOL
00202       case TPINODE:
00203         codeobj.template run<KokkosClassic::TPINode>(instList_,comm_, tpiNode_);
00204         break;
00205 #endif        
00206 #ifdef HAVE_KOKKOSCLASSIC_THRUST
00207       case THRUSTGPUNODE:
00208         codeobj.template run<KokkosClassic::ThrustGPUNode>(instList_,comm_, thrustNode_);
00209         break;
00210 #endif        
00211       default:
00212         TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, 
00213             Teuchos::typeName(*this) << "::runUserCode(): Invalid node type." << std::endl);
00214     } // end of switch
00215   }
00216 
00217   template <template<class Node> class UserCode>
00218   void HybridPlatform::runUserCode() {
00219     createNode();
00220     switch (nodeType_) {
00221       case SERIALNODE:
00222         UserCode<KokkosClassic::SerialNode>::run(instList_,comm_, serialNode_);
00223         break;
00224 #ifdef HAVE_KOKKOSCLASSIC_TBB
00225       case TBBNODE:
00226         UserCode<KokkosClassic::TBBNode>::run(instList_,comm_, tbbNode_);
00227         break;
00228 #endif        
00229 #ifdef HAVE_KOKKOSCLASSIC_OPENMP
00230       case OMPNODE:
00231         UserCode<KokkosClassic::OpenMPNode>::run(instList_,comm_, ompNode_);
00232         break;
00233 #endif        
00234 #ifdef HAVE_KOKKOSCLASSIC_THREADPOOL
00235       case TPINODE:
00236         UserCode<KokkosClassic::TPINode>::run(instList_,comm_, tpiNode_);
00237         break;
00238 #endif        
00239 #ifdef HAVE_KOKKOSCLASSIC_THRUST
00240       case THRUSTGPUNODE:
00241         UserCode<KokkosClassic::ThrustGPUNode>::run(instList_,comm_, thrustNode_);
00242         break;
00243 #endif        
00244       default:
00245         TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, 
00246             Teuchos::typeName(*this) << "::runUserCode(): Invalid node type." << std::endl);
00247     } // end of switch
00248   }
00249 
00250   TPETRA_HYBRIDPLATFORM_ADD_NODE_SUPPORT_DECL(KokkosClassic::SerialNode)
00251 #ifdef HAVE_KOKKOSCLASSIC_TBB
00252   TPETRA_HYBRIDPLATFORM_ADD_NODE_SUPPORT_DECL(KokkosClassic::TBBNode)
00253 #endif        
00254 #ifdef HAVE_KOKKOSCLASSIC_OPENMP
00255   TPETRA_HYBRIDPLATFORM_ADD_NODE_SUPPORT_DECL(KokkosClassic::OpenMPNode)
00256 #endif        
00257 #ifdef HAVE_KOKKOSCLASSIC_THREADPOOL
00258   TPETRA_HYBRIDPLATFORM_ADD_NODE_SUPPORT_DECL(KokkosClassic::TPINode)
00259 #endif        
00260 #ifdef HAVE_KOKKOSCLASSIC_THRUST
00261   TPETRA_HYBRIDPLATFORM_ADD_NODE_SUPPORT_DECL(KokkosClassic::ThrustGPUNode)
00262 #endif
00263 
00264 } // namespace Tpetra
00265 
00266 #endif // TPETRA_HYBRIDPLATFORM_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines