petsc-master 2014-12-20
Report Typos and Errors


creates a MPI AIJ matrix using arrays that contain the "diagonal" and "off-diagonal" part of the matrix in CSR format.


#include "petscmat.h" 
PetscErrorCode  MatCreateMPIAIJWithSplitArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,PetscInt i[],PetscInt j[],PetscScalar a[],PetscInt oi[], PetscInt oj[],PetscScalar oa[],Mat *mat)
Collective on MPI_Comm

Input Parameters

comm - MPI communicator
m - number of local rows (Cannot be PETSC_DECIDE)
n - This value should be the same as the local size used in creating the x vector for the matrix-vector product y = Ax. (or PETSC_DECIDE to have calculated if N is given) For square matrices n is almost always m.
M - number of global rows (or PETSC_DETERMINE to have calculated if m is given)
N - number of global columns (or PETSC_DETERMINE to have calculated if n is given)
i - row indices for "diagonal" portion of matrix
j - column indices
a - matrix values
oi - row indices for "off-diagonal" portion of matrix
oj - column indices
oa - matrix values

Output Parameter

mat -the matrix


The i, j, and a arrays ARE NOT copied by this routine into the internal format used by PETSc. The user must free the arrays once the matrix has been destroyed and not before.

The i and j indices are 0 based

See MatCreateAIJ() for the definition of "diagonal" and "off-diagonal" portion of the matrix

This sets local rows and cannot be used to set off-processor values.

Use of this routine is discouraged because it is inflexible and cumbersome to use. It is extremely rare that a legacy application natively assembles into exactly this split format. The code to do so is nontrivial and does not easily support in-place reassembly. It is recommended to use MatSetValues() (or a variant thereof) because the resulting assembly is easier to implement, will work with any matrix format, and the user does not have to keep track of the underlying array. Use MatSetOption(A,MAT_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE) to disable all communication if it is known that only local entries will be set.


matrix, aij, compressed row, sparse, parallel

See Also

MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatMPIAIJSetPreallocation(), MatMPIAIJSetPreallocationCSR(),
MPIAIJ, MatCreateAIJ(), MatCreateMPIAIJWithArrays() C@*/ PetscErrorCode MatCreateMPIAIJWithSplitArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,PetscInt i[],PetscInt j[],PetscScalar a[],PetscInt oi[], PetscInt oj[],PetscScalar oa[],Mat *mat) { PetscErrorCode ierr; Mat_MPIAIJ *maij;

PetscFunctionBegin; if (m < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"local number of rows (m) cannot be PETSC_DECIDE, or negative"); if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); if (oi[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"oi (row indices) must start with 0"); ierr = MatCreate(comm,mat);CHKERRQ(ierr); ierr = MatSetSizes(*mat,m,n,M,N);CHKERRQ(ierr); ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr); maij = (Mat_MPIAIJ*) (*mat)->data;

(*mat)->preallocated = PETSC_TRUE;

ierr = PetscLayoutSetUp((*mat)->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp((*mat)->cmap);CHKERRQ(ierr);

ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,m,n,i,j,a,&maij->A);CHKERRQ(ierr); ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,m,(*mat)->cmap->N,oi,oj,oa,&maij->B);CHKERRQ(ierr);

ierr = MatAssemblyBegin(maij->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(maij->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(maij->B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(maij->B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatSetOption(*mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); PetscFunctionReturn(0); }

/* Special version for direct calls from Fortran */ #include <petsc-private/fortranimpl.h>

#if defined(PETSC_HAVE_FORTRAN_CAPS) #define matsetvaluesmpiaij_ MATSETVALUESMPIAIJ #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) #define matsetvaluesmpiaij_ matsetvaluesmpiaij #endif

/* Change these macros so can be used in void function */ #undef CHKERRQ #define CHKERRQ(ierr) CHKERRABORT(PETSC_COMM_WORLD,ierr) #undef SETERRQ2 #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) #undef SETERRQ3 #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) #undef SETERRQ #define SETERRQ(c,ierr,b) CHKERRABORT(c,ierr)

#undef __FUNCT__ #define __FUNCT__ "matsetvaluesmpiaij_" PETSC_EXTERN void PETSC_STDCALL matsetvaluesmpiaij_(Mat *mmat,PetscInt *mm,const PetscInt im[],PetscInt *mn,const PetscInt in[],const PetscScalar v[],InsertMode *maddv,PetscErrorCode *_ierr) { Mat mat = *mmat; PetscInt m = *mm, n = *mn; InsertMode addv = *maddv; Mat_MPIAIJ *aij = (Mat_MPIAIJ*)mat->data; PetscScalar value; PetscErrorCode ierr;

MatCheckPreallocated(mat,1); if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv;

#if defined(PETSC_USE_DEBUG) else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); #endif { PetscInt i,j,rstart = mat->rmap->rstart,rend = mat->rmap->rend; PetscInt cstart = mat->cmap->rstart,cend = mat->cmap->rend,row,col; PetscBool roworiented = aij->roworiented;

/* Some Variables required in the macro */ Mat A = aij->A; Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; PetscInt *aimax = a->imax,*ai = a->i,*ailen = a->ilen,*aj = a->j; MatScalar *aa = a->a; PetscBool ignorezeroentries = (((a->ignorezeroentries)&&(addv==ADD_VALUES)) ? PETSC_TRUE : PETSC_FALSE); Mat B = aij->B; Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; PetscInt *bimax = b->imax,*bi = b->i,*bilen = b->ilen,*bj = b->j,bm = aij->B->rmap->n,am = aij->A->rmap->n; MatScalar *ba = b->a;

PetscInt *rp1,*rp2,ii,nrow1,nrow2,_i,rmax1,rmax2,N,low1,high1,low2,high2,t,lastcol1,lastcol2; PetscInt nonew = a->nonew; MatScalar *ap1,*ap2;

PetscFunctionBegin; for (i=0; i<m; i++) { if (im[i] < 0) continue; #if defined(PETSC_USE_DEBUG) if (im[i] >= mat->rmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",im[i],mat->rmap->N-1); #endif if (im[i] >= rstart && im[i] < rend) { row = im[i] - rstart; lastcol1 = -1; rp1 = aj + ai[row]; ap1 = aa + ai[row]; rmax1 = aimax[row]; nrow1 = ailen[row]; low1 = 0; high1 = nrow1; lastcol2 = -1; rp2 = bj + bi[row]; ap2 = ba + bi[row]; rmax2 = bimax[row]; nrow2 = bilen[row]; low2 = 0; high2 = nrow2;

for (j=0; j<n; j++) { if (roworiented) value = v[i*n+j]; else value = v[i+j*m]; if (ignorezeroentries && value == 0.0 && (addv == ADD_VALUES)) continue; if (in[j] >= cstart && in[j] < cend) { col = in[j] - cstart; MatSetValues_SeqAIJ_A_Private(row,col,value,addv); } else if (in[j] < 0) continue; #if defined(PETSC_USE_DEBUG) else if (in[j] >= mat->cmap->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[j],mat->cmap->N-1); #endif else { if (mat->was_assembled) { if (!aij->colmap) { ierr = MatCreateColmap_MPIAIJ_Private(mat);CHKERRQ(ierr); } #if defined(PETSC_USE_CTABLE) ierr = PetscTableFind(aij->colmap,in[j]+1,&col);CHKERRQ(ierr); col--; #else col = aij->colmap[in[j]] - 1; #endif if (col < 0 && !((Mat_SeqAIJ*)(aij->A->data))->nonew) { ierr = MatDisAssemble_MPIAIJ(mat);CHKERRQ(ierr); col = in[j]; /* Reinitialize the variables required by MatSetValues_SeqAIJ_B_Private() */ B = aij->B; b = (Mat_SeqAIJ*)B->data; bimax = b->imax; bi = b->i; bilen = b->ilen; bj = b->j; rp2 = bj + bi[row]; ap2 = ba + bi[row]; rmax2 = bimax[row]; nrow2 = bilen[row]; low2 = 0; high2 = nrow2; bm = aij->B->rmap->n; ba = b->a; } } else col = in[j]; MatSetValues_SeqAIJ_B_Private(row,col,value,addv); } } } else if (!aij->donotstash) { if (roworiented) { ierr = MatStashValuesRow_Private(&mat->stash,im[i],n,in,v+i*n,(PetscBool)(ignorezeroentries && (addv == ADD_VALUES)));CHKERRQ(ierr); } else { ierr = MatStashValuesCol_Private(&mat->stash,im[i],n,in,v+i,m,(PetscBool)(ignorezeroentries && (addv == ADD_VALUES)));CHKERRQ(ierr); } } } } PetscFunctionReturnVoid(); }

Index of all Mat routines
Table of Contents for all manual pages
Index of all manual pages