如何在LAPACK中找到最佳块大小和LWORK

时间:2018-03-21 15:07:42

标签: fortran lapack

我试图找到使用带有lapack的Fortran的nxn Hermitian矩阵的逆和本征函数。

如何为ldalworkliworklrwork等参数选择最佳值。我浏览一些例子并找到这些选择

integer,parameter::lda=nh
integer,parameter::lwork=2*nh+nh*nh
integer,parameter::liwork=3+5*nh
integer,parameter::lrwork=1 + 5*nh + 2*nh*nh

其中nh是矩阵的维度。我还找到了lwork=16*nh的另一个例子。我怎样才能确定最佳选择?此时,我正在处理500x500埃尔米特矩阵(最大值)。

我发现this documentation暗示

  

工作

     

(工作空间)REAL数组,维度(LWORK)

     

退出时,如果INFO = 0,则WORK(1)返回最佳LWORK。

     

LWORK

     

(输入)INTEGER

     

数组WORK的维度。 LWORKmax(1,N)。

     

为获得最佳性能LWORKN* NB,其中NB是ILAENV返回的最佳块大小。

对于给定的矩阵维度,是否可以使用WORKILAENV找出最佳块大小?

我正在使用gfortran和ifort与mkl。

修改

基于@percusse和@kvantour's answer的评论,这里有一个示例代码

character,parameter::jobz="v",uplo="u"
integer, parameter::nh=15
complex*16::m(nh,nh),m1(nh,nh)

integer,parameter::lda=nh
integer::ipiv(nh),info

complex*16::work(1)
real*8::rwork(1), w(nh)
integer::iwork(1)
real*8::x1(nh,nh),x2(nh,nh)

call random_seed()
call random_number(x1)
call random_number(x2)

m=cmplx(x1,x2)
m1=conjg(m)
m1=transpose(m1)
m=(m+m1)/2.0

call zheevd(jobz,uplo,nh,m,lda,w,work,-1,rwork,-1,iwork, -1,info)

print*,"info : ", info
print*,"lwork: ", int(work(1))   , 2*nh+nh*nh
print*,"lrwork:", int(rwork(1))  , 1 + 5*nh + 2*nh*nh
print*,"liwork:", int(iwork(1))  , 3+5*nh

end
  

info:0

     

lwork:255 255

     

工作:526 526

     

liwork:78 78

1 个答案:

答案 0 :(得分:3)

我不确定你的意思“是否有可能使用WORKILAENV找出特定机器架构的最佳块大小?” 。但是,您可以找到特定问题的最佳值。

EG。如果要使用cheev找到复杂Hermitian矩阵的特征值,可以让例程返回值:

subroutine CHEEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, INFO )
  character                , intent(in)    :: JOBZ
  character                , intent(in)    :: UPLO
  integer                  , intent(in)    ::  N
  complex, dimension(lda,*), intent(inout) :: A
  integer                  , intent(in)    :: LDA
  real   , dimension(*)    , intent(out)   :: W
  complex, dimension(*)    , intent(out)   :: WORK
  integer                  , intent(in)    :: LWORK
  real   , dimension(*)    , intent(out)   :: RWORK
  integer                  , intent(out)   :: INFO 

然后documentation明确指出(建议过去这更容易阅读):

  

WORKCOMPLEX数组,维(MAX(1,LWORK))             退出时,如果INFO = 0,则WORK(1)会返回最佳LWORK

     

LWORKINTEGER             数组WORK的长度。 LWORK >= max(1,2*N-1)。             为了获得最佳效率,LWORK >= (NB+1)*N,             其中NBCHETRD返回的ILAENV的块大小。如果LWORK = -1,则假定工作空间查询;例程             仅计算WORK数组的最佳大小,返回             此值作为WORK数组的第一个条目,并且没有错误             与LWORK相关的邮件由XERBLA发出。

所以你需要做的就是

call cheev(jobz, uplo, n, a, lda, w, work, -1, rwork, info)
lwork=int(work(1))
dallocate(work)
allocate(work(lwork))
call cheev(jobz, uplo, n, a, lda, w, work, lwork, rwork, info)