Skip to content

Commit b024a5f

Browse files
committed
Adding multi-bulge Hessenberg QR iteration; uniting HessQRCtrl and HessenbergSchurCtrl; fixing a mistake in the previous, overzealous commit to fix an Intel compilation issue reported in Issue #177
1 parent 18e9304 commit b024a5f

File tree

24 files changed

+584
-114
lines changed

24 files changed

+584
-114
lines changed

examples/lapack_like/ChunkedPseudospectra.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,9 @@ main( int argc, char* argv[] )
241241
DistMatrix<C> QCpx(g);
242242
SchurCtrl<Real> ctrl;
243243
#ifdef EL_HAVE_SCALAPACK
244-
ctrl.qrCtrl.blockHeight = nbDist;
245-
ctrl.qrCtrl.blockWidth = nbDist;
246-
ctrl.qrCtrl.distAED = false;
244+
ctrl.hessSchurCtrl.blockHeight = nbDist;
245+
ctrl.hessSchurCtrl.blockWidth = nbDist;
246+
ctrl.hessSchurCtrl.distAED = false;
247247
#else
248248
ctrl.useSDC = true;
249249
ctrl.sdcCtrl.cutoff = cutoff;

examples/lapack_like/Pseudospectra.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,9 @@ main( int argc, char* argv[] )
249249
psCtrl.basisSize = basisSize;
250250
psCtrl.progress = progress;
251251
#ifdef EL_HAVE_SCALAPACK
252-
psCtrl.schurCtrl.qrCtrl.blockHeight = nbDist;
253-
psCtrl.schurCtrl.qrCtrl.blockWidth = nbDist;
254-
psCtrl.schurCtrl.qrCtrl.distAED = false;
252+
psCtrl.schurCtrl.hessSchurCtrl.blockHeight = nbDist;
253+
psCtrl.schurCtrl.hessSchurCtrl.blockWidth = nbDist;
254+
psCtrl.schurCtrl.hessSchurCtrl.distAED = false;
255255
#else
256256
psCtrl.schurCtrl.sdcCtrl.cutoff = cutoff;
257257
psCtrl.schurCtrl.sdcCtrl.maxInnerIts = maxInnerIts;

examples/lapack_like/RealSchur.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ main( int argc, char* argv[] )
5151
DistMatrix<Complex<Real>,VR,STAR> w;
5252
SchurCtrl<Real> ctrl;
5353
#ifdef EL_HAVE_SCALAPACK
54-
ctrl.qrCtrl.distAED = aed;
54+
ctrl.hessSchurCtrl.distAED = aed;
5555
// TODO: distribution block size
5656
#else
5757
ctrl.useSDC = true;

examples/lapack_like/Schur.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ main( int argc, char* argv[] )
5555
DistMatrix<C,VR,STAR> w(g);
5656
SchurCtrl<Real> ctrl;
5757
#ifdef EL_HAVE_SCALAPACK
58-
//ctrl.qrCtrl.blockHeight = nbDist;
59-
//ctrl.qrCtrl.blockWidth = nbDist;
60-
ctrl.qrCtrl.distAED = false;
58+
//ctrl.hessSchurCtrl.blockHeight = nbDist;
59+
//ctrl.hessSchurCtrl.blockWidth = nbDist;
60+
ctrl.hessSchurCtrl.distAED = false;
6161
#else
6262
ctrl.useSDC = true;
6363
ctrl.sdcCtrl.cutoff = cutoff;

include/El/lapack_like/spectral.h

+32-8
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ EL_EXPORT ElError ElSecularSVDCtrlDefault_d
8080
/* Hermitian tridiagonal eigensolvers
8181
================================== */
8282
typedef enum {
83-
EL_HERM_TRIDIAG_EIG_QR = 0,
84-
EL_HERM_TRIDIAG_EIG_DC = 1,
85-
EL_HERM_TRIDIAG_EIG_MRRR = 2
83+
EL_HERM_TRIDIAG_EIG_QR=0,
84+
EL_HERM_TRIDIAG_EIG_DC=1,
85+
EL_HERM_TRIDIAG_EIG_MRRR=2
8686
} ElHermitianTridiagEigAlg;
8787

8888
/* HermitianEigSubset */
@@ -587,12 +587,36 @@ EL_EXPORT ElError ElHermitianPolarDecompDist_z
587587

588588
/* Schur decomposition
589589
=================== */
590-
/* HessQRCtrl */
590+
typedef enum {
591+
EL_HESSENBERG_SCHUR_AED=0,
592+
EL_HESSENBERG_SCHUR_MULTIBULGE=1,
593+
EL_HESSENBERG_SCHUR_SIMPLE=2
594+
} ElHessenbergSchurAlg;
595+
596+
/* HessenbergSchurCtrl */
591597
typedef struct {
598+
ElInt winBeg;
599+
ElInt winEnd;
600+
bool fullTriangle;
601+
bool wantSchurVecs;
602+
bool demandConverged;
603+
604+
ElHessenbergSchurAlg alg;
605+
bool recursiveAED;
606+
bool accumulateReflections;
607+
608+
bool progress;
609+
610+
ElInt minMultiBulgeSize;
611+
612+
ElInt (*numShifts)(ElInt,ElInt);
613+
ElInt (*deflationSize)(ElInt,ElInt,ElInt);
614+
ElInt (*sufficientDeflation)(ElInt);
615+
592616
bool distAED;
593617
ElInt blockHeight, blockWidth;
594-
} ElHessQRCtrl;
595-
EL_EXPORT ElError ElHessQRCtrlDefault( ElHessQRCtrl* ctrl );
618+
} ElHessenbergSchurCtrl;
619+
EL_EXPORT ElError ElHessenbergSchurCtrlDefault( ElHessenbergSchurCtrl* ctrl );
596620

597621
/* SDCCtrl */
598622
typedef struct {
@@ -620,15 +644,15 @@ EL_EXPORT ElError ElSDCCtrlDefault_d( ElSDCCtrl_d* ctrl );
620644
/* SchurCtrl */
621645
typedef struct {
622646
bool useSDC;
623-
ElHessQRCtrl qrCtrl;
647+
ElHessenbergSchurCtrl hessSchurCtrl;
624648
ElSDCCtrl_s sdcCtrl;
625649
bool time;
626650
} ElSchurCtrl_s;
627651
EL_EXPORT ElError ElSchurCtrlDefault_s( ElSchurCtrl_s* ctrl );
628652

629653
typedef struct {
630654
bool useSDC;
631-
ElHessQRCtrl qrCtrl;
655+
ElHessenbergSchurCtrl hessSchurCtrl;
632656
ElSDCCtrl_d sdcCtrl;
633657
bool time;
634658
} ElSchurCtrl_d;

include/El/lapack_like/spectral.hpp

+14-10
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,12 @@ inline Int SufficientDeflation( Int deflationSize )
682682
} // namespace aed
683683
} // namespace hess_schur
684684

685+
enum HessenbergSchurAlg {
686+
HESSENBERG_SCHUR_AED=0,
687+
HESSENBERG_SCHUR_MULTIBULGE=1,
688+
HESSENBERG_SCHUR_SIMPLE=2
689+
};
690+
685691
struct HessenbergSchurCtrl
686692
{
687693
Int winBeg=0;
@@ -690,15 +696,15 @@ struct HessenbergSchurCtrl
690696
bool wantSchurVecs=false;
691697
bool demandConverged=true;
692698

693-
bool useAED=true;
699+
HessenbergSchurAlg alg=HESSENBERG_SCHUR_AED;
694700
bool recursiveAED=true;
695701
bool accumulateReflections=true;
696702

697703
bool progress=false;
698704

699705
// Cf. LAPACK's IPARMQ for this choice;
700706
// note that LAPACK's hard minimum of 12 does not apply to us
701-
Int minAEDSize = 75;
707+
Int minMultiBulgeSize = 75;
702708

703709
function<Int(Int,Int)> numShifts =
704710
function<Int(Int,Int)>(hess_schur::aed::NumShifts);
@@ -708,6 +714,11 @@ struct HessenbergSchurCtrl
708714

709715
function<Int(Int)> sufficientDeflation =
710716
function<Int(Int)>(hess_schur::aed::SufficientDeflation);
717+
718+
// For the distributed Hessenberg QR algorithm
719+
// TODO(poulson): Move this into a substructure?
720+
bool distAED=false;
721+
Int blockHeight=DefaultBlockHeight(), blockWidth=DefaultBlockWidth();
711722
};
712723

713724
template<typename Real>
@@ -756,18 +767,11 @@ struct SDCCtrl
756767
SignCtrl<Real> signCtrl;
757768
};
758769

759-
// TODO: Combine with HessenbergSchurCtrl
760-
struct HessQRCtrl
761-
{
762-
bool distAED=false;
763-
Int blockHeight=DefaultBlockHeight(), blockWidth=DefaultBlockWidth();
764-
};
765-
766770
template<typename Real>
767771
struct SchurCtrl
768772
{
769773
bool useSDC=false;
770-
HessQRCtrl qrCtrl;
774+
HessenbergSchurCtrl hessSchurCtrl;
771775
SDCCtrl<Real> sdcCtrl;
772776
bool time=false;
773777
};

include/El/lapack_like/spectral/CReflect.hpp

+66-10
Original file line numberDiff line numberDiff line change
@@ -724,19 +724,75 @@ inline ElSVDCtrl_d CReflect( const SVDCtrl<double>& ctrl )
724724
return ctrlC;
725725
}
726726

727-
/* HessQRCtrl */
728-
inline ElHessQRCtrl CReflect( const HessQRCtrl& ctrl )
729-
{
730-
ElHessQRCtrl ctrlC;
727+
/* HessenbergSchurCtrl */
728+
inline ElHessenbergSchurAlg CReflect( const HessenbergSchurAlg& alg )
729+
{ return static_cast<ElHessenbergSchurAlg>(alg); }
730+
inline HessenbergSchurAlg CReflect( const ElHessenbergSchurAlg& alg )
731+
{ return static_cast<HessenbergSchurAlg>(alg); }
732+
733+
inline ElHessenbergSchurCtrl CReflect( const HessenbergSchurCtrl& ctrl )
734+
{
735+
ElHessenbergSchurCtrl ctrlC;
736+
ctrlC.winBeg = ctrl.winBeg;
737+
ctrlC.winEnd = ctrl.winEnd;
738+
ctrlC.fullTriangle = ctrl.fullTriangle;
739+
ctrlC.wantSchurVecs = ctrl.wantSchurVecs;
740+
ctrlC.demandConverged = ctrl.demandConverged;
741+
742+
ctrlC.alg = CReflect(ctrl.alg);
743+
ctrlC.recursiveAED = ctrl.recursiveAED;
744+
ctrlC.accumulateReflections = ctrl.accumulateReflections;
745+
746+
ctrlC.progress = ctrl.progress;
747+
748+
ctrlC.minMultiBulgeSize = ctrl.minMultiBulgeSize;
749+
auto numShiftsRes = ctrl.numShifts.target<ElInt(*)(ElInt,ElInt)>();
750+
if( numShiftsRes )
751+
ctrlC.numShifts = *numShiftsRes;
752+
else
753+
RuntimeError("Could not convert numShifts to C function pointer");
754+
755+
auto deflationSizeRes =
756+
ctrl.deflationSize.target<ElInt(*)(ElInt,ElInt,ElInt)>();
757+
if( deflationSizeRes )
758+
ctrlC.deflationSize = *deflationSizeRes;
759+
else
760+
RuntimeError("Could not convert deflationSize to C function pointer");
761+
762+
auto sufficientDeflationRes =
763+
ctrl.sufficientDeflation.target<ElInt(*)(ElInt)>();
764+
if( sufficientDeflationRes )
765+
ctrlC.sufficientDeflation = *sufficientDeflationRes;
766+
else
767+
RuntimeError
768+
("Could not convert sufficientDeflation to C function pointer");
769+
731770
ctrlC.distAED = ctrl.distAED;
732771
ctrlC.blockHeight = ctrl.blockHeight;
733772
ctrlC.blockWidth = ctrl.blockWidth;
734773
return ctrlC;
735774
}
736775

737-
inline HessQRCtrl CReflect( const ElHessQRCtrl& ctrlC )
776+
inline HessenbergSchurCtrl CReflect( const ElHessenbergSchurCtrl& ctrlC )
738777
{
739-
HessQRCtrl ctrl;
778+
HessenbergSchurCtrl ctrl;
779+
ctrl.winBeg = ctrlC.winBeg;
780+
ctrl.winEnd = ctrlC.winEnd;
781+
ctrl.fullTriangle = ctrlC.fullTriangle;
782+
ctrl.wantSchurVecs = ctrlC.wantSchurVecs;
783+
ctrl.demandConverged = ctrlC.demandConverged;
784+
785+
ctrl.alg = CReflect(ctrlC.alg);
786+
ctrl.recursiveAED = ctrlC.recursiveAED;
787+
ctrl.accumulateReflections = ctrlC.accumulateReflections;
788+
789+
ctrl.progress = ctrlC.progress;
790+
791+
ctrl.minMultiBulgeSize = ctrlC.minMultiBulgeSize;
792+
ctrl.numShifts = ctrlC.numShifts;
793+
ctrl.deflationSize = ctrlC.deflationSize;
794+
ctrl.sufficientDeflation = ctrlC.sufficientDeflation;
795+
740796
ctrl.distAED = ctrlC.distAED;
741797
ctrl.blockHeight = ctrlC.blockHeight;
742798
ctrl.blockWidth = ctrlC.blockWidth;
@@ -799,7 +855,7 @@ inline ElSchurCtrl_s CReflect( const SchurCtrl<float>& ctrl )
799855
{
800856
ElSchurCtrl_s ctrlC;
801857
ctrlC.useSDC = ctrl.useSDC;
802-
ctrlC.qrCtrl = CReflect( ctrl.qrCtrl );
858+
ctrlC.hessSchurCtrl = CReflect( ctrl.hessSchurCtrl );
803859
ctrlC.sdcCtrl = CReflect( ctrl.sdcCtrl );
804860
ctrlC.time = ctrl.time;
805861
return ctrlC;
@@ -808,7 +864,7 @@ inline ElSchurCtrl_d CReflect( const SchurCtrl<double>& ctrl )
808864
{
809865
ElSchurCtrl_d ctrlC;
810866
ctrlC.useSDC = ctrl.useSDC;
811-
ctrlC.qrCtrl = CReflect( ctrl.qrCtrl );
867+
ctrlC.hessSchurCtrl = CReflect( ctrl.hessSchurCtrl );
812868
ctrlC.sdcCtrl = CReflect( ctrl.sdcCtrl );
813869
ctrlC.time = ctrl.time;
814870
return ctrlC;
@@ -818,7 +874,7 @@ inline SchurCtrl<float> CReflect( const ElSchurCtrl_s& ctrlC )
818874
{
819875
SchurCtrl<float> ctrl;
820876
ctrl.useSDC = ctrlC.useSDC;
821-
ctrl.qrCtrl = CReflect( ctrlC.qrCtrl );
877+
ctrl.hessSchurCtrl = CReflect( ctrlC.hessSchurCtrl );
822878
ctrl.sdcCtrl = CReflect( ctrlC.sdcCtrl );
823879
ctrl.time = ctrlC.time;
824880
return ctrl;
@@ -827,7 +883,7 @@ inline SchurCtrl<double> CReflect( const ElSchurCtrl_d& ctrlC )
827883
{
828884
SchurCtrl<double> ctrl;
829885
ctrl.useSDC = ctrlC.useSDC;
830-
ctrl.qrCtrl = CReflect( ctrlC.qrCtrl );
886+
ctrl.hessSchurCtrl = CReflect( ctrlC.hessSchurCtrl );
831887
ctrl.sdcCtrl = CReflect( ctrlC.sdcCtrl );
832888
ctrl.time = ctrlC.time;
833889
return ctrl;

python/lapack_like/spectral.py

+23-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ..blas_like import Copy, EntrywiseMap
1111
from ..io import ProcessEvents
1212
import ctypes
13+
from ctypes import CFUNCTYPE
1314

1415
# Cubic secular
1516
# =============
@@ -550,12 +551,28 @@ class SignCtrl_d(ctypes.Structure):
550551
def __init__(self):
551552
lib.ElSignCtrlDefault_d(pointer(self))
552553

553-
lib.ElHessQRCtrlDefault.argtypes = [c_void_p]
554-
class HessQRCtrl(ctypes.Structure):
555-
_fields_ = [("distAED",bType),
554+
(HESSENBERG_SCHUR_AED,HESSENBERG_SCHUR_MULTIBULGE,HESSENBERG_SCHUR_SIMPLE)= \
555+
(0,1,2)
556+
557+
lib.ElHessenbergSchurCtrlDefault.argtypes = [c_void_p]
558+
class HessenbergSchurCtrl(ctypes.Structure):
559+
_fields_ = [("winBeg",iType),
560+
("winEnd",iType),
561+
("fullTriangle",bType),
562+
("wantSchurVecs",bType),
563+
("demandConverged",bType),
564+
("alg",c_uint),
565+
("recursiveAED",bType),
566+
("accumulateReflections",bType),
567+
("progress",bType),
568+
("minMultiBulgeSize",iType),
569+
("numShifts",CFUNCTYPE(iType,iType,iType)),
570+
("deflationSize",CFUNCTYPE(iType,iType,iType,iType)),
571+
("sufficientDeflation",CFUNCTYPE(iType,iType)),
572+
("distAED",bType),
556573
("blockHeight",iType),("blockWidth",iType)]
557574
def __init__(self):
558-
lib.ElHessQRCtrlDefault(pointer(self))
575+
lib.ElHessenbergSchurCtrlDefault(pointer(self))
559576

560577
lib.ElSDCCtrlDefault_s.argtypes = [c_void_p]
561578
class SDCCtrl_s(ctypes.Structure):
@@ -584,7 +601,7 @@ def __init__(self):
584601
lib.ElSchurCtrlDefault_s.argtypes = [c_void_p]
585602
class SchurCtrl_s(ctypes.Structure):
586603
_fields_ = [("useSDC",bType),
587-
("qrCtrl",HessQRCtrl),
604+
("hessSchurCtrl",HessenbergSchurCtrl),
588605
("sdcCtrl",SDCCtrl_s),
589606
("time",bType)]
590607
def __init__(self):
@@ -593,7 +610,7 @@ def __init__(self):
593610
lib.ElSchurCtrlDefault_d.argtypes = [c_void_p]
594611
class SchurCtrl_d(ctypes.Structure):
595612
_fields_ = [("useSDC",bType),
596-
("qrCtrl",HessQRCtrl),
613+
("hessSchurCtrl",HessenbergSchurCtrl),
597614
("sdcCtrl",SDCCtrl_d),
598615
("time",bType)]
599616
def __init__(self):

0 commit comments

Comments
 (0)