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; } }