1 /*
2    Copyright (c) 2009-2014, Jack Poulson
3    All rights reserved.
4 
5    This file is part of Elemental and is under the BSD 2-Clause License,
6    which can be found in the LICENSE file in the root directory, or at
7    http://opensource.org/licenses/BSD-2-Clause
8 */
9 #pragma once
10 #ifndef ELEM_VIEWS_VIEW_HPP
11 #define ELEM_VIEWS_VIEW_HPP
12 
13 namespace elem {
14 
15 template<typename T>
View(Matrix<T> & A,Matrix<T> & B)16 inline void View( Matrix<T>& A, Matrix<T>& B )
17 {
18     DEBUG_ONLY(CallStackEntry cse("View"))
19     A.Attach( B.Height(), B.Width(), B.Buffer(), B.LDim() );
20 }
21 
22 template<typename T>
View(Matrix<T> & B)23 inline Matrix<T> View( Matrix<T>& B )
24 {
25     Matrix<T> A;
26     View( A, B );
27     return A;
28 }
29 
30 template<typename T,Dist U,Dist V>
View(DistMatrix<T,U,V> & A,DistMatrix<T,U,V> & B)31 inline void View( DistMatrix<T,U,V>& A, DistMatrix<T,U,V>& B )
32 {
33     DEBUG_ONLY(CallStackEntry cse("View"))
34     A.Attach
35     ( B.Height(), B.Width(), B.Grid(), B.ColAlign(), B.RowAlign(),
36       B.Buffer(), B.LDim(), B.Root() );
37 }
38 
39 template<typename T,Dist U,Dist V>
View(DistMatrix<T,U,V> & B)40 inline DistMatrix<T,U,V> View( DistMatrix<T,U,V>& B )
41 {
42     DistMatrix<T,U,V> A(B.Grid());
43     View( A, B );
44     return A;
45 }
46 
47 template<typename T,Dist U,Dist V>
View(BlockDistMatrix<T,U,V> & A,DistMatrix<T,U,V> & B)48 inline void View( BlockDistMatrix<T,U,V>& A, DistMatrix<T,U,V>& B )
49 {
50     DEBUG_ONLY(CallStackEntry cse("View"))
51     A.Attach
52     ( B.Height(), B.Width(), B.Grid(), 1, 1, B.ColAlign(), B.RowAlign(), 0, 0,
53       B.Buffer(), B.LDim(), B.Root() );
54 }
55 
56 template<typename T,Dist U,Dist V>
View(DistMatrix<T,U,V> & A,BlockDistMatrix<T,U,V> & B)57 inline void View( DistMatrix<T,U,V>& A, BlockDistMatrix<T,U,V>& B )
58 {
59     DEBUG_ONLY(CallStackEntry cse("View"))
60     if( B.BlockHeight() != 1 || B.BlockWidth() != 1 )
61         LogicError("Block size was ",B.BlockHeight()," x ",B.BlockWidth(),
62                     "instead of 1x1");
63     A.Attach
64     ( B.Height(), B.Width(), B.Grid(), B.ColAlign(), B.RowAlign(),
65       B.Buffer(), B.LDim(), B.Root() );
66 }
67 
68 template<typename T>
LockedView(Matrix<T> & A,const Matrix<T> & B)69 inline void LockedView( Matrix<T>& A, const Matrix<T>& B )
70 {
71     DEBUG_ONLY(CallStackEntry cse("LockedView"))
72     A.LockedAttach( B.Height(), B.Width(), B.LockedBuffer(), B.LDim() );
73 }
74 
75 template<typename T>
LockedView(const Matrix<T> & B)76 inline Matrix<T> LockedView( const Matrix<T>& B )
77 {
78     Matrix<T> A;
79     LockedView( A, B );
80     return A;
81 }
82 
83 template<typename T,Dist U,Dist V>
LockedView(DistMatrix<T,U,V> & A,const DistMatrix<T,U,V> & B)84 inline void LockedView( DistMatrix<T,U,V>& A, const DistMatrix<T,U,V>& B )
85 {
86     DEBUG_ONLY(CallStackEntry cse("LockedView"))
87     A.LockedAttach
88     ( B.Height(), B.Width(), B.Grid(), B.ColAlign(), B.RowAlign(),
89       B.LockedBuffer(), B.LDim(), B.Root() );
90 }
91 
92 template<typename T,Dist U,Dist V>
LockedView(const DistMatrix<T,U,V> & B)93 inline DistMatrix<T,U,V> LockedView( const DistMatrix<T,U,V>& B )
94 {
95     DistMatrix<T,U,V> A(B.Grid());
96     LockedView( A, B );
97     return A;
98 }
99 
100 template<typename T,Dist U,Dist V>
LockedView(BlockDistMatrix<T,U,V> & A,const DistMatrix<T,U,V> & B)101 inline void LockedView( BlockDistMatrix<T,U,V>& A, const DistMatrix<T,U,V>& B )
102 {
103     DEBUG_ONLY(CallStackEntry cse("LockedView"))
104     A.LockedAttach
105     ( B.Height(), B.Width(), B.Grid(), 1, 1, B.ColAlign(), B.RowAlign(), 0, 0,
106       B.LockedBuffer(), B.LDim(), B.Root() );
107 }
108 
109 template<typename T,Dist U,Dist V>
LockedView(DistMatrix<T,U,V> & A,const BlockDistMatrix<T,U,V> & B)110 inline void LockedView( DistMatrix<T,U,V>& A, const BlockDistMatrix<T,U,V>& B )
111 {
112     DEBUG_ONLY(CallStackEntry cse("LockedView"))
113     if( B.BlockHeight() != 1 || B.BlockWidth() != 1 )
114         LogicError("Block size was ",B.BlockHeight()," x ",B.BlockWidth(),
115                     "instead of 1x1");
116     A.LockedAttach
117     ( B.Height(), B.Width(), B.Grid(), B.ColAlign(), B.RowAlign(),
118       B.LockedBuffer(), B.LDim(), B.Root() );
119 }
120 
121 template<typename T>
View(Matrix<T> & A,Matrix<T> & B,Int i,Int j,Int height,Int width)122 inline void View
123 ( Matrix<T>& A, Matrix<T>& B,
124   Int i, Int j, Int height, Int width )
125 {
126     DEBUG_ONLY(
127         CallStackEntry cse("View");
128         if( i < 0 || j < 0 )
129             LogicError("Indices must be non-negative");
130         if( height < 0 || width < 0 )
131             LogicError("Height and width must be non-negative");
132         if( (i+height) > B.Height() || (j+width) > B.Width() )
133             LogicError
134             ("Trying to view outside of a Matrix: (",i,",",j,") up to (",
135              i+height-1,",",j+width-1,") of ",B.Height()," x ",B.Width(),
136              " Matrix");
137     )
138     A.Attach( height, width, B.Buffer(i,j), B.LDim() );
139 }
140 
141 template<typename T>
View(Matrix<T> & B,Int i,Int j,Int height,Int width)142 inline Matrix<T> View( Matrix<T>& B, Int i, Int j, Int height, Int width )
143 {
144     Matrix<T> A;
145     View( A, B, i, j, height, width );
146     return A;
147 }
148 
149 template<typename T,Dist U,Dist V>
View(DistMatrix<T,U,V> & A,DistMatrix<T,U,V> & B,Int i,Int j,Int height,Int width)150 inline void View
151 ( DistMatrix<T,U,V>& A, DistMatrix<T,U,V>& B,
152   Int i, Int j, Int height, Int width )
153 {
154     DEBUG_ONLY(
155         CallStackEntry cse("View");
156         B.AssertValidSubmatrix( i, j, height, width );
157     )
158     const Int colAlign = (B.ColAlign()+i) % B.ColStride();
159     const Int rowAlign = (B.RowAlign()+j) % B.RowStride();
160     if( B.Participating() )
161     {
162         const Int iLoc = Length( i, B.ColShift(), B.ColStride() );
163         const Int jLoc = Length( j, B.RowShift(), B.RowStride() );
164         A.Attach
165         ( height, width, B.Grid(), colAlign, rowAlign,
166           B.Buffer(iLoc,jLoc), B.LDim(), B.Root() );
167     }
168     else
169     {
170         A.Attach
171         ( height, width, B.Grid(), colAlign, rowAlign, 0, B.LDim(), B.Root() );
172     }
173 }
174 
175 template<typename T,Dist U,Dist V>
View(DistMatrix<T,U,V> & B,Int i,Int j,Int height,Int width)176 inline DistMatrix<T,U,V> View
177 ( DistMatrix<T,U,V>& B, Int i, Int j, Int height, Int width )
178 {
179     DistMatrix<T,U,V> A(B.Grid());
180     View( A, B, i, j, height, width );
181     return A;
182 }
183 
184 template<typename T>
LockedView(Matrix<T> & A,const Matrix<T> & B,Int i,Int j,Int height,Int width)185 inline void LockedView
186 ( Matrix<T>& A, const Matrix<T>& B,
187   Int i, Int j, Int height, Int width )
188 {
189     DEBUG_ONLY(
190         CallStackEntry cse("LockedView");
191         if( i < 0 || j < 0 )
192             LogicError("Indices must be non-negative");
193         if( height < 0 || width < 0 )
194             LogicError("Height and width must be non-negative");
195         if( (i+height) > B.Height() || (j+width) > B.Width() )
196             LogicError
197             ("Trying to view outside of a Matrix: (",i,",",j,") up to (",
198              i+height-1,",",j+width-1,") of ",B.Height()," x ",B.Width(),
199              " Matrix");
200     )
201     A.LockedAttach( height, width, B.LockedBuffer(i,j), B.LDim() );
202 }
203 
204 template<typename T>
LockedView(const Matrix<T> & B,Int i,Int j,Int height,Int width)205 inline Matrix<T> LockedView
206 ( const Matrix<T>& B, Int i, Int j, Int height, Int width )
207 {
208     Matrix<T> A;
209     LockedView( A, B, i, j, height, width );
210     return A;
211 }
212 
213 template<typename T,Dist U,Dist V>
LockedView(DistMatrix<T,U,V> & A,const DistMatrix<T,U,V> & B,Int i,Int j,Int height,Int width)214 inline void LockedView
215 ( DistMatrix<T,U,V>& A, const DistMatrix<T,U,V>& B,
216   Int i, Int j, Int height, Int width )
217 {
218     DEBUG_ONLY(
219         CallStackEntry cse("LockedView");
220         B.AssertValidSubmatrix( i, j, height, width );
221     )
222     const Int colAlign = (B.ColAlign()+i) % B.ColStride();
223     const Int rowAlign = (B.RowAlign()+j) % B.RowStride();
224     if( B.Participating() )
225     {
226         const Int iLoc = Length( i, B.ColShift(), B.ColStride() );
227         const Int jLoc = Length( j, B.RowShift(), B.RowStride() );
228         A.LockedAttach
229         ( height, width, B.Grid(), colAlign, rowAlign,
230           B.LockedBuffer(iLoc,jLoc), B.LDim(), B.Root() );
231     }
232     else
233     {
234         A.LockedAttach
235         ( height, width, B.Grid(), colAlign, rowAlign, 0, B.LDim(), B.Root() );
236     }
237 }
238 
239 template<typename T,Dist U,Dist V>
LockedView(const DistMatrix<T,U,V> & B,Int i,Int j,Int height,Int width)240 inline DistMatrix<T,U,V> LockedView
241 ( const DistMatrix<T,U,V>& B, Int i, Int j, Int height, Int width )
242 {
243     DistMatrix<T,U,V> A(B.Grid());
244     LockedView( A, B, i, j, height, width );
245     return A;
246 }
247 
248 template<typename T>
ViewRange(Matrix<T> & A,Matrix<T> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)249 void ViewRange
250 ( Matrix<T>& A, Matrix<T>& B, Int iBeg, Int jBeg, Int iEnd, Int jEnd )
251 {
252     DEBUG_ONLY(CallStackEntry cse("ViewRange"))
253     View( A, B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
254 }
255 
256 template<typename T>
ViewRange(Matrix<T> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)257 Matrix<T> ViewRange
258 ( Matrix<T>& B, Int iBeg, Int jBeg, Int iEnd, Int jEnd )
259 {
260     DEBUG_ONLY(CallStackEntry cse("ViewRange"))
261     return View( B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
262 }
263 
264 template<typename T,Dist U,Dist V>
ViewRange(DistMatrix<T,U,V> & A,DistMatrix<T,U,V> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)265 void ViewRange
266 ( DistMatrix<T,U,V>& A, DistMatrix<T,U,V>& B,
267   Int iBeg, Int jBeg, Int iEnd, Int jEnd )
268 {
269     DEBUG_ONLY(CallStackEntry cse("ViewRange"))
270     View( A, B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
271 }
272 
273 template<typename T,Dist U,Dist V>
ViewRange(DistMatrix<T,U,V> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)274 DistMatrix<T,U,V> ViewRange
275 ( DistMatrix<T,U,V>& B, Int iBeg, Int jBeg, Int iEnd, Int jEnd )
276 {
277     DEBUG_ONLY(CallStackEntry cse("ViewRange"))
278     return View( B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
279 }
280 
281 template<typename T>
LockedViewRange(Matrix<T> & A,const Matrix<T> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)282 void LockedViewRange
283 ( Matrix<T>& A, const Matrix<T>& B, Int iBeg, Int jBeg, Int iEnd, Int jEnd )
284 {
285     DEBUG_ONLY(CallStackEntry cse("LockedViewRange"))
286     LockedView( A, B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
287 }
288 
289 template<typename T>
LockedViewRange(const Matrix<T> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)290 Matrix<T> LockedViewRange
291 ( const Matrix<T>& B, Int iBeg, Int jBeg, Int iEnd, Int jEnd )
292 {
293     DEBUG_ONLY(CallStackEntry cse("LockedViewRange"))
294     return LockedView( B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
295 }
296 
297 template<typename T,Dist U,Dist V>
LockedViewRange(DistMatrix<T,U,V> & A,const DistMatrix<T,U,V> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)298 void LockedViewRange
299 ( DistMatrix<T,U,V>& A, const DistMatrix<T,U,V>& B,
300   Int iBeg, Int jBeg, Int iEnd, Int jEnd )
301 {
302     DEBUG_ONLY(CallStackEntry cse("LockedViewRange"))
303     LockedView( A, B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
304 }
305 
306 template<typename T,Dist U,Dist V>
LockedViewRange(const DistMatrix<T,U,V> & B,Int iBeg,Int jBeg,Int iEnd,Int jEnd)307 DistMatrix<T,U,V> LockedViewRange
308 ( const DistMatrix<T,U,V>& B, Int iBeg, Int jBeg, Int iEnd, Int jEnd )
309 {
310     DEBUG_ONLY(CallStackEntry cse("LockedViewRange"))
311     return LockedView( B, iBeg, jBeg, iEnd-iBeg, jEnd-jBeg );
312 }
313 
314 template<typename T>
View1x2(Matrix<T> & A,Matrix<T> & BL,Matrix<T> & BR)315 inline void View1x2( Matrix<T>& A, Matrix<T>& BL, Matrix<T>& BR )
316 {
317     DEBUG_ONLY(
318         CallStackEntry cse("View1x2");
319         if( BL.Locked() || BR.Locked() )
320             LogicError("Cannot grab an unlocked view of a locked matrix");
321         if( BL.Height() != BR.Height() )
322             LogicError("1x2 must have consistent height to combine");
323         if( BL.LDim() != BR.LDim() )
324             LogicError("1x2 must have consistent ldims to combine");
325         if( BR.Buffer() != (BL.Buffer()+BL.LDim()*BL.Width()) )
326             LogicError("1x2 must have contiguous memory");
327     )
328     A.Attach( BL.Height(), BL.Width()+BR.Width(), BL.Buffer(), BL.LDim() );
329 }
330 
331 template<typename T>
View1x2(Matrix<T> & BL,Matrix<T> & BR)332 inline Matrix<T> View1x2( Matrix<T>& BL, Matrix<T>& BR )
333 {
334     Matrix<T> A;
335     View1x2( A, BL, BR );
336     return A;
337 }
338 
339 template<typename T,Dist U,Dist V>
View1x2(DistMatrix<T,U,V> & A,DistMatrix<T,U,V> & BL,DistMatrix<T,U,V> & BR)340 inline void View1x2
341 ( DistMatrix<T,U,V>& A, DistMatrix<T,U,V>& BL, DistMatrix<T,U,V>& BR )
342 {
343     DEBUG_ONLY(
344         CallStackEntry cse("View1x2");
345         AssertConforming1x2( BL, BR );
346         BL.AssertSameGrid( BR.Grid() );
347     )
348     A.Attach
349     ( BL.Height(), BL.Width()+BR.Width(), BL.Grid(),
350       BL.ColAlign(), BL.RowAlign(), BL.Buffer(), BL.LDim(), BL.Root() );
351 }
352 
353 template<typename T,Dist U,Dist V>
View1x2(DistMatrix<T,U,V> & BL,DistMatrix<T,U,V> & BR)354 inline DistMatrix<T,U,V> View1x2( DistMatrix<T,U,V>& BL, DistMatrix<T,U,V>& BR )
355 {
356     DistMatrix<T,U,V> A(BL.Grid());
357     View1x2( A, BL, BR );
358     return A;
359 }
360 
361 template<typename T>
LockedView1x2(Matrix<T> & A,const Matrix<T> & BL,const Matrix<T> & BR)362 inline void LockedView1x2
363 ( Matrix<T>& A, const Matrix<T>& BL, const Matrix<T>& BR )
364 {
365     DEBUG_ONLY(
366         CallStackEntry cse("LockedView1x2");
367         if( BL.Height() != BR.Height() )
368             LogicError("1x2 must have consistent height to combine");
369         if( BL.LDim() != BR.LDim() )
370             LogicError("1x2 must have consistent ldims to combine");
371         if( BR.LockedBuffer() != (BL.LockedBuffer()+BL.LDim()*BL.Width()) )
372             LogicError("1x2 must have contiguous memory");
373     )
374     A.LockedAttach
375     ( BL.Height(), BL.Width()+BR.Width(), BL.LockedBuffer(), BL.LDim() );
376 }
377 
378 template<typename T>
LockedView1x2(const Matrix<T> & BL,const Matrix<T> & BR)379 inline Matrix<T> LockedView1x2( const Matrix<T>& BL, const Matrix<T>& BR )
380 {
381     Matrix<T> A;
382     LockedView1x2( A, BL, BR );
383     return A;
384 }
385 
386 template<typename T,Dist U,Dist V>
LockedView1x2(DistMatrix<T,U,V> & A,const DistMatrix<T,U,V> & BL,const DistMatrix<T,U,V> & BR)387 inline void LockedView1x2
388 (       DistMatrix<T,U,V>& A,
389   const DistMatrix<T,U,V>& BL,
390   const DistMatrix<T,U,V>& BR )
391 {
392     DEBUG_ONLY(
393         CallStackEntry cse("LockedView1x2");
394         AssertConforming1x2( BL, BR );
395         BL.AssertSameGrid( BR.Grid() );
396     )
397     A.LockedAttach
398     ( BL.Height(), BL.Width()+BR.Width(), BL.Grid(),
399       BL.ColAlign(), BL.RowAlign(), BL.LockedBuffer(), BL.LDim(), BL.Root() );
400 }
401 
402 template<typename T,Dist U,Dist V>
LockedView1x2(const DistMatrix<T,U,V> & BL,const DistMatrix<T,U,V> & BR)403 inline DistMatrix<T,U,V> LockedView1x2
404 ( const DistMatrix<T,U,V>& BL, const DistMatrix<T,U,V>& BR )
405 {
406     DistMatrix<T,U,V> A(BL.Grid());
407     LockedView1x2( A, BL, BR );
408     return A;
409 }
410 
411 template<typename T>
View2x1(Matrix<T> & A,Matrix<T> & BT,Matrix<T> & BB)412 inline void View2x1( Matrix<T>& A, Matrix<T>& BT, Matrix<T>& BB )
413 {
414     DEBUG_ONLY(
415         CallStackEntry cse("View2x1");
416         if( BT.Locked() || BB.Locked() )
417             LogicError("Cannot grab an unlocked view of a locked matrix");
418         if( BT.Width() != BB.Width() )
419             LogicError("2x1 must have consistent width to combine");
420         if( BT.LDim() != BB.LDim() )
421             LogicError("2x1 must have consistent ldim to combine");
422         if( BB.Buffer() != (BT.Buffer() + BT.Height()) )
423             LogicError("2x1 must have contiguous memory");
424     )
425     A.Attach( BT.Height()+BB.Height(), BT.Width(), BT.Buffer(), BT.LDim() );
426 }
427 
428 template<typename T>
View2x1(Matrix<T> & BT,Matrix<T> & BB)429 inline Matrix<T> View2x1( Matrix<T>& BT, Matrix<T>& BB )
430 {
431     Matrix<T> A;
432     View2x1( A, BT, BB );
433     return A;
434 }
435 
436 template<typename T,Dist U,Dist V>
View2x1(DistMatrix<T,U,V> & A,DistMatrix<T,U,V> & BT,DistMatrix<T,U,V> & BB)437 inline void View2x1
438 ( DistMatrix<T,U,V>& A, DistMatrix<T,U,V>& BT, DistMatrix<T,U,V>& BB )
439 {
440     DEBUG_ONLY(
441         CallStackEntry cse("View2x1");
442         AssertConforming2x1( BT, BB );
443         BT.AssertSameGrid( BB.Grid() );
444     )
445     A.Attach
446     ( BT.Height()+BB.Height(), BT.Width(), BT.Grid(),
447       BT.ColAlign(), BT.RowAlign(), BT.Buffer(), BT.LDim(), BT.Root() );
448 }
449 
450 template<typename T,Dist U,Dist V>
View2x1(DistMatrix<T,U,V> & BT,DistMatrix<T,U,V> & BB)451 inline DistMatrix<T,U,V> View2x1( DistMatrix<T,U,V>& BT, DistMatrix<T,U,V>& BB )
452 {
453     DistMatrix<T,U,V> A(BT.Grid());
454     View2x1( A, BT, BB );
455     return A;
456 }
457 
458 template<typename T>
LockedView2x1(Matrix<T> & A,const Matrix<T> & BT,const Matrix<T> & BB)459 inline void LockedView2x1
460 ( Matrix<T>& A, const Matrix<T>& BT, const Matrix<T>& BB )
461 {
462     DEBUG_ONLY(
463         CallStackEntry cse("LockedView2x1");
464         if( BT.Width() != BB.Width() )
465             LogicError("2x1 must have consistent width to combine");
466         if( BT.LDim() != BB.LDim() )
467             LogicError("2x1 must have consistent ldim to combine");
468         if( BB.LockedBuffer() != (BT.LockedBuffer() + BT.Height()) )
469             LogicError("2x1 must have contiguous memory");
470     )
471     A.LockedAttach
472     ( BT.Height()+BB.Height(), BT.Width(), BT.LockedBuffer(), BT.LDim() );
473 }
474 
475 template<typename T>
LockedView2x1(const Matrix<T> & BT,const Matrix<T> & BB)476 inline Matrix<T> LockedView2x1
477 ( const Matrix<T>& BT, const Matrix<T>& BB )
478 {
479     Matrix<T> A;
480     LockedView2x1( A, BT, BB );
481     return A;
482 }
483 
484 template<typename T,Dist U,Dist V>
LockedView2x1(DistMatrix<T,U,V> & A,const DistMatrix<T,U,V> & BT,const DistMatrix<T,U,V> & BB)485 inline void LockedView2x1
486 (       DistMatrix<T,U,V>& A,
487   const DistMatrix<T,U,V>& BT,
488   const DistMatrix<T,U,V>& BB )
489 {
490     DEBUG_ONLY(
491         CallStackEntry cse("LockedView2x1");
492         AssertConforming2x1( BT, BB );
493         BT.AssertSameGrid( BB.Grid() );
494     )
495     A.LockedAttach
496     ( BT.Height()+BB.Height(), BT.Width(), BT.Grid(),
497       BT.ColAlign(), BT.RowAlign(), BT.LockedBuffer(), BT.LDim(), BT.Root() );
498 }
499 
500 template<typename T,Dist U,Dist V>
LockedView2x1(const DistMatrix<T,U,V> & BT,const DistMatrix<T,U,V> & BB)501 inline DistMatrix<T,U,V> LockedView2x1
502 ( const DistMatrix<T,U,V>& BT, const DistMatrix<T,U,V>& BB )
503 {
504     DistMatrix<T,U,V> A(BT.Grid());
505     LockedView2x1( A, BT, BB );
506     return A;
507 }
508 
509 template<typename T>
View2x2(Matrix<T> & A,Matrix<T> & BTL,Matrix<T> & BTR,Matrix<T> & BBL,Matrix<T> & BBR)510 inline void View2x2
511 ( Matrix<T>& A,
512   Matrix<T>& BTL, Matrix<T>& BTR,
513   Matrix<T>& BBL, Matrix<T>& BBR )
514 {
515     DEBUG_ONLY(
516         CallStackEntry cse("View2x2");
517         if( BTL.Locked() || BTR.Locked() || BBL.Locked() || BBR.Locked() )
518             LogicError("Cannot grab an unlocked view of a locked matrix");
519         if( BTL.Width() != BBL.Width()   ||
520             BTR.Width() != BBR.Width()   ||
521             BTL.Height() != BTR.Height() ||
522             BBL.Height() != BBR.Height()   )
523             LogicError("2x2 must conform to combine");
524         if( BTL.LDim() != BTR.LDim() ||
525             BTR.LDim() != BBL.LDim() ||
526             BBL.LDim() != BBR.LDim()   )
527             LogicError("2x2 must have consistent ldims to combine");
528         if( BBL.Buffer() != (BTL.Buffer() + BTL.Height()) ||
529             BBR.Buffer() != (BTR.Buffer() + BTR.Height()) ||
530             BTR.Buffer() != (BTL.Buffer() + BTL.LDim()*BTL.Width()) )
531             LogicError("2x2 must have contiguous memory");
532     )
533     A.Attach
534     ( BTL.Height()+BBL.Height(), BTL.Width()+BTR.Width(),
535       BTL.Buffer(), BTL.LDim() );
536 }
537 
538 template<typename T>
View2x2(Matrix<T> & BTL,Matrix<T> & BTR,Matrix<T> & BBL,Matrix<T> & BBR)539 inline Matrix<T> View2x2
540 ( Matrix<T>& BTL, Matrix<T>& BTR,
541   Matrix<T>& BBL, Matrix<T>& BBR )
542 {
543     Matrix<T> A;
544     View2x2( A, BTL, BTR, BBL, BBR );
545     return A;
546 }
547 
548 template<typename T,Dist U,Dist V>
View2x2(DistMatrix<T,U,V> & A,DistMatrix<T,U,V> & BTL,DistMatrix<T,U,V> & BTR,DistMatrix<T,U,V> & BBL,DistMatrix<T,U,V> & BBR)549 inline void View2x2
550 ( DistMatrix<T,U,V>& A,
551   DistMatrix<T,U,V>& BTL, DistMatrix<T,U,V>& BTR,
552   DistMatrix<T,U,V>& BBL, DistMatrix<T,U,V>& BBR )
553 {
554     DEBUG_ONLY(
555         CallStackEntry cse("View2x2");
556         AssertConforming2x2( BTL, BTR, BBL, BBR );
557         BTL.AssertSameGrid( BTR.Grid() );
558         BTL.AssertSameGrid( BBL.Grid() );
559         BTL.AssertSameGrid( BBR.Grid() );
560     )
561     A.Attach
562     ( BTL.Height()+BBL.Height(), BTL.Width()+BTR.Width(), BTL.Grid(),
563       BTL.ColAlign(), BTL.RowAlign(), BTL.Buffer(), BTL.LDim(), BTL.Root() );
564 }
565 
566 template<typename T,Dist U,Dist V>
View2x2(DistMatrix<T,U,V> & BTL,DistMatrix<T,U,V> & BTR,DistMatrix<T,U,V> & BBL,DistMatrix<T,U,V> & BBR)567 inline DistMatrix<T,U,V> View2x2
568 ( DistMatrix<T,U,V>& BTL, DistMatrix<T,U,V>& BTR,
569   DistMatrix<T,U,V>& BBL, DistMatrix<T,U,V>& BBR )
570 {
571     DistMatrix<T,U,V> A(BTL.Grid());
572     View2x2( A, BTL, BTR, BBL, BBR );
573     return A;
574 }
575 
576 template<typename T>
LockedView2x2(Matrix<T> & A,const Matrix<T> & BTL,const Matrix<T> & BTR,const Matrix<T> & BBL,const Matrix<T> & BBR)577 inline void LockedView2x2
578 (       Matrix<T>& A,
579   const Matrix<T>& BTL,
580   const Matrix<T>& BTR,
581   const Matrix<T>& BBL,
582   const Matrix<T>& BBR )
583 {
584     DEBUG_ONLY(
585         CallStackEntry cse("LockedView2x2");
586         if( BTL.Width() != BBL.Width()   ||
587             BTR.Width() != BBR.Width()   ||
588             BTL.Height() != BTR.Height() ||
589             BBL.Height() != BBR.Height()   )
590             LogicError("2x2 must conform to combine");
591         if( BTL.LDim() != BTR.LDim() ||
592             BTR.LDim() != BBL.LDim() ||
593             BBL.LDim() != BBR.LDim()   )
594             LogicError("2x2 must have consistent ldims to combine");
595         if( BBL.LockedBuffer() != (BTL.LockedBuffer()+BTL.Height()) ||
596             BBR.LockedBuffer() != (BTR.LockedBuffer()+BTR.Height()) ||
597             BTR.LockedBuffer() != (BTL.LockedBuffer()+BTL.LDim()*BTL.Width()) )
598             LogicError("2x2 must have contiguous memory");
599     )
600     A.LockedAttach
601     ( BTL.Height()+BBL.Height(), BTL.Width()+BTR.Width(),
602       BTL.LockedBuffer(), BTL.LDim() );
603 }
604 
605 template<typename T>
LockedView2x2(const Matrix<T> & BTL,const Matrix<T> & BTR,const Matrix<T> & BBL,const Matrix<T> & BBR)606 inline Matrix<T> LockedView2x2
607 ( const Matrix<T>& BTL, const Matrix<T>& BTR,
608   const Matrix<T>& BBL, const Matrix<T>& BBR )
609 {
610     Matrix<T> A;
611     LockedView2x2( A, BTL, BTR, BBL, BBR );
612     return A;
613 }
614 
615 template<typename T,Dist U,Dist V>
LockedView2x2(DistMatrix<T,U,V> & A,const DistMatrix<T,U,V> & BTL,const DistMatrix<T,U,V> & BTR,const DistMatrix<T,U,V> & BBL,const DistMatrix<T,U,V> & BBR)616 inline void LockedView2x2
617 (       DistMatrix<T,U,V>& A,
618   const DistMatrix<T,U,V>& BTL, const DistMatrix<T,U,V>& BTR,
619   const DistMatrix<T,U,V>& BBL, const DistMatrix<T,U,V>& BBR )
620 {
621     DEBUG_ONLY(
622         CallStackEntry cse("LockedView2x2");
623         AssertConforming2x2( BTL, BTR, BBL, BBR );
624         BTL.AssertSameGrid( BTR.Grid() );
625         BTL.AssertSameGrid( BBL.Grid() );
626         BTL.AssertSameGrid( BBR.Grid() );
627     )
628     A.LockedAttach
629     ( BTL.Height()+BBL.Height(), BTL.Width()+BTR.Width(), BTL.Grid(),
630       BTL.ColAlign(), BTL.RowAlign(), BTL.LockedBuffer(), BTL.LDim(),
631       BTL.Root() );
632 }
633 
634 template<typename T,Dist U,Dist V>
LockedView2x2(const DistMatrix<T,U,V> & BTL,const DistMatrix<T,U,V> & BTR,const DistMatrix<T,U,V> & BBL,const DistMatrix<T,U,V> & BBR)635 inline DistMatrix<T,U,V> LockedView2x2
636 ( const DistMatrix<T,U,V>& BTL, const DistMatrix<T,U,V>& BTR,
637   const DistMatrix<T,U,V>& BBL, const DistMatrix<T,U,V>& BBR )
638 {
639     DistMatrix<T,U,V> A(BTL.Grid());
640     LockedView2x2( A, BTL, BTR, BBL, BBR );
641     return A;
642 }
643 
644 } // namespace elem
645 
646 #endif // ifndef ELEM_VIEWS_VIEW_HPP
647