1b97cf49bSBarry Smith #ifdef PETSC_RCS_HEADER 2*4bc6d8c0SBarry Smith static char vcid[] = "$Id: mpiadj.c,v 1.13 1998/05/29 20:37:39 bsmith Exp bsmith $"; 3b97cf49bSBarry Smith #endif 4b97cf49bSBarry Smith 5b97cf49bSBarry Smith /* 6b97cf49bSBarry Smith Defines the basic matrix operations for the ADJ adjacency list matrix data-structure. 7b97cf49bSBarry Smith */ 8b97cf49bSBarry Smith 9b97cf49bSBarry Smith #include "pinclude/pviewer.h" 10b97cf49bSBarry Smith #include "sys.h" 110752156aSBarry Smith #include "src/mat/impls/adj/mpi/mpiadj.h" 12b97cf49bSBarry Smith 13b97cf49bSBarry Smith 14b97cf49bSBarry Smith #undef __FUNC__ 150752156aSBarry Smith #define __FUNC__ "MatView_MPIAdj_ASCII" 160752156aSBarry Smith extern int MatView_MPIAdj_ASCII(Mat A,Viewer viewer) 17b97cf49bSBarry Smith { 180752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 19b97cf49bSBarry Smith int ierr, i,j, m = a->m, format; 20b97cf49bSBarry Smith FILE *fd; 21b97cf49bSBarry Smith char *outputname; 220752156aSBarry Smith MPI_Comm comm = A->comm; 23b97cf49bSBarry Smith 24b97cf49bSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 25b97cf49bSBarry Smith ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr); 26b97cf49bSBarry Smith ierr = ViewerGetFormat(viewer,&format); 27b97cf49bSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO) { 283a40ed3dSBarry Smith PetscFunctionReturn(0); 290752156aSBarry Smith } else { 30b97cf49bSBarry Smith for ( i=0; i<m; i++ ) { 310752156aSBarry Smith PetscSynchronizedFPrintf(comm,fd,"row %d:",i+a->rstart); 32b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 330752156aSBarry Smith PetscSynchronizedFPrintf(comm,fd," %d ",a->j[j]); 340752156aSBarry Smith } 350752156aSBarry Smith PetscSynchronizedFPrintf(comm,fd,"\n"); 36b97cf49bSBarry Smith } 37b97cf49bSBarry Smith } 380752156aSBarry Smith PetscSynchronizedFlush(comm); 393a40ed3dSBarry Smith PetscFunctionReturn(0); 40b97cf49bSBarry Smith } 41b97cf49bSBarry Smith 42b97cf49bSBarry Smith #undef __FUNC__ 430752156aSBarry Smith #define __FUNC__ "MatView_MPIAdj" 44e1311b90SBarry Smith int MatView_MPIAdj(Mat A,Viewer viewer) 45b97cf49bSBarry Smith { 46b97cf49bSBarry Smith ViewerType vtype; 47b97cf49bSBarry Smith int ierr; 48b97cf49bSBarry Smith 49b97cf49bSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 500752156aSBarry Smith if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){ 513a40ed3dSBarry Smith ierr = MatView_MPIAdj_ASCII(A,viewer);CHKERRQ(ierr); 525cd90555SBarry Smith } else { 535cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 54b97cf49bSBarry Smith } 553a40ed3dSBarry Smith PetscFunctionReturn(0); 56b97cf49bSBarry Smith } 57b97cf49bSBarry Smith 58b97cf49bSBarry Smith #undef __FUNC__ 590752156aSBarry Smith #define __FUNC__ "MatDestroy_MPIAdj" 6094d884c6SBarry Smith int MatDestroy_MPIAdj(Mat mat) 61b97cf49bSBarry Smith { 6294d884c6SBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) mat->data; 6394d884c6SBarry Smith int ierr; 6494d884c6SBarry Smith 6594d884c6SBarry Smith PetscFunctionBegin; 6694d884c6SBarry Smith if (--mat->refct > 0) PetscFunctionReturn(0); 6794d884c6SBarry Smith 6894d884c6SBarry Smith if (mat->mapping) { 6994d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->mapping); CHKERRQ(ierr); 7094d884c6SBarry Smith } 7194d884c6SBarry Smith if (mat->bmapping) { 7294d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->bmapping); CHKERRQ(ierr); 7394d884c6SBarry Smith } 74b97cf49bSBarry Smith 753a40ed3dSBarry Smith #if defined(USE_PETSC_LOG) 7694d884c6SBarry Smith PLogObjectState((PetscObject)mat,"Rows=%d, Cols=%d, NZ=%d",mat->m,mat->n,a->nz); 77b97cf49bSBarry Smith #endif 78b97cf49bSBarry Smith if (a->diag) PetscFree(a->diag); 79b97cf49bSBarry Smith PetscFree(a->i); 80b97cf49bSBarry Smith PetscFree(a->j); 810752156aSBarry Smith PetscFree(a->rowners); 82b97cf49bSBarry Smith PetscFree(a); 83b97cf49bSBarry Smith 8494d884c6SBarry Smith PLogObjectDestroy(mat); 8594d884c6SBarry Smith PetscHeaderDestroy(mat); 863a40ed3dSBarry Smith PetscFunctionReturn(0); 87b97cf49bSBarry Smith } 88b97cf49bSBarry Smith 89b97cf49bSBarry Smith 90b97cf49bSBarry Smith #undef __FUNC__ 910752156aSBarry Smith #define __FUNC__ "MatSetOption_MPIAdj" 920752156aSBarry Smith int MatSetOption_MPIAdj(Mat A,MatOption op) 93b97cf49bSBarry Smith { 940752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 95b97cf49bSBarry Smith 96b97cf49bSBarry Smith if (op == MAT_STRUCTURALLY_SYMMETRIC) { 97b97cf49bSBarry Smith a->symmetric = PETSC_TRUE; 98b97cf49bSBarry Smith } else { 99981c4779SBarry Smith PLogInfo(A,"MatSetOption_MPIAdj:Option ignored\n"); 100b97cf49bSBarry Smith } 1013a40ed3dSBarry Smith PetscFunctionReturn(0); 102b97cf49bSBarry Smith } 103b97cf49bSBarry Smith 104b97cf49bSBarry Smith 105b97cf49bSBarry Smith /* 106b97cf49bSBarry Smith Adds diagonal pointers to sparse matrix structure. 107b97cf49bSBarry Smith */ 108b97cf49bSBarry Smith 109b97cf49bSBarry Smith #undef __FUNC__ 1100752156aSBarry Smith #define __FUNC__ "MatMarkDiag_MPIAdj" 1110752156aSBarry Smith int MatMarkDiag_MPIAdj(Mat A) 112b97cf49bSBarry Smith { 1130752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 114b97cf49bSBarry Smith int i,j, *diag, m = a->m; 115b97cf49bSBarry Smith 116b97cf49bSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 117b97cf49bSBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 118b97cf49bSBarry Smith for ( i=0; i<a->m; i++ ) { 119b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 120b97cf49bSBarry Smith if (a->j[j] == i) { 121b97cf49bSBarry Smith diag[i] = j; 122b97cf49bSBarry Smith break; 123b97cf49bSBarry Smith } 124b97cf49bSBarry Smith } 125b97cf49bSBarry Smith } 126b97cf49bSBarry Smith a->diag = diag; 1273a40ed3dSBarry Smith PetscFunctionReturn(0); 128b97cf49bSBarry Smith } 129b97cf49bSBarry Smith 130b97cf49bSBarry Smith #undef __FUNC__ 1310752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj" 1320752156aSBarry Smith int MatGetSize_MPIAdj(Mat A,int *m,int *n) 133b97cf49bSBarry Smith { 1340752156aSBarry Smith if (m) *m = A->M; 1350752156aSBarry Smith if (n) *n = A->N; 1363a40ed3dSBarry Smith PetscFunctionReturn(0); 137b97cf49bSBarry Smith } 138b97cf49bSBarry Smith 139b97cf49bSBarry Smith #undef __FUNC__ 1400752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj" 1410752156aSBarry Smith int MatGetLocalSize_MPIAdj(Mat A,int *m,int *n) 142b97cf49bSBarry Smith { 1430752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 1440752156aSBarry Smith if (m) *m = a->m; 1450752156aSBarry Smith if (n) *n = A->N; 1463a40ed3dSBarry Smith PetscFunctionReturn(0); 147b97cf49bSBarry Smith } 148b97cf49bSBarry Smith 149b97cf49bSBarry Smith #undef __FUNC__ 1500752156aSBarry Smith #define __FUNC__ "MatGetOwnershipRange_MPIAdj" 1510752156aSBarry Smith int MatGetOwnershipRange_MPIAdj(Mat A,int *m,int *n) 152b97cf49bSBarry Smith { 1530752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 1540752156aSBarry Smith *m = a->rstart; *n = a->rend; 1553a40ed3dSBarry Smith PetscFunctionReturn(0); 156b97cf49bSBarry Smith } 157b97cf49bSBarry Smith 158b97cf49bSBarry Smith #undef __FUNC__ 1590752156aSBarry Smith #define __FUNC__ "MatGetRow_MPIAdj" 1600752156aSBarry Smith int MatGetRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v) 161b97cf49bSBarry Smith { 1620752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 163b97cf49bSBarry Smith int *itmp; 164b97cf49bSBarry Smith 1650752156aSBarry Smith row -= a->rstart; 1660752156aSBarry Smith 167a8c6a408SBarry Smith if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 168b97cf49bSBarry Smith 169b97cf49bSBarry Smith *nz = a->i[row+1] - a->i[row]; 170b97cf49bSBarry Smith if (v) *v = PETSC_NULL; 171b97cf49bSBarry Smith if (idx) { 172b97cf49bSBarry Smith itmp = a->j + a->i[row]; 173b97cf49bSBarry Smith if (*nz) { 174b97cf49bSBarry Smith *idx = itmp; 175b97cf49bSBarry Smith } 176b97cf49bSBarry Smith else *idx = 0; 177b97cf49bSBarry Smith } 1783a40ed3dSBarry Smith PetscFunctionReturn(0); 179b97cf49bSBarry Smith } 180b97cf49bSBarry Smith 181b97cf49bSBarry Smith #undef __FUNC__ 1820752156aSBarry Smith #define __FUNC__ "MatRestoreRow_MPIAdj" 1830752156aSBarry Smith int MatRestoreRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v) 184b97cf49bSBarry Smith { 1853a40ed3dSBarry Smith PetscFunctionReturn(0); 186b97cf49bSBarry Smith } 187b97cf49bSBarry Smith 188b97cf49bSBarry Smith #undef __FUNC__ 1890752156aSBarry Smith #define __FUNC__ "MatGetBlockSize_MPIAdj" 1900752156aSBarry Smith int MatGetBlockSize_MPIAdj(Mat A, int *bs) 191b97cf49bSBarry Smith { 192b97cf49bSBarry Smith *bs = 1; 1933a40ed3dSBarry Smith PetscFunctionReturn(0); 194b97cf49bSBarry Smith } 195b97cf49bSBarry Smith 196b97cf49bSBarry Smith 197b97cf49bSBarry Smith #undef __FUNC__ 1980752156aSBarry Smith #define __FUNC__ "MatEqual_MPIAdj" 1990752156aSBarry Smith int MatEqual_MPIAdj(Mat A,Mat B, PetscTruth* flg) 200b97cf49bSBarry Smith { 2010752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *)A->data, *b = (Mat_MPIAdj *)B->data; 202ca161407SBarry Smith int flag = 1,ierr; 203b97cf49bSBarry Smith 204a8c6a408SBarry Smith if (B->type != MATMPIADJ) SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 205b97cf49bSBarry Smith 206b97cf49bSBarry Smith /* If the matrix dimensions are not equal, or no of nonzeros */ 2070752156aSBarry Smith if ((a->m != b->m ) ||( a->nz != b->nz)) { 2080752156aSBarry Smith flag = 0; 209b97cf49bSBarry Smith } 210b97cf49bSBarry Smith 211b97cf49bSBarry Smith /* if the a->i are the same */ 212b97cf49bSBarry Smith if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) { 2130752156aSBarry Smith flag = 0; 214b97cf49bSBarry Smith } 215b97cf49bSBarry Smith 216b97cf49bSBarry Smith /* if a->j are the same */ 217b97cf49bSBarry Smith if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) { 2180752156aSBarry Smith flag = 0; 219b97cf49bSBarry Smith } 220b97cf49bSBarry Smith 221ca161407SBarry Smith ierr = MPI_Allreduce(&flag,flg,1,MPI_INT,MPI_LAND,A->comm);CHKERRQ(ierr); 2220752156aSBarry Smith 2230752156aSBarry Smith 2243a40ed3dSBarry Smith PetscFunctionReturn(0); 225b97cf49bSBarry Smith } 226b97cf49bSBarry Smith 227b97cf49bSBarry Smith 228b97cf49bSBarry Smith /* -------------------------------------------------------------------*/ 229b97cf49bSBarry Smith static struct _MatOps MatOps = {0, 2300752156aSBarry Smith MatGetRow_MPIAdj,MatRestoreRow_MPIAdj, 231b97cf49bSBarry Smith 0,0, 232b97cf49bSBarry Smith 0,0, 233b97cf49bSBarry Smith 0,0, 234b97cf49bSBarry Smith 0,0, 235b97cf49bSBarry Smith 0,0, 236b97cf49bSBarry Smith 0, 237b97cf49bSBarry Smith 0, 2380752156aSBarry Smith 0,MatEqual_MPIAdj, 239b97cf49bSBarry Smith 0,0,0, 240b97cf49bSBarry Smith 0,0, 241b97cf49bSBarry Smith 0, 2420752156aSBarry Smith MatSetOption_MPIAdj,0,0, 243b97cf49bSBarry Smith 0,0,0,0, 2440752156aSBarry Smith MatGetSize_MPIAdj,MatGetLocalSize_MPIAdj,MatGetOwnershipRange_MPIAdj, 245b97cf49bSBarry Smith 0,0, 246b97cf49bSBarry Smith 0,0, 247b97cf49bSBarry Smith 0,0,0, 248b97cf49bSBarry Smith 0,0,0, 2490752156aSBarry Smith 0,0, 250b97cf49bSBarry Smith 0,0, 251b97cf49bSBarry Smith 0, 252b97cf49bSBarry Smith 0,0,0, 253b97cf49bSBarry Smith 0, 2540752156aSBarry Smith MatGetBlockSize_MPIAdj, 255b97cf49bSBarry Smith 0, 256b97cf49bSBarry Smith 0, 257b97cf49bSBarry Smith 0, 258b97cf49bSBarry Smith 0, 259b97cf49bSBarry Smith 0, 2600752156aSBarry Smith 0, 2610752156aSBarry Smith 0, 2620752156aSBarry Smith 0}; 263b97cf49bSBarry Smith 264b97cf49bSBarry Smith 265b97cf49bSBarry Smith #undef __FUNC__ 2660752156aSBarry Smith #define __FUNC__ "MatCreateMPIAdj" 267b97cf49bSBarry Smith /*@C 2680752156aSBarry Smith MatCreateMPIAdj - Creates a sparse matrix representing an adjacency list. 269b97cf49bSBarry Smith The matrix does not have numerical values associated with it, but is 270b97cf49bSBarry Smith intended for ordering (to reduce bandwidth etc) and partitioning. 271b97cf49bSBarry Smith 272ef5ee4d1SLois Curfman McInnes Collective on MPI_Comm 273ef5ee4d1SLois Curfman McInnes 274b97cf49bSBarry Smith Input Parameters: 275ef5ee4d1SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 2760752156aSBarry Smith . m - number of local rows 277b97cf49bSBarry Smith . n - number of columns 278b97cf49bSBarry Smith . i - the indices into j for the start of each row 279ef5ee4d1SLois Curfman McInnes - j - the column indices for each row (sorted for each row). 280ef5ee4d1SLois Curfman McInnes The indices in i and j start with zero (NOT with one). 281b97cf49bSBarry Smith 282b97cf49bSBarry Smith Output Parameter: 283b97cf49bSBarry Smith . A - the matrix 284b97cf49bSBarry Smith 285*4bc6d8c0SBarry Smith Notes: This matrix object does not support most matrix operations, include 286*4bc6d8c0SBarry Smith MatSetValues(). 287*4bc6d8c0SBarry Smith You must NOT free the ii and jj arrays yourself. PETSc will free them 288b97cf49bSBarry Smith when the matrix is destroyed. 289b97cf49bSBarry Smith 290ef5ee4d1SLois Curfman McInnes Possible values for MatSetOption() - MAT_STRUCTURALLY_SYMMETRIC 291b97cf49bSBarry Smith 2920752156aSBarry Smith .seealso: MatCreate(), MatCreateSeqAdj(), MatGetReordering() 293b97cf49bSBarry Smith @*/ 2940752156aSBarry Smith int MatCreateMPIAdj(MPI_Comm comm,int m,int n,int *i,int *j, Mat *A) 295b97cf49bSBarry Smith { 296b97cf49bSBarry Smith Mat B; 2970752156aSBarry Smith Mat_MPIAdj *b; 2980752156aSBarry Smith int ii,ierr, flg,size,rank; 299b97cf49bSBarry Smith 300b97cf49bSBarry Smith MPI_Comm_size(comm,&size); 3010752156aSBarry Smith MPI_Comm_rank(comm,&rank); 302b97cf49bSBarry Smith 303b97cf49bSBarry Smith *A = 0; 304f830108cSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATMPIADJ,comm,MatDestroy,MatView); 305b97cf49bSBarry Smith PLogObjectCreate(B); 3060752156aSBarry Smith B->data = (void *) (b = PetscNew(Mat_MPIAdj)); CHKPTRQ(b); 3070752156aSBarry Smith PetscMemzero(b,sizeof(Mat_MPIAdj)); 308f830108cSBarry Smith PetscMemcpy(B->ops,&MatOps,sizeof(struct _MatOps)); 309e1311b90SBarry Smith B->ops->destroy = MatDestroy_MPIAdj; 310e1311b90SBarry Smith B->ops->view = MatView_MPIAdj; 311b97cf49bSBarry Smith B->factor = 0; 312b97cf49bSBarry Smith B->lupivotthreshold = 1.0; 313b97cf49bSBarry Smith B->mapping = 0; 314b97cf49bSBarry Smith B->assembled = PETSC_FALSE; 315b97cf49bSBarry Smith 3160752156aSBarry Smith b->m = m; B->m = m; 317ca161407SBarry Smith ierr = MPI_Allreduce(&m,&B->M,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 3180752156aSBarry Smith B->n = n; B->N = n; 3190752156aSBarry Smith 3200752156aSBarry Smith b->rowners = (int *) PetscMalloc((size+1)*sizeof(int)); CHKPTRQ(b->rowners); 3210752156aSBarry Smith PLogObjectMemory(B,(size+2)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPIAdj)); 322ca161407SBarry Smith ierr = MPI_Allgather(&m,1,MPI_INT,b->rowners+1,1,MPI_INT,comm);CHKERRQ(ierr); 3230752156aSBarry Smith b->rowners[0] = 0; 3240752156aSBarry Smith for ( ii=2; ii<=size; ii++ ) { 3250752156aSBarry Smith b->rowners[ii] += b->rowners[ii-1]; 3260752156aSBarry Smith } 3270752156aSBarry Smith b->rstart = b->rowners[rank]; 3280752156aSBarry Smith b->rend = b->rowners[rank+1]; 329b97cf49bSBarry Smith 330b97cf49bSBarry Smith b->j = j; 331b97cf49bSBarry Smith b->i = i; 332b97cf49bSBarry Smith 333b97cf49bSBarry Smith b->nz = i[m]; 334b97cf49bSBarry Smith b->diag = 0; 335b97cf49bSBarry Smith b->symmetric = PETSC_FALSE; 336b97cf49bSBarry Smith 337b97cf49bSBarry Smith *A = B; 338b97cf49bSBarry Smith 339b97cf49bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 340b97cf49bSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 341b97cf49bSBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 342b97cf49bSBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3433a40ed3dSBarry Smith PetscFunctionReturn(0); 344b97cf49bSBarry Smith } 345b97cf49bSBarry Smith 346b97cf49bSBarry Smith 347b97cf49bSBarry Smith 348