|
Tpetra Matrix/Vector Services
Version of the Day
|
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 #include <Tpetra_ConfigDefs.hpp> 00043 00044 // mfh 29 Jun 2014: It makes life easier for Sierra developers if 00045 // Trilinos just builds all .cpp files unconditionally, rather than 00046 // making the decision whether to build them dependent on CMake 00047 // options. Thus, we just exclude all the content of this file if MPI 00048 // is not enabled. 00049 #ifdef HAVE_TPETRA_MPI 00050 # include <Tpetra_MpiPlatform.hpp> 00051 00052 namespace Tpetra { 00053 00054 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00055 MpiPlatform () : 00056 comm_ (Teuchos::createMpiComm<int> (Teuchos::opaqueWrapper<MPI_Comm> (MPI_COMM_WORLD))), 00057 node_ (Teuchos::null) 00058 { 00059 // mfh 29 Jun 2014: Don't initialize the Node yet. This ensures 00060 // that (new) Kokkos won't get initialized with the wrong 00061 // command-line arguments, at least not until getNode() is called. 00062 // Initializing Kokkos with the wrong command-line arguments may 00063 // result in poor performance due to the wrong assignment of 00064 // software threads to hardware execution units. 00065 // 00066 // if (node_.is_null ()) { 00067 // node_ = KokkosClassic::DefaultNode::getDefaultNode (); 00068 // } 00069 } 00070 00071 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00072 MpiPlatform (int* argc, char*** argv) : 00073 comm_ (Teuchos::null), 00074 node_ (Teuchos::null) 00075 { 00076 initialize (argc, argv); 00077 comm_ = getDefaultComm (); 00078 00079 // mfh 29 Jun 2014: Don't initialize the Node yet. See above note. 00080 // 00081 // if (node_.is_null ()) { 00082 // node_ = KokkosClassic::DefaultNode::getDefaultNode (); 00083 // } 00084 } 00085 00086 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00087 MpiPlatform (const Teuchos::RCP<NodeType>& node) : 00088 comm_ (Teuchos::createMpiComm<int> (Teuchos::opaqueWrapper<MPI_Comm> (MPI_COMM_WORLD))), 00089 node_ (node) 00090 { 00091 // mfh 29 Jun 2014: Don't initialize the Node yet. This ensures 00092 // that (new) Kokkos won't get initialized with the wrong 00093 // command-line arguments, at least not until getNode() is 00094 // called. Initializing Kokkos with the wrong command-line 00095 // arguments may result in poor performance due to the wrong 00096 // assignment of software threads to hardware execution units. 00097 // 00098 // if (node_.is_null ()) { 00099 // node_ = KokkosClassic::DefaultNode::getDefaultNode (); 00100 // } 00101 } 00102 00103 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00104 MpiPlatform (int* argc, char*** argv, const Teuchos::RCP<NodeType>& node) : 00105 comm_ (Teuchos::null), 00106 node_ (node) 00107 { 00108 initialize (argc, argv); 00109 comm_ = getDefaultComm (); 00110 00111 // mfh 29 Jun 2014: Don't initialize the Node yet. See above note. 00112 // 00113 // if (node_.is_null ()) { 00114 // node_ = KokkosClassic::DefaultNode::getDefaultNode (); 00115 // } 00116 } 00117 00118 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00119 MpiPlatform (const Teuchos::RCP<NodeType>& node, 00120 const Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> >& rawMpiComm) 00121 : comm_ (Teuchos::null), 00122 node_ (node) 00123 { 00124 TEUCHOS_TEST_FOR_EXCEPTION( 00125 rawMpiComm.is_null (), std::invalid_argument, "Tpetra::MpiPlatform " 00126 "constructor: The input RCP<OpaqueWrapper<MPI_Comm> > is null. That " 00127 "means something different than MPI_COMM_NULL. If you want to give " 00128 "MPI_COMM_NULL to this constructor, please wrap MPI_COMM_NULL in a " 00129 "nonnull Teuchos::OpaqueWrapper by using the " 00130 "Teuchos::opaqueWrapper<MPI_Comm>() nonmember constructor."); 00131 comm_ = Teuchos::createMpiComm<int> (rawMpiComm); 00132 00133 // mfh 29 Jun 2014: Don't initialize the Node yet. See above note. 00134 // 00135 // if (node_.is_null ()) { 00136 // node_ = KokkosClassic::DefaultNode::getDefaultNode (); 00137 // } 00138 } 00139 00140 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00141 MpiPlatform (int* argc, 00142 char*** argv, 00143 const Teuchos::RCP<NodeType>& node, 00144 const Teuchos::RCP<const Teuchos::OpaqueWrapper<MPI_Comm> >& rawMpiComm) 00145 : comm_ (Teuchos::null), 00146 node_ (node) 00147 { 00148 TEUCHOS_TEST_FOR_EXCEPTION( 00149 rawMpiComm.is_null (), std::invalid_argument, "Tpetra::MpiPlatform " 00150 "constructor: The input RCP<OpaqueWrapper<MPI_Comm> > is null. That " 00151 "means something different than MPI_COMM_NULL. If you want to give " 00152 "MPI_COMM_NULL to this constructor, please wrap MPI_COMM_NULL in a " 00153 "nonnull Teuchos::OpaqueWrapper by using the " 00154 "Teuchos::opaqueWrapper<MPI_Comm>() nonmember constructor."); 00155 comm_ = Teuchos::createMpiComm<int> (rawMpiComm); 00156 00157 // NOTE (mfh 29 Jun 2014): The OpaqueWrapper might wrap the 00158 // MPI_Comm in something that calls MPI_Comm_free. Thus, we 00159 // can't just ignore it; we have to give it to the comm_ so that 00160 // its destructor (which might call MPI_Comm_free) will be 00161 // called at the right time. This is why we don't set comm 00162 // using getDefaultComm(). This is also why we pass comm_ 00163 // directly to initialize(): that way there aren't two 00164 // references to the raw MPI_Comm floating around, and comm_'s 00165 // destructor will get to do the right thing. 00166 initialize (argc, argv, comm_); 00167 00168 // mfh 29 Jun 2014: Don't initialize the Node yet. See above note. 00169 // 00170 // if (node_.is_null ()) { 00171 // node_ = KokkosClassic::DefaultNode::getDefaultNode (); 00172 // } 00173 } 00174 00175 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00176 MpiPlatform (const Teuchos::RCP<NodeType>& node, MPI_Comm rawMpiComm) 00177 : comm_ (Teuchos::createMpiComm<int> (Teuchos::opaqueWrapper<MPI_Comm> (rawMpiComm))), 00178 node_ (node) 00179 { 00180 // mfh 29 Jun 2014: Don't initialize the Node yet. See above note. 00181 // 00182 // if (node_.is_null ()) { 00183 // node_ = KokkosClassic::DefaultNode::getDefaultNode (); 00184 // } 00185 } 00186 00187 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00188 MpiPlatform (int* argc, 00189 char*** argv, 00190 const Teuchos::RCP<NodeType>& node, 00191 MPI_Comm rawMpiComm) 00192 : comm_ (Teuchos::null), 00193 node_ (node) 00194 { 00195 initialize (argc, argv, rawMpiComm); 00196 comm_ = getDefaultComm (); 00197 00198 // mfh 29 Jun 2014: Don't initialize the Node yet. See above note. 00199 // 00200 // if (node_.is_null ()) { 00201 // node_ = KokkosClassic::Details::getNode<Node> (); 00202 // } 00203 } 00204 00205 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00206 ~MpiPlatform () {} 00207 00208 Teuchos::RCP<const Teuchos::Comm<int> > 00209 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00210 getComm () const { 00211 TEUCHOS_TEST_FOR_EXCEPTION( 00212 comm_.is_null (), std::logic_error, "Tpetra::MpiPlatform::getComm: " 00213 "The default communicator is null. This should never happen. " 00214 "Please report this bug to the Tpetra developers."); 00215 return comm_; 00216 } 00217 00218 Teuchos::RCP<MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>::NodeType> 00219 MpiPlatform<KokkosClassic::DefaultNode::DefaultNodeType>:: 00220 getNode () const 00221 { 00222 typedef MpiPlatform<NodeType> this_type; 00223 if (node_.is_null ()) { 00224 // NOTE (mfh 29 Jun 2014): Creating an instance of one of the 00225 // new Kokkos wrapper Nodes _must_ call Kokkos::initialize. 00226 // If Kokkos has not been initialized yet, this may result in 00227 // Kokkos being initialized correctly, since we have no way to 00228 // pass it the command-line arguments at this point. This is 00229 // why we should prefer the *Platform constructors that take 00230 // argc and argv, since they can (and do) call 00231 // Kokkos::initialize (by calling Tpetra::initialize). 00232 // 00233 // mfh 29 Jun 2014: We're only keeping the *Platform classes 00234 // for backwards compatibility anyway, so I don't feel bad 00235 // about the const_cast here. 00236 const_cast<this_type*> (this)->node_ = 00237 KokkosClassic::DefaultNode::getDefaultNode (); 00238 TEUCHOS_TEST_FOR_EXCEPTION( 00239 node_.is_null (), std::logic_error, "Tpetra::MpiPlatform::getNode: " 00240 "KokkosClassic::DefaultNode::getDefaultNode() returned null. " 00241 "This should never happen. " 00242 "Please report this bug to the Tpetra developers."); 00243 } 00244 return node_; 00245 } 00246 00247 } // namespace Tpetra 00248 00249 #endif // HAVE_TPETRA_MPI
1.7.6.1