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
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_'的引用