一、SuperLU介绍
SuperLU:是一个通用库,用于直接求解大型稀疏非对称线性方程组。该库是用C编写的,可以从C或Fortran程序调用。它使用MPI、OpenMP和CUDA来支持各种形式的并行性。它支持实数据类型和复杂数据类型、单精度和双精度以及64位整数索引。库例程使用部分旋转执行LU分解,三角系统通过正向和反向替换进行求解。LU分解例程可以处理非方矩阵,但三角解仅对方矩阵执行。矩阵列可以通过库或用户提供的例程进行预排序(分解前)。这种稀疏性的预排序完全独立于因式分解。为提高向后稳定性,提供了工作精度迭代求精子程序。还提供了使系统平衡、估计条件数、计算相对后向误差和估计精化解的误差界的例程。
官网下载SuperLU文件地址:http://crd-legacy.lbl.gov/~xiaoye/SuperLU/
二、生成SuperLU静态库文件
1、 生成SuperLU.lib
2.1.1、新建项目
我已经下载了SuperLU相关文件到D:\other-systems\SUPERLU\SuperLU目录下 此处为了方便后期使用SuperLU库,项目命名为SuperLU。 新建项目之后将之前下好的D:\other-systems\SUPERLU\SuperLU\SRC 中的所有的.c文件添加到项目源文件文件夹中,所有的.h文件添加到项目头文件文件夹中。
2.1.2、配置属性
项目右键—>属性 工程的属性-> C/C+±>常规->附加包含目录中添加D:\other-systems\SUPERLU\SuperLU\SRC 文件夹路径 然后在工程 右击 -> 属性 -> 配置属性 -> 常规-> 配置类型-> 选择 静态库(.lib)单击确定。 或者在建立工程的时候选择直接创建静态库;
2.1.3、编译
在Debug模式调试编译无error后生成Release版本,直接编译会出现以下错误 原因是Visual C++ 2017 使用了更加安全的 run-time library routines 。新的Security CRT functions(就是那些带有“_s”后缀的函数),请参见:《CRT函数的安全增强的版本》 下面给出这个问题的解决方案: 方法一:将原来的旧函数替换成新的 Security CRT functions。 方法二:用以下方法屏蔽这个警告: 1. 在预编译头文件stdafx.h里(注意:一定要在没有include任何头文件之前)定义下面的宏: #define _CRT_SECURE_NO_DEPRECATE 2. 或声明 #pragma warning(disable:4996) 3. 更改预处理定义: 项目->属性->配置属性->C/C++ -> 预处理器 -> 预处理器定义,增加: _CRT_SECURE_NO_DEPRECATE
做以上修改之后又出现以下错误 原因: 在VS2017创建项目时,会有一个勾选项,叫做“安全开发生命周期(SDL)检查”,这个东西是微软在VS2012新推出的东西,为了是能更好的监管开发者的代码安全,如果勾选上这一项,那么他将严格按照SDL的规则编译代码,会有一些以前常用的函数无法通过编译,比如在VS2010中的scanf是warning那么在VS2017中就是error了。 也就是在编译的时候,当SDL检查启用时,编译器会严格检测缓冲区的溢出,并且会在delete某个指针时,自动为这个指针定义一个非有效的值,防止在delete以后仍用到这个指针时出错。还有就是会在你定义一个对象时,自动为这个对象赋值零。 从这些功能来看,有些功能还是不错的,不但方便了程序员使用也增强了程序的健壮性,但是对老版本程序的兼容就会出现问题,以前程序中编译通过的内容也许在VS2012中就没有办法通过。 解决办法: 问题解决方法: 有一个选择打开和关闭SDL检查的位置就是:项目属性->配置属性->C/C+±>SDL检查,选测是或者否。 此时我们选择”否”,则上面的那个错误就不会出现了 再编译就不会出错了 此时我们改为生成Release版本编译 在Release文件下生成了SuperLU.lib
2、 生成SuperLU.lib
2.2.1、新建项目
此处为了方便后期使用BLAS库,项目命名为BLAS。 由于SuperLU需要调用BLAS库中的一些函数,所以需要编译BLAS库。SuperLU官网上说BLAS库速度不快,推荐使用Intel MKL、ATLAS、GotoBLAS。为方便仅以SuperLU下载文件中附带的CBLAS文件夹下的BLAS为例编译,BLAS的编译与前者SuperLU类似。 1) 新建工程(命名BLAS),将D:\other-systems\SUPERLU\SuperLU\CBLAS文件夹下的头文件和源文件添加到工程文件目录中,然后将工程属性改为静态库(.lib)。 2) 将D:\other-systems\SUPERLU\SuperLU\CBLAS添加到 项目 -> 属性 -> C/C++ -> 常规 -> 附加包含目录; 3) 在Debug模式下调试编译,成功后生成Release版本。 编译过程中遇到以上问题的解决办法一样。
3、 调用SuperLU.lib库
2.3.1、新建mySuperLU项目,并配置SuperLU库
(1)将路径 D:\other-systems\SUPERLU\SuperLU\SRC添加到 项目属性 —> VC++目录 —>包含目录中,将之前编译好的SuperLU.lib(release文件夹下)和BLAS.lib(release文件夹下)复制到E:\programmer\mySuperLU\Debug文件夹下,没有的话可以新建,然后将E:\programmer\mySuperLU\Debug路径添加到项目属性 —> VC++目录 —>库目录中; (2) 再把路径E:\programmer\SuperLU\Release(此路径下包含文件SuperLu.lib)和路径E:\programmer\SuperLU\Release(此路径下包含文件BLAS.lib)添加到项目属性 —> 链接器 —>常规—>附加库目录中;
(3)将SuperLU.lib和BLAS.lib添加到项目属性—>链接器—>输入—>附加依赖项—>编辑—>附加依赖项—>确定。
2.3.2、调用方法
代码来源于SuperLU Package.(新建mySuperLU.c文件)
#include "stdafx.h"
#include "slu_ddefs.h"
void main(int argc, char *argv[])
{
SuperMatrix A, L, U, B;
double *a, *rhs;
double s, u, p, e, r, l;
int *asub, *xa;
int *perm_r;
int *perm_c;
int nrhs, info, i, m, n, nnz, permc_spec;
superlu_options_t options;
SuperLUStat_t stat;
m = n = 5;
nnz = 12;
if (!(a = doubleMalloc(nnz))) ABORT("Malloc fails for a[].");
if (!(asub = intMalloc(nnz))) ABORT("Malloc fails for asub[].");
if (!(xa = intMalloc(n + 1))) ABORT("Malloc fails for xa[].");
s = 19.0; u = 21.0; p = 16.0; e = 5.0; r = 18.0; l = 12.0;
a[0] = s; a[1] = l; a[2] = l; a[3] = u; a[4] = l; a[5] = l;
a[6] = u; a[7] = p; a[8] = u; a[9] = e; a[10] = u; a[11] = r;
asub[0] = 0; asub[1] = 1; asub[2] = 4; asub[3] = 1;
asub[4] = 2; asub[5] = 4; asub[6] = 0; asub[7] = 2;
asub[8] = 0; asub[9] = 3; asub[10] = 3; asub[11] = 4;
xa[0] = 0; xa[1] = 3; xa[2] = 6; xa[3] = 8; xa[4] = 10; xa[5] = 12;
dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE);
nrhs = 1;
if (!(rhs = doubleMalloc(m * nrhs))) ABORT("Malloc fails for rhs[].");
for (i = 0; i < m; ++i) rhs[i] = 1.0;
dCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_D, SLU_GE);
if (!(perm_r = intMalloc(m))) ABORT("Malloc fails for perm_r[].");
if (!(perm_c = intMalloc(n))) ABORT("Malloc fails for perm_c[].");
set_default_options(&options);
options.ColPerm = NATURAL;
StatInit(&stat);
dgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info);
dPrint_CompCol_Matrix("A", &A);
dPrint_CompCol_Matrix("U", &U);
dPrint_SuperNode_Matrix("L", &L);
print_int_vec("\nperm_r", m, perm_r);
dPrint_Dense_Matrix("B", &B);
SUPERLU_FREE(rhs);
SUPERLU_FREE(perm_r);
SUPERLU_FREE(perm_c);
Destroy_CompCol_Matrix(&A);
Destroy_SuperMatrix_Store(&B);
Destroy_SuperNode_Matrix(&L);
Destroy_CompCol_Matrix(&U);
StatFree(&stat);
getchar();
}
VS2017C++ const char* 类型的实参与char *类型的形参不兼容解决办法 解决方法 法1 将结构体中定义的 char * 前面加上 "const"修饰 法2 在Visual Studio 2019右侧栏创建的项目上右击“项目名称”——>“属性”——>“C/C++”——>“语言”,将“符合模式”改为“否”即可。如下所示: 再编译则可以成功 参考链接:https://blog.csdn.net/Santorinisu/article/details/80275557 https://blog.csdn.net/jingmiaa/article/details/52344057 https://blog.csdn.net/gindar/article/details/8010794
|