void GatherSubdiagonal ( const DistMatrix<F,MC,MR,BLOCK>& H, const IR& winInd, DistMatrix<Base<F>,STAR,STAR>& hSubWin ) { DEBUG_CSE const Int winSize = winInd.end - winInd.beg; const Int blockSize = H.BlockHeight(); const Grid& grid = H.Grid(); const auto& HLoc = H.LockedMatrix(); DEBUG_ONLY( if( H.BlockHeight() != H.BlockWidth() ) LogicError("Assumed square distribution blocks"); if( H.ColCut() != H.RowCut() ) LogicError("Assumed symmetric cuts"); if( blockSize < 2 ) LogicError("Assumed blocks of size at least two"); )
void TransformRows ( const Matrix<F>& Z, DistMatrix<F,MC,MR,BLOCK>& H ) { DEBUG_CSE const Int height = H.Height(); const Grid& grid = H.Grid(); const Int blockHeight = H.BlockHeight(); const Int firstBlockHeight = blockHeight - H.ColCut(); if( height <= firstBlockHeight || grid.Height() == 1 ) { if( grid.Row() == H.RowOwner(0) ) { // This process row can locally update its portion of H Matrix<F> HLocCopy( H.Matrix() ); Gemm( ADJOINT, NORMAL, F(1), Z, HLocCopy, H.Matrix() ); } } else if( height <= firstBlockHeight + blockHeight ) { const bool firstRow = H.RowOwner( 0 ); const bool secondRow = H.RowOwner( firstBlockHeight ); if( grid.Row() == firstRow ) { // // Replace H with // // | ZLeft, ZRight |' | HTop |, // | HBottom | // // where HTop is owned by this process row and HBottom by the next. // auto ZLeft = Z( ALL, IR(0,firstBlockHeight) ); // Partition space for the combined matrix Matrix<F> HCombine( height, H.LocalWidth() ); auto HTop = HCombine( IR(0,firstBlockHeight), ALL ); auto HBottom = HCombine( IR(firstBlockHeight,END), ALL ); // Copy our portion into the combined matrix HTop = H.LockedMatrix(); // Exchange the data El::SendRecv( HTop, HBottom, H.ColComm(), secondRow, secondRow ); // Form our portion of the result Gemm( ADJOINT, NORMAL, F(1), ZLeft, HCombine, H.Matrix() ); } else if( grid.Row() == secondRow ) { // // Replace H with // // | ZLeft, ZRight |' | HTop |, // | HBottom | // // where HTop is owned by the previous process row and HBottom by // this one. // auto ZRight = Z( ALL, IR(firstBlockHeight,END) ); // Partition space for the combined matrix Matrix<F> HCombine( height, H.LocalWidth() ); auto HTop = HCombine( IR(0,firstBlockHeight), ALL ); auto HBottom = HCombine( IR(firstBlockHeight,END), ALL ); // Copy our portion into the combined matrix HBottom = H.LockedMatrix(); // Exchange the data El::SendRecv( HBottom, HTop, H.ColComm(), firstRow, firstRow ); // Form our portion of the result Gemm( ADJOINT, NORMAL, F(1), ZRight, HCombine, H.Matrix() ); } } else { // Fall back to the entire process column interacting. // TODO(poulson): Only form the subset of the result that we need. DistMatrix<F,STAR,MR,BLOCK> H_STAR_MR( H ); Matrix<F> HLocCopy( H_STAR_MR.Matrix() ); Gemm( ADJOINT, NORMAL, F(1), Z, HLocCopy, H_STAR_MR.Matrix() ); H = H_STAR_MR; } }
void TransformRows ( const Matrix<F>& V, DistMatrix<F,MC,MR,BLOCK>& A ) { DEBUG_CSE const Int height = A.Height(); const Grid& grid = A.Grid(); const Int blockHeight = A.BlockHeight(); const Int firstBlockHeight = blockHeight - A.ColCut(); if( height <= firstBlockHeight || grid.Height() == 1 ) { if( grid.Row() == A.RowOwner(0) ) { // This process row can locally update its portion of A TransformRows( V, A.Matrix() ); } } else if( height <= firstBlockHeight + blockHeight ) { const int firstRow = A.RowOwner( 0 ); const int secondRow = A.RowOwner( firstBlockHeight ); if( grid.Row() == firstRow ) { // // Replace A with // // | VLeft, VRight |' | ATop |, // | ABottom | // // where ATop is owned by this process row and ABottom by the next. // auto VLeft = V( ALL, IR(0,firstBlockHeight) ); // Partition space for the combined matrix Matrix<F> ACombine( height, A.LocalWidth() ); auto ATop = ACombine( IR(0,firstBlockHeight), ALL ); auto ABottom = ACombine( IR(firstBlockHeight,END), ALL ); // Copy our portion into the combined matrix ATop = A.LockedMatrix(); // Exchange the data El::SendRecv( ATop, ABottom, A.ColComm(), secondRow, secondRow ); // Form our portion of the result Gemm( ADJOINT, NORMAL, F(1), VLeft, ACombine, A.Matrix() ); } else if( grid.Row() == secondRow ) { // // Replace A with // // | VLeft, VRight |' | ATop |, // | ABottom | // // where ATop is owned by the previous process row and ABottom by // this one. // auto VRight = V( ALL, IR(firstBlockHeight,END) ); // Partition space for the combined matrix Matrix<F> ACombine( height, A.LocalWidth() ); auto ATop = ACombine( IR(0,firstBlockHeight), ALL ); auto ABottom = ACombine( IR(firstBlockHeight,END), ALL ); // Copy our portion into the combined matrix ABottom = A.LockedMatrix(); // Exchange the data El::SendRecv( ABottom, ATop, A.ColComm(), firstRow, firstRow ); // Form our portion of the result Gemm( ADJOINT, NORMAL, F(1), VRight, ACombine, A.Matrix() ); } } else { // Fall back to the entire process column interacting. // TODO(poulson): Only form the subset of the result that we need. DistMatrix<F,STAR,MR,BLOCK> A_STAR_MR( A ); Matrix<F> ALocCopy( A_STAR_MR.Matrix() ); Gemm( ADJOINT, NORMAL, F(1), V, ALocCopy, A_STAR_MR.Matrix() ); A = A_STAR_MR; } }