在Linux下编译程序时,出现scalapack链接错误。如何解决这个问题?

时间:2019-05-16 03:57:10

标签: scalapack

c ++和Fortran程序使用Intel Math Kernel Library和openmpi。在Linux下编译程序时,出现scalapack链接错误。如何解决这个问题?

程序需要链接到基于Intel Fortran和C的Intel Math Kernel Library和MPI的Open-MPI版本

!------------------------------------------------ -------------------------------------------------- -----------------------------------     子程序mpi_worker_ScaLapackMM() !------------------------------------------------- -------------------------------------------------- --------------------------------

! !矩阵矩阵乘法 !

integer :: i, istat, numroc, info, ictxt
integer :: myid, ierr, nprocs 

integer   :: mycol, myrow, nb
integer   :: npcol, nprow
integer,parameter :: descriptor_len=9


integer   :: l_nrows_wj,l_ncols_wj    
integer   :: l_nrows_wjtwj,l_ncols_wjtwj

integer   :: desc_wj( descriptor_len ),desc_wjg( descriptor_len )
integer   :: desc_wjtwj( descriptor_len )
integer   :: desc_wjtwjg( descriptor_len )

integer   :: rootNodeContext, sizeM, sizeN

real(RealPrec), dimension(:,:),allocatable :: wj_loc,wjtwj_loc

! !我是哪个处理器,还有几个? !     调用blacs_pinfo(myid,nprocs)

! !向所有处理器广播矩阵的大小: !     如果(myid == 0)sizeM = size(wj,dim = 1)     如果(myid == 0)sizeN = size(wj,dim = 2)     呼叫mpi_bcast(sizeM,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)     呼叫mpi_bcast(sizeN,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)


!设置2d处理器网格的尺寸: !     调用gridsetup(nprocs,nprow,npcol)     !小型处理器网格,简短的胖矩阵调整:     !这适用于某些CPU(例如Triton),其中pdsyrk停滞在脂肪矩阵和小网格上     如果((nprocs <= 16)和(sizeN / sizeM> 2))然后         nprow = 1         npcol = nprocs     结束

! !初始化单个blacs上下文: !     致电blacs_get(-1,0,ictxt)     调用blacs_gridinit(ictxt,'r',nprow,npcol)     致电blacs_gridinfo(ictxt,nprow,npcol,myrow,mycol)


!计算矩阵的阻塞因子: !     调用blockset(nb,64,sizeM,sizeN,nprow,npcol)


!分布式矩阵:获取编号。本地行/列。创建说明: !     l_nrows_wj = numroc(sizeM,nb,myrow,0,nprow)     l_ncols_wj = numroc(sizeN,nb,mycol,0,npcol)     呼叫descinit(desc_wj,sizeM,sizeN,nb,nb,0,0,ictxt,l_nrows_wj,info)

l_nrows_wjtwj = numroc(sizeN,nb,myrow,0,nprow)
l_ncols_wjtwj = numroc(sizeN,nb,mycol,0,npcol)
call descinit( desc_wjtwj, sizeN, sizeN, nb, nb, 0, 0, ictxt, l_nrows_wjtwj, info ) 

allocate (wj_loc(l_nrows_wj, l_ncols_wj ), stat=istat)
if (istat /= 0) then
    write(*,*) 'Error allocating wj_loc! l_nrows_wj,l_ncols_wj =',l_nrows_wj,l_ncols_wj
    stop
endif

allocate (wjtwj_loc(l_nrows_wjtwj, l_ncols_wjtwj ), stat=istat) 
if (istat /= 0) then
    write(*,*) 'Error allocating wjtwj_loc! l_nrows_wjtwj,l_ncols_wjtwj =',l_nrows_wjtwj, l_ncols_wjtwj
    stop
endif

! !将全局wj的子块从主对象分配到所有过程: !     调用blacs_get(-1,0,rootNodeContext)     调用blacs_gridinit(rootNodeContext,'row-major',1,1)

 if (myid == 0) then
    call descinit( desc_wjg, sizeM, sizeN, sizeM, sizeN, 0, 0, rootNodeContext, sizeM, info )
    call descinit( desc_wjtwjg, sizeN, sizeN, sizeN, sizeN, 0, 0, rootNodeContext, sizeN, info )
else 
    desc_wjg        = 0
    desc_wjg(2)     = -1
    desc_wjtwjg     = 0
    desc_wjtwjg(2)  = -1
endif

call pdgemr2d( sizeM, sizeN, wj, 1, 1, desc_wjg, wj_loc, 1, 1, desc_wj, desc_wj( 2 ) )

! !并行矩阵相乘: !
    调用pdsyrk('u','t',sizeN,sizeM,1d0,wj_loc,1,1,desc_wj,0d0,wjtwj_loc,1,1,desc_wjtwj)

! !将wjtwj_loc中的解决方案发送回矩阵wjtwj: !

call pdgemr2d( sizeN, sizeN, wjtwj_loc, 1, 1, desc_wjtwj, wjtwj, 1, 1, desc_wjtwjg, ictxt )
if (myid == 0) then  
    ! fill in lower triangle
    do i=2,sizeN
        wjtwj(i,1:i-1) = wjtwj(1:i-1,i)
    enddo    
endif
if (myid == 0)  call blacs_gridexit( rootNodeContext ) 

! !取消分配本地数组... !     如果(已分配(wj_loc))取消分配(wj_loc)     如果(已分配(wjtwj_loc))取消分配(wjtwj_loc)

! !关闭双语法例咨询委员会: !
    致电blacs_gridexit(ictxt)

end subroutine mpi_worker_ScaLapackMM

!------------------------------------------------ -------------------------------------------------- -----------------------------------     子程序mpi_worker_ScaLapackMS(istat) !------------------------------------------------- -------------------------------------------------- -------------------------------- ! !矩阵分解和求解 !
!这是从mare2dem_mpi.f90中的solveLinearSystem_scalapack()调用的 !

integer :: numroc, info,ictxt
integer :: myid, ierr, nprocs, istat

integer   :: mycol, myrow, nb
integer   :: npcol, nprow
integer,parameter :: descriptor_len=9

integer   :: l_nrows_amat,l_ncols_amat    
integer   :: l_nrows_pm_test,l_ncols_pm_test

integer   :: desc_amat( descriptor_len )
integer   :: desc_pm_test( descriptor_len )
integer   :: desc_amatg( descriptor_len )
integer   :: desc_pm_testg( descriptor_len )    

integer   ::  rootNodeContext,   sizeN

real(RealPrec), dimension(:,:),allocatable :: amat_loc
real(RealPrec), dimension(:,:)  ,allocatable :: pm_test_loc

! !我是哪个处理器,还有几个? !     调用blacs_pinfo(myid,nprocs)

! !向所有节点广播矩阵N x N大小: !     如果(myid == 0)sizeN = size(amat,dim = 1)     呼叫mpi_bcast(sizeN,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)


!设置2d处理器网格的尺寸: !     调用gridsetup(nprocs,nprow,npcol)

! !初始化单个blacs上下文: !     致电blacs_get(-1,0,ictxt)     调用blacs_gridinit(ictxt,'r',nprow,npcol)     致电blacs_gridinfo(ictxt,nprow,npcol,myrow,mycol)


!计算矩阵的阻塞因子: !     调用blockset(nb,64,sizeN,sizeN,nprow,npcol)!


!分布式矩阵:获取编号。本地行/列。创建说明: !     l_nrows_amat = numroc(sizeN,nb,myrow,0,nprow)     l_ncols_amat = numroc(sizeN,nb,mycol,0,npcol)     呼叫descinit(desc_amat,sizeN,sizeN,nb,nb,0,0,ictxt,l_nrows_amat,info)

l_nrows_pm_test = numroc(sizeN,nb,myrow,0,nprow)
l_ncols_pm_test = 1  
call descinit( desc_pm_test, sizeN, 1, nb, 1, 0, 0, ictxt, l_nrows_pm_test, info )  

allocate (amat_loc(l_nrows_amat, l_ncols_amat ), stat=istat)
if (istat /= 0) then
    write(*,*) 'Error allocating amat_loc! l_nrows_amat,l_ncols_amat =',l_nrows_amat,l_ncols_amat
    stop
endif 

allocate (pm_test_loc(l_nrows_pm_test, l_ncols_pm_test ), stat=istat) 
if (istat /= 0) then
    write(*,*) 'Error allocating pm_test_loc! l_nrows_pm_test,l_ncols_pm_test =',l_nrows_pm_test,l_ncols_pm_test
    stop
endif     

! !将master的全局amat和pm_test子块分配给所有进程: !     调用blacs_get(-1,0,rootNodeContext)     调用blacs_gridinit(rootNodeContext,'row-major',1,1)     如果(myid == 0)然后         调用descinit(desc_amatg,sizeN,sizeN,sizeN,sizeN,0,0,rootNodeContext,sizeN,info)         调用descinit(desc_pm_testg,sizeN,1,sizeN,1,0,0,rootNodeContext,sizeN,info)     其他         desc_amatg = 0         desc_amatg(2)= -1         desc_pm_testg = 0         desc_pm_testg(2)= -1     结束

call pdgemr2d( sizeN, sizeN, amat, 1, 1, desc_amatg, amat_loc, 1, 1, desc_amat, desc_amat( 2 ) )

call pdgemr2d( sizeN, 1, pm_test, 1, 1, desc_pm_testg, pm_test_loc, 1, 1, desc_pm_test, desc_pm_test( 2 ) )

! !并行矩阵求解器: !     调用pdpotrf('u',sizeN,amat_loc,1,1,desc_amat,info)     如果(info / = 0)然后         write()'调用pdpotrf出错!资讯:',info         停     endif

call pdpotrs( 'u',  sizeN, 1, amat_loc, 1, 1, desc_amat, pm_test_loc, 1, 1, desc_pm_test,  info )
if (info /= 0) then
    write(*,*) 'Error calling pdpotrs! info: ',info
    stop
endif  

! !将向量中的解决方案发送回主机: !
    致电pdgemr2d(sizeN,1,pm_test_loc,1,1,desc_pm_test,pm_test,1,1,desc_pm_testg,ictxt)

if (myid == 0) call blacs_gridexit( rootNodeContext ) 

! !取消分配本地数组... !     如果(已分配(amat_loc))取消分配(amat_loc)     如果(已分配(pm_test_loc))取消分配(pm_test_loc)

! !关闭双语法例咨询委员会: !
    致电blacs_gridexit(ictxt)

end subroutine mpi_worker_ScaLapackMS

endif

make显示的编译结果:

mpif90 -O2 -fpp -m64 kdtree2.o fem2D_utilities.o binaryTree.o call_triangle.o sort.o c_fortran_zgssv.o superlu_zsolver.o umf4_f77zwrapper.o umfpack_zsolver.o string_helpers.o em.o mt.2 mt1 .o Occam.o c_fortran_triangle.o FilterModules.o mare2dem_common.o spline_kx_module.o mare2dem_worker.o mare2dem_io.o mare2dem_mpi.o EM2D.o RunMARE2DEM.o ./libraries/SuperPar_4.0/Sulu/Site/SuperLU_4.0/Sulib /UMFPACK/Lib/libumfpack.a ./libraries/SuiteSparse/AMD/Lib/libamd.a ./libraries/SuiteSparse/CHOLMOD/Lib/libcholmod.a ./libraries/SuiteSparse/COLAMD/Lib/libcolamd.a ./libraries /SuiteSparse/CAMD/Lib/libcamd.a ./libraries/SuiteSparse/CCOLAMD/Lib/libccolamd.a ./libraries/metis-4.0/libmetis.a ./libraries/scalapack-2.0.2/libscalapack.a \         -L / home / users / nqiu / intel / mkl / lib / intel64 / -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -o MARE2DEM Occam.o:在函数occam_mp_mpi_worker_scalapackmm_': Occam.f90:(.text+0x1278a): undefined reference to numroc_中 Occam.f90 :(。text + 0x127a9):对numroc_' Occam.f90:(.text+0x127e1): undefined reference to descinit_'的未定义引用 Occam.f90 :(。text + 0x12801):对numroc_' Occam.f90:(.text+0x12820): undefined reference to numroc_'的未定义引用 Occam.f90 :(。text + 0x12857):对descinit_' Occam.f90:(.text+0x12c37): undefined reference to pdgemr2d_'的未定义引用 Occam.f90 :(。text + 0x12c88):对pdsyrk_' Occam.f90:(.text+0x12cd4): undefined reference to pdgemr2d_'的未定义引用 Occam.f90 :(。text + 0x13127):对descinit_' Occam.f90:(.text+0x1315d): undefined reference to descinit_'的未定义引用 Occam.o:在函数occam_mp_mpi_worker_scalapackms_': Occam.f90:(.text+0x134dd): undefined reference to numroc_中 Occam.f90 :(。text + 0x13510):对numroc_' Occam.f90:(.text+0x1355b): undefined reference to descinit_'的未定义引用 Occam.f90 :(。text + 0x1358b):对numroc_' Occam.f90:(.text+0x135da): undefined reference to descinit_'的未定义引用 Occam.f90 :(。text + 0x139e2):对pdgemr2d_' Occam.f90:(.text+0x13a2f): undefined reference to pdgemr2d_'的未定义引用 Occam.f90 :(。text + 0x13a61):对pdpotrf_' Occam.f90:(.text+0x13ada): undefined reference to pdpotrs_'的未定义引用 Occam.f90 :(。text + 0x13b41):未定义对pdgemr2d_' Occam.f90:(.text+0x13f4e): undefined reference to descinit_'的引用 Occam.f90 :(。text + 0x13f8b):未定义对`descinit_'的引用

0 个答案:

没有答案