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 #include "elemental-lite.hpp"
10 #include ELEM_TRANSPOSE_INC
11 #include ELEM_ZEROS_INC
12
13 namespace elem {
14
15 // Public section
16 // ##############
17
18 // Constructors and destructors
19 // ============================
20
21 template<typename T,Dist U,Dist V>
GeneralBlockDistMatrix(const elem::Grid & g,Int root)22 GeneralBlockDistMatrix<T,U,V>::GeneralBlockDistMatrix
23 ( const elem::Grid& g, Int root )
24 : AbstractBlockDistMatrix<T>(g,root)
25 { }
26
27 template<typename T,Dist U,Dist V>
GeneralBlockDistMatrix(const elem::Grid & g,Int blockHeight,Int blockWidth,Int root)28 GeneralBlockDistMatrix<T,U,V>::GeneralBlockDistMatrix
29 ( const elem::Grid& g, Int blockHeight, Int blockWidth, Int root )
30 : AbstractBlockDistMatrix<T>(g,blockHeight,blockWidth,root)
31 { }
32
33 template<typename T,Dist U,Dist V>
GeneralBlockDistMatrix(GeneralBlockDistMatrix<T,U,V> && A)34 GeneralBlockDistMatrix<T,U,V>::GeneralBlockDistMatrix
35 ( GeneralBlockDistMatrix<T,U,V>&& A ) ELEM_NOEXCEPT
36 : AbstractBlockDistMatrix<T>(std::move(A))
37 { }
38
39 // Assignment and reconfiguration
40 // ==============================
41
42 template<typename T,Dist U,Dist V>
43 GeneralBlockDistMatrix<T,U,V>&
operator =(GeneralBlockDistMatrix<T,U,V> && A)44 GeneralBlockDistMatrix<T,U,V>::operator=( GeneralBlockDistMatrix<T,U,V>&& A )
45 {
46 AbstractBlockDistMatrix<T>::operator=( std::move(A) );
47 return *this;
48 }
49
50 template<typename T,Dist U,Dist V>
51 void
AlignColsWith(const elem::BlockDistData & data,bool constrain)52 GeneralBlockDistMatrix<T,U,V>::AlignColsWith
53 ( const elem::BlockDistData& data, bool constrain )
54 {
55 DEBUG_ONLY(CallStackEntry cse("GBDM::AlignColsWith"))
56 this->SetGrid( *data.grid );
57 this->SetRoot( data.root );
58 if( data.colDist == U || data.colDist == UPart )
59 this->AlignCols
60 ( data.blockHeight, data.colAlign, data.colCut, constrain );
61 else if( data.rowDist == U || data.rowDist == UPart )
62 this->AlignCols
63 ( data.blockWidth, data.rowAlign, data.rowCut, constrain );
64 else if( data.colDist == UScat )
65 this->AlignCols
66 ( data.blockHeight, data.colAlign % this->ColStride(), data.colCut,
67 constrain );
68 else if( data.rowDist == UScat )
69 this->AlignCols
70 ( data.blockWidth, data.rowAlign % this->ColStride(), data.rowCut,
71 constrain );
72 DEBUG_ONLY(
73 else if( U != UGath && data.colDist != UGath && data.rowDist != UGath )
74 LogicError("Nonsensical alignment");
75 )
76 }
77
78 template<typename T,Dist U,Dist V>
79 void
AlignRowsWith(const elem::BlockDistData & data,bool constrain)80 GeneralBlockDistMatrix<T,U,V>::AlignRowsWith
81 ( const elem::BlockDistData& data, bool constrain )
82 {
83 DEBUG_ONLY(CallStackEntry cse("GBDM::AlignRowsWith"))
84 this->SetGrid( *data.grid );
85 this->SetRoot( data.root );
86 if( data.colDist == V || data.colDist == VPart )
87 this->AlignRows
88 ( data.blockHeight, data.colAlign, data.colCut, constrain );
89 else if( data.rowDist == V || data.rowDist == VPart )
90 this->AlignRows
91 ( data.blockWidth, data.rowAlign, data.rowCut, constrain );
92 else if( data.colDist == VScat )
93 this->AlignRows
94 ( data.blockHeight, data.colAlign % this->RowStride(), data.colCut,
95 constrain );
96 else if( data.rowDist == VScat )
97 this->AlignRows
98 ( data.blockWidth, data.rowAlign % this->RowStride(), data.rowCut,
99 constrain );
100 DEBUG_ONLY(
101 else if( V != VGath && data.colDist != VGath && data.rowDist != VGath )
102 LogicError("Nonsensical alignment");
103 )
104 }
105
106 template<typename T,Dist U,Dist V>
107 void
Translate(BlockDistMatrix<T,U,V> & A) const108 GeneralBlockDistMatrix<T,U,V>::Translate( BlockDistMatrix<T,U,V>& A ) const
109 {
110 DEBUG_ONLY(CallStackEntry cse("GBDM::Translate"))
111 const Int height = this->Height();
112 const Int width = this->Width();
113 const Int blockHeight = this->BlockHeight();
114 const Int blockWidth = this->BlockWidth();
115 const Int colAlign = this->ColAlign();
116 const Int rowAlign = this->RowAlign();
117 const Int colCut = this->ColCut();
118 const Int rowCut = this->RowCut();
119 const Int root = this->Root();
120 A.SetGrid( this->Grid() );
121 if( !A.RootConstrained() )
122 A.SetRoot( root, false );
123 if( !A.ColConstrained() )
124 A.AlignCols( blockHeight, colAlign, colCut, false );
125 if( !A.RowConstrained() )
126 A.AlignRows( blockWidth, rowAlign, rowCut, false );
127 A.Resize( height, width );
128 const bool aligned =
129 blockHeight == A.BlockHeight() && blockWidth == A.BlockWidth() &&
130 colAlign == A.ColAlign() && rowAlign == A.RowAlign() &&
131 colCut == A.ColCut() && rowCut == A.RowCut();
132 if( aligned && root == A.Root() )
133 {
134 A.matrix_ = this->matrix_;
135 }
136 else
137 {
138 // TODO: Implement this in a more efficient manner, perhaps through
139 // many rounds of point-to-point communication
140 // TODO: Turn this into a general routine for redistributing
141 // between any matrix distributions supported by Elemental.
142 // The key addition is mpi::Translate.
143 const Int distSize = A.DistSize();
144 const Int mLocal = this->LocalHeight();
145 const Int nLocal = this->LocalWidth();
146 const Int mLocalA = A.LocalHeight();
147 const Int nLocalA = A.LocalWidth();
148
149 // Determine how much data our process sends and recvs from every
150 // other process
151 std::vector<int> sendCounts(distSize,0),
152 recvCounts(distSize,0);
153 for( Int jLoc=0; jLoc<nLocal; ++jLoc )
154 {
155 const Int j = this->GlobalCol(jLoc);
156 for( Int iLoc=0; iLoc<mLocal; ++iLoc )
157 {
158 const Int i = this->GlobalRow(iLoc);
159 const Int owner = A.Owner(i,j);
160 ++sendCounts[owner];
161 }
162 }
163 for( Int jLoc=0; jLoc<nLocalA; ++jLoc )
164 {
165 const Int j = A.GlobalCol(jLoc);
166 for( Int iLoc=0; iLoc<mLocalA; ++iLoc )
167 {
168 const Int i = A.GlobalRow(iLoc);
169 const Int owner = this->Owner(i,j);
170 ++recvCounts[owner];
171 }
172 }
173
174 // Translate the send/recv counts into displacements and allocate
175 // the send and recv buffers
176 std::vector<int> sendDispls(distSize), recvDispls(distSize);
177 int totalSend=0, totalRecv=0;
178 for( int q=0; q<distSize; ++q )
179 {
180 sendDispls[q] = totalSend;
181 recvDispls[q] = totalRecv;
182 totalSend += sendCounts[q];
183 totalRecv += recvCounts[q];
184 }
185 std::vector<T> sendBuf(totalSend), recvBuf(totalRecv);
186
187 // Pack the send data
188 std::vector<int> offsets = sendDispls;
189 for( Int jLoc=0; jLoc<nLocal; ++jLoc )
190 {
191 const Int j = this->GlobalCol(jLoc);
192 for( Int iLoc=0; iLoc<mLocal; ++iLoc )
193 {
194 const Int i = this->GlobalRow(iLoc);
195 const Int owner = A.Owner(i,j);
196 sendBuf[offsets[owner]++] = this->GetLocal(iLoc,jLoc);
197 }
198 }
199
200 // Perform the all-to-all communication
201 mpi::AllToAll
202 ( sendBuf.data(), sendCounts.data(), sendDispls.data(),
203 recvBuf.data(), recvCounts.data(), recvDispls.data(),
204 this->DistComm() );
205 SwapClear( sendBuf );
206
207 // Unpack the received data
208 offsets = recvDispls;
209 for( Int jLoc=0; jLoc<nLocalA; ++jLoc )
210 {
211 const Int j = A.GlobalCol(jLoc);
212 for( Int iLoc=0; iLoc<mLocalA; ++iLoc )
213 {
214 const Int i = A.GlobalRow(iLoc);
215 const Int owner = this->Owner(i,j);
216 A.SetLocal( iLoc, jLoc, recvBuf[offsets[owner]++] );
217 }
218 }
219 }
220 }
221
222 template<typename T,Dist U,Dist V>
223 void
AllGather(BlockDistMatrix<T,UGath,VGath> & A) const224 GeneralBlockDistMatrix<T,U,V>::AllGather
225 ( BlockDistMatrix<T,UGath,VGath>& A ) const
226 {
227 DEBUG_ONLY(
228 CallStackEntry cse("GBDM::AllGather");
229 this->AssertSameGrid( A.Grid() );
230 )
231 LogicError("This routine is not yet written");
232 }
233
234 template<typename T,Dist U,Dist V>
235 void
ColAllGather(BlockDistMatrix<T,UGath,V> & A) const236 GeneralBlockDistMatrix<T,U,V>::ColAllGather
237 ( BlockDistMatrix<T,UGath,V>& A ) const
238 {
239 DEBUG_ONLY(
240 CallStackEntry cse("GBDM::ColAllGather");
241 this->AssertSameGrid( A.Grid() );
242 )
243 LogicError("This routine is not yet written");
244 }
245
246 template<typename T,Dist U,Dist V>
247 void
RowAllGather(BlockDistMatrix<T,U,VGath> & A) const248 GeneralBlockDistMatrix<T,U,V>::RowAllGather
249 ( BlockDistMatrix<T,U,VGath>& A ) const
250 {
251 DEBUG_ONLY(
252 CallStackEntry cse("GBDM::RowAllGather");
253 this->AssertSameGrid( A.Grid() );
254 )
255 LogicError("This routine is not yet written");
256 }
257
258 template<typename T,Dist U,Dist V>
259 void
PartialColAllGather(BlockDistMatrix<T,UPart,V> & A) const260 GeneralBlockDistMatrix<T,U,V>::PartialColAllGather
261 ( BlockDistMatrix<T,UPart,V>& A ) const
262 {
263 DEBUG_ONLY(
264 CallStackEntry cse("GBDM::PartialColAllGather");
265 this->AssertSameGrid( A.Grid() );
266 )
267 LogicError("This routine is not yet written");
268 }
269
270 template<typename T,Dist U,Dist V>
271 void
PartialRowAllGather(BlockDistMatrix<T,U,VPart> & A) const272 GeneralBlockDistMatrix<T,U,V>::PartialRowAllGather
273 ( BlockDistMatrix<T,U,VPart>& A ) const
274 {
275 DEBUG_ONLY(
276 CallStackEntry cse("GBDM::PartialRowAllGather");
277 this->AssertSameGrid( A.Grid() );
278 )
279 LogicError("This routine is not yet written");
280 }
281
282 template<typename T,Dist U,Dist V>
283 void
FilterFrom(const BlockDistMatrix<T,UGath,VGath> & A)284 GeneralBlockDistMatrix<T,U,V>::FilterFrom
285 ( const BlockDistMatrix<T,UGath,VGath>& A )
286 {
287 DEBUG_ONLY(
288 CallStackEntry cse("GBDM::FilterFrom");
289 this->AssertSameGrid( A.Grid() );
290 )
291 LogicError("This routine is not yet written");
292 }
293
294 template<typename T,Dist U,Dist V>
295 void
ColFilterFrom(const BlockDistMatrix<T,UGath,V> & A)296 GeneralBlockDistMatrix<T,U,V>::ColFilterFrom
297 ( const BlockDistMatrix<T,UGath,V>& A )
298 {
299 DEBUG_ONLY(
300 CallStackEntry cse("GBDM::ColFilterFrom");
301 this->AssertSameGrid( A.Grid() );
302 )
303 LogicError("This routine is not yet written");
304 }
305
306 template<typename T,Dist U,Dist V>
307 void
RowFilterFrom(const BlockDistMatrix<T,U,VGath> & A)308 GeneralBlockDistMatrix<T,U,V>::RowFilterFrom
309 ( const BlockDistMatrix<T,U,VGath>& A )
310 {
311 DEBUG_ONLY(
312 CallStackEntry cse("GBDM::RowFilterFrom");
313 this->AssertSameGrid( A.Grid() );
314 )
315 LogicError("This routine is not yet written");
316 }
317
318 template<typename T,Dist U,Dist V>
319 void
PartialColFilterFrom(const BlockDistMatrix<T,UPart,V> & A)320 GeneralBlockDistMatrix<T,U,V>::PartialColFilterFrom
321 ( const BlockDistMatrix<T,UPart,V>& A )
322 {
323 DEBUG_ONLY(
324 CallStackEntry cse("GBDM::PartialColFilterFrom");
325 this->AssertSameGrid( A.Grid() );
326 )
327 LogicError("This routine is not yet written");
328 }
329
330 template<typename T,Dist U,Dist V>
331 void
PartialRowFilterFrom(const BlockDistMatrix<T,U,VPart> & A)332 GeneralBlockDistMatrix<T,U,V>::PartialRowFilterFrom
333 ( const BlockDistMatrix<T,U,VPart>& A )
334 {
335 DEBUG_ONLY(
336 CallStackEntry cse("GBDM::PartialRowFilterFrom");
337 this->AssertSameGrid( A.Grid() );
338 )
339 LogicError("This routine is not yet written");
340 }
341
342 template<typename T,Dist U,Dist V>
343 void
PartialColAllToAllFrom(const BlockDistMatrix<T,UPart,VScat> & A)344 GeneralBlockDistMatrix<T,U,V>::PartialColAllToAllFrom
345 ( const BlockDistMatrix<T,UPart,VScat>& A )
346 {
347 DEBUG_ONLY(
348 CallStackEntry cse("GBDM::PartialColAllToAllFrom");
349 this->AssertSameGrid( A.Grid() );
350 )
351 LogicError("This routine is not yet written");
352 }
353
354 template<typename T,Dist U,Dist V>
355 void
PartialRowAllToAllFrom(const BlockDistMatrix<T,UScat,VPart> & A)356 GeneralBlockDistMatrix<T,U,V>::PartialRowAllToAllFrom
357 ( const BlockDistMatrix<T,UScat,VPart>& A )
358 {
359 DEBUG_ONLY(
360 CallStackEntry cse("GBDM::PartialRowAllToAllFrom");
361 this->AssertSameGrid( A.Grid() );
362 )
363 LogicError("This routine is not yet written");
364 }
365
366 template<typename T,Dist U,Dist V>
367 void
PartialColAllToAll(BlockDistMatrix<T,UPart,VScat> & A) const368 GeneralBlockDistMatrix<T,U,V>::PartialColAllToAll
369 ( BlockDistMatrix<T,UPart,VScat>& A ) const
370 {
371 DEBUG_ONLY(
372 CallStackEntry cse("GBDM::PartialColAllToAll");
373 this->AssertSameGrid( A.Grid() );
374 )
375 LogicError("This routine is not yet written");
376 }
377
378 template<typename T,Dist U,Dist V>
379 void
PartialRowAllToAll(BlockDistMatrix<T,UScat,VPart> & A) const380 GeneralBlockDistMatrix<T,U,V>::PartialRowAllToAll
381 ( BlockDistMatrix<T,UScat,VPart>& A ) const
382 {
383 DEBUG_ONLY(
384 CallStackEntry cse("GBDM::PartialRowAllToAll");
385 this->AssertSameGrid( A.Grid() );
386 )
387 LogicError("This routine is not yet written");
388 }
389
390 template<typename T,Dist U,Dist V>
391 void
RowSumScatterFrom(const BlockDistMatrix<T,U,VGath> & A)392 GeneralBlockDistMatrix<T,U,V>::RowSumScatterFrom
393 ( const BlockDistMatrix<T,U,VGath>& A )
394 {
395 DEBUG_ONLY(
396 CallStackEntry cse("GBDM::RowSumScatterFrom");
397 this->AssertSameGrid( A.Grid() );
398 )
399 this->AlignColsAndResize
400 ( A.BlockHeight(), A.ColAlign(), A.ColCut(), A.Height(), A.Width(),
401 false, false );
402 // NOTE: This will be *slightly* slower than necessary due to the result
403 // of the MPI operations being added rather than just copied
404 Zeros( this->Matrix(), this->LocalHeight(), this->LocalWidth() );
405 this->RowSumScatterUpdate( T(1), A );
406 }
407
408 template<typename T,Dist U,Dist V>
409 void
ColSumScatterFrom(const BlockDistMatrix<T,UGath,V> & A)410 GeneralBlockDistMatrix<T,U,V>::ColSumScatterFrom
411 ( const BlockDistMatrix<T,UGath,V>& A )
412 {
413 DEBUG_ONLY(
414 CallStackEntry cse("GBDM::ColSumScatterFrom");
415 this->AssertSameGrid( A.Grid() );
416 )
417 this->AlignRowsAndResize
418 ( A.BlockWidth(), A.RowAlign(), A.RowCut(), A.Height(), A.Width(),
419 false, false );
420 // NOTE: This will be *slightly* slower than necessary due to the result
421 // of the MPI operations being added rather than just copied
422 Zeros( this->Matrix(), this->LocalHeight(), this->LocalWidth() );
423 this->ColSumScatterUpdate( T(1), A );
424 }
425
426 template<typename T,Dist U,Dist V>
427 void
SumScatterFrom(const BlockDistMatrix<T,UGath,VGath> & A)428 GeneralBlockDistMatrix<T,U,V>::SumScatterFrom
429 ( const BlockDistMatrix<T,UGath,VGath>& A )
430 {
431 DEBUG_ONLY(
432 CallStackEntry cse("GBDM::SumScatterFrom");
433 this->AssertSameGrid( A.Grid() );
434 )
435 this->Resize( A.Height(), A.Width() );
436 // NOTE: This will be *slightly* slower than necessary due to the result
437 // of the MPI operations being added rather than just copied
438 Zeros( this->Matrix(), this->LocalHeight(), this->LocalWidth() );
439 this->SumScatterUpdate( T(1), A );
440 }
441
442 template<typename T,Dist U,Dist V>
443 void
PartialRowSumScatterFrom(const BlockDistMatrix<T,U,VPart> & A)444 GeneralBlockDistMatrix<T,U,V>::PartialRowSumScatterFrom
445 ( const BlockDistMatrix<T,U,VPart>& A )
446 {
447 DEBUG_ONLY(
448 CallStackEntry cse("GBDM::PartialRowSumScatterFrom");
449 this->AssertSameGrid( A.Grid() );
450 )
451 this->AlignAndResize
452 ( A.BlockHeight(), A.BlockWidth(),
453 A.ColAlign(), A.RowAlign(), A.ColCut(), A.RowCut(),
454 A.Height(), A.Width(), false, false );
455 // NOTE: This will be *slightly* slower than necessary due to the result
456 // of the MPI operations being added rather than just copied
457 Zeros( this->Matrix(), this->LocalHeight(), this->LocalWidth() );
458 this->PartialRowSumScatterUpdate( T(1), A );
459 }
460
461 template<typename T,Dist U,Dist V>
462 void
PartialColSumScatterFrom(const BlockDistMatrix<T,UPart,V> & A)463 GeneralBlockDistMatrix<T,U,V>::PartialColSumScatterFrom
464 ( const BlockDistMatrix<T,UPart,V>& A )
465 {
466 DEBUG_ONLY(
467 CallStackEntry cse("GBDM::PartialColSumScatterFrom");
468 this->AssertSameGrid( A.Grid() );
469 )
470 this->AlignAndResize
471 ( A.BlockHeight(), A.BlockWidth(),
472 A.ColAlign(), A.RowAlign(), A.ColCut(), A.RowCut(),
473 A.Height(), A.Width(), false, false );
474 // NOTE: This will be *slightly* slower than necessary due to the result
475 // of the MPI operations being added rather than just copied
476 Zeros( this->Matrix(), this->LocalHeight(), this->LocalWidth() );
477 this->PartialColSumScatterUpdate( T(1), A );
478 }
479
480 template<typename T,Dist U,Dist V>
481 void
RowSumScatterUpdate(T alpha,const BlockDistMatrix<T,U,VGath> & A)482 GeneralBlockDistMatrix<T,U,V>::RowSumScatterUpdate
483 ( T alpha, const BlockDistMatrix<T,U,VGath>& A )
484 {
485 DEBUG_ONLY(
486 CallStackEntry cse("GBDM::RowSumScatterUpdate");
487 this->AssertNotLocked();
488 this->AssertSameGrid( A.Grid() );
489 this->AssertSameSize( A.Height(), A.Width() );
490 )
491 if( !this->Participating() )
492 return;
493
494 LogicError("This routine is not yet written");
495 }
496
497 template<typename T,Dist U,Dist V>
498 void
ColSumScatterUpdate(T alpha,const BlockDistMatrix<T,UGath,V> & A)499 GeneralBlockDistMatrix<T,U,V>::ColSumScatterUpdate
500 ( T alpha, const BlockDistMatrix<T,UGath,V>& A )
501 {
502 DEBUG_ONLY(
503 CallStackEntry cse("GBDM::ColSumScatterUpdate");
504 this->AssertNotLocked();
505 this->AssertSameGrid( A.Grid() );
506 this->AssertSameSize( A.Height(), A.Width() );
507 )
508 LogicError("This routine is not yet written");
509 }
510
511 template<typename T,Dist U,Dist V>
512 void
SumScatterUpdate(T alpha,const BlockDistMatrix<T,UGath,VGath> & A)513 GeneralBlockDistMatrix<T,U,V>::SumScatterUpdate
514 ( T alpha, const BlockDistMatrix<T,UGath,VGath>& A )
515 {
516 DEBUG_ONLY(
517 CallStackEntry cse("GBDM::SumScatterUpdate");
518 this->AssertNotLocked();
519 this->AssertSameGrid( A.Grid() );
520 this->AssertSameSize( A.Height(), A.Width() );
521 )
522 if( !this->Participating() )
523 return;
524 LogicError("This routine is not yet written");
525 }
526
527 template<typename T,Dist U,Dist V>
528 void
PartialRowSumScatterUpdate(T alpha,const BlockDistMatrix<T,U,VPart> & A)529 GeneralBlockDistMatrix<T,U,V>::PartialRowSumScatterUpdate
530 ( T alpha, const BlockDistMatrix<T,U,VPart>& A )
531 {
532 DEBUG_ONLY(
533 CallStackEntry cse("GBDM::PartialRowSumScatterUpdate");
534 this->AssertNotLocked();
535 this->AssertSameGrid( A.Grid() );
536 this->AssertSameSize( A.Height(), A.Width() );
537 )
538 if( !this->Participating() )
539 return;
540
541 LogicError("This routine is not yet written");
542 }
543
544 template<typename T,Dist U,Dist V>
545 void
PartialColSumScatterUpdate(T alpha,const BlockDistMatrix<T,UPart,V> & A)546 GeneralBlockDistMatrix<T,U,V>::PartialColSumScatterUpdate
547 ( T alpha, const BlockDistMatrix<T,UPart,V>& A )
548 {
549 DEBUG_ONLY(
550 CallStackEntry cse("GBDM::PartialColSumScatterUpdate");
551 this->AssertNotLocked();
552 this->AssertSameGrid( A.Grid() );
553 this->AssertSameSize( A.Height(), A.Width() );
554 )
555 if( !this->Participating() )
556 return;
557
558 LogicError("This routine is not yet written");
559 }
560
561 template<typename T,Dist U,Dist V>
562 void
TransposeColAllGather(BlockDistMatrix<T,V,UGath> & A,bool conjugate) const563 GeneralBlockDistMatrix<T,U,V>::TransposeColAllGather
564 ( BlockDistMatrix<T,V,UGath>& A, bool conjugate ) const
565 {
566 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposeColAllGather"))
567 BlockDistMatrix<T,V,U> ATrans( this->Grid() );
568 ATrans.AlignWith( *this );
569 ATrans.Resize( this->Width(), this->Height() );
570 Transpose( this->LockedMatrix(), ATrans.Matrix(), conjugate );
571 ATrans.RowAllGather( A );
572 }
573
574 template<typename T,Dist U,Dist V>
575 void
TransposePartialColAllGather(BlockDistMatrix<T,V,UPart> & A,bool conjugate) const576 GeneralBlockDistMatrix<T,U,V>::TransposePartialColAllGather
577 ( BlockDistMatrix<T,V,UPart>& A, bool conjugate ) const
578 {
579 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposePartialColAllGather"))
580 BlockDistMatrix<T,V,U> ATrans( this->Grid() );
581 ATrans.AlignWith( *this );
582 ATrans.Resize( this->Width(), this->Height() );
583 Transpose( this->LockedMatrix(), ATrans.Matrix(), conjugate );
584 ATrans.PartialRowAllGather( A );
585 }
586
587 template<typename T,Dist U,Dist V>
588 void
AdjointColAllGather(BlockDistMatrix<T,V,UGath> & A) const589 GeneralBlockDistMatrix<T,U,V>::AdjointColAllGather
590 ( BlockDistMatrix<T,V,UGath>& A ) const
591 {
592 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointRowAllGather"))
593 this->TransposeColAllGather( A, true );
594 }
595
596 template<typename T,Dist U,Dist V>
597 void
AdjointPartialColAllGather(BlockDistMatrix<T,V,UPart> & A) const598 GeneralBlockDistMatrix<T,U,V>::AdjointPartialColAllGather
599 ( BlockDistMatrix<T,V,UPart>& A ) const
600 {
601 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointPartialColAllGather"))
602 this->TransposePartialColAllGather( A, true );
603 }
604
605 template<typename T,Dist U,Dist V>
606 void
TransposeColFilterFrom(const BlockDistMatrix<T,V,UGath> & A,bool conjugate)607 GeneralBlockDistMatrix<T,U,V>::TransposeColFilterFrom
608 ( const BlockDistMatrix<T,V,UGath>& A, bool conjugate )
609 {
610 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposeColFilterFrom"))
611 BlockDistMatrix<T,V,U> AFilt( A.Grid() );
612 if( this->ColConstrained() )
613 AFilt.AlignRowsWith( *this, false );
614 if( this->RowConstrained() )
615 AFilt.AlignColsWith( *this, false );
616 AFilt.RowFilterFrom( A );
617 if( !this->ColConstrained() )
618 this->AlignColsWith( AFilt, false );
619 if( !this->RowConstrained() )
620 this->AlignRowsWith( AFilt, false );
621 this->Resize( A.Width(), A.Height() );
622 Transpose( AFilt.LockedMatrix(), this->Matrix(), conjugate );
623 }
624
625 template<typename T,Dist U,Dist V>
626 void
TransposeRowFilterFrom(const BlockDistMatrix<T,VGath,U> & A,bool conjugate)627 GeneralBlockDistMatrix<T,U,V>::TransposeRowFilterFrom
628 ( const BlockDistMatrix<T,VGath,U>& A, bool conjugate )
629 {
630 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposeRowFilterFrom"))
631 BlockDistMatrix<T,V,U> AFilt( A.Grid() );
632 if( this->ColConstrained() )
633 AFilt.AlignRowsWith( *this, false );
634 if( this->RowConstrained() )
635 AFilt.AlignColsWith( *this, false );
636 AFilt.ColFilterFrom( A );
637 if( !this->ColConstrained() )
638 this->AlignColsWith( AFilt, false );
639 if( !this->RowConstrained() )
640 this->AlignRowsWith( AFilt, false );
641 this->Resize( A.Width(), A.Height() );
642 Transpose( AFilt.LockedMatrix(), this->Matrix(), conjugate );
643 }
644
645 template<typename T,Dist U,Dist V>
646 void
TransposePartialColFilterFrom(const BlockDistMatrix<T,V,UPart> & A,bool conjugate)647 GeneralBlockDistMatrix<T,U,V>::TransposePartialColFilterFrom
648 ( const BlockDistMatrix<T,V,UPart>& A, bool conjugate )
649 {
650 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposePartialColFilterFrom"))
651 BlockDistMatrix<T,V,U> AFilt( A.Grid() );
652 if( this->ColConstrained() )
653 AFilt.AlignRowsWith( *this, false );
654 if( this->RowConstrained() )
655 AFilt.AlignColsWith( *this, false );
656 AFilt.PartialRowFilterFrom( A );
657 if( !this->ColConstrained() )
658 this->AlignColsWith( AFilt, false );
659 if( !this->RowConstrained() )
660 this->AlignRowsWith( AFilt, false );
661 this->Resize( A.Width(), A.Height() );
662 Transpose( AFilt.LockedMatrix(), this->Matrix(), conjugate );
663 }
664
665 template<typename T,Dist U,Dist V>
666 void
TransposePartialRowFilterFrom(const BlockDistMatrix<T,VPart,U> & A,bool conjugate)667 GeneralBlockDistMatrix<T,U,V>::TransposePartialRowFilterFrom
668 ( const BlockDistMatrix<T,VPart,U>& A, bool conjugate )
669 {
670 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposePartialRowFilterFrom"))
671 BlockDistMatrix<T,V,U> AFilt( A.Grid() );
672 if( this->ColConstrained() )
673 AFilt.AlignRowsWith( *this, false );
674 if( this->RowConstrained() )
675 AFilt.AlignColsWith( *this, false );
676 AFilt.PartialColFilterFrom( A );
677 if( !this->ColConstrained() )
678 this->AlignColsWith( AFilt, false );
679 if( !this->RowConstrained() )
680 this->AlignRowsWith( AFilt, false );
681 this->Resize( A.Width(), A.Height() );
682 Transpose( AFilt.LockedMatrix(), this->Matrix(), conjugate );
683 }
684
685 template<typename T,Dist U,Dist V>
686 void
AdjointColFilterFrom(const BlockDistMatrix<T,V,UGath> & A)687 GeneralBlockDistMatrix<T,U,V>::AdjointColFilterFrom
688 ( const BlockDistMatrix<T,V,UGath>& A )
689 {
690 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointColFilterFrom"))
691 this->TransposeColFilterFrom( A, true );
692 }
693
694 template<typename T,Dist U,Dist V>
695 void
AdjointRowFilterFrom(const BlockDistMatrix<T,VGath,U> & A)696 GeneralBlockDistMatrix<T,U,V>::AdjointRowFilterFrom
697 ( const BlockDistMatrix<T,VGath,U>& A )
698 {
699 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointRowFilterFrom"))
700 this->TransposeRowFilterFrom( A, true );
701 }
702
703 template<typename T,Dist U,Dist V>
704 void
AdjointPartialColFilterFrom(const BlockDistMatrix<T,V,UPart> & A)705 GeneralBlockDistMatrix<T,U,V>::AdjointPartialColFilterFrom
706 ( const BlockDistMatrix<T,V,UPart>& A )
707 {
708 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointPartialColFilterFrom"))
709 this->TransposePartialColFilterFrom( A, true );
710 }
711
712 template<typename T,Dist U,Dist V>
713 void
AdjointPartialRowFilterFrom(const BlockDistMatrix<T,VPart,U> & A)714 GeneralBlockDistMatrix<T,U,V>::AdjointPartialRowFilterFrom
715 ( const BlockDistMatrix<T,VPart,U>& A )
716 {
717 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointPartialRowFilterFrom"))
718 this->TransposePartialRowFilterFrom( A, true );
719 }
720
721 template<typename T,Dist U,Dist V>
722 void
TransposeColSumScatterFrom(const BlockDistMatrix<T,V,UGath> & A,bool conjugate)723 GeneralBlockDistMatrix<T,U,V>::TransposeColSumScatterFrom
724 ( const BlockDistMatrix<T,V,UGath>& A, bool conjugate )
725 {
726 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposeColSumScatterFrom"))
727 BlockDistMatrix<T,V,U> ASumFilt( A.Grid() );
728 if( this->ColConstrained() )
729 ASumFilt.AlignRowsWith( *this, false );
730 if( this->RowConstrained() )
731 ASumFilt.AlignColsWith( *this, false );
732 ASumFilt.RowSumScatterFrom( A );
733 if( !this->ColConstrained() )
734 this->AlignColsWith( ASumFilt, false );
735 if( !this->RowConstrained() )
736 this->AlignRowsWith( ASumFilt, false );
737 this->Resize( A.Width(), A.Height() );
738 Transpose( ASumFilt.LockedMatrix(), this->Matrix(), conjugate );
739 }
740
741 template<typename T,Dist U,Dist V>
742 void
TransposePartialColSumScatterFrom(const BlockDistMatrix<T,V,UPart> & A,bool conjugate)743 GeneralBlockDistMatrix<T,U,V>::TransposePartialColSumScatterFrom
744 ( const BlockDistMatrix<T,V,UPart>& A, bool conjugate )
745 {
746 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposePartialColSumScatterFrom"))
747 BlockDistMatrix<T,V,U> ASumFilt( A.Grid() );
748 if( this->ColConstrained() )
749 ASumFilt.AlignRowsWith( *this, false );
750 if( this->RowConstrained() )
751 ASumFilt.AlignColsWith( *this, false );
752 ASumFilt.PartialRowSumScatterFrom( A );
753 if( !this->ColConstrained() )
754 this->AlignColsWith( ASumFilt, false );
755 if( !this->RowConstrained() )
756 this->AlignRowsWith( ASumFilt, false );
757 this->Resize( A.Width(), A.Height() );
758 Transpose( ASumFilt.LockedMatrix(), this->Matrix(), conjugate );
759 }
760
761 template<typename T,Dist U,Dist V>
762 void
AdjointColSumScatterFrom(const BlockDistMatrix<T,V,UGath> & A)763 GeneralBlockDistMatrix<T,U,V>::AdjointColSumScatterFrom
764 ( const BlockDistMatrix<T,V,UGath>& A )
765 {
766 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointColSumScatterFrom"))
767 this->TransposeColSumScatterFrom( A, true );
768 }
769
770 template<typename T,Dist U,Dist V>
771 void
AdjointPartialColSumScatterFrom(const BlockDistMatrix<T,V,UPart> & A)772 GeneralBlockDistMatrix<T,U,V>::AdjointPartialColSumScatterFrom
773 ( const BlockDistMatrix<T,V,UPart>& A )
774 {
775 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointPartialColSumScatterFrom"))
776 this->TransposePartialColSumScatterFrom( A, true );
777 }
778
779 template<typename T,Dist U,Dist V>
780 void
TransposeColSumScatterUpdate(T alpha,const BlockDistMatrix<T,V,UGath> & A,bool conjugate)781 GeneralBlockDistMatrix<T,U,V>::TransposeColSumScatterUpdate
782 ( T alpha, const BlockDistMatrix<T,V,UGath>& A, bool conjugate )
783 {
784 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposeColSumScatterUpdate"))
785 BlockDistMatrix<T,V,U> ASumFilt( A.Grid() );
786 if( this->ColConstrained() )
787 ASumFilt.AlignRowsWith( *this, false );
788 if( this->RowConstrained() )
789 ASumFilt.AlignColsWith( *this, false );
790 ASumFilt.RowSumScatterFrom( A );
791 if( !this->ColConstrained() )
792 this->AlignColsWith( ASumFilt, false );
793 if( !this->RowConstrained() )
794 this->AlignRowsWith( ASumFilt, false );
795 // ALoc += alpha ASumFiltLoc'
796 elem::Matrix<T>& ALoc = this->Matrix();
797 const elem::Matrix<T>& BLoc = ASumFilt.LockedMatrix();
798 const Int localHeight = ALoc.Height();
799 const Int localWidth = ALoc.Width();
800 if( conjugate )
801 {
802 for( Int jLoc=0; jLoc<localWidth; ++jLoc )
803 for( Int iLoc=0; iLoc<localHeight; ++iLoc )
804 ALoc.Update( iLoc, jLoc, alpha*Conj(BLoc.Get(jLoc,iLoc)) );
805 }
806 else
807 {
808 for( Int jLoc=0; jLoc<localWidth; ++jLoc )
809 for( Int iLoc=0; iLoc<localHeight; ++iLoc )
810 ALoc.Update( iLoc, jLoc, alpha*BLoc.Get(jLoc,iLoc) );
811 }
812 }
813
814 template<typename T,Dist U,Dist V>
815 void
TransposePartialColSumScatterUpdate(T alpha,const BlockDistMatrix<T,V,UPart> & A,bool conjugate)816 GeneralBlockDistMatrix<T,U,V>::TransposePartialColSumScatterUpdate
817 ( T alpha, const BlockDistMatrix<T,V,UPart>& A, bool conjugate )
818 {
819 DEBUG_ONLY(CallStackEntry cse("GBDM::TransposePartialColSumScatterUpdate"))
820 BlockDistMatrix<T,V,U> ASumFilt( A.Grid() );
821 if( this->ColConstrained() )
822 ASumFilt.AlignRowsWith( *this, false );
823 if( this->RowConstrained() )
824 ASumFilt.AlignColsWith( *this, false );
825 ASumFilt.PartialRowSumScatterFrom( A );
826 if( !this->ColConstrained() )
827 this->AlignColsWith( ASumFilt, false );
828 if( !this->RowConstrained() )
829 this->AlignRowsWith( ASumFilt, false );
830 // ALoc += alpha ASumFiltLoc'
831 elem::Matrix<T>& ALoc = this->Matrix();
832 const elem::Matrix<T>& BLoc = ASumFilt.LockedMatrix();
833 const Int localHeight = ALoc.Height();
834 const Int localWidth = ALoc.Width();
835 if( conjugate )
836 {
837 for( Int jLoc=0; jLoc<localWidth; ++jLoc )
838 for( Int iLoc=0; iLoc<localHeight; ++iLoc )
839 ALoc.Update( iLoc, jLoc, alpha*Conj(BLoc.Get(jLoc,iLoc)) );
840 }
841 else
842 {
843 for( Int jLoc=0; jLoc<localWidth; ++jLoc )
844 for( Int iLoc=0; iLoc<localHeight; ++iLoc )
845 ALoc.Update( iLoc, jLoc, alpha*BLoc.Get(jLoc,iLoc) );
846 }
847 }
848
849 template<typename T,Dist U,Dist V>
850 void
AdjointColSumScatterUpdate(T alpha,const BlockDistMatrix<T,V,UGath> & A)851 GeneralBlockDistMatrix<T,U,V>::AdjointColSumScatterUpdate
852 ( T alpha, const BlockDistMatrix<T,V,UGath>& A )
853 {
854 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointColSumScatterUpdate"))
855 this->TransposeColSumScatterUpdate( alpha, A, true );
856 }
857
858 template<typename T,Dist U,Dist V>
859 void
AdjointPartialColSumScatterUpdate(T alpha,const BlockDistMatrix<T,V,UPart> & A)860 GeneralBlockDistMatrix<T,U,V>::AdjointPartialColSumScatterUpdate
861 ( T alpha, const BlockDistMatrix<T,V,UPart>& A )
862 {
863 DEBUG_ONLY(CallStackEntry cse("GBDM::AdjointPartialColSumScatterUpdate"))
864 this->TransposePartialColSumScatterUpdate( alpha, A, true );
865 }
866
867 // Diagonal manipulation
868 // =====================
869 template<typename T,Dist U,Dist V>
870 bool
DiagonalAlignedWith(const elem::BlockDistData & d,Int offset) const871 GeneralBlockDistMatrix<T,U,V>::DiagonalAlignedWith
872 ( const elem::BlockDistData& d, Int offset ) const
873 {
874 DEBUG_ONLY(CallStackEntry cse("GBDM::DiagonalAlignedWith"))
875 // TODO: Ensure blocksize is compatible...the blocksizes needed for a
876 // diagonal distribution are variable except for special cases.
877 LogicError("This routine is not yet written");
878 return false;
879 }
880
881 template<typename T,Dist U,Dist V>
882 Int
DiagonalRoot(Int offset) const883 GeneralBlockDistMatrix<T,U,V>::DiagonalRoot( Int offset ) const
884 {
885 DEBUG_ONLY(CallStackEntry cse("GBDM::DiagonalRoot"))
886 LogicError("This routine is not yet written");
887 return 0;
888 }
889
890 template<typename T,Dist U,Dist V>
891 Int
DiagonalAlign(Int offset) const892 GeneralBlockDistMatrix<T,U,V>::DiagonalAlign( Int offset ) const
893 {
894 DEBUG_ONLY(CallStackEntry cse("GBDM::DiagonalAlign"))
895 LogicError("This routine is not yet written");
896 return 0;
897 }
898
899 template<typename T,Dist U,Dist V>
900 void
GetDiagonal(BlockDistMatrix<T,UDiag,VDiag> & d,Int offset) const901 GeneralBlockDistMatrix<T,U,V>::GetDiagonal
902 ( BlockDistMatrix<T,UDiag,VDiag>& d, Int offset ) const
903 {
904 DEBUG_ONLY(CallStackEntry cse("GBDM::GetDiagonal"))
905 this->GetDiagonalHelper
906 ( d, offset, []( T& alpha, T beta ) { alpha = beta; } );
907 }
908
909 template<typename T,Dist U,Dist V>
910 void
GetRealPartOfDiagonal(BlockDistMatrix<Base<T>,UDiag,VDiag> & d,Int offset) const911 GeneralBlockDistMatrix<T,U,V>::GetRealPartOfDiagonal
912 ( BlockDistMatrix<Base<T>,UDiag,VDiag>& d, Int offset ) const
913 {
914 DEBUG_ONLY(CallStackEntry cse("GBDM::GetRealPartOfDiagonal"))
915 this->GetDiagonalHelper
916 ( d, offset, []( Base<T>& alpha, T beta ) { alpha = RealPart(beta); } );
917 }
918
919 template<typename T,Dist U,Dist V>
920 void
GetImagPartOfDiagonal(BlockDistMatrix<Base<T>,UDiag,VDiag> & d,Int offset) const921 GeneralBlockDistMatrix<T,U,V>::GetImagPartOfDiagonal
922 ( BlockDistMatrix<Base<T>,UDiag,VDiag>& d, Int offset ) const
923 {
924 DEBUG_ONLY(CallStackEntry cse("GBDM::GetImagPartOfDiagonal"))
925 this->GetDiagonalHelper
926 ( d, offset, []( Base<T>& alpha, T beta ) { alpha = ImagPart(beta); } );
927 }
928
929 template<typename T,Dist U,Dist V>
930 auto
GetDiagonal(Int offset) const931 GeneralBlockDistMatrix<T,U,V>::GetDiagonal( Int offset ) const
932 -> BlockDistMatrix<T,UDiag,VDiag>
933 {
934 BlockDistMatrix<T,UDiag,VDiag> d( this->Grid() );
935 GetDiagonal( d, offset );
936 return d;
937 }
938
939 template<typename T,Dist U,Dist V>
940 auto
GetRealPartOfDiagonal(Int offset) const941 GeneralBlockDistMatrix<T,U,V>::GetRealPartOfDiagonal( Int offset ) const
942 -> BlockDistMatrix<Base<T>,UDiag,VDiag>
943 {
944 BlockDistMatrix<Base<T>,UDiag,VDiag> d( this->Grid() );
945 GetRealPartOfDiagonal( d, offset );
946 return d;
947 }
948
949 template<typename T,Dist U,Dist V>
950 auto
GetImagPartOfDiagonal(Int offset) const951 GeneralBlockDistMatrix<T,U,V>::GetImagPartOfDiagonal( Int offset ) const
952 -> BlockDistMatrix<Base<T>,UDiag,VDiag>
953 {
954 BlockDistMatrix<Base<T>,UDiag,VDiag> d( this->Grid() );
955 GetImagPartOfDiagonal( d, offset );
956 return d;
957 }
958
959 template<typename T,Dist U,Dist V>
960 void
SetDiagonal(const BlockDistMatrix<T,UDiag,VDiag> & d,Int offset)961 GeneralBlockDistMatrix<T,U,V>::SetDiagonal
962 ( const BlockDistMatrix<T,UDiag,VDiag>& d, Int offset )
963 {
964 DEBUG_ONLY(CallStackEntry cse("GBDM::SetDiagonal"))
965 this->SetDiagonalHelper
966 ( d, offset, []( T& alpha, T beta ) { alpha = beta; } );
967 }
968
969 template<typename T,Dist U,Dist V>
970 void
SetRealPartOfDiagonal(const BlockDistMatrix<Base<T>,UDiag,VDiag> & d,Int offset)971 GeneralBlockDistMatrix<T,U,V>::SetRealPartOfDiagonal
972 ( const BlockDistMatrix<Base<T>,UDiag,VDiag>& d, Int offset )
973 {
974 DEBUG_ONLY(CallStackEntry cse("GBDM::SetRealPartOfDiagonal"))
975 this->SetDiagonalHelper
976 ( d, offset,
977 []( T& alpha, Base<T> beta ) { elem::SetRealPart(alpha,beta); } );
978 }
979
980 template<typename T,Dist U,Dist V>
981 void
SetImagPartOfDiagonal(const BlockDistMatrix<Base<T>,UDiag,VDiag> & d,Int offset)982 GeneralBlockDistMatrix<T,U,V>::SetImagPartOfDiagonal
983 ( const BlockDistMatrix<Base<T>,UDiag,VDiag>& d, Int offset )
984 {
985 DEBUG_ONLY(CallStackEntry cse("GBDM::SetImagPartOfDiagonal"))
986 this->SetDiagonalHelper
987 ( d, offset,
988 []( T& alpha, Base<T> beta ) { elem::SetImagPart(alpha,beta); } );
989 }
990
991 template<typename T,Dist U,Dist V>
992 void
UpdateDiagonal(T gamma,const BlockDistMatrix<T,UDiag,VDiag> & d,Int offset)993 GeneralBlockDistMatrix<T,U,V>::UpdateDiagonal
994 ( T gamma, const BlockDistMatrix<T,UDiag,VDiag>& d, Int offset )
995 {
996 DEBUG_ONLY(CallStackEntry cse("GBDM::UpdateDiagonal"))
997 this->SetDiagonalHelper
998 ( d, offset, [gamma]( T& alpha, T beta ) { alpha += gamma*beta; } );
999 }
1000
1001 template<typename T,Dist U,Dist V>
1002 void
UpdateRealPartOfDiagonal(Base<T> gamma,const BlockDistMatrix<Base<T>,UDiag,VDiag> & d,Int offset)1003 GeneralBlockDistMatrix<T,U,V>::UpdateRealPartOfDiagonal
1004 ( Base<T> gamma, const BlockDistMatrix<Base<T>,UDiag,VDiag>& d, Int offset )
1005 {
1006 DEBUG_ONLY(CallStackEntry cse("GBDM::UpdateRealPartOfDiagonal"))
1007 this->SetDiagonalHelper
1008 ( d, offset,
1009 [gamma]( T& alpha, Base<T> beta )
1010 { elem::UpdateRealPart(alpha,gamma*beta); } );
1011 }
1012
1013 template<typename T,Dist U,Dist V>
1014 void
UpdateImagPartOfDiagonal(Base<T> gamma,const BlockDistMatrix<Base<T>,UDiag,VDiag> & d,Int offset)1015 GeneralBlockDistMatrix<T,U,V>::UpdateImagPartOfDiagonal
1016 ( Base<T> gamma, const BlockDistMatrix<Base<T>,UDiag,VDiag>& d, Int offset )
1017 {
1018 DEBUG_ONLY(CallStackEntry cse("GBDM::UpdateImagPartOfDiagonal"))
1019 this->SetDiagonalHelper
1020 ( d, offset,
1021 [gamma]( T& alpha, Base<T> beta )
1022 { elem::UpdateImagPart(alpha,gamma*beta); } );
1023 }
1024
1025 // Private section
1026 // ###############
1027
1028 // Diagonal helper functions
1029 // =========================
1030 template<typename T,Dist U,Dist V>
1031 template<typename S,class Function>
1032 void
GetDiagonalHelper(BlockDistMatrix<S,UDiag,VDiag> & d,Int offset,Function func) const1033 GeneralBlockDistMatrix<T,U,V>::GetDiagonalHelper
1034 ( BlockDistMatrix<S,UDiag,VDiag>& d, Int offset, Function func ) const
1035 {
1036 DEBUG_ONLY(CallStackEntry cse("GBDM::GetDiagonalHelper"))
1037 LogicError("This routine is not yet written");
1038 }
1039
1040 template<typename T,Dist U,Dist V>
1041 template<typename S,class Function>
1042 void
SetDiagonalHelper(const BlockDistMatrix<S,UDiag,VDiag> & d,Int offset,Function func)1043 GeneralBlockDistMatrix<T,U,V>::SetDiagonalHelper
1044 ( const BlockDistMatrix<S,UDiag,VDiag>& d, Int offset, Function func )
1045 {
1046 DEBUG_ONLY(
1047 CallStackEntry cse("GBDM::SetDiagonalHelper");
1048 if( !this->DiagonalAlignedWith( d, offset ) )
1049 LogicError("Invalid diagonal alignment");
1050 )
1051 LogicError("This routine is not yet written");
1052 }
1053
1054 // Instantiations for {Int,Real,Complex<Real>} for each Real in {float,double}
1055 // ###########################################################################
1056
1057 #define DISTPROTO(T,U,V) template class GeneralBlockDistMatrix<T,U,V>
1058
1059 #define PROTO(T)\
1060 DISTPROTO(T,CIRC,CIRC);\
1061 DISTPROTO(T,MC, MR );\
1062 DISTPROTO(T,MC, STAR);\
1063 DISTPROTO(T,MD, STAR);\
1064 DISTPROTO(T,MR, MC );\
1065 DISTPROTO(T,MR, STAR);\
1066 DISTPROTO(T,STAR,MC );\
1067 DISTPROTO(T,STAR,MD );\
1068 DISTPROTO(T,STAR,MR );\
1069 DISTPROTO(T,STAR,STAR);\
1070 DISTPROTO(T,STAR,VC );\
1071 DISTPROTO(T,STAR,VR );\
1072 DISTPROTO(T,VC, STAR);\
1073 DISTPROTO(T,VR, STAR);
1074
1075 #ifndef ELEM_DISABLE_COMPLEX
1076 #ifndef ELEM_DISABLE_FLOAT
1077 PROTO(Int);
1078 PROTO(float);
1079 PROTO(double);
1080 PROTO(Complex<float>);
1081 PROTO(Complex<double>);
1082 #else // ifndef ELEM_DISABLE_FLOAT
1083 PROTO(Int);
1084 PROTO(double);
1085 PROTO(Complex<double>);
1086 #endif // ifndef ELEM_DISABLE_FLOAT
1087 #else // ifndef ELEM_DISABLE_COMPLEX
1088 #ifndef ELEM_DISABLE_FLOAT
1089 PROTO(Int);
1090 PROTO(float);
1091 PROTO(double);
1092 #else // ifndef ELEM_DISABLE_FLOAT
1093 PROTO(Int);
1094 PROTO(double);
1095 #endif // ifndef ELEM_DISABLE_FLOAT
1096 #endif // ifndef ELEM_DISABLE_COMPLEX
1097
1098 } // namespace elem
1099