Reputation: 1
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
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