MyraMath
factor.h
Go to the documentation of this file.
1 // ========================================================================= //
2 // This file is part of MyraMath, copyright (c) 2014-2019 by Ryan A Chilton //
3 // and distributed by MyraCore, LLC. See LICENSE.txt for license terms. //
4 // ========================================================================= //
5 
6 #ifndef MYRAMATH_MULTIFRONTAL_ZLDLH_FACTOR_H
7 #define MYRAMATH_MULTIFRONTAL_ZLDLH_FACTOR_H
8 
14 #include <myramath/multifrontal/detail/llt/factor.h>
15 
16 #include <myramath/dense/hetrf.h>
17 #include <myramath/dense/trsm.h>
18 #include <myramath/dense/syrk.h>
19 #include <myramath/dense/gemm.h>
20 #include <myramath/dense/detail/nwork.h>
21 
22 #include <myramath/dense/Matrix.h>
24 
27 
28 namespace myra {
29 namespace multifrontal {
30 namespace zldlh {
31 namespace factor {
32 
33 template<class Precision> class JobGraphBase : public ::myra::multifrontal::detail::llt::factor::JobGraphBase2<ZLDLHKernel<Precision> >
34  {
35  public:
36 
37  // Structural typedefs for base class.
38  typedef std::complex<Precision> Number;
40  typedef ::myra::multifrontal::detail::llt::factor::JobGraphBase2<Kernel> Base;
41 
42  // Typedefs related to numeric storage on LContainer
43  typedef ::myra::multifrontal::detail::llt::LContainer<Kernel> LContainer;
45  typedef Matrix<Number> Block;
46 
47  // Constructor - requires reference to LContainer under construction.
48  JobGraphBase(LContainer* in_lcontainer)
49  : Base(in_lcontainer), lcontainer(in_lcontainer) { }
50 
51  // Virtual copy constructor.
52  virtual ::myra::JobGraphBase* clone() const
53  { return new JobGraphBase(*this); }
54 
55  protected:
56 
57  // Factors An(k,k) = Ln(k,k)*Ln(k,k)'
58  virtual uint64_t factor(int n, int k)
59  {
60  // Assign internode contributions if on first k-iteration.
61  if (k == 0) this->assign_contributions(n,k);
62  return lcontainer->factor(n,k);
63  }
64 
65  // Solves Ln(i,k)*Ln(k,k)' = An(i,k)
66  virtual uint64_t trsm(int n, int k, int i)
67  {
68  // Assign internode contributions if on first k-iteration.
69  if (k == 0) this->assign_contributions(n,i,k);
70  MatrixRange<Number> An_ik = this->a(n,i,k);
71  const Kernel& Ln_kk = this->l(n,k);
72  uint64_t w = Ln_kk.solveL(An_ik,'R','H');
73  Ln_kk.solveI(An_ik,'R');
74  return w;
75  }
76 
77  // Downdates An(ij,ij) -= Ln(ij,k)*Ln(ij,k)'
78  virtual uint64_t rankk(int n, int k, int ij)
79  {
80  // Useful constants.
81  Precision one(1);
82  Precision zero(0);
83  // Downdate An(ij,ij) -= Ln(ij,k)*Ln(ij,k)' [herk]
84  LowerMatrixRange<Number> An_ij = this->a(n,ij);
85  CMatrixRange<Number> Ln_ijk = this->l(n,ij,k);
86  // Carefully choose beta and order of steps to avoid workspace initialization.
87  Precision beta = k ? one : zero;
88  // Two herk's required, with alpha = +/- one.
89  std::pair<int,int> inertia = this->l(n,k).inertia();
90  uint64_t w = 0;
91  w += herk_nwork(An_ij, Ln_ijk. left(inertia.first) , 'N', -one, beta);
92  w += herk_nwork(An_ij, Ln_ijk.right(inertia.second), 'N', one, one );
93  // Add internode contributions if on first k-iteration.
94  if (k == 0) this->add_contributions(n,ij);
95  return w;
96  }
97 
98  // Downdates An(i,j) -= Ln(i,k)*Ln(j,k)'
99  virtual uint64_t gemm(int n, int k, int i, int j)
100  {
101  // Useful constants.
102  Number one(1);
103  Number zero(0);
104  // Downdate An(i,j) -= Ln(i,k)*Ln(j,k)' [gemm]
105  MatrixRange<Number> An_ij = this->a(n,i,j);
106  CMatrixRange<Number> Ln_ik = this->l(n,i,k);
107  CMatrixRange<Number> Ln_jk = this->l(n,j,k);
108  // Carefully choose beta and order of steps to avoid workspace initialization.
109  Number beta = k ? one : zero;
110  // Two gemm's required, with alpha = +/- one.
111  std::pair<int,int> inertia = this->l(n,k).inertia();
112  uint64_t w = 0;
113  w += gemm_nwork(An_ij, Ln_ik. left(inertia.first ), 'N', Ln_jk. left(inertia.first ), 'H', -one, beta);
114  w += gemm_nwork(An_ij, Ln_ik.right(inertia.second), 'N', Ln_jk.right(inertia.second), 'H', one, one );
115  // Add internode contributions if on first k-iteration.
116  if (k == 0) this->add_contributions(n,i,j);
117  return w;
118  }
119 
120  private:
121 
122  // Reference to LContainer under construction.
123  LContainer* lcontainer;
124 
125  }; // class JobGraph
126 
127 } } } } // namespace
128 
129 #endif
Interface class for representing subranges of dense Matrix&#39;s.
Represents a mutable LowerMatrixRange.
Definition: conjugate.h:28
Tabulates an IxJ matrix. Allows random access, has column major layout to be compatible with BLAS/LAP...
Definition: bdsqr.h:20
LDL&#39; decompositions for real hermitian Matrix A (indefinite is fine).
Factors A into L*L&#39;, presents solve methods.
Definition: Kernel.h:39
Range construct for a lower triangular matrix stored in rectangular packed format.
Definition: syntax.dox:1
Represents a const MatrixRange.
Definition: bothcat.h:22
Routines for backsolving by a triangular Matrix or LowerMatrix.
Specialized container for a lower triangular matrix, O(N^2/2) storage. Used by symmetry exploiting ma...
CMatrixRange< Number > right(int j) const
Returns the j rightmost columns, this(:,J-j:J)
Definition: MatrixRange.cpp:596
Represents a mutable MatrixRange.
Definition: conjugate.h:26
General purpose dense matrix container, O(i*j) storage.
Stores a lower triangular matrix in rectangular packed format.
Definition: conjugate.h:22
void solveI(const MatrixRange< Number > &B, char side) const
Solves I*X=B or X*I=B, overwrites B with X.
Definition: Kernel.h:170
Routines for symmetric rank-k updates, a specialized form of Matrix*Matrix multiplication.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.
uint64_t solveL(const MatrixRange< Number > &B, char side, char op) const
Solves op(L)*X=B or X*op(L)=B, overwrites B with X.
Definition: Kernel.h:78