基于vsFortran使用mkl库的求解线性大型稀疏矩阵pardiso函数时出现的两点错误(已解决)

       一:之前在用pardiso函数计算线弹性有限元程序的时候,当节点比较多的时候,我发现vsFortran的结果窗口会爆出栈溢出(stack overflow)的情况(具体界面忘截图了)。我上网查阅了一下,发现visual studio Fortran可以通过修改:属性->linker->system中的Heapk Commit,Heap Reserve ,Stack Commit ,Stack Reserve 值来修改最大的堆和栈。

根据这个问答网站:OMP: Error #136: Cannot create thread ( and #6, #8, #178 ) - Fortran project that reproduces the problem attached - Intel Community这四个值最大可以填成:268435456(即256MB)。我发现改完这个之后栈溢出的问题的确得到了解决,可以算到更多自由度的方程组了(虽然提升不是特别大,因为最后还要看你电脑硬件的配置)。所以我就没有把这个错误当一回事。 

       最近我在计算多物理场有限元的时候,我想先写一个热传导的有限元,再把之前的线弹性的整合一下(关于有限元的面向对象修改之后会写,大家可以期待一下哈哈哈)。结果在写完之后用一两个单元进行测试的时候,发现程序运行到call pardiso的时候出现了下面的错误:

OMP: Error #136: Cannot create thread.
OMP: System error #8: 内存资源不足,无法处理此命令。

          我一开始以为是数组读取有问题,比如说数组指针的内存泄漏了,导致内存被占满了。但是用vs的诊断工具也没有看出来哪里有问题。因为pardiso是自带并行计算的,关于并行计算omp的错误我也不懂,后面找了一圈也没有发现问题在哪里。然后还是最后误打误撞把之前的Heap Commit,Heap Reserve ,Stack Commit ,Stack Reserve 值改为0就发现问题解决了,然后我就发现如果你在使用pardiso计算的时候如果稀疏矩阵的维度比较大(比如上十万或者百万级别),那么就可以把这个Heap Commit,Heap Reserve ,Stack Commit ,Stack Reserve 值改成268435456,如果你的矩阵维度比较小就要把这个值填0或者要小一点了。不然就会出现上面的错误。

      二:此外我还发现在因为pardiso使用的是CSR的稀疏矩阵存储格式,所以对于所需要的a,ja,ia,b矩阵的精度要求不一样,其中存放具体元素值的a和b矩阵必须要双精度(double percision),而描述具体元素在稀疏位置的ja,ia矩阵必须要定义为单精度(single percision),否则在call PARDISO的时候会导致找不到对应的subroutine。(怪我没有仔细看mkl库的使用手册)

      三:最后如果大家如果有什么相关的问题可以在评论区交流,大佬要是发现什么错误也请多多指正。之后我会想办法更新面向对象的有限元编程

  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值