Anasazi  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 
20 namespace 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;
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:
142  dist_tsqr_ptr nodeDistTsqr_, networkDistTsqr_;
143  };
144 
145 } // namespace TSQR
146 
147 #endif // __TSQR_Tsqr_TwoLevelDistTsqr_hpp
FactorOutput factor(MatView< LocalOrdinal, Scalar > R_mine)
Compute QR factorization of R factors, one per MPI process.
bool QR_produces_R_factor_with_nonnegative_diagonal() const
Interprocess part of TSQR.