Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tpetra_TsqrAdaptor_MP_Vector.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
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 TPETRA_TSQR_ADAPTOR_MP_VECTOR_HPP
43 #define TPETRA_TSQR_ADAPTOR_MP_VECTOR_HPP
44 
45 #include <Tpetra_ConfigDefs.hpp> // HAVE_TPETRA_TSQR, etc.
46 
47 #ifdef HAVE_TPETRA_TSQR
48 
50 
51 # include <Tsqr_NodeTsqrFactory.hpp> // create intranode TSQR object
52 # include <Tsqr.hpp> // full (internode + intranode) TSQR
53 # include <Tsqr_DistTsqr.hpp> // internode TSQR
54 // Subclass of TSQR::MessengerBase, implemented using Teuchos
55 // communicator template helper functions
56 # include <Tsqr_TeuchosMessenger.hpp>
57 # include <Tpetra_MultiVector.hpp>
59 # include <stdexcept>
60 
61 // Base TsqrAdator template we will specialize
62 # include <Tpetra_TsqrAdaptor.hpp>
63 
64 namespace Tpetra {
65 
72  template <class Storage, class LO, class GO, class Node>
73  class TsqrAdaptor< Tpetra::MultiVector< Sacado::MP::Vector<Storage>,
74  LO, GO, Node > > :
76  public:
77  typedef Tpetra::MultiVector< Sacado::MP::Vector<Storage>, LO, GO, Node > MV;
78  typedef typename MV::scalar_type mp_scalar_type;
79 
80  // For Sacado::MP::Vector< Storage<Ordinal,Scalar,Device> > this is Scalar
82  typedef typename mp_scalar_type::ordinal_type mp_ordinal_type;
83  typedef typename MV::local_ordinal_type ordinal_type;
84  typedef typename MV::node_type node_type;
86  typedef typename Teuchos::ScalarTraits<scalar_type>::magnitudeType magnitude_type;
87 
88  private:
89  //typedef TSQR::MatView<ordinal_type, scalar_type> matview_type;
90  typedef TSQR::NodeTsqrFactory<node_type, scalar_type, ordinal_type> node_tsqr_factory_type;
91  typedef typename node_tsqr_factory_type::node_tsqr_type node_tsqr_type;
92  typedef TSQR::DistTsqr<ordinal_type, scalar_type> dist_tsqr_type;
93  typedef TSQR::Tsqr<ordinal_type, scalar_type, node_tsqr_type> tsqr_type;
94 
95  public:
102  TsqrAdaptor (const Teuchos::RCP<Teuchos::ParameterList>& plist) :
103  nodeTsqr_ (new node_tsqr_type),
104  distTsqr_ (new dist_tsqr_type),
105  tsqr_ (new tsqr_type (nodeTsqr_, distTsqr_)),
106  ready_ (false)
107  {
108  setParameterList (plist);
109  }
110 
112  TsqrAdaptor () :
113  nodeTsqr_ (new node_tsqr_type),
114  distTsqr_ (new dist_tsqr_type),
115  tsqr_ (new tsqr_type (nodeTsqr_, distTsqr_)),
116  ready_ (false)
117  {
118  setParameterList (Teuchos::null);
119  }
120 
122  getValidParameters () const
123  {
124  using Teuchos::RCP;
125  using Teuchos::rcp;
127  using Teuchos::parameterList;
128 
129  if (defaultParams_.is_null()) {
130  RCP<ParameterList> params = parameterList ("TSQR implementation");
131  params->set ("NodeTsqr", *(nodeTsqr_->getValidParameters ()));
132  params->set ("DistTsqr", *(distTsqr_->getValidParameters ()));
133  defaultParams_ = params;
134  }
135  return defaultParams_;
136  }
137 
138  void
139  setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& plist)
140  {
142  using Teuchos::parameterList;
143  using Teuchos::RCP;
144  using Teuchos::sublist;
145 
146  RCP<ParameterList> params = plist.is_null() ?
147  parameterList (*getValidParameters ()) : plist;
148  nodeTsqr_->setParameterList (sublist (params, "NodeTsqr"));
149  distTsqr_->setParameterList (sublist (params, "DistTsqr"));
150 
151  this->setMyParamList (params);
152  }
153 
175  void
176  factorExplicit (MV& A,
177  MV& Q,
178  dense_matrix_type& R,
179  const bool forceNonnegativeDiagonal=false)
180  {
181  prepareTsqr (Q); // Finish initializing TSQR.
182 
183  ordinal_type numRows;
184  ordinal_type numCols;
185  ordinal_type LDA;
186  ordinal_type LDQ;
187  scalar_type* A_ptr;
188  scalar_type* Q_ptr;
189 
190  getNonConstView (numRows, numCols, A_ptr, LDA, A);
191  getNonConstView (numRows, numCols, Q_ptr, LDQ, Q);
192  const bool contiguousCacheBlocks = false;
193  tsqr_->factorExplicitRaw (numRows, numCols, A_ptr, LDA,
194  Q_ptr, LDQ, R.values (), R.stride (),
195  contiguousCacheBlocks,
196  forceNonnegativeDiagonal);
197  }
198 
229  int
230  revealRank (MV& Q,
231  dense_matrix_type& R,
232  const magnitude_type& tol)
233  {
234  prepareTsqr (Q); // Finish initializing TSQR.
235 
236  // FIXME (mfh 18 Oct 2010) Check Teuchos::Comm<int> object in Q
237  // to make sure it is the same communicator as the one we are
238  // using in our dist_tsqr_type implementation.
239 
240  ordinal_type numRows;
241  ordinal_type numCols;
242  scalar_type* Q_ptr;
243  ordinal_type LDQ;
244  getNonConstView (numRows, numCols, Q_ptr, LDQ, Q);
245  const bool contiguousCacheBlocks = false;
246  return tsqr_->revealRankRaw (numRows, numCols, Q_ptr, LDQ,
247  R.values (), R.stride (), tol,
248  contiguousCacheBlocks);
249  }
250 
251  private:
254 
257 
260 
262  mutable Teuchos::RCP<const Teuchos::ParameterList> defaultParams_;
263 
265  bool ready_;
266 
287  void
288  prepareTsqr (const MV& mv)
289  {
290  if (! ready_) {
291  prepareDistTsqr (mv);
292  prepareNodeTsqr (mv);
293  ready_ = true;
294  }
295  }
296 
300  void
301  prepareNodeTsqr (const MV& mv)
302  {
303  node_tsqr_factory_type::prepareNodeTsqr (nodeTsqr_, mv.getMap()->getNode());
304  }
305 
312  void
313  prepareDistTsqr (const MV& mv)
314  {
315  using Teuchos::RCP;
316  using Teuchos::rcp_implicit_cast;
317  typedef TSQR::TeuchosMessenger<scalar_type> mess_type;
318  typedef TSQR::MessengerBase<scalar_type> base_mess_type;
319 
320  RCP<const Teuchos::Comm<int> > comm = mv.getMap()->getComm();
321  RCP<mess_type> mess (new mess_type (comm));
322  RCP<base_mess_type> messBase = rcp_implicit_cast<base_mess_type> (mess);
323  distTsqr_->init (messBase);
324  }
325 
332  static void
333  getNonConstView (ordinal_type& numRows,
334  ordinal_type& numCols,
335  scalar_type*& A_ptr,
336  ordinal_type& LDA,
337  const MV& A)
338  {
339  // FIXME (mfh 25 Oct 2010) We should be able to run TSQR even if
340  // storage of A uses nonconstant stride internally. We would
341  // have to copy and pack into a matrix with constant stride, and
342  // then unpack on exit. For now we choose just to raise an
343  // exception.
345  (! A.isConstantStride (), std::invalid_argument,
346  "TSQR does not currently support Tpetra::MultiVector "
347  "inputs that do not have constant stride.");
348 
349  // FIXME (mfh 16 Jan 2016) When I got here, I found strides[0]
350  // instead of strides[1] for the stride. I don't think this is
351  // right. However, I don't know about these Stokhos scalar
352  // types so I'll just do what was here.
353  //
354  // STOKHOS' TYPES ARE NOT TESTED WITH TSQR REGULARLY SO IT IS
355  // POSSIBLE THAT THE ORIGINAL CODE WAS WRONG.
356 
357  typedef typename MV::dual_view_type view_type;
358  typedef typename view_type::t_dev::array_type flat_array_type;
359 
360  // Reinterpret the data as a longer array of the base scalar
361  // type. TSQR currently forbids MultiVector input with
362  // nonconstant stride, so we need not worry about that here.
363 
364  flat_array_type flat_mv = A.getLocalViewDevice();
365 
366  numRows = static_cast<ordinal_type> (flat_mv.extent(0));
367  numCols = static_cast<ordinal_type> (flat_mv.extent(1));
368  A_ptr = flat_mv.data ();
369 
370  ordinal_type strides[2];
371  flat_mv.stride (strides);
372  LDA = strides[0];
373  }
374  };
375 
376 } // namespace Tpetra
377 
378 #endif // HAVE_TPETRA_TSQR
379 
380 #endif // TPETRA_TSQR_ADAPTOR_MP_VECTOR_HPP
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Kokkos::Serial node_type
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
bool is_null(const RCP< T > &p)
KokkosClassic::DefaultNode::DefaultNodeType Node