MyraMath
SchurTree.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_SYMBOLIC_SCHURTREE_H
7 #define MYRAMATH_MULTIFRONTAL_SYMBOLIC_SCHURTREE_H
8 
14 #include <myramath/MYRAMATH_EXPORT.h>
18 
19 // Options pack.
21 
22 // Required for AssemblyTree:Node
24 
25 // Required std::libraries.
26 #include <map>
27 #include <vector>
28 #include <iosfwd>
29 #include <stdint.h>
30 
31 namespace myra {
32 
33 // Forward declarations.
34 class intCRange;
35 class PatternRange;
36 class InputStream;
37 class OutputStream;
38 class AssemblyTree;
39 
40 
42 class MYRAMATH_EXPORT SchurTree
43  {
44  public:
45 
47  typedef std::pair<const int*,const int*> Range;
49 
50  // Inner class detail, storage type within WriteMap
52  {
53  public:
54  int node;
55  int column;
56  int block;
57  int offset;
58  };
59 
60  // Inner class detail, data structure that records which Node's write to column j.
61  class WriteMap2
62  {
63  public:
64 
65  // Default constructor, makes empty container.
66  WriteMap2();
67 
68  // Constructs from a SchurTree.
69  WriteMap2(const SchurTree& stree);
70 
71  // Copy constructor.
72  WriteMap2(const WriteMap2& that);
73 
74  // Presents a range of Node's that write to column j.
75  const SchurTree::WriteMapItem* begin(int j) const;
76  const SchurTree::WriteMapItem* end(int j) const;
77 
78  // Inspection routine, prints debugging information on out.
79  void inspect(std::ostream& out) const;
80 
81  // Destructor.
82  ~WriteMap2();
83 
84  private:
85 
86  // Internal representation.
87  std::vector<WriteMapItem> items;
88  std::vector<int> strides;
89 
90  };
91 
92  // Inner class detail, data structure that records which Node's write to column j.
93  class WriteMap
94  {
95  public:
96 
97  // Copy constructor.
98  WriteMap(const WriteMap& that);
99 
100  // Presents a range of Node's that write to column j.
101  const int* begin(int j) const;
102  const int* end(int j) const;
103 
104  // Inspection routine, prints debugging information on out.
105  void inspect(std::ostream& out) const;
106 
107  // Destructor.
108  ~WriteMap();
109 
110  private:
111 
112  // Private constructor, SchurTree manipulates contents directly.
113  WriteMap();
114 
115  // Internal representation.
116  std::vector<int> nodes;
117  std::vector<int> strides;
118 
119  friend class SchurTree;
120  };
121 
122  // Inner class detail, single Node of the SchurTree
123  class Node
124  {
125  public:
126 
127  // Unique identifier for this node.
128  int id;
129 
130  // Number of pivots (p), nonpivots (q), and columns (j)
131  int p;
132  int q;
133  int j;
134  std::vector<int> i_pattern;
135  std::vector<int> j_pattern;
136 
137  // Number of pivot blocks (P) and nonpivot blocks (Q) and column blocks (J)
138  int P;
139  int Q;
140  int J;
141  std::vector<int> i_blocking;
142  std::vector<int> j_blocking;
143 
144  // Striding vector, cumsum(blocking)
145  std::vector<int> i_striding;
146  std::vector<int> j_striding;
147 
148  // Parent/child links.
149  Node* parent;
150  std::vector<Node*> children;
151 
152  // Default constructor, empty Node
153  Node();
154 
155  // Constructor, requires matching AssemblyTree::Node
156  Node(const AssemblyTree::Node& anode);
157 
158  // InputStream constructor.
159  Node(InputStream& in);
160 
161  // Writes to OutputStream.
162  void write(OutputStream& out);
163 
164  // Returns id of parent (or -1 if *this is a root)
165  int parent_id() const;
166 
167  // Returns id's of all children.
168  std::vector<int> children_ids() const;
169 
170  // Inspection routine, prints debugging information on out.
171  void inspect(std::ostream& out) const;
172 
173  // ------------------------------------ Pattern interrogation.
174 
175  // Returns pattern of pivots.
176  Range p_pattern() const
177  { return Range(i_pattern.data(), i_pattern.data()+p); }
178 
179  // Returns pattern of nonpivots.
180  Range q_pattern() const
181  { return Range(i_pattern.data()+p, i_pattern.data()+p+q); }
182 
183  // Returns blocking of pivots.
184  Range p_blocking() const
185  { return Range(i_blocking.data(), i_blocking.data()+P); }
186 
187  // Returns blocking of nonpivots.
188  Range q_blocking() const
189  { return Range(i_blocking.data()+P, i_blocking.data()+P+Q); }
190 
191  // Returns pattern of block ib, for ib in [0,P+Q]
192  Range iblock_pattern(int ib) const
193  { return Range(i_pattern.data()+i_striding[ib], i_pattern.data()+i_striding[ib+1]); }
194 
195  // Returns pattern of block jb, for jb in [0,J]
196  Range jblock_pattern(int jb) const
197  { return Range(j_pattern.data()+j_striding[jb], j_pattern.data()+j_striding[jb+1]); }
198 
199  // Returns true iff two SchurTree::Node's j_patterns have common entries.
200  static bool j_intersects(const Node& n1, const Node& n2);
201 
202  // Finds the (block,offset) to a given column j.
203  std::pair<int,int> j_find(int j) const;
204 
205  // ------------------------------------ Space/time queries.
206 
207  // Returns (permanent,temporary) storage requirements.
208  std::pair<uint64_t,uint64_t> n_words() const;
209 
210  // Returns nodal contribution n_work_solve()
211  uint64_t n_work_solve() const;
212 
213  // Returns nodal contribution to n_work_syrk()
214  uint64_t n_work_rankk() const;
215 
216  // Returns nodal contributions to n_work_gemm()
217  static uint64_t n_work_gemm(const Node& x, const Node& y);
218 
219  // ------------------------------------ Dependency tracking along i-axis
220 
221  // Given a contribution block ib in [P,P+Q], returns the set of (parent,iblock)'s that it pushes contributions into.
222  Range iblock_up(int ib) const;
223 
224  // Given a block ib, returns the set of children[c] iblocks it pulls contributions from.
225  Range iblock_down(int ib, int c) const;
226 
227  // ------------------------------------ Dependency tracking along j-axis
228 
229  // Given a block jb in [0,J], returns the set of (parent,jblock)'s that it pushes contributions into.
230  Range jblock_up(int jb) const;
231 
232  // Given a block jb, returns the set of children[c] jblocks it pulls contributions from.
233  Range jblock_down(int jb, int c) const;
234 
235  private:
236 
237  // Caches the child to parent relationships, exposed by iblock_up()
238  std::vector<int> iup_data;
239  Array1<int> iup_begin;
240  Array1<int> iup_end;
241 
242  // Caches the parent to child relationships, exposed by block_down()
243  std::vector<int> idown_data;
244  Array2<int> idown_begin;
245  Array2<int> idown_end;
246 
247  // Given a contribution block b in [P,P+Q], returns the set of (parent,block)'s that it pushes contributions into.
248  // Implementation detail of finalize()
249  std::vector<int> iblock_up_finalize(int b, int blocksize) const;
250 
251  // Given a block b, returns the set of children[c] blocks it pulls contributions from.
252  // Implementation detail of finalize()
253  std::vector<int> iblock_down_finalize(int b, int c, int blocksize) const;
254 
255  // Given a sorted range of indices, finds the match for each one in this->pattern. (or -1, if !found)
256  // Implementation detail of block_up_finalize() and block_down_finalize()
257  std::vector<int> imap(Range range) const;
258 
259  // Populates the caches above.
260  void ifinalize(int blocksize);
261 
262  // Caches the child to parent relationships, exposed by iblock_up()
263  std::vector<int> jup_data;
264  Array1<int> jup_begin;
265  Array1<int> jup_end;
266 
267  // Caches the parent to child relationships, exposed by block_down()
268  std::vector<int> jdown_data;
269  Array2<int> jdown_begin;
270  Array2<int> jdown_end;
271 
272  // Given a block jb in [0,J], returns the set of (parent,jblock)'s that it pushes contributions into.
273  // Implementation detail of finalize()
274  std::vector<int> jblock_up_finalize(int jb, int blocksize) const;
275 
276  // Given a block jb, returns the set of children[c] jblocks it pulls contributions from.
277  // Implementation detail of finalize()
278  std::vector<int> jblock_down_finalize(int jb, int c, int blocksize) const;
279 
280  // Given a sorted range of j-indices, finds the match for each on in this->j_pattern (or -1, if !found)
281  // Implementation detail of finalize()
282  std::vector<int> jmap(Range range) const;
283 
284  // Populates the caches above.
285  void jfinalize(int blocksize);
286 
287  friend class SchurTree;
288  };
289 
291  SchurTree();
292 
294  SchurTree(const AssemblyTree& A, const PatternRange& B, Options options = Options::create());
295 
297  SchurTree(const AssemblyTree& A, const intCRange& B, int J, Options options = Options::create());
298 
300  SchurTree(const SchurTree& that);
301 
303  SchurTree(InputStream& in);
304 
306  void write(OutputStream& out) const;
307 
309  void swap(SchurTree& that);
310 
311 #ifdef MYRAMATH_ENABLE_CPP11
312  SchurTree(SchurTree&& that);
314 #endif
315 
317  SchurTree& operator = (SchurTree that);
318 
320  std::pair<int,int> size() const;
321 
323  int n_nodes() const;
324 
326  const Node& node(int n) const;
327 
329  std::vector<int> roots() const;
330 
332  std::vector<int> leaves() const;
333 
335  std::vector<int> postorder() const;
336  std::vector<int> preorder() const;
337 
339  const std::vector<int>& s2a() const;
340 
342  std::map<int,int> a2s() const;
343 
345  WriteMap writemap() const;
346  WriteMap2 writemap2() const;
347 
349  // High water mark should be approximately the sum of .first + .second
350  std::pair<uint64_t,uint64_t> n_words() const;
351 
353  uint64_t n_work_solve() const;
354 
356  uint64_t n_work_rankk() const;
357 
359  static uint64_t n_work_gemm(const SchurTree& X, const SchurTree& Y);
360 
362  static std::vector<int> intersect(const SchurTree& X, const SchurTree& Y);
363 
365  Array2<int> rankk_j_intersects() const;
366  Array2<int> rankk_j_intersects_old() const; // TODO remove
367 
369  static Array2<int> gemm_j_intersects(const SchurTree& X, const SchurTree& Y);
370  static Array2<int> gemm_j_intersects_old(const SchurTree& X, const SchurTree& Y); // TODO remove
371 
373  void inspect(std::ostream& out) const;
374 
376  ~SchurTree();
377 
378  private:
379 
380  // Implementation details of traversals.
381  void postorder_detail(int n, std::vector<int>& answer) const;
382  void preorder_detail(int n, std::vector<int>& answer) const;
383 
384  // Size of B.
385  int I;
386  int J;
387 
388  // Container of Nodes.
389  std::vector<Node*> nodes;
390 
391  // Mapping from SchurTree::Node's to AssemblyTree::Node's
392  std::vector<int> schur2assembly;
393 
394  // Blocksize, induced by underlying AssemblyTree.
395  int blocksize;
396 
397  };
398 
400 std::ostream& operator<< (std::ostream& out, const SchurTree::WriteMapItem& item);
401 std::ostream& operator<< (std::ostream& out, const SchurTree::WriteMap& map);
402 std::ostream& operator<< (std::ostream& out, const SchurTree::WriteMap2& map);
403 std::ostream& operator<< (std::ostream& out, const SchurTree::Node& stree);
404 std::ostream& operator<< (std::ostream& out, const SchurTree& stree);
405 
406 } // namespace myra
407 
408 #endif
std::pair< const int *, const int * > Range
Useful typedefs.
Definition: SchurTree.h:47
Options pack for routines in /multifrontal.
Definition: Options.h:24
Symbolic analysis data structure for all multifrontal solvers.
Definition: AssemblyTree.h:38
Container of values, allows random (i) access.
Container of values, allows random (i,j) access.
Symbolic analysis data structure for multifrontal schur complement.
Definition: SchurTree.h:42
Definition: SchurTree.h:123
Definition: syntax.dox:1
Represents an immutable view of a Pattern.
Definition: PatternRange.h:31
Abstraction layer, serializable objects write themselves to these.
Definition: Streams.h:39
Definition: SchurTree.h:51
Various utility functions/classes related to scalar Number types.
Abstraction layer, deserializable objects read themselves from these.
Definition: Streams.h:47
Describes data layout and job dependencies for symmetric-pattern multifrontal solvers.
Definition: SchurTree.h:93
Options pack for routines in /multifrontal.
Definition: SchurTree.h:61
Definition: AssemblyTree.h:47
Represents a const intRange.
Definition: intRange.h:142