void TransformColumns ( const Matrix<F>& Z, DistMatrix<F,MC,MR,BLOCK>& H ) { DEBUG_CSE const Int width = H.Width(); const Grid& grid = H.Grid(); const Int blockWidth = H.BlockWidth(); const Int firstBlockWidth = blockWidth - H.RowCut(); if( width <= firstBlockWidth || grid.Width() == 1 ) { if( grid.Col() == H.ColOwner(0) ) { // This process row can locally update its portion of H Matrix<F> HLocCopy( H.Matrix() ); Gemm( NORMAL, NORMAL, F(1), HLocCopy, Z, H.Matrix() ); } } else if( width <= firstBlockWidth + blockWidth ) { const bool firstCol = H.ColOwner( 0 ); const bool secondCol = H.ColOwner( firstBlockWidth ); if( grid.Col() == firstCol ) { // // Replace H with // // | HLeft, HRight | | ZLeft, ZRight |, // // where HLeft is owned by this process column and HRight by the // next. // auto ZLeft = Z( ALL, IR(0,firstBlockWidth) ); // Partition space for the combined matrix Matrix<F> HCombine( H.LocalHeight(), width ); auto HLeft = HCombine( ALL, IR(0,firstBlockWidth) ); auto HRight = HCombine( ALL, IR(firstBlockWidth,END) ); // Copy our portion into the combined matrix HLeft = H.LockedMatrix(); // Exchange the data El::SendRecv( HLeft, HRight, H.RowComm(), secondCol, secondCol ); // Form our portion of the result Gemm( NORMAL, NORMAL, F(1), HCombine, ZLeft, H.Matrix() ); } else if( grid.Col() == secondCol ) { // // Replace H with // // | HLeft, HRight | | ZLeft, ZRight |, // // where HLeft is owned by the previous process column and HRight // by this one. // auto ZRight = Z( ALL, IR(firstBlockWidth,END) ); // Partition space for the combined matrix Matrix<F> HCombine( H.LocalHeight(), width ); auto HLeft = HCombine( ALL, IR(0,firstBlockWidth) ); auto HRight = HCombine( ALL, IR(firstBlockWidth,END) ); // Copy our portion into the combined matrix HRight = H.LockedMatrix(); // Exchange the data El::SendRecv( HRight, HLeft, H.RowComm(), firstCol, firstCol ); // Form our portion of the result Gemm( NORMAL, NORMAL, F(1), HCombine, ZRight, 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,MC,STAR,BLOCK> H_MC_STAR( H ); Matrix<F> HLocCopy( H_MC_STAR.Matrix() ); Gemm( NORMAL, NORMAL, F(1), HLocCopy, Z, H_MC_STAR.Matrix() ); H = H_MC_STAR; } }
void TransformColumns ( const Matrix<F>& V, DistMatrix<F,MC,MR,BLOCK>& A ) { DEBUG_CSE const Int width = A.Width(); const Grid& grid = A.Grid(); const Int blockWidth = A.BlockWidth(); const Int firstBlockWidth = blockWidth - A.RowCut(); if( width <= firstBlockWidth || grid.Width() == 1 ) { if( grid.Col() == A.ColOwner(0) ) { // This process row can locally update its portion of A TransformColumns( V, A.Matrix() ); } } else if( width <= firstBlockWidth + blockWidth ) { const int firstCol = A.ColOwner( 0 ); const int secondCol = A.ColOwner( firstBlockWidth ); if( grid.Col() == firstCol ) { // // Replace A with // // | ALeft, ARight | | VLeft, VRight |, // // where ALeft is owned by this process column and ARight by the // next. // // Partition space for the combined matrix Matrix<F> ACombine( A.LocalHeight(), width ); auto ALeft = ACombine( ALL, IR(0,firstBlockWidth) ); auto ARight = ACombine( ALL, IR(firstBlockWidth,END) ); // Copy our portion into the combined matrix ALeft = A.LockedMatrix(); // Exchange the data El::SendRecv( ALeft, ARight, A.RowComm(), secondCol, secondCol ); // Form our portion of the result auto VLeft = V( ALL, IR(0,firstBlockWidth) ); Gemm( NORMAL, NORMAL, F(1), ACombine, VLeft, A.Matrix() ); } else if( grid.Col() == secondCol ) { // // Replace A with // // | ALeft, ARight | | VLeft, VRight |, // // where ALeft is owned by the previous process column and ARight // by this one. // // Partition space for the combined matrix Matrix<F> ACombine( A.LocalHeight(), width ); auto ALeft = ACombine( ALL, IR(0,firstBlockWidth) ); auto ARight = ACombine( ALL, IR(firstBlockWidth,END) ); // Copy our portion into the combined matrix ARight = A.LockedMatrix(); // Exchange the data El::SendRecv( ARight, ALeft, A.RowComm(), firstCol, firstCol ); // Form our portion of the result auto VRight = V( ALL, IR(firstBlockWidth,END) ); Gemm( NORMAL, NORMAL, F(1), ACombine, VRight, 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,MC,STAR,BLOCK> A_MC_STAR( A ); Matrix<F> ALocCopy( A_MC_STAR.Matrix() ); Gemm( NORMAL, NORMAL, F(1), ALocCopy, V, A_MC_STAR.Matrix() ); A = A_MC_STAR; } }