HLTran
HLTran

Reputation: 1

PETsc mpiaij matrix is shrinking with added number of processprs

I am trying to do some matrix matrix multiplication using PETsc but if I increase the number of processes using the mpiexec -n, the matrix would be smaller than expected by the factor of number of processes. The matrices seem to also be splitting blocks both by rows and columns. How do I change it such that the matrix is only split by either rows or columns only?

This is the code I used:

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; 
}

if I run mpiexec -n 1 ./program then these would be the expected matrices

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.)

and the C*Ctransposed matrix to be

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.) 

if I run mpiexec -n 4 this I got these instead, and the columns seem to be shrinking based on the number of processes:

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.)

Upvotes: 0

Views: 71

Answers (1)

HLTran
HLTran

Reputation: 1

I found that PETSc only distributes the rows and not columns, so each processes get the full range of the columns. Therefore, the call to MatGetOwnershipRangeColumn() was not necessary. Though I am not sure when MatGetOwnershipRangeColumn() should be used.

Upvotes: 0

Related Questions