diff --git a/Eigen/src/Core/products/TriangularSolverMatrix.h b/Eigen/src/Core/products/TriangularSolverMatrix.h index 798cd6c09..eeb445f0b 100644 --- a/Eigen/src/Core/products/TriangularSolverMatrix.h +++ b/Eigen/src/Core/products/TriangularSolverMatrix.h @@ -81,10 +81,8 @@ struct ei_triangular_solve_matrix// const Scalar* _lhs, int lhsStride, Scalar* _rhs, int rhsStride) { - Map > lhs(_lhs, size, size); - Map > rhs(_rhs, size, cols); - //ei_const_blas_data_mapper lhs(_lhs,lhsStride); - //ei_const_blas_data_mapper rhs(_rhs,rhsStride); + ei_const_blas_data_mapper lhs(_lhs,lhsStride); + ei_blas_data_mapper rhs(_rhs,rhsStride); typedef ei_product_blocking_traits Blocking; enum { @@ -93,17 +91,19 @@ struct ei_triangular_solve_matrix// }; int kc = std::min(Blocking::Max_kc/4,size); // cache block size along the K direction - int mc = std::min(Blocking::Max_mc,size); // cache block size along the M direction + int mc = std::min(Blocking::Max_mc,size); // cache block size along the M direction Scalar* blockA = ei_aligned_stack_new(Scalar, kc*mc); -// Scalar* blockB = new Scalar[10*kc*cols*Blocking::PacketSize]; Scalar* blockB = ei_aligned_stack_new(Scalar, kc*cols*Blocking::PacketSize); ei_gebp_kernel > gebp_kernel; + ei_gemm_pack_lhs pack_lhs; - for(int k2=0; k20; + IsLowerTriangular ? k2+=kc : k2-=kc) { - const int actual_kc = std::min(k2+kc,size)-k2; + const int actual_kc = std::min(IsLowerTriangular ? size-k2 : k2, kc); // We have selected and packed a big horizontal panel R1 of rhs. Let B be the packed copy of this panel, // and R2 the remaining part of rhs. The corresponding vertical panel of lhs is split into @@ -114,7 +114,7 @@ struct ei_triangular_solve_matrix// // - update B from the new R1 => actually this has to be performed continuously during the above step // - R2 = L2 * B => GEPP - // The tricky part: R1 = L1^-1 B while updating B from R1 + // The tricky part: compute R1 = L1^-1 B while updating B from R1 // The idea is to split L1 into multiple small vertical panels. // Each panel can be split into a small triangular part A1 which is processed without optimization, // and the remaining small part A2 which is processed using gebp with appropriate block strides @@ -122,76 +122,80 @@ struct ei_triangular_solve_matrix// // for each small vertical panels of lhs for (int k1=0; k1(SmallPanelWidth,actual_kc-k1); + int actualPanelWidth = std::min(actual_kc-k1, SmallPanelWidth); // tr solve for (int k=0; k() -// .solveInPlace(rhs.col(j).segment(k2+k1,actualPanelWidth)); -// lhs.block(k2+k1,k2+k1,actualPanelWidth,actualPanelWidth).template triangularView() -// .solveInPlace(rhs.block(k2+k1,0,actualPanelWidth,cols)); + + int lengthTarget = actual_kc-k1-actualPanelWidth; + int startBlock = IsLowerTriangular ? k2+k1 : k2-k1-actualPanelWidth; + int blockBOffset = IsLowerTriangular ? k1 : lengthTarget; // update the respective rows of B from rhs ei_gemm_pack_rhs_panel() - (blockB, _rhs+k2+k1, rhsStride, -1, actualPanelWidth, cols, actual_kc, k1); + (blockB, _rhs+startBlock, rhsStride, -1, actualPanelWidth, cols, actual_kc, blockBOffset); // GEBP - int i = k1+actualPanelWidth; - int rs = actual_kc-i; - - if (rs>0) + if (lengthTarget>0) { - ei_gemm_pack_lhs() - (blockA, &lhs(k2+i, k2+k1), lhsStride, actualPanelWidth, rs); + int startTarget = IsLowerTriangular ? k2+k1+actualPanelWidth : k2-actual_kc; - gebp_kernel(_rhs+i+k2, rhsStride, - blockA, blockB, rs, actualPanelWidth, cols, actualPanelWidth, actual_kc, 0, k1*Blocking::PacketSize); + pack_lhs(blockA, &lhs(startTarget,startBlock), lhsStride, actualPanelWidth, lengthTarget); + + gebp_kernel(_rhs+startTarget, rhsStride, blockA, blockB, lengthTarget, actualPanelWidth, cols, + actualPanelWidth, actual_kc, 0, blockBOffset*Blocking::PacketSize); } } } - // - R2 = A2 * B => GEPP - for(int i2=k2+kc; i2 GEPP { - const int actual_mc = std::min(i2+mc,size)-i2; - ei_gemm_pack_lhs() - (blockA, &lhs(i2, k2), lhsStride, actual_kc, actual_mc); - - gebp_kernel(_rhs+i2, rhsStride, blockA, blockB, actual_mc, actual_kc, cols); + int start = IsLowerTriangular ? k2+kc : 0; + int end = IsLowerTriangular ? size : k2-kc; + for(int i2=start; i20) + { + pack_lhs(blockA, &lhs(i2, IsLowerTriangular ? k2 : k2-kc), lhsStride, actual_kc, actual_mc); + + gebp_kernel(_rhs+i2, rhsStride, blockA, blockB, actual_mc, actual_kc, cols); + } + } } } ei_aligned_stack_delete(Scalar, blockA, kc*mc); ei_aligned_stack_delete(Scalar, blockB, kc*cols*Blocking::PacketSize); -// delete[] blockB; } };