Windows下编译 Mumps Solver
简介
MUMPS Solver 是一种用于求解大规模线性方程组的开源软件,Mumps官网:https://mumps-solver.org,获取 MUMPS Solver 源代码可在https://mumps-solver.org/index.php?page=dwnld 提交信息后获取。
编译前提
- cmake
- ninja 编译器
- OneApi_base_toolkit —提供C、C++编译器与 MKL
- OneApi_hpc_toolkit —提供Fortran编译器与 MPI
相关文档
- Mumps官方用户手册: https://mumps-solver.org/doc/userguide_5.6.0.pdf
- Cmake编译说明文档:https://github.com/scivision/mumps/blob/main/Readme_Windows.md
- 编译成功后项目集成使用文档: https://github.com/scivision/mumps/issues/3
编译过程
-
克隆仓库到本地:
git clone https://github.com/scivision/mumps.git
-
使用 oneApi 命令行环境以获取对应环境变量、可通过以下两种方式:
a. 开始菜单找到Intel oneAPI command prompt for Intel 64 for Visual Studio
右键以管理员身份打开
b. 任意管理员权限cmd 窗口输入C:\Program Files (x86)\Intel\oneAPI\setvars.bat
-
进到源码仓库目录
cd /d D:\mumps\mumps-5.6.0.0
-
执行编译命令
cmake -G Ninja -B build -DBUILD_SINGLE=yes -DBUILD_DOUBLE=yes -DBUILD_COMPLEX=yes -DBUILD_COMPLEX16=yes
在输出无任何报错的情况下
cmake --build build
-
运行测试
ctest --test-dir build
-
此时需注意生成的lib文件在build目录下还不能直接用于项目、需要执行安装命令
cmake –install build
会将对应库文件与头文件安装到路径C:\Program Files (x86)\MUMPS
下 -
新建 example 目录、放入以下文件
a. d_example.c1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79/*
*
* This file is part of MUMPS 5.5.1, released
* on Tue Jul 12 13:17:24 UTC 2022
*
*/
/* Example program using the C interface to the
* double real arithmetic version of MUMPS, dmumps_c.
* We solve the system A x = RHS with
* A = diag(1 2) and RHS = [1 4]^T
* Solution is [1 2]^T */
int main(int argc, char ** argv)
{
DMUMPS_STRUC_C id;
MUMPS_INT n = 2;
MUMPS_INT8 nnz = 2;
MUMPS_INT irn[] = {1,2};
MUMPS_INT jcn[] = {1,2};
double a[2];
double rhs[2];
/* When compiling with -DINTSIZE64, MUMPS_INT is 64-bit but MPI
ilp64 versions may still require standard int for C interface. */
/* MUMPS_INT myid, ierr; */
int myid, ierr;
int error = 0;
ierr = MPI_Init(&argc, &argv);
ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* Define A and rhs */
rhs[0]=1.0;rhs[1]=4.0;
a[0]=1.0;a[1]=2.0;
/* Initialize a MUMPS instance. Use MPI_COMM_WORLD */
id.comm_fortran=USE_COMM_WORLD;
id.par=1; id.sym=0;
id.job=JOB_INIT;
dmumps_c(&id);
/* Define the problem on the host */
if (myid == 0) {
id.n = n; id.nnz =nnz; id.irn=irn; id.jcn=jcn;
id.a = a; id.rhs = rhs;
}
/* No outputs */
id.ICNTL(1)=-1; id.ICNTL(2)=-1; id.ICNTL(3)=-1; id.ICNTL(4)=0;
/* Call the MUMPS package (analyse, factorization and solve). */
id.job=6;
dmumps_c(&id);
if (id.infog[0]<0) {
printf(" (PROC %d) ERROR RETURN: \tINFOG(1)= %d\n\t\t\t\tINFOG(2)= %d\n",
myid, id.infog[0], id.infog[1]);
error = 1;
}
/* Terminate instance. */
id.job=JOB_END;
dmumps_c(&id);
if (myid == 0) {
if (!error) {
printf("Solution is : (%8.2f %8.2f)\n", rhs[0],rhs[1]);
} else {
printf("An error has occured, please check error code returned by MUMPS.\n");
}
}
ierr = MPI_Finalize();
return 0;
}b. CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48cmake_minimum_required(VERSION 3.13...3.25)
project(MUMPSExamples
LANGUAGES C Fortran
)
enable_testing()
if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU|Intel")
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Werror-implicit-function-declaration>)
endif()
if(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
file(GENERATE OUTPUT .gitignore CONTENT "*")
endif()
find_package(MUMPS CONFIG REQUIRED)
message(STATUS "MUMPS_DIR: ${MUMPS_DIR}")
function(precision_ex a)
add_executable(${a}_example ${a}_example.c)
target_link_libraries(${a}_example PRIVATE MUMPS::MUMPS)
if(MUMPS_parallel)
add_test(NAME ${a}_example_C
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 $<TARGET_FILE:${a}_example>)
else()
add_test(NAME ${a}_example_C COMMAND ${a}_example)
endif()
endfunction()
if(MUMPS_d_FOUND)
precision_ex("d")
endif()
# test properties
get_property(test_names DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY TESTS)
if(MUMPS_parallel)
set_property(TEST ${test_names} PROPERTY RESOURCE_LOCK cpu_mpi)
endif()
if(WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)
get_property(imp_mumps TARGET MUMPS::COMMON PROPERTY IMPORTED_LOCATION_RELEASE)
if(imp_mumps)
get_filename_component(imp_mumps_dir ${imp_mumps} DIRECTORY)
endif()
set_property(TEST ${test_names} PROPERTY ENVIRONMENT_MODIFICATION "PATH=path_list_append:${imp_mumps_dir};PATH=path_list_append:${CMAKE_PREFIX_PATH}/bin")
endif() -
在
oneapi
命令行环境进入到example
路径、执行
cmake -B build -DMUMPS_ROOT="C:\Program Files (x86)\MUMPS"
-
生成可执行程序
a. 执行cmake --build build
b. 到build
目录下用 Visual Studio 打开sln
工程文件执行生成 -
执行生成的
d_example.exe
查看输出是否为
Solution is : ( 1.00 2.00)
集成 Metis 库
- 在编译
mumps
之前需要编译metis
cmake -Dprefix=d:\mumps\metis -P scripts\build_metis.cmake
- 编译
mumps
cmake -G Ninja -B build -DBUILD_SINGLE=yes -DBUILD_DOUBLE=yes -DBUILD_COMPLEX=yes -DBUILD_COMPLEX16=yes -DCMAKE_PREFIX_PATH=d:\mumps\metis -Dmetis=on