[petsc-dev] Join A and B seq matrices of a mpi matrix.

Barry Smith bsmith at mcs.anl.gov
Tue Sep 17 20:47:43 CDT 2013


  Don't worry about the extra memory of the copy; LU factorizations take much more space than the original matrix so this "duplicate" matrix is no big deal. At least to start, later if profiling shows it is a problem you could create a new matrix class that is already "joined" and feed that directly to cpardiso.

   Barry

On Sep 17, 2013, at 5:35 PM, Jose David Bermeol <jbermeol at purdue.edu> wrote:

> Hi, right now I'm coding a solver for MATMPIAIJ matrices, as you know this kind of matrix has a diagonal matrix A of size n x n and a matrix B with the off-diagonal matrices of size n x (N - n). The problem is that my solver for each MPI process receive 3 arrays that represents the rows in the MPI process(aij format), that means the complete n x N matrix.
> 
> What I did was a join of the A and B matrix, however this implies almost to duplicate everything in memory. 
> 
> I don't know if you know a better strategy for this(less memory overhead). Thanks
> 
> Here is my code if you see something that can be improve:
> 
> /*
> * MATMPIAIJ matrices are divided in two matrices,
> * diagonal matrix(A) and off-diagonal matrix(B),
> * both in aij format, as cpardiso only recives one matrix,
> * this method will join A and B matrix in one, return aij
> * representation and number of non-zero elements.
> *
> * This method will copy(duplicate) A and B elements in a new matrix.
> *
> * Input:
> * 		- Mat A: MATMPIAIJ matrix
> * 		- int shift: matrix index.(cpardiso requires fortan indexing)
> * 			- 0 for c representation
> * 			- 1 for fortran representation
> * 		- MatReuse reuse:
> * 			- MAT_INITIAL_MATRIX: Create a new aij representation
> * 			- MAT_REUSE_MATRIX: Reuse all aij representation and just change values
> * 	Output:
> * 		- int *nnz: Number of nonzero-elements.
> * 		- int **r pointer to i index
> * 		- int **c pointer to j elements
> * 		- PetscScalar **v: Non-zero elements
> */
> #undef __FUNCT__
> #define __FUNCT__ "MatJoin_CPARDISO"
> PetscErrorCode MatJoin_CPARDISO(Mat A, int shift, MatReuse reuse, int *nnz, int **r, int **c, PetscScalar **v){
> 
>  const PetscInt    *ai, *aj, *bi, *bj, *garray, m=A->rmap->n, *ajj, *bjj;
>  PetscErrorCode    ierr;
>  PetscInt          rstart, nz, i, jj, countA, countB, idxA, idxB;
>  PetscInt          *row,*col;
>  const PetscScalar *av, *bv,*v1,*v2;
>  PetscScalar       *val;
>  Mat_MPIAIJ        *mat = (Mat_MPIAIJ*)A->data;
>  Mat_SeqAIJ        *aa  = (Mat_SeqAIJ*)(mat->A)->data;
>  Mat_SeqAIJ        *bb  = (Mat_SeqAIJ*)(mat->B)->data;
> 
>  PetscFunctionBegin;
>  ai=aa->i; aj=aa->j; bi=bb->i; bj=bb->j; rstart= A->rmap->rstart;
>  av=aa->a; bv=bb->a;
> 
>  garray = mat->garray;
> 
>  if (reuse == MAT_INITIAL_MATRIX) {
>    nz   = aa->nz + bb->nz;
>    *nnz = nz;
>    ierr = PetscMalloc(((nz + m + 1)*sizeof(PetscInt) + nz*sizeof(PetscScalar)), &row);CHKERRQ(ierr);
>    col  = row + m + 1;
>    val  = (PetscScalar*)(col + nz);
> 
>    *r = row; *c = col; *v = val;
>  } else {
>    row = *r; col = *c; val = *v;
>  }
> 
>  jj = 0;
>  for (i=0; i<m; i++) {
> 
>    countA = ai[i+1] - ai[i];
>    countB = bi[i+1] - bi[i];
>    ajj    = aj + ai[i];
>    bjj    = bj + bi[i];
>    v1     = av + ai[i];
>    v2     = bv + bi[i];
> 
>    if(reuse == MAT_INITIAL_MATRIX){
>      row[i] = jj + shift;
>    }
>    idxA = 0; idxB = 0;
> 
>    if(countA + countB == 0){
>    } else if(countB == 0){
>      for (idxA = 0; idxA < countA; idxA++) {
>        if(reuse == MAT_INITIAL_MATRIX){
>          col[jj] = rstart + ajj[idxA] + shift;
>        }
>        val[jj] = v1[idxA];
>        jj++;
>      }
>    } else if(countA == 0){
>      for (idxB = 0; idxB < countB; idxB++) {
>        if(reuse == MAT_INITIAL_MATRIX){
>          col[jj] = garray[bjj[idxB]] + shift;
>        }
>        val[jj] = v2[idxB];
>        jj++;
>      }
>    } else {
>      while(rstart + ajj[idxA] > garray[bjj[idxB]]){
>    	if(reuse == MAT_INITIAL_MATRIX){
>          col[jj] = garray[bjj[idxB]] + shift;
>    	}
>        val[jj] = v2[idxB];
>    	idxB++;
>    	jj++;
>      }
> 
>      for (idxA = 0; idxA < countA; idxA++) {
>        if(reuse == MAT_INITIAL_MATRIX){
>    	  col[jj] = rstart + ajj[idxA] + shift;
>    	}
>        val[jj] = v1[idxA];
>  	jj++;
>      }
> 
>      for (; idxB < countB; idxB++) {
>        if(reuse == MAT_INITIAL_MATRIX){
>          col[jj] = garray[bjj[idxB]] + shift;
>        }
>        val[jj] = v2[idxB];
>        jj++;
>      }
>    }
>  }
>  if(reuse == MAT_INITIAL_MATRIX){
>    row[m] = jj + shift;
>  }
>  PetscFunctionReturn(0);
> }
> 
> 
> 




More information about the petsc-dev mailing list