1b97cf49bSBarry Smith #ifdef PETSC_RCS_HEADER 2*e1311b90SBarry Smith static char vcid[] = "$Id: mpiadj.c,v 1.8 1998/03/12 23:19:41 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" 44*e1311b90SBarry 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); 52b97cf49bSBarry Smith } 533a40ed3dSBarry Smith PetscFunctionReturn(0); 54b97cf49bSBarry Smith } 55b97cf49bSBarry Smith 56b97cf49bSBarry Smith #undef __FUNC__ 570752156aSBarry Smith #define __FUNC__ "MatDestroy_MPIAdj" 58*e1311b90SBarry Smith int MatDestroy_MPIAdj(Mat A) 59b97cf49bSBarry Smith { 600752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 61b97cf49bSBarry Smith 623a40ed3dSBarry Smith #if defined(USE_PETSC_LOG) 63*e1311b90SBarry Smith PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 64b97cf49bSBarry Smith #endif 65b97cf49bSBarry Smith if (a->diag) PetscFree(a->diag); 66b97cf49bSBarry Smith PetscFree(a->i); 67b97cf49bSBarry Smith PetscFree(a->j); 680752156aSBarry Smith PetscFree(a->rowners); 69b97cf49bSBarry Smith PetscFree(a); 70b97cf49bSBarry Smith 71b97cf49bSBarry Smith PLogObjectDestroy(A); 72b97cf49bSBarry Smith PetscHeaderDestroy(A); 733a40ed3dSBarry Smith PetscFunctionReturn(0); 74b97cf49bSBarry Smith } 75b97cf49bSBarry Smith 76b97cf49bSBarry Smith 77b97cf49bSBarry Smith #undef __FUNC__ 780752156aSBarry Smith #define __FUNC__ "MatSetOption_MPIAdj" 790752156aSBarry Smith int MatSetOption_MPIAdj(Mat A,MatOption op) 80b97cf49bSBarry Smith { 810752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 82b97cf49bSBarry Smith 83b97cf49bSBarry Smith if (op == MAT_STRUCTURALLY_SYMMETRIC) { 84b97cf49bSBarry Smith a->symmetric = PETSC_TRUE; 85b97cf49bSBarry Smith } else { 86981c4779SBarry Smith PLogInfo(A,"MatSetOption_MPIAdj:Option ignored\n"); 87b97cf49bSBarry Smith } 883a40ed3dSBarry Smith PetscFunctionReturn(0); 89b97cf49bSBarry Smith } 90b97cf49bSBarry Smith 91b97cf49bSBarry Smith 92b97cf49bSBarry Smith /* 93b97cf49bSBarry Smith Adds diagonal pointers to sparse matrix structure. 94b97cf49bSBarry Smith */ 95b97cf49bSBarry Smith 96b97cf49bSBarry Smith #undef __FUNC__ 970752156aSBarry Smith #define __FUNC__ "MatMarkDiag_MPIAdj" 980752156aSBarry Smith int MatMarkDiag_MPIAdj(Mat A) 99b97cf49bSBarry Smith { 1000752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 101b97cf49bSBarry Smith int i,j, *diag, m = a->m; 102b97cf49bSBarry Smith 103b97cf49bSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 104b97cf49bSBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 105b97cf49bSBarry Smith for ( i=0; i<a->m; i++ ) { 106b97cf49bSBarry Smith for ( j=a->i[i]; j<a->i[i+1]; j++ ) { 107b97cf49bSBarry Smith if (a->j[j] == i) { 108b97cf49bSBarry Smith diag[i] = j; 109b97cf49bSBarry Smith break; 110b97cf49bSBarry Smith } 111b97cf49bSBarry Smith } 112b97cf49bSBarry Smith } 113b97cf49bSBarry Smith a->diag = diag; 1143a40ed3dSBarry Smith PetscFunctionReturn(0); 115b97cf49bSBarry Smith } 116b97cf49bSBarry Smith 117b97cf49bSBarry Smith #undef __FUNC__ 1180752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj" 1190752156aSBarry Smith int MatGetSize_MPIAdj(Mat A,int *m,int *n) 120b97cf49bSBarry Smith { 1210752156aSBarry Smith if (m) *m = A->M; 1220752156aSBarry Smith if (n) *n = A->N; 1233a40ed3dSBarry Smith PetscFunctionReturn(0); 124b97cf49bSBarry Smith } 125b97cf49bSBarry Smith 126b97cf49bSBarry Smith #undef __FUNC__ 1270752156aSBarry Smith #define __FUNC__ "MatGetSize_MPIAdj" 1280752156aSBarry Smith int MatGetLocalSize_MPIAdj(Mat A,int *m,int *n) 129b97cf49bSBarry Smith { 1300752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 1310752156aSBarry Smith if (m) *m = a->m; 1320752156aSBarry Smith if (n) *n = A->N; 1333a40ed3dSBarry Smith PetscFunctionReturn(0); 134b97cf49bSBarry Smith } 135b97cf49bSBarry Smith 136b97cf49bSBarry Smith #undef __FUNC__ 1370752156aSBarry Smith #define __FUNC__ "MatGetOwnershipRange_MPIAdj" 1380752156aSBarry Smith int MatGetOwnershipRange_MPIAdj(Mat A,int *m,int *n) 139b97cf49bSBarry Smith { 1400752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 1410752156aSBarry Smith *m = a->rstart; *n = a->rend; 1423a40ed3dSBarry Smith PetscFunctionReturn(0); 143b97cf49bSBarry Smith } 144b97cf49bSBarry Smith 145b97cf49bSBarry Smith #undef __FUNC__ 1460752156aSBarry Smith #define __FUNC__ "MatGetRow_MPIAdj" 1470752156aSBarry Smith int MatGetRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v) 148b97cf49bSBarry Smith { 1490752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *) A->data; 150b97cf49bSBarry Smith int *itmp; 151b97cf49bSBarry Smith 1520752156aSBarry Smith row -= a->rstart; 1530752156aSBarry Smith 154a8c6a408SBarry Smith if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 155b97cf49bSBarry Smith 156b97cf49bSBarry Smith *nz = a->i[row+1] - a->i[row]; 157b97cf49bSBarry Smith if (v) *v = PETSC_NULL; 158b97cf49bSBarry Smith if (idx) { 159b97cf49bSBarry Smith itmp = a->j + a->i[row]; 160b97cf49bSBarry Smith if (*nz) { 161b97cf49bSBarry Smith *idx = itmp; 162b97cf49bSBarry Smith } 163b97cf49bSBarry Smith else *idx = 0; 164b97cf49bSBarry Smith } 1653a40ed3dSBarry Smith PetscFunctionReturn(0); 166b97cf49bSBarry Smith } 167b97cf49bSBarry Smith 168b97cf49bSBarry Smith #undef __FUNC__ 1690752156aSBarry Smith #define __FUNC__ "MatRestoreRow_MPIAdj" 1700752156aSBarry Smith int MatRestoreRow_MPIAdj(Mat A,int row,int *nz,int **idx,Scalar **v) 171b97cf49bSBarry Smith { 1723a40ed3dSBarry Smith PetscFunctionReturn(0); 173b97cf49bSBarry Smith } 174b97cf49bSBarry Smith 175b97cf49bSBarry Smith #undef __FUNC__ 1760752156aSBarry Smith #define __FUNC__ "MatGetBlockSize_MPIAdj" 1770752156aSBarry Smith int MatGetBlockSize_MPIAdj(Mat A, int *bs) 178b97cf49bSBarry Smith { 179b97cf49bSBarry Smith *bs = 1; 1803a40ed3dSBarry Smith PetscFunctionReturn(0); 181b97cf49bSBarry Smith } 182b97cf49bSBarry Smith 183b97cf49bSBarry Smith 184b97cf49bSBarry Smith #undef __FUNC__ 1850752156aSBarry Smith #define __FUNC__ "MatEqual_MPIAdj" 1860752156aSBarry Smith int MatEqual_MPIAdj(Mat A,Mat B, PetscTruth* flg) 187b97cf49bSBarry Smith { 1880752156aSBarry Smith Mat_MPIAdj *a = (Mat_MPIAdj *)A->data, *b = (Mat_MPIAdj *)B->data; 189ca161407SBarry Smith int flag = 1,ierr; 190b97cf49bSBarry Smith 191a8c6a408SBarry Smith if (B->type != MATMPIADJ) SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 192b97cf49bSBarry Smith 193b97cf49bSBarry Smith /* If the matrix dimensions are not equal, or no of nonzeros */ 1940752156aSBarry Smith if ((a->m != b->m ) ||( a->nz != b->nz)) { 1950752156aSBarry Smith flag = 0; 196b97cf49bSBarry Smith } 197b97cf49bSBarry Smith 198b97cf49bSBarry Smith /* if the a->i are the same */ 199b97cf49bSBarry Smith if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) { 2000752156aSBarry Smith flag = 0; 201b97cf49bSBarry Smith } 202b97cf49bSBarry Smith 203b97cf49bSBarry Smith /* if a->j are the same */ 204b97cf49bSBarry Smith if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) { 2050752156aSBarry Smith flag = 0; 206b97cf49bSBarry Smith } 207b97cf49bSBarry Smith 208ca161407SBarry Smith ierr = MPI_Allreduce(&flag,flg,1,MPI_INT,MPI_LAND,A->comm);CHKERRQ(ierr); 2090752156aSBarry Smith 2100752156aSBarry Smith 2113a40ed3dSBarry Smith PetscFunctionReturn(0); 212b97cf49bSBarry Smith } 213b97cf49bSBarry Smith 214b97cf49bSBarry Smith 215b97cf49bSBarry Smith /* -------------------------------------------------------------------*/ 216b97cf49bSBarry Smith static struct _MatOps MatOps = {0, 2170752156aSBarry Smith MatGetRow_MPIAdj,MatRestoreRow_MPIAdj, 218b97cf49bSBarry Smith 0,0, 219b97cf49bSBarry Smith 0,0, 220b97cf49bSBarry Smith 0,0, 221b97cf49bSBarry Smith 0,0, 222b97cf49bSBarry Smith 0,0, 223b97cf49bSBarry Smith 0, 224b97cf49bSBarry Smith 0, 2250752156aSBarry Smith 0,MatEqual_MPIAdj, 226b97cf49bSBarry Smith 0,0,0, 227b97cf49bSBarry Smith 0,0, 228b97cf49bSBarry Smith 0, 2290752156aSBarry Smith MatSetOption_MPIAdj,0,0, 230b97cf49bSBarry Smith 0,0,0,0, 2310752156aSBarry Smith MatGetSize_MPIAdj,MatGetLocalSize_MPIAdj,MatGetOwnershipRange_MPIAdj, 232b97cf49bSBarry Smith 0,0, 233b97cf49bSBarry Smith 0,0, 234b97cf49bSBarry Smith 0,0,0, 235b97cf49bSBarry Smith 0,0,0, 2360752156aSBarry Smith 0,0, 237b97cf49bSBarry Smith 0,0, 238b97cf49bSBarry Smith 0, 239b97cf49bSBarry Smith 0,0,0, 240b97cf49bSBarry Smith 0, 2410752156aSBarry Smith MatGetBlockSize_MPIAdj, 242b97cf49bSBarry Smith 0, 243b97cf49bSBarry Smith 0, 244b97cf49bSBarry Smith 0, 245b97cf49bSBarry Smith 0, 246b97cf49bSBarry Smith 0, 2470752156aSBarry Smith 0, 2480752156aSBarry Smith 0, 2490752156aSBarry Smith 0}; 250b97cf49bSBarry Smith 251b97cf49bSBarry Smith 252b97cf49bSBarry Smith #undef __FUNC__ 2530752156aSBarry Smith #define __FUNC__ "MatCreateMPIAdj" 254b97cf49bSBarry Smith /*@C 2550752156aSBarry Smith MatCreateMPIAdj - Creates a sparse matrix representing an adjacency list. 256b97cf49bSBarry Smith The matrix does not have numerical values associated with it, but is 257b97cf49bSBarry Smith intended for ordering (to reduce bandwidth etc) and partitioning. 258b97cf49bSBarry Smith 259b97cf49bSBarry Smith Input Parameters: 260b97cf49bSBarry Smith . comm - MPI communicator, set to PETSC_COMM_SELF 2610752156aSBarry Smith . m - number of local rows 262b97cf49bSBarry Smith . n - number of columns 263b97cf49bSBarry Smith . i - the indices into j for the start of each row 264b97cf49bSBarry Smith . j - the column indices for each row (sorted for each row) 265b97cf49bSBarry Smith The indices in i and j start with zero NOT one. 266b97cf49bSBarry Smith 267b97cf49bSBarry Smith Output Parameter: 268b97cf49bSBarry Smith . A - the matrix 269b97cf49bSBarry Smith 2700752156aSBarry Smith Notes: You must NOT free the ii and jj arrays yourself. PETSc will free them 271b97cf49bSBarry Smith when the matrix is destroyed. 272b97cf49bSBarry Smith 273b58e66f3SSatish Balay . MatSetOption() possible values - MAT_STRUCTURALLY_SYMMETRIC 274b97cf49bSBarry Smith 2750752156aSBarry Smith .seealso: MatCreate(), MatCreateSeqAdj(), MatGetReordering() 276b97cf49bSBarry Smith @*/ 2770752156aSBarry Smith int MatCreateMPIAdj(MPI_Comm comm,int m,int n,int *i,int *j, Mat *A) 278b97cf49bSBarry Smith { 279b97cf49bSBarry Smith Mat B; 2800752156aSBarry Smith Mat_MPIAdj *b; 2810752156aSBarry Smith int ii,ierr, flg,size,rank; 282b97cf49bSBarry Smith 283b97cf49bSBarry Smith MPI_Comm_size(comm,&size); 2840752156aSBarry Smith MPI_Comm_rank(comm,&rank); 285b97cf49bSBarry Smith 286b97cf49bSBarry Smith *A = 0; 287f830108cSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATMPIADJ,comm,MatDestroy,MatView); 288b97cf49bSBarry Smith PLogObjectCreate(B); 2890752156aSBarry Smith B->data = (void *) (b = PetscNew(Mat_MPIAdj)); CHKPTRQ(b); 2900752156aSBarry Smith PetscMemzero(b,sizeof(Mat_MPIAdj)); 291f830108cSBarry Smith PetscMemcpy(B->ops,&MatOps,sizeof(struct _MatOps)); 292*e1311b90SBarry Smith B->ops->destroy = MatDestroy_MPIAdj; 293*e1311b90SBarry Smith B->ops->view = MatView_MPIAdj; 294b97cf49bSBarry Smith B->factor = 0; 295b97cf49bSBarry Smith B->lupivotthreshold = 1.0; 296b97cf49bSBarry Smith B->mapping = 0; 297b97cf49bSBarry Smith B->assembled = PETSC_FALSE; 298b97cf49bSBarry Smith 2990752156aSBarry Smith b->m = m; B->m = m; 300ca161407SBarry Smith ierr = MPI_Allreduce(&m,&B->M,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 3010752156aSBarry Smith B->n = n; B->N = n; 3020752156aSBarry Smith 3030752156aSBarry Smith b->rowners = (int *) PetscMalloc((size+1)*sizeof(int)); CHKPTRQ(b->rowners); 3040752156aSBarry Smith PLogObjectMemory(B,(size+2)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPIAdj)); 305ca161407SBarry Smith ierr = MPI_Allgather(&m,1,MPI_INT,b->rowners+1,1,MPI_INT,comm);CHKERRQ(ierr); 3060752156aSBarry Smith b->rowners[0] = 0; 3070752156aSBarry Smith for ( ii=2; ii<=size; ii++ ) { 3080752156aSBarry Smith b->rowners[ii] += b->rowners[ii-1]; 3090752156aSBarry Smith } 3100752156aSBarry Smith b->rstart = b->rowners[rank]; 3110752156aSBarry Smith b->rend = b->rowners[rank+1]; 312b97cf49bSBarry Smith 313b97cf49bSBarry Smith b->j = j; 314b97cf49bSBarry Smith b->i = i; 315b97cf49bSBarry Smith 316b97cf49bSBarry Smith b->nz = i[m]; 317b97cf49bSBarry Smith b->diag = 0; 318b97cf49bSBarry Smith b->symmetric = PETSC_FALSE; 319b97cf49bSBarry Smith 320b97cf49bSBarry Smith *A = B; 321b97cf49bSBarry Smith 322b97cf49bSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 323b97cf49bSBarry Smith if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 324b97cf49bSBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 325b97cf49bSBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3263a40ed3dSBarry Smith PetscFunctionReturn(0); 327b97cf49bSBarry Smith } 328b97cf49bSBarry Smith 329b97cf49bSBarry Smith 330b97cf49bSBarry Smith 331