PETsc mpiaij 基质正在缩小,工艺数量增加

PETsc mpiaij matrix is shrinking with added number of processprs

提问人:HLTran 提问时间:2/26/2023 最后编辑:MikeCATHLTran 更新时间:5/18/2023 访问量:55

问:

我正在尝试使用 PETsc 进行一些矩阵矩阵乘法,但是如果我使用 mpiexec -n 增加进程数,则矩阵将小于进程数倍数的预期。 矩阵似乎也按行和列拆分块。如何更改它,使矩阵仅按行或列拆分?

这是我使用的代码:

static char help[] = "Matrix multiplication program.\n\n"; 
#include <petsc.h> 
#define ROOT 0
int main(int argc,char *argv[]) {
    Mat C,CCt;
    PetscMPIInt numNode, myNode;
    PetscInt i, j, iStart, iEnd, jStart, jEnd,  m = 8, n = 8;
    PetscScalar v;
    PetscRandom rnd;

    PetscCall(PetscInitialize(&argc,&argv,NULL,help));
    PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&numNode));
    PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&myNode));
    
    //random gen

    PetscCall(PetscRandomCreate(PETSC_COMM_WORLD,&rnd));
    PetscCall(PetscRandomSetSeed(rnd,12));

    //ininitalize Matrix
    PetscCall(MatCreate(PETSC_COMM_WORLD, &C));
    PetscCall(MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, m, n));
    PetscCall(MatSetFromOptions(C));
    PetscCall(MatSetUp(C));
    
    
    PetscCall(MatGetOwnershipRange(C, &iStart, &iEnd)); //return the range of row within local
    PetscCall(MatGetOwnershipRangeColumn(C,&jStart, &jEnd));
    PetscCall(PetscPrintf(PETSC_COMM_SELF,"Hello from %d local j range is %d to %d\n",myNode,jStart,jEnd));
    PetscCall(PetscPrintf(PETSC_COMM_SELF,"Hello from %d local i range is %d to %d\n",myNode,iStart,iEnd));
    //set values to matrix
    
    for (i = iStart; i < iEnd; i++) { //loop through all rows
        for (j = jStart; j < jEnd; j++){
            //PetscCall(PetscRandomGetValue(rnd,&v));
            v = 1;
            PetscCall(MatSetValues(C, 1, &i, 1, &j, &v, INSERT_VALUES));
        } 
    }
    
    

    PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
    PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
    
    //matrix mult
    PetscCall(MatMatTransposeMult(C,C,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CCt));

    //view matrix
    PetscCall(MatView(C,PETSC_VIEWER_STDOUT_WORLD));
    PetscCall(MatView(CCt,PETSC_VIEWER_STDOUT_WORLD));
    

    // Clean up
    PetscCall(MatDestroy(&C));
    PetscCall(MatDestroy(&CCt));
    PetscCall(PetscFinalize());
    return 0; 
}

如果我运行,那么这些将是预期的矩阵mpiexec -n 1 ./program

C matrix
Mat Object: 1 MPI process
  type: seqaij
row 0: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 1: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 2: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 3: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 4: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 5: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 6: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 7: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.)  (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.)

和 C*C 转置矩阵为

Mat Object: 1 MPI process
  type: seqaij
row 0: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 
row 1: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 
row 2: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 
row 3: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 
row 4: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 
row 5: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 
row 6: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 
row 7: (0, 8.)  (1, 8.)  (2, 8.)  (3, 8.)  (4, 8.)  (5, 8.)  (6, 8.)  (7, 8.) 

如果我运行这个,我会得到这些,并且列似乎正在根据进程的数量缩小:mpiexec -n 4

Mat Object: 4 MPI processes
  type: mpiaij
row 0: (0, 1.)  (1, 1.) 
row 1: (0, 1.)  (1, 1.) 
row 2: (2, 1.)  (3, 1.) 
row 3: (2, 1.)  (3, 1.) 
row 4: (4, 1.)  (5, 1.) 
row 5: (4, 1.)  (5, 1.) 
row 6: (6, 1.)  (7, 1.) 
row 7: (6, 1.)  (7, 1.) 
Mat Object: 4 MPI processes
  type: mpiaij
row 0: (0, 2.)  (1, 2.) 
row 1: (0, 2.)  (1, 2.) 
row 2: (2, 2.)  (3, 2.) 
row 3: (2, 2.)  (3, 2.) 
row 4: (4, 2.)  (5, 2.) 
row 5: (4, 2.)  (5, 2.) 
row 6: (6, 2.)  (7, 2.) 
row 7: (6, 2.)  (7, 2.)

mpiexec -n 2

Mat Object: 2 MPI processes
  type: mpiaij
row 0: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.) 
row 1: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.) 
row 2: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.) 
row 3: (0, 1.)  (1, 1.)  (2, 1.)  (3, 1.) 
row 4: (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 5: (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 6: (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
row 7: (4, 1.)  (5, 1.)  (6, 1.)  (7, 1.) 
Mat Object: 2 MPI processes
  type: mpiaij
row 0: (0, 4.)  (1, 4.)  (2, 4.)  (3, 4.) 
row 1: (0, 4.)  (1, 4.)  (2, 4.)  (3, 4.) 
row 2: (0, 4.)  (1, 4.)  (2, 4.)  (3, 4.) 
row 3: (0, 4.)  (1, 4.)  (2, 4.)  (3, 4.) 
row 4: (4, 4.)  (5, 4.)  (6, 4.)  (7, 4.) 
row 5: (4, 4.)  (5, 4.)  (6, 4.)  (7, 4.) 
row 6: (4, 4.)  (5, 4.)  (6, 4.)  (7, 4.) 
row 7: (4, 4.)  (5, 4.)  (6, 4.)  (7, 4.)
C++ C MPICH PETSC

评论


答:

0赞 HLTran 5/18/2023 #1

我发现 PETSc 只分布行而不是列,因此每个进程都获得了完整的列。因此,没有必要调用。虽然我不确定什么时候应该使用。MatGetOwnershipRangeColumn()MatGetOwnershipRangeColumn()

评论

1赞 Community 5/18/2023
您的答案可以通过额外的支持信息得到改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。