鲲鹏社区首页
中文
注册
开发者
我要评分
获取效率
正确性
完整性
易理解
在线提单
论坛求助

集群版

可替换性

用户通过给结构体中的变量赋值控制求解过程,可以通过给JOB参数赋不同的值控制MUMPS执行的具体操作,控制MUMPS求解功能的主要参数还包括数组ICNTL和CNTL。另一方面,用户可以通过结构体获取最中间或者最终的求解结果。当前KML_SCASOLVER支持多节点多进程多线程,可以替代MUMPS的多节点多进程功能。当前已实现double类型的MUMPS接口,JOB参数为-1、-2、1、2、3、6,支持一般矩阵、对称正定矩阵和一般对称矩阵。

迁移步骤

MUMPS提供C接口,KML_SCASOLVER同样也提供了C接口,直接进行适配层的迁移。

  1. 将#include "dmumps_c.h"改为#include "MUMPS_kp.h"。
  2. 通过加载HPCkit相关环境变量,设置KML求解器适配器的头文件MUMPS_kp.h所在路径和kscasolver态库路径,具体加载方式可参见《Kunpeng HPCKit 25.2.0 安装指南》中“设置环境变量”章节,然后在适配层当前目录下生成适配层动态库。
    mpicc dmumps_kunpeng.c -o libdmumps.so  -lkscasolver --shared -fPIC
  3. 重新编译应用,
    mpicc program.c  -ldmumps  -lkscasolver -lkservice -lklapack_full  -lkblas  -lkm -lm

迁移前后,mumps的初始化接口与使用KML适配层的初始化接口不一样,mumps的初始化在传入A矩阵之前,而KML适配层需要在传入A矩阵之后。

迁移前
 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
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "dmumps_c.h"
int main ( int argc , char**argv ) {
    DMUMPS_STRUC_C id ;
    int n = 2;
    int64_t nnz = 2;
    int irn[] = { 1, 2 }; // MUMPS只支持COO存储格式
    int jcn[] = { 1, 2 };
    double *a = (double *)malloc(2*sizeof(double));
    double *rhs = (double *)malloc(2*sizeof(double));
    //double a[2];
    //double rhs[2];
    double sol[] = {0, 0};
    int myid, ierr;
    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 MUMPS instance.Use MPI COMM WORLD.*/ 
    id.job = JOB_INIT;
    id.par = 1;
    id.sym = 0;
    id.comm_fortran = USE_COMM_WORLD;
    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;
    }

#define ICNTL(I) icntl[(I)-1] /*macro s.t.indices match documentation*/ /*No outputs */ 
    id.ICNTL(1) = -1;
    id.ICNTL(2) = -1;
    id.ICNTL(3) = -1;
    id.ICNTL(4) = 0;
    /*Call the MUMPS package.*/ 
    id.job = 6; //Analyze + Factorize + Solve
    dmumps_c(&id);
    id.job = JOB_END;
    dmumps_c(&id);
    /*Terminate instance */ if (myid == 0)
    {
        printf( " Solution is : (%8.2f %8.2f)\n", rhs[0], rhs[1]);
    }
    ierr = MPI_Finalize();
    return 0;
}
迁移后
 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
48
49
50
51
52
53
54
55
56
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "MUMPS_kp.h"
int main ( int argc , char**argv ) {
    DMUMPS_STRUC_C id ;
    int n = 2;
    int64_t nnz = 2;
    int irn[] = { 1, 2 }; // MUMPS只支持COO存储格式
    int jcn[] = { 1, 2 };
    double *a = (double *)malloc(2*sizeof(double));
    double *rhs = (double *)malloc(2*sizeof(double));
    //double a[2];
    //double rhs[2];
    double sol[] = {0, 0};
    int myid, ierr;
    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 MUMPS instance.Use MPI COMM WORLD.*/ 
    id.job = JOB_INIT;
    id.par = 1;
    id.sym = 0;
    id.comm_fortran = USE_COMM_WORLD;   
    if (myid == 0)
    {
        id.n = n;
        id.nnz = nnz;
        id.irn = irn;
        id.jcn = jcn;
        id.a = a;
        id.rhs = rhs;
    }
    dmumps_c(&id); /*Define the problem on the host */ 

#define ICNTL(I) icntl[(I)-1] /*macro s.t.indices match documentation*/ /*No outputs */ 
    id.ICNTL(1) = -1;
    id.ICNTL(2) = -1;
    id.ICNTL(3) = -1;
    id.ICNTL(4) = 0;
    /*Call the MUMPS package.*/ 
    id.job = 6; //Analyze + Factorize + Solve
    dmumps_c(&id);
    id.job = JOB_END;
    dmumps_c(&id);
    /*Terminate instance */ if (myid == 0)
    {
        printf( " Solution is : (%8.2f %8.2f)\n", rhs[0], rhs[1]);
    }
    ierr = MPI_Finalize();
    return 0;
}

示例

迁移前后,mumps的初始化接口与使用KML适配层的初始化接口不一样,mumps的初始化在传入A矩阵之前,而KML适配层需要在传入A矩阵之后。

迁移前
 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
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "dmumps_c.h"
int main ( int argc , char**argv ) {
    DMUMPS_STRUC_C id ;
    int n = 2;
    int64_t nnz = 2;
    int irn[] = { 1, 2 }; // MUMPS只支持COO存储格式
    int jcn[] = { 1, 2 };
    double *a = (double *)malloc(2*sizeof(double));
    double *rhs = (double *)malloc(2*sizeof(double));
    //double a[2];
    //double rhs[2];
    double sol[] = {0, 0};
    int myid, ierr;
    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 MUMPS instance.Use MPI COMM WORLD.*/ 
    id.job = JOB_INIT;
    id.par = 1;
    id.sym = 0;
    id.comm_fortran = USE_COMM_WORLD;
    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;
    }

#define ICNTL(I) icntl[(I)-1] /*macro s.t.indices match documentation*/ /*No outputs */ 
    id.ICNTL(1) = -1;
    id.ICNTL(2) = -1;
    id.ICNTL(3) = -1;
    id.ICNTL(4) = 0;
    /*Call the MUMPS package.*/ 
    id.job = 6; //Analyze + Factorize + Solve
    dmumps_c(&id);
    id.job = JOB_END;
    dmumps_c(&id);
    /*Terminate instance */ if (myid == 0)
    {
        printf( " Solution is : (%8.2f %8.2f)\n", rhs[0], rhs[1]);
    }
    ierr = MPI_Finalize();
    return 0;
}
迁移后
 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
48
49
50
51
52
53
54
55
56
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "MUMPS_kp.h"
int main ( int argc , char**argv ) {
    DMUMPS_STRUC_C id ;
    int n = 2;
    int64_t nnz = 2;
    int irn[] = { 1, 2 }; // MUMPS只支持COO存储格式
    int jcn[] = { 1, 2 };
    double *a = (double *)malloc(2*sizeof(double));
    double *rhs = (double *)malloc(2*sizeof(double));
    //double a[2];
    //double rhs[2];
    double sol[] = {0, 0};
    int myid, ierr;
    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 MUMPS instance.Use MPI COMM WORLD.*/ 
    id.job = JOB_INIT;
    id.par = 1;
    id.sym = 0;
    id.comm_fortran = USE_COMM_WORLD;   
    if (myid == 0)
    {
        id.n = n;
        id.nnz = nnz;
        id.irn = irn;
        id.jcn = jcn;
        id.a = a;
        id.rhs = rhs;
    }
    dmumps_c(&id); /*Define the problem on the host */ 

#define ICNTL(I) icntl[(I)-1] /*macro s.t.indices match documentation*/ /*No outputs */ 
    id.ICNTL(1) = -1;
    id.ICNTL(2) = -1;
    id.ICNTL(3) = -1;
    id.ICNTL(4) = 0;
    /*Call the MUMPS package.*/ 
    id.job = 6; //Analyze + Factorize + Solve
    dmumps_c(&id);
    id.job = JOB_END;
    dmumps_c(&id);
    /*Terminate instance */ if (myid == 0)
    {
        printf( " Solution is : (%8.2f %8.2f)\n", rhs[0], rhs[1]);
    }
    ierr = MPI_Finalize();
    return 0;
}