Fortran Coder

标题: 新手在VS及MinGW中调用arpack数值计算库遇到的问题 [打印本页]

作者: cstg    时间: 2017-3-30 15:00
标题: 新手在VS及MinGW中调用arpack数值计算库遇到的问题
大家好,我刚刚接触fortran这门语言。想要学习一些数值软件库的写法、用法,日后可以自己编写一些算法。现在在第一次尝试调用arpack库时出现了一个问题,想要向论坛求助!
我用的是VS2015,同时安装了intel parallel studio XE,编写形如hello world的程序没有出现问题。我首先是根据http://www.cnblogs.com/zeze/p/5959520.html所说的方法成功安装并配置好了arpack库,并且用MinGW编译器试运行了其中的example文件夹下的示例都没有出现问题。然后为了试验在VS上运行,我编写了如下程序,其中调用了arpack目录下lapack中的dgemm.f程序。(下面这个程序的目的是比较fortran中的矩阵乘法与lapack中的矩阵乘法的效率上的差距)。但是,VS却报了30多个错。我看了下,都是指向dgemm.f这个程序的。但我认为dgemm.f是不应该出错的,于是我又用MinGW去手动分开编译这两个文件,发现dgemm.f在编译时没有出错,但是在编译我的exmain时却报了很多错,原因都指向其中include的dgemm.f文件。我使用的编译命令是:
$ gfortran -c dgemm.f -o dgemm.o
$ gfortran -c exmain.f90 -o exmain.o
另外,如果我在VS中直接编译dgemm.f,也会出错。
我在想的是会不会是因为两个文件的格式不同的原因?dgemm是固定格式写的,而exmain是自由格式的问题,在编译过程中导致出错?那我自由格式应该如何调用固定格式的程序?我这方面很小白,恳请大家能帮一下!!!谢谢啦!

其中dgemm.f我放在了附件里。

[Fortran] 纯文本查看 复制代码
program exmain
    include 'dgemm.f'
    implicit none
    integer, parameter :: m=1000
    DOUBLE PRECISION a(m,m), b(m,m), c(m,m),d(m,m),t
    integer i,j
    real t1, t2, t3
    c=0
    call RANDOM_SEED()
    do i=1,m
        do j=1,m
           call RANDOM_NUMBER(t)
           a(i,j)=t*5
           b(i,j)=t*5
        end do
    end do
   
    call cpu_time(t1)
    c=matmul(a,b)
    call cpu_time(t2)
    d=dgemm('N','N',m,m,m,1,a,m,b,m,0,c,m)
    call cpu_time(t3)
    write (*,*)t2-t1
    write (*,*)t3-t2
    stop
    end program



dgemm.f

9.93 KB, 下载次数: 1

所调用的程序


作者: pasuka    时间: 2017-3-30 17:55
本帖最后由 pasuka 于 2017-3-30 17:59 编辑

1、IVF自带的FEAST为啥不试一试?大部分情况下,性能持平或者超过ARPACK;
2、非要ARPACK的话,请去下载这个仍然在维护的版本
opencollab/arpack-ng: Collection of Fortran77 subroutines designed to solve large scale eigenvalue problems.
https://github.com/opencollab/arpack-ng
3、LAPACK的例子参考
http://www.nag.com/lapack-ex/lapack-ex.html
或者IVF帮助文档
4、不考虑跨平台,MinGW可以暂时搁置5、有C或C++基础,直接转投armadillo或者Eigen阵营


作者: Jackdaw    时间: 2017-3-30 18:18
DGEMM是一个subroutine,不是function,你写的调用方式错了
作者: cstg    时间: 2017-3-30 20:35
Jackdaw 发表于 2017-3-30 18:18
DGEMM是一个subroutine,不是function,你写的调用方式错了

哦哦!谢谢!!!确实写错了。不过我现在改过来后还是照常出错。更重要的是我直接在VS中编译dgemm.f也出错,而用MinGW直接编译则正常(虽然编译exmain时还是出错了),这让我没有想通。
作者: cstg    时间: 2017-3-30 20:39
pasuka 发表于 2017-3-30 17:55
1、IVF自带的FEAST为啥不试一试?大部分情况下,性能持平或者超过ARPACK;
2、非要ARPACK的话,请去下载这 ...

我对于FEAST、armadi并不了解,我也是新学。你说的版本以及例子我会去试一下,太感谢了!不过我觉得我应该还是在哪里犯了个低级错误,很想知道是在哪里。
作者: Jackdaw    时间: 2017-3-30 21:50
cstg 发表于 2017-3-30 20:35
哦哦!谢谢!!!确实写错了。不过我现在改过来后还是照常出错。更重要的是我直接在VS中编译dgemm.f也出 ...

那就接着改吧,我看那个程序参数说明里面很清楚,读懂后修改即可
作者: cstg    时间: 2017-3-30 23:02
Jackdaw 发表于 2017-3-30 21:50
那就接着改吧,我看那个程序参数说明里面很清楚,读懂后修改即可

但是仍然报的错还是都是指向dgemm.f的。。。。就是说主要的问题还是没有解决。。
下面四张图第一张是程序所报的错,后面三张是我安装好arpack并进行makefile等操作后对VS的配置。是不是我这里面出了错???其实我也是第一次使用这样的数值计算库。。。
另外比如报错的第一条,似乎是说我有两个主程序(即C中有两个main函数),但是从图片右边的解决方案资源管理器可以看出并没有,而且dgemm是subroutine,应该不会有这个问题啊。。。所以很凌乱。。。我感觉还是因为我的一些对库使用的低级错误导致的。。。如果能发现我的错误地方就太感谢了!!!

图片1.png (126.73 KB, 下载次数: 501)

图片1.png

图片2.png (33.93 KB, 下载次数: 506)

图片2.png

图片3.png (31.33 KB, 下载次数: 484)

图片3.png

图片4.png (40.54 KB, 下载次数: 471)

图片4.png

作者: cstg    时间: 2017-3-30 23:07
另外我也试过在VS中用固定格式写的更简单的(但调用了dgemm.f)程序。。。还是出错。。
作者: vvt    时间: 2017-3-31 07:44
本帖最后由 vvt 于 2017-3-31 07:47 编辑

你不能在自由格式源代码“.f90”中 include 固定格式的源代码“.f”通常的约定:
函数库里的源代码文件,编译成目标文件,与您书写的源代码文件编译成的目标文件共同链接。
函数库里的头文件,被您书写的源代码文件 include。(这个头文件可能有,可能没有)

实际上,我认为你的 include 语句完全是多余的。

作者: cstg    时间: 2017-3-31 15:07
vvt 发表于 2017-3-31 07:44
你不能在自由格式源代码“.f90”中 include 固定格式的源代码“.f”通常的约定:
函数库里的源代码文件,编 ...

啊啊,你说的好有道理!我在取消了include后用MinGW就编译并且链接成功了!非常感谢!

其实不同格式的先编成目标文件后再链接成一个可执行文件这件事我最近在学习时也看到过,但用起来时原理就忘了。。。
不过我还是有些疑问的地方,1.比如在C程中我一直持有的观点是如果要用到其他文件中定义的函数的话,一定要include那个文件后才能编译成功,因为预编译过程中要先把include的部分给替换掉成所调用的函数文件。但这里却不需要使用include,而我现在是使用MinGW编译的,就是说似乎没有利用到lib文件,这让我很想不通,是fortran的特性吗?
2. 虽然这里用MinGW编译成功了,但是在VS中还是失败,错误显示是链接中出现的问题:        error LNK2019: 无法解析的外部符号 _DGEMM,该符号在函数 _MAIN__ 中被引用 arpack_test_main.obj               
这是不是意味着我配置arpack的lib的过程有误?可是我确实是严格安装博客上的过程做的。。唯一一个让我感觉不踏实的地方在于博客上要求使用Visual Studio命令提示,我VS2015没找到对应名字,于是就使用了“VS2015开发人员命令提示符”去操作,这个是做对的吗?
3. 我对lib的理解还很粗浅。我的理解是这样的:比如我现在成功编译其实并没有使用lib文件,我其实是直接拿源文件过来编译链接的,但这样可能要同时链接很多程序(比如这次我除了链接dgemm.o外还链接了dgemm.f中所使用的另外两个文件),这样对大型工程就没办法做了,所以整合成一个lib文件,只要通过某种方式include了lib文件,那么至少在IDE下通过一定的设置就可以直接调用和链接那些文件了。我这样的理解对吗?如果对的话,在非IDE下改如何使用lib文件呢,比如用MinGW?我对编译器的使用方面非常小白,如果有什么推荐去阅读的资料就太好了!
非常感谢!

作者: vvt    时间: 2017-3-31 17:56
本帖最后由 vvt 于 2017-3-31 17:59 编辑

C语言的特性是需要函数原型(它是 h 头文件的主要内容)
而fortran的语言特性,不需要函数原型。所以 fortran 里很少用到头文件。

在C语言和fortran语言中,include都是会被替换的(详见 http://fpp.w.fcode.cn),C语言是为了获得函数原型,而fortran则必要性并不强。(具体看包含文件的内容,有些函数库需要include一个头文件,出于各种目的)

我对arpack也不了解。找不到 _DGEMM 可能是 lib 配置不合适。你再自己看看吧。

不管是命令行还是VS,都可以有效的管理项目。它们的形式不同,但不存在说“必须用命令行”或“必须用VS”。(实质上,VS只是对命令行进行了界面化的包装)

是的,lib文件其实就是 .o 文件的集合。你这样理解是对的。命令行下使用 lib 文件,资料应该有不少,比如本论坛的视频教程 http://v.fcode.cn 应用篇第4期。

推荐阅读资料《程序员的自我修养——链接、装载与库》
作者: cstg    时间: 2017-3-31 18:58
vvt 发表于 2017-3-31 17:56
C语言的特性是需要函数原型(它是 h 头文件的主要内容)
而fortran的语言特性,不需要函数原型。所以 fortr ...

非常感谢您的耐心解答与所给出的资料,感觉明白了不少。还遗留下的一些疑问我先从您给的资料中来找答案吧,可能看了更多的资料后这些问题就解决了。

再次感谢!




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2