Anasazi Version of the Day
Loading...
Searching...
No Matches
Tsqr_TwoLevelDistTsqr.hpp
1// @HEADER
2// *****************************************************************************
3// Anasazi: Block Eigensolvers Package
4//
5// Copyright 2004 NTESS and the Anasazi contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef __TSQR_Tsqr_TwoLevelDistTsqr_hpp
11#define __TSQR_Tsqr_TwoLevelDistTsqr_hpp
12
13#include <Tsqr_DistTsqr.hpp>
14#include <Tsqr_MpiCommFactory.hpp>
15#include <sstream>
16
19
20namespace TSQR {
21
28 template< class LocalOrdinal,
29 class Scalar,
30 class DistTsqrType = DistTsqr< LocalOrdinal, Scalar > >
32 public:
33 typedef Scalar scalar_type;
34 typedef LocalOrdinal ordinal_type;
35 typedef DistTsqrType dist_tsqr_type;
36 typedef typename dist_tsqr_type::rank_type rank_type;
37 typedef typename Teuchos::RCP< dist_tsqr_type > dist_tsqr_ptr;
38 typedef typename dist_tsqr_type::FactorOutput DistTsqrFactorOutput;
39 typedef std::pair< DistTsqrFactorOutput, DistTsqrFactorOutput > FactorOutput;
40
44 worldMess_ (TSQR::MPI::makeMpiCommWorld()),
45 nodeDistTsqr_ (TSQR::MPI::makeMpiCommNode()),
46 networkDistTsqr_ (TSQR::MPI::makeMpiCommNetwork())
47 {}
48
53
57 return nodeDistTsqr_->QR_produces_R_factor_with_nonnegative_diagonal() &&
58 networkDistTsqr_->QR_produces_R_factor_with_nonnegative_diagonal();
59 }
60
78 FactorOutput
79 factor (MatView< LocalOrdinal, Scalar > R_mine)
80 {
81 DistTsqrFactorOutput nodeOutput = nodeDistTsqr_->factor (R_mine);
82 DistTsqrFactorOutput networkOutput = networkDistTsqr_->factor (R_mine);
83 return std::make_pair (nodeOutput, networkOutput);
84 }
85
86 void
87 apply (const ApplyType& applyType,
88 const LocalOrdinal ncols_C,
89 const LocalOrdinal ncols_Q,
90 Scalar C_mine[],
91 const LocalOrdinal ldc_mine,
92 const FactorOutput& factorOutput)
93 {
94 if (applyType.transposed())
95 {
96 nodeDistTsqr_->apply (applyType, ncols_C, ncols_Q,
97 C_mine, ldc_mine, factorOutput.first);
98 networkDistTsqr_->apply (applyType, ncols_C, ncols_Q,
99 C_mine, ldc_mine, factorOutput.second);
100 }
101 else
102 {
103 networkDistTsqr_->apply (applyType, ncols_C, ncols_Q,
104 C_mine, ldc_mine, factorOutput.second);
105 nodeDistTsqr_->apply (applyType, ncols_C, ncols_Q,
106 C_mine, ldc_mine, factorOutput.first);
107 }
108 }
109
110 void
111 explicit_Q (const LocalOrdinal ncols_Q,
112 Scalar Q_mine[],
113 const LocalOrdinal ldq_mine,
114 const FactorOutput& factorOutput)
115 {
116 typedef MatView< LocalOrdinal, Scalar > matview_type;
117 matview_type Q_view (ncols_Q, ncols_Q, Q_mine, ldq_mine, Scalar(0));
118 Q_view.fill (Scalar(0));
119
120 const rank_type myRank = worldMess_->rank();
121 if (myRank == 0)
122 {
123 if (networkMess_->rank() != 0)
124 {
125 std::ostringstream os;
126 os << "My rank with respect to MPI_COMM_WORLD is 0, but my rank "
127 "with respect to MPI_COMM_NETWORK is nonzero (= "
128 << networkMess_->rank() << "). We could deal with this by "
129 "swapping data between those two ranks, but we haven\'t "
130 "implemented that fix yet.";
131 throw std::logic_error (os.str());
132 }
133 for (LocalOrdinal j = 0; j < ncols_Q; ++j)
134 Q_view(j, j) = Scalar (1);
135 }
136 apply (ApplyType::NoTranspose, ncols_Q, ncols_Q,
137 Q_mine, ldq_mine, factorOutput);
138 }
139
140 private:
141 Teuchos::RCP< MessengerBase< Scalar > > worldMess_;
142 dist_tsqr_ptr nodeDistTsqr_, networkDistTsqr_;
143 };
144
145} // namespace TSQR
146
147#endif // __TSQR_Tsqr_TwoLevelDistTsqr_hpp
Interprocess part of TSQR.
bool QR_produces_R_factor_with_nonnegative_diagonal() const
FactorOutput factor(MatView< LocalOrdinal, Scalar > R_mine)
Compute QR factorization of R factors, one per MPI process.