1 /*$Id: mpiadj.c,v 1.33 1999/11/24 21:54:06 bsmith Exp bsmith $*/ 2 3 /* 4 Defines the basic matrix operations for the ADJ adjacency list matrix data-structure. 5 */ 6 #include "sys.h" 7 #include "src/mat/impls/csr/mpi/mpicsr.h" 8 9 #undef __FUNC__ 10 #define __FUNC__ "MatView_MPICSR_ASCII" 11 extern int MatView_MPICSR_ASCII(Mat A,Viewer viewer) 12 { 13 Mat_MPICSR *a = (Mat_MPICSR*)A->data; 14 int ierr,i,j,m = a->m, format; 15 char *outputname; 16 17 PetscFunctionBegin; 18 ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 19 ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 20 if (format == VIEWER_FORMAT_ASCII_INFO) { 21 PetscFunctionReturn(0); 22 } else { 23 ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 24 for (i=0; i<m; i++) { 25 ierr = ViewerASCIISynchronizedPrintf(viewer,"row %d:",i+a->rstart);CHKERRQ(ierr); 26 for (j=a->i[i]; j<a->i[i+1]; j++) { 27 ierr = ViewerASCIISynchronizedPrintf(viewer," %d ",a->j[j]);CHKERRQ(ierr); 28 } 29 ierr = ViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 30 } 31 ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 32 } 33 ierr = ViewerFlush(viewer);CHKERRQ(ierr); 34 PetscFunctionReturn(0); 35 } 36 37 #undef __FUNC__ 38 #define __FUNC__ "MatView_MPICSR" 39 int MatView_MPICSR(Mat A,Viewer viewer) 40 { 41 int ierr; 42 PetscTruth isascii; 43 44 PetscFunctionBegin; 45 ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 46 if (isascii) { 47 ierr = MatView_MPICSR_ASCII(A,viewer);CHKERRQ(ierr); 48 } else { 49 SETERRQ1(1,1,"Viewer type %s not supported by MPICSR",((PetscObject)viewer)->type_name); 50 } 51 PetscFunctionReturn(0); 52 } 53 54 #undef __FUNC__ 55 #define __FUNC__ "MatDestroy_MPICSR" 56 int MatDestroy_MPICSR(Mat mat) 57 { 58 Mat_MPICSR *a = (Mat_MPICSR*)mat->data; 59 int ierr; 60 61 PetscFunctionBegin; 62 63 if (mat->mapping) { 64 ierr = ISLocalToGlobalMappingDestroy(mat->mapping);CHKERRQ(ierr); 65 } 66 if (mat->bmapping) { 67 ierr = ISLocalToGlobalMappingDestroy(mat->bmapping);CHKERRQ(ierr); 68 } 69 if (mat->rmap) { 70 ierr = MapDestroy(mat->rmap);CHKERRQ(ierr); 71 } 72 if (mat->cmap) { 73 ierr = MapDestroy(mat->cmap);CHKERRQ(ierr); 74 } 75 76 #if defined(PETSC_USE_LOG) 77 PLogObjectState((PetscObject)mat,"Rows=%d, Cols=%d, NZ=%d",mat->m,mat->n,a->nz); 78 #endif 79 if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 80 ierr = PetscFree(a->i);CHKERRQ(ierr); 81 ierr = PetscFree(a->j);CHKERRQ(ierr); 82 ierr = PetscFree(a->rowners);CHKERRQ(ierr); 83 ierr = PetscFree(a);CHKERRQ(ierr); 84 85 PLogObjectDestroy(mat); 86 PetscHeaderDestroy(mat); 87 PetscFunctionReturn(0); 88 } 89 90 91 #undef __FUNC__ 92 #define __FUNC__ "MatSetOption_MPICSR" 93 int MatSetOption_MPICSR(Mat A,MatOption op) 94 { 95 Mat_MPICSR *a = (Mat_MPICSR*)A->data; 96 97 PetscFunctionBegin; 98 if (op == MAT_STRUCTURALLY_SYMMETRIC) { 99 a->symmetric = PETSC_TRUE; 100 } else { 101 PLogInfo(A,"MatSetOption_MPICSR:Option ignored\n"); 102 } 103 PetscFunctionReturn(0); 104 } 105 106 107 /* 108 Adds diagonal pointers to sparse matrix structure. 109 */ 110 111 #undef __FUNC__ 112 #define __FUNC__ "MatMarkDiagonal_MPICSR" 113 int MatMarkDiagonal_MPICSR(Mat A) 114 { 115 Mat_MPICSR *a = (Mat_MPICSR*)A->data; 116 int i,j,*diag,m = a->m; 117 118 PetscFunctionBegin; 119 diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag); 120 PLogObjectMemory(A,(m+1)*sizeof(int)); 121 for (i=0; i<a->m; i++) { 122 for (j=a->i[i]; j<a->i[i+1]; j++) { 123 if (a->j[j] == i) { 124 diag[i] = j; 125 break; 126 } 127 } 128 } 129 a->diag = diag; 130 PetscFunctionReturn(0); 131 } 132 133 #undef __FUNC__ 134 #define __FUNC__ "MatGetSize_MPICSR" 135 int MatGetSize_MPICSR(Mat A,int *m,int *n) 136 { 137 PetscFunctionBegin; 138 if (m) *m = A->M; 139 if (n) *n = A->N; 140 PetscFunctionReturn(0); 141 } 142 143 #undef __FUNC__ 144 #define __FUNC__ "MatGetSize_MPICSR" 145 int MatGetLocalSize_MPICSR(Mat A,int *m,int *n) 146 { 147 Mat_MPICSR *a = (Mat_MPICSR*)A->data; 148 PetscFunctionBegin; 149 if (m) *m = a->m; 150 if (n) *n = A->N; 151 PetscFunctionReturn(0); 152 } 153 154 #undef __FUNC__ 155 #define __FUNC__ "MatGetOwnershipRange_MPICSR" 156 int MatGetOwnershipRange_MPICSR(Mat A,int *m,int *n) 157 { 158 Mat_MPICSR *a = (Mat_MPICSR*)A->data; 159 PetscFunctionBegin; 160 *m = a->rstart; *n = a->rend; 161 PetscFunctionReturn(0); 162 } 163 164 #undef __FUNC__ 165 #define __FUNC__ "MatGetRow_MPICSR" 166 int MatGetRow_MPICSR(Mat A,int row,int *nz,int **idx,Scalar **v) 167 { 168 Mat_MPICSR *a = (Mat_MPICSR*)A->data; 169 int *itmp; 170 171 PetscFunctionBegin; 172 row -= a->rstart; 173 174 if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 175 176 *nz = a->i[row+1] - a->i[row]; 177 if (v) *v = PETSC_NULL; 178 if (idx) { 179 itmp = a->j + a->i[row]; 180 if (*nz) { 181 *idx = itmp; 182 } 183 else *idx = 0; 184 } 185 PetscFunctionReturn(0); 186 } 187 188 #undef __FUNC__ 189 #define __FUNC__ "MatRestoreRow_MPICSR" 190 int MatRestoreRow_MPICSR(Mat A,int row,int *nz,int **idx,Scalar **v) 191 { 192 PetscFunctionBegin; 193 PetscFunctionReturn(0); 194 } 195 196 #undef __FUNC__ 197 #define __FUNC__ "MatGetBlockSize_MPICSR" 198 int MatGetBlockSize_MPICSR(Mat A,int *bs) 199 { 200 PetscFunctionBegin; 201 *bs = 1; 202 PetscFunctionReturn(0); 203 } 204 205 206 #undef __FUNC__ 207 #define __FUNC__ "MatEqual_MPICSR" 208 int MatEqual_MPICSR(Mat A,Mat B,PetscTruth* flg) 209 { 210 Mat_MPICSR *a = (Mat_MPICSR *)A->data,*b = (Mat_MPICSR *)B->data; 211 int ierr; 212 PetscTruth flag; 213 214 PetscFunctionBegin; 215 if (B->type != MATMPICSR) SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 216 217 /* If the matrix dimensions are not equal,or no of nonzeros */ 218 if ((a->m != b->m) ||(a->nz != b->nz)) { 219 flag = PETSC_FALSE; 220 } 221 222 /* if the a->i are the same */ 223 ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),&flag);CHKERRQ(ierr); 224 225 /* if a->j are the same */ 226 ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),&flag);CHKERRQ(ierr); 227 228 ierr = MPI_Allreduce(&flag,flg,1,MPI_INT,MPI_LAND,A->comm);CHKERRQ(ierr); 229 PetscFunctionReturn(0); 230 } 231 232 233 /* -------------------------------------------------------------------*/ 234 static struct _MatOps MatOps_Values = {0, 235 MatGetRow_MPICSR, 236 MatRestoreRow_MPICSR, 237 0, 238 0, 239 0, 240 0, 241 0, 242 0, 243 0, 244 0, 245 0, 246 0, 247 0, 248 0, 249 0, 250 MatEqual_MPICSR, 251 0, 252 0, 253 0, 254 0, 255 0, 256 0, 257 MatSetOption_MPICSR, 258 0, 259 0, 260 0, 261 0, 262 0, 263 0, 264 MatGetSize_MPICSR, 265 MatGetLocalSize_MPICSR, 266 MatGetOwnershipRange_MPICSR, 267 0, 268 0, 269 0, 270 0, 271 0, 272 0, 273 0, 274 0, 275 0, 276 0, 277 0, 278 0, 279 0, 280 0, 281 0, 282 0, 283 0, 284 0, 285 0, 286 MatGetBlockSize_MPICSR, 287 0, 288 0, 289 0, 290 0, 291 0, 292 0, 293 0, 294 0, 295 0, 296 0, 297 0, 298 0, 299 MatGetMaps_Petsc}; 300 301 302 #undef __FUNC__ 303 #define __FUNC__ "MatCreateMPICSR" 304 /*@C 305 MatCreateMPICSR - Creates a sparse matrix representing an adjacency list. 306 The matrix does not have numerical values associated with it, but is 307 intended for ordering (to reduce bandwidth etc) and partitioning. 308 309 Collective on MPI_Comm 310 311 Input Parameters: 312 + comm - MPI communicator, set to PETSC_COMM_SELF 313 . m - number of local rows 314 . n - number of columns 315 . i - the indices into j for the start of each row 316 . j - the column indices for each row (sorted for each row). 317 The indices in i and j start with zero (NOT with one). 318 - values -[optional] edge weights 319 320 Output Parameter: 321 . A - the matrix 322 323 Level: intermediate 324 325 Notes: This matrix object does not support most matrix operations, include 326 MatSetValues(). 327 You must NOT free the ii and jj arrays yourself. PETSc will free them 328 when the matrix is destroyed. 329 330 Possible values for MatSetOption() - MAT_STRUCTURALLY_SYMMETRIC 331 332 .seealso: MatCreate(), MatCreateSeqAdj(), MatGetOrdering() 333 @*/ 334 int MatCreateMPICSR(MPI_Comm comm,int m,int n,int *i,int *j,MatScalar *values,Mat *A) 335 { 336 Mat B; 337 Mat_MPICSR *b; 338 int ii,ierr,size,rank; 339 PetscTruth flg; 340 341 PetscFunctionBegin; 342 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 343 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 344 345 *A = 0; 346 PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATMPICSR,"Mat",comm,MatDestroy,MatView); 347 PLogObjectCreate(B); 348 B->data = (void*)(b = PetscNew(Mat_MPICSR));CHKPTRQ(b); 349 ierr = PetscMemzero(b,sizeof(Mat_MPICSR));CHKERRQ(ierr); 350 ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 351 B->ops->destroy = MatDestroy_MPICSR; 352 B->ops->view = MatView_MPICSR; 353 B->factor = 0; 354 B->lupivotthreshold = 1.0; 355 B->mapping = 0; 356 B->assembled = PETSC_FALSE; 357 358 b->m = m; B->m = m; 359 ierr = MPI_Allreduce(&m,&B->M,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 360 B->n = n; B->N = n; 361 362 /* the information in the maps duplicates the information computed below, eventually 363 we should remove the duplicate information that is not contained in the maps */ 364 ierr = MapCreateMPI(comm,m,B->M,&B->rmap);CHKERRQ(ierr); 365 /* we don't know the "local columns" so just use the row information :-(*/ 366 ierr = MapCreateMPI(comm,m,B->M,&B->cmap);CHKERRQ(ierr); 367 368 b->rowners = (int*)PetscMalloc((size+1)*sizeof(int));CHKPTRQ(b->rowners); 369 PLogObjectMemory(B,(size+2)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPICSR)); 370 ierr = MPI_Allgather(&m,1,MPI_INT,b->rowners+1,1,MPI_INT,comm);CHKERRQ(ierr); 371 b->rowners[0] = 0; 372 for (ii=2; ii<=size; ii++) { 373 b->rowners[ii] += b->rowners[ii-1]; 374 } 375 b->rstart = b->rowners[rank]; 376 b->rend = b->rowners[rank+1]; 377 378 b->j = j; 379 b->i = i; 380 b->values = values; 381 382 b->nz = i[m]; 383 b->diag = 0; 384 b->symmetric = PETSC_FALSE; 385 386 *A = B; 387 388 ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 389 if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); } 390 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 391 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 392 PetscFunctionReturn(0); 393 } 394 395 396 397 398 399 400 401 402 403