主题:经典错误解决不了:openmp中segmentation fault
baccle
[专家分:190] 发布于 2011-07-13 15:41:00
程序串行时没有错误,一加上openmp并行后就运行不了,报错是
/var/spool/torque/mom_priv/jobs/6127.node1.SC: line 11: 629 Segmentation fault
上网查了一下这个错误的原因,然后做了以下这些
1.在工作目录下找到.bashrc文件,加入语句export STACKSIZE=500M
2.在提交任务的脚本中加入语句 export STACSIZE=500M
3.在SSH页面上运行ulimit -s 500000
4.在openmp并行区,把比较大的数组都改成了动态数组
不过都没用,还是同样的错误,不知道该怎么办了,上来请教高手们
谢谢!!!
(用的是gfortran编译器,曙光集群)
回复列表 (共23个回复)
11 楼
baccle [专家分:190] 发布于 2011-07-15 17:08:00
我在.bashrc中写的是这么一句话 export OMP_STACKSIZE=500M
在提交任务的脚本中写是 export OMP_STACKSIZE=500M
export OMP_NUM_THREADS=8
难道在Gfortran下要改成 export GOMP_STACKSIZE=500M ??? 没听说过啊
12 楼
baccle [专家分:190] 发布于 2011-07-16 20:30:00
弄了两天,又有新的进展,现在将错误重新描述一下:
(用的是gfortran编译器,硬件是曙光集群上的一个计算节点)
1.当不使用openmp时,编译时选项打开-O3,-ftree-vectorize,可以正常运行,没有任何错误
2.使用openmp时(使用8个线程),编译选项打开-O3,-ftree-vectorize,只有当程序中的数组较小时(40*40)可以正常运行 (这个数组在并行区是私有变量,就是说每个线程都要另复制一份),数组大了报错
3.使用openmp(使用8个线程),编译选项打开-O1,-ftree-vectorize,程序中的数组大小可以到100*100,数组大了报错
4.使用openmp(8个线程),程序中的数组800*800,不管用O几编译运行时都会报错。
5.使用openmp(2个线程),程序中的数组800*800,报错
运行时报出的错误是 /var/spool/torque/mom_priv/jobs/6291.node1.SC: line 10: 16904 Segmentation fault ./fujia
已经把export OMP_STACKSIZE=2000M 这句话加入提交任务的脚本中,在程序运行之前设置了ulimit -s 512000
在window系统下,用intel编译器编译的同样的程序,使用openmp,能开的优化基本都开了(-ipo,-O3,-align,矢量化)数组开到800*800,没有任何错误,运行结果正确。
比较崩溃,各位高手们,这个问题到底这么解决啊?感觉鸭梨好大啊
13 楼
cgl_lgs [专家分:21040] 发布于 2011-07-17 09:53:00
估计IVF把较大的线程局部数组放到了堆上,所以再怎样也不会崩溃。而gfortran则是放在栈中(这样会比较快),所以稍微大些栈就受不了了。
另:我看你是把程序提交到job列表中,这样如果作业系统有栈空间限制则会有问题,你不管设置OMP用多大栈,那它也不能超过作业系统的限值的:)
[b]独立运行一下程序试试?[/b]
14 楼
baccle [专家分:190] 发布于 2011-07-17 14:57:00
独立运行时什么意思呢?是不用作业提交系统提交任务吗?那就是直接在登录节点上运行程序了?
这样原则上不允许,但刚才小试了一下,还是报错segmentation fault啊
我以前试过,把大数组改成动态分配,也是没有用的
如果确实是gfortran编译器的问题那也就没办法了,各位大侠,如果还有别的可能性的话我还想试试。
15 楼
dongyuanxun [专家分:7180] 发布于 2011-07-17 15:30:00
我想说的是
export OMP_STACKSIZE=2000M
ulimit -s 512000
这两句难道不是冲突的么,实际以系统限制为准
动态数组显然没用啊,gcc的OpenMP是传递给pthreads了,人家又不知道你是啥
16 楼
baccle [专家分:190] 发布于 2011-07-17 15:46:00
把它们改成一样的数字,也是没法运行,报同样的错误
17 楼
dongyuanxun [专家分:7180] 发布于 2011-07-17 15:58:00
编译时加入
-Wl,--stack 0x11111111111111
也可能是
-Wl,--stack=0x11111111111111
不行再加入-fno-automatic
还不行给出全部代码逐步分析
18 楼
cgl_lgs [专家分:21040] 发布于 2011-07-17 19:29:00
唉,我是說有可能IVF对大数组做OMP时使用的是堆,而不是说由你做成动态数组。
如果直接执行都不可以嘛。。。
你在你的本地运行可以不?如果还是不行,试试重编译下内核,调整一下相关选项——我记不住具体啥选项了,猜着看吧:)然后看看可否?
又或是:编译调试版本,在本地调试运行看看?
19 楼
baccle [专家分:190] 发布于 2011-07-17 20:54:00
前辈,我们的本地电脑上装的都是windows和intel fortran
我们是做科学计算的,都不大懂linux内核什么的……,这不是做嵌入式开发的才会接触到的吗,是不是这个问题只能在这个层面上解决了?
唉,压力好大啊
20 楼
cgl_lgs [专家分:21040] 发布于 2011-07-17 20:58:00
唉,那就编译Debug版本然后放到作业系统里运行,看看具体是在哪儿出的错吧。如果可以的话,也可以用gdb来调试:)
我来回复