高性能计算

gfortran 和mpif90的不同引发scalapack链接错误

2009年12月10日 阅读(1,014)

一.用这两个进行编译
gfortran -c pdlaread.f
mpif90 -c pdlaread.f
然后用nm pdlaread.o进行查看,发现fortran函数gfortran加了一个下划线 而mpif90则加了两个。
这也是之前出现下面的错误的原因。
一个解决方案,使用gfortran编译成目标文件,仅用mpif90进行链接。但是用mpif90链接时却出现另一个错误
usr/local/bin/mpif90: line 294: eval: -o: 无效的选项。所以也不可行,需要进行寻找方法。

二.使用 mpif90 -o xdscaex pdscaex.o pdscaexinfo.o pdlaread.o pdlawrite.o
出现如下错误:
/usr/local/bin/mpif90: line 294: eval: -o: 无效的选项
可以看到这个mpif90在另一个目录下,并不是我们安装的那个mpif90.将原来的那个/usr/local/bin/mpif90删除。
实际上-o -c 是gfortran支持的。

然后ln /home/duanple/intel/ict/3.0.1/mpi/3.0/bin/mpif90 /usr/local/bin/mpif90
再运行就可以了。

出现这个错误的原因在于机子上重复安装了intel的ict的mpi 以及mpich,而这两个对fortran的函数处理所不一样的,导致出现了下面的这种undefined reference to `blacs_pinfo__’错误。我们在编译blacs时用的是c语言编译器,它生成的目标文件,函数后面只加了一个下划线。而后面由于我们重新安装了mpich,在编译scaex时,mpich的mpif90实际上使用的不是gfortran,所以本来可以用intel的mpi编译的程序,现在又编译不通了,因为mpich的mpif90生成的fortran的目标文件,函数后面只加了两个下划线,这样我们的blacs库编译后实际上有blacs_pinfo_,而pdscaex.o里调用的却是`blacs_pinfo__’,这样显然就找不到正确的函数了。

进一步分析,发现对于一个c函数后面是否加上一个多余的"_",这跟编译时的参数也有关。
gcc -o Cblacs_pinfo.o -c -O4 -DSYSINC -I/home/duanple/intel/ict/3.0.1/mpi/3.0/include -DAdd_   -DBlacsDebugLvl=0   -DCSameF77   -DCallFromC -DMainInC    blacs_pinfo_.c

这里面关于fortran函数编译后加下划线,实际上涉及到c和fortran的混合编程问题:
http://wiki.ubuntu.org.cn/Mix_C_Fortran

综上,链接出现的问题实际上可以用nm命令来进行分析。

-------------------------------------------------
mpif90 -lg2c  -o xdscaex pdscaex.o pdscaexinfo.o pdlaread.o pdlawrite.o  /home/duanple/scalapack/scalapack-1.8.0/libscalapack.a /home/duanple/scalapack/BLACS/LIB/blacsF77init_MPI-LINUX-0.a /home/duanple/scalapack/BLACS/LIB/blacs_MPI-LINUX-0.a /home/duanple/scalapack/BLACS/LIB/blacsF77init_MPI-LINUX-0.a /home/duanple/scalapack/lapack-3.2.1/lapack_LINUX.a /home/duanple/scalapack/lapack-3.2.1/blas_LINUX.a /home/duanple/intel/ict/3.0.1/mpi/3.0/lib/libmpi.a

利用上述命令编译基于scalpack的scaex时,出现如下链接错误:
pdscaex.o: In function `MAIN__’:
pdscaex.f:(.text+0x26): undefined reference to `blacs_pinfo__’
pdscaex.f:(.text+0xa3): undefined reference to `blacs_get__’
pdscaex.f:(.text+0xc9): undefined reference to `blacs_gridinit__’
……
查找原因:按理来说blacsF77init_MPI-LINUX-0.a里应该含有这些函数,于是利用nm命令,查看里面是否含有这些函数。

nm /home/duanple/scalapack/BLACS/LIB/blacs_MPI-LINUX-0.a| grep blacs.*
nm pdlawrite.o| grep blacs_barrier.*

发现第一个输出的是blacs_pinfo_
第二个是blacs_pinfo__
两者的差别就在,后一个比前一个多了一个"_"。

差别就在这里,可能的原因是在编译blacs的时候,用的gfortran,而pdlawrite.o是用mpif90编译的。

You Might Also Like