1 2 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 3 4 PETSC_INTERN PetscErrorCode MatSetBlockSizes_Default(Mat mat,PetscInt rbs, PetscInt cbs) 5 { 6 PetscFunctionBegin; 7 if (!mat->preallocated) PetscFunctionReturn(0); 8 if (mat->rmap->bs > 0 && mat->rmap->bs != rbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot change row block size %D to %D\n",mat->rmap->bs,rbs); 9 if (mat->cmap->bs > 0 && mat->cmap->bs != cbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot change column block size %D to %D\n",mat->cmap->bs,cbs); 10 PetscFunctionReturn(0); 11 } 12 13 PETSC_INTERN PetscErrorCode MatShift_Basic(Mat Y,PetscScalar a) 14 { 15 PetscErrorCode ierr; 16 PetscInt i,start,end; 17 PetscScalar alpha = a; 18 PetscBool prevoption; 19 20 PetscFunctionBegin; 21 ierr = MatGetOption(Y,MAT_NO_OFF_PROC_ENTRIES,&prevoption);CHKERRQ(ierr); 22 ierr = MatSetOption(Y,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 23 ierr = MatGetOwnershipRange(Y,&start,&end);CHKERRQ(ierr); 24 for (i=start; i<end; i++) { 25 if (i < Y->cmap->N) { 26 ierr = MatSetValues(Y,1,&i,1,&i,&alpha,ADD_VALUES);CHKERRQ(ierr); 27 } 28 } 29 ierr = MatAssemblyBegin(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30 ierr = MatAssemblyEnd(Y,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31 ierr = MatSetOption(Y,MAT_NO_OFF_PROC_ENTRIES,prevoption);CHKERRQ(ierr); 32 PetscFunctionReturn(0); 33 } 34 35 /*@ 36 MatCreate - Creates a matrix where the type is determined 37 from either a call to MatSetType() or from the options database 38 with a call to MatSetFromOptions(). The default matrix type is 39 AIJ, using the routines MatCreateSeqAIJ() or MatCreateAIJ() 40 if you do not set a type in the options database. If you never 41 call MatSetType() or MatSetFromOptions() it will generate an 42 error when you try to use the matrix. 43 44 Collective 45 46 Input Parameter: 47 . comm - MPI communicator 48 49 Output Parameter: 50 . A - the matrix 51 52 Options Database Keys: 53 + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() 54 . -mat_type mpiaij - AIJ type, uses MatCreateAIJ() 55 . -mat_type seqdense - dense type, uses MatCreateSeqDense() 56 . -mat_type mpidense - dense type, uses MatCreateDense() 57 . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() 58 - -mat_type mpibaij - block AIJ type, uses MatCreateBAIJ() 59 60 Even More Options Database Keys: 61 See the manpages for particular formats (e.g., MatCreateSeqAIJ()) 62 for additional format-specific options. 63 64 Notes: 65 66 Level: beginner 67 68 User manual sections: 69 + sec_matcreate 70 - chapter_matrices 71 72 .seealso: MatCreateSeqAIJ(), MatCreateAIJ(), 73 MatCreateSeqDense(), MatCreateDense(), 74 MatCreateSeqBAIJ(), MatCreateBAIJ(), 75 MatCreateSeqSBAIJ(), MatCreateSBAIJ(), 76 MatConvert() 77 @*/ 78 PetscErrorCode MatCreate(MPI_Comm comm,Mat *A) 79 { 80 Mat B; 81 PetscErrorCode ierr; 82 83 PetscFunctionBegin; 84 PetscValidPointer(A,2); 85 86 *A = NULL; 87 ierr = MatInitializePackage();CHKERRQ(ierr); 88 89 ierr = PetscHeaderCreate(B,MAT_CLASSID,"Mat","Matrix","Mat",comm,MatDestroy,MatView);CHKERRQ(ierr); 90 ierr = PetscLayoutCreate(comm,&B->rmap);CHKERRQ(ierr); 91 ierr = PetscLayoutCreate(comm,&B->cmap);CHKERRQ(ierr); 92 ierr = PetscStrallocpy(VECSTANDARD,&B->defaultvectype);CHKERRQ(ierr); 93 94 B->congruentlayouts = PETSC_DECIDE; 95 B->preallocated = PETSC_FALSE; 96 *A = B; 97 PetscFunctionReturn(0); 98 } 99 100 /*@ 101 MatSetErrorIfFailure - Causes Mat to generate an error, for example a zero pivot, is detected. 102 103 Logically Collective on Mat 104 105 Input Parameters: 106 + mat - matrix obtained from MatCreate() 107 - flg - PETSC_TRUE indicates you want the error generated 108 109 Level: advanced 110 111 .seealso: PCSetErrorIfFailure() 112 @*/ 113 PetscErrorCode MatSetErrorIfFailure(Mat mat,PetscBool flg) 114 { 115 PetscFunctionBegin; 116 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 117 PetscValidLogicalCollectiveBool(mat,flg,2); 118 mat->erroriffailure = flg; 119 PetscFunctionReturn(0); 120 } 121 122 /*@ 123 MatSetSizes - Sets the local and global sizes, and checks to determine compatibility 124 125 Collective on Mat 126 127 Input Parameters: 128 + A - the matrix 129 . m - number of local rows (or PETSC_DECIDE) 130 . n - number of local columns (or PETSC_DECIDE) 131 . M - number of global rows (or PETSC_DETERMINE) 132 - N - number of global columns (or PETSC_DETERMINE) 133 134 Notes: 135 m (n) and M (N) cannot be both PETSC_DECIDE 136 If one processor calls this with M (N) of PETSC_DECIDE then all processors must, otherwise the program will hang. 137 138 If PETSC_DECIDE is not used for the arguments 'm' and 'n', then the 139 user must ensure that they are chosen to be compatible with the 140 vectors. To do this, one first considers the matrix-vector product 141 'y = A x'. The 'm' that is used in the above routine must match the 142 local size used in the vector creation routine VecCreateMPI() for 'y'. 143 Likewise, the 'n' used must match that used as the local size in 144 VecCreateMPI() for 'x'. 145 146 You cannot change the sizes once they have been set. 147 148 The sizes must be set before MatSetUp() or MatXXXSetPreallocation() is called. 149 150 Level: beginner 151 152 .seealso: MatGetSize(), PetscSplitOwnership() 153 @*/ 154 PetscErrorCode MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N) 155 { 156 PetscFunctionBegin; 157 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 158 if (M > 0) PetscValidLogicalCollectiveInt(A,M,4); 159 if (N > 0) PetscValidLogicalCollectiveInt(A,N,5); 160 if (M > 0 && m > M) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local column size %D cannot be larger than global column size %D",m,M); 161 if (N > 0 && n > N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local row size %D cannot be larger than global row size %D",n,N); 162 if ((A->rmap->n >= 0 && A->rmap->N >= 0) && (A->rmap->n != m || (M > 0 && A->rmap->N != M))) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change/reset row sizes to %D local %D global after previously setting them to %D local %D global",m,M,A->rmap->n,A->rmap->N); 163 if ((A->cmap->n >= 0 && A->cmap->N >= 0) && (A->cmap->n != n || (N > 0 && A->cmap->N != N))) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change/reset column sizes to %D local %D global after previously setting them to %D local %D global",n,N,A->cmap->n,A->cmap->N); 164 A->rmap->n = m; 165 A->cmap->n = n; 166 A->rmap->N = M > -1 ? M : A->rmap->N; 167 A->cmap->N = N > -1 ? N : A->cmap->N; 168 PetscFunctionReturn(0); 169 } 170 171 /*@ 172 MatSetFromOptions - Creates a matrix where the type is determined 173 from the options database. Generates a parallel MPI matrix if the 174 communicator has more than one processor. The default matrix type is 175 AIJ, using the routines MatCreateSeqAIJ() and MatCreateAIJ() if 176 you do not select a type in the options database. 177 178 Collective on Mat 179 180 Input Parameter: 181 . A - the matrix 182 183 Options Database Keys: 184 + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() 185 . -mat_type mpiaij - AIJ type, uses MatCreateAIJ() 186 . -mat_type seqdense - dense type, uses MatCreateSeqDense() 187 . -mat_type mpidense - dense type, uses MatCreateDense() 188 . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() 189 - -mat_type mpibaij - block AIJ type, uses MatCreateBAIJ() 190 191 Even More Options Database Keys: 192 See the manpages for particular formats (e.g., MatCreateSeqAIJ()) 193 for additional format-specific options. 194 195 Level: beginner 196 197 .seealso: MatCreateSeqAIJ((), MatCreateAIJ(), 198 MatCreateSeqDense(), MatCreateDense(), 199 MatCreateSeqBAIJ(), MatCreateBAIJ(), 200 MatCreateSeqSBAIJ(), MatCreateSBAIJ(), 201 MatConvert() 202 @*/ 203 PetscErrorCode MatSetFromOptions(Mat B) 204 { 205 PetscErrorCode ierr; 206 const char *deft = MATAIJ; 207 char type[256]; 208 PetscBool flg,set; 209 210 PetscFunctionBegin; 211 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 212 213 ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr); 214 215 if (B->rmap->bs < 0) { 216 PetscInt newbs = -1; 217 ierr = PetscOptionsInt("-mat_block_size","Set the blocksize used to store the matrix","MatSetBlockSize",newbs,&newbs,&flg);CHKERRQ(ierr); 218 if (flg) { 219 ierr = PetscLayoutSetBlockSize(B->rmap,newbs);CHKERRQ(ierr); 220 ierr = PetscLayoutSetBlockSize(B->cmap,newbs);CHKERRQ(ierr); 221 } 222 } 223 224 ierr = PetscOptionsFList("-mat_type","Matrix type","MatSetType",MatList,deft,type,256,&flg);CHKERRQ(ierr); 225 if (flg) { 226 ierr = MatSetType(B,type);CHKERRQ(ierr); 227 } else if (!((PetscObject)B)->type_name) { 228 ierr = MatSetType(B,deft);CHKERRQ(ierr); 229 } 230 231 ierr = PetscOptionsName("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",&B->checksymmetryonassembly);CHKERRQ(ierr); 232 ierr = PetscOptionsReal("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",B->checksymmetrytol,&B->checksymmetrytol,NULL);CHKERRQ(ierr); 233 ierr = PetscOptionsBool("-mat_null_space_test","Checks if provided null space is correct in MatAssemblyEnd()","MatSetNullSpaceTest",B->checknullspaceonassembly,&B->checknullspaceonassembly,NULL);CHKERRQ(ierr); 234 ierr = PetscOptionsBool("-mat_error_if_failure","Generate an error if an error occurs when factoring the matrix","MatSetErrorIfFailure",B->erroriffailure,&B->erroriffailure,NULL);CHKERRQ(ierr); 235 236 if (B->ops->setfromoptions) { 237 ierr = (*B->ops->setfromoptions)(PetscOptionsObject,B);CHKERRQ(ierr); 238 } 239 240 flg = PETSC_FALSE; 241 ierr = PetscOptionsBool("-mat_new_nonzero_location_err","Generate an error if new nonzeros are created in the matrix structure (useful to test preallocation)","MatSetOption",flg,&flg,&set);CHKERRQ(ierr); 242 if (set) {ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,flg);CHKERRQ(ierr);} 243 flg = PETSC_FALSE; 244 ierr = PetscOptionsBool("-mat_new_nonzero_allocation_err","Generate an error if new nonzeros are allocated in the matrix structure (useful to test preallocation)","MatSetOption",flg,&flg,&set);CHKERRQ(ierr); 245 if (set) {ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,flg);CHKERRQ(ierr);} 246 247 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 248 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)B);CHKERRQ(ierr); 249 ierr = PetscOptionsEnd();CHKERRQ(ierr); 250 PetscFunctionReturn(0); 251 } 252 253 /*@C 254 MatXAIJSetPreallocation - set preallocation for serial and parallel AIJ, BAIJ, and SBAIJ matrices and their unassembled versions. 255 256 Collective on Mat 257 258 Input Arguments: 259 + A - matrix being preallocated 260 . bs - block size 261 . dnnz - number of nonzero column blocks per block row of diagonal part of parallel matrix 262 . onnz - number of nonzero column blocks per block row of off-diagonal part of parallel matrix 263 . dnnzu - number of nonzero column blocks per block row of upper-triangular part of diagonal part of parallel matrix 264 - onnzu - number of nonzero column blocks per block row of upper-triangular part of off-diagonal part of parallel matrix 265 266 Level: beginner 267 268 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatSeqBAIJSetPreallocation(), MatMPIBAIJSetPreallocation(), MatSeqSBAIJSetPreallocation(), MatMPISBAIJSetPreallocation(), 269 PetscSplitOwnership() 270 @*/ 271 PetscErrorCode MatXAIJSetPreallocation(Mat A,PetscInt bs,const PetscInt dnnz[],const PetscInt onnz[],const PetscInt dnnzu[],const PetscInt onnzu[]) 272 { 273 PetscErrorCode ierr; 274 PetscInt cbs; 275 void (*aij)(void); 276 void (*is)(void); 277 void (*hyp)(void) = NULL; 278 279 PetscFunctionBegin; 280 if (bs != PETSC_DECIDE) { /* don't mess with an already set block size */ 281 ierr = MatSetBlockSize(A,bs);CHKERRQ(ierr); 282 } 283 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 284 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 285 ierr = MatGetBlockSizes(A,&bs,&cbs);CHKERRQ(ierr); 286 /* these routines assumes bs == cbs, this should be checked somehow */ 287 ierr = MatSeqBAIJSetPreallocation(A,bs,0,dnnz);CHKERRQ(ierr); 288 ierr = MatMPIBAIJSetPreallocation(A,bs,0,dnnz,0,onnz);CHKERRQ(ierr); 289 ierr = MatSeqSBAIJSetPreallocation(A,bs,0,dnnzu);CHKERRQ(ierr); 290 ierr = MatMPISBAIJSetPreallocation(A,bs,0,dnnzu,0,onnzu);CHKERRQ(ierr); 291 /* 292 In general, we have to do extra work to preallocate for scalar (AIJ) or unassembled (IS) matrices so we check whether it will do any 293 good before going on with it. 294 */ 295 ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 296 ierr = PetscObjectQueryFunction((PetscObject)A,"MatISSetPreallocation_C",&is);CHKERRQ(ierr); 297 #if defined(PETSC_HAVE_HYPRE) 298 ierr = PetscObjectQueryFunction((PetscObject)A,"MatHYPRESetPreallocation_C",&hyp);CHKERRQ(ierr); 299 #endif 300 if (!aij && !is && !hyp) { 301 ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",&aij);CHKERRQ(ierr); 302 } 303 if (aij || is || hyp) { 304 if (bs == cbs && bs == 1) { 305 ierr = MatSeqAIJSetPreallocation(A,0,dnnz);CHKERRQ(ierr); 306 ierr = MatMPIAIJSetPreallocation(A,0,dnnz,0,onnz);CHKERRQ(ierr); 307 ierr = MatISSetPreallocation(A,0,dnnz,0,onnz);CHKERRQ(ierr); 308 #if defined(PETSC_HAVE_HYPRE) 309 ierr = MatHYPRESetPreallocation(A,0,dnnz,0,onnz);CHKERRQ(ierr); 310 #endif 311 } else { /* Convert block-row precallocation to scalar-row */ 312 PetscInt i,m,*sdnnz,*sonnz; 313 ierr = MatGetLocalSize(A,&m,NULL);CHKERRQ(ierr); 314 ierr = PetscMalloc2((!!dnnz)*m,&sdnnz,(!!onnz)*m,&sonnz);CHKERRQ(ierr); 315 for (i=0; i<m; i++) { 316 if (dnnz) sdnnz[i] = dnnz[i/bs] * cbs; 317 if (onnz) sonnz[i] = onnz[i/bs] * cbs; 318 } 319 ierr = MatSeqAIJSetPreallocation(A,0,dnnz ? sdnnz : NULL);CHKERRQ(ierr); 320 ierr = MatMPIAIJSetPreallocation(A,0,dnnz ? sdnnz : NULL,0,onnz ? sonnz : NULL);CHKERRQ(ierr); 321 ierr = MatISSetPreallocation(A,0,dnnz ? sdnnz : NULL,0,onnz ? sonnz : NULL);CHKERRQ(ierr); 322 #if defined(PETSC_HAVE_HYPRE) 323 ierr = MatHYPRESetPreallocation(A,0,dnnz ? sdnnz : NULL,0,onnz ? sonnz : NULL);CHKERRQ(ierr); 324 #endif 325 ierr = PetscFree2(sdnnz,sonnz);CHKERRQ(ierr); 326 } 327 } 328 PetscFunctionReturn(0); 329 } 330 331 /* 332 Merges some information from Cs header to A; the C object is then destroyed 333 334 This is somewhat different from MatHeaderReplace() it would be nice to merge the code 335 */ 336 PetscErrorCode MatHeaderMerge(Mat A,Mat *C) 337 { 338 PetscErrorCode ierr; 339 PetscInt refct; 340 PetscOps Abops; 341 struct _MatOps Aops; 342 char *mtype,*mname,*mprefix; 343 344 PetscFunctionBegin; 345 /* save the parts of A we need */ 346 Abops = ((PetscObject)A)->bops[0]; 347 Aops = A->ops[0]; 348 refct = ((PetscObject)A)->refct; 349 mtype = ((PetscObject)A)->type_name; 350 mname = ((PetscObject)A)->name; 351 mprefix = ((PetscObject)A)->prefix; 352 353 /* zero these so the destroy below does not free them */ 354 ((PetscObject)A)->type_name = 0; 355 ((PetscObject)A)->name = 0; 356 357 /* free all the interior data structures from mat */ 358 ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 359 360 ierr = PetscFree(A->defaultvectype);CHKERRQ(ierr); 361 ierr = PetscLayoutDestroy(&A->rmap);CHKERRQ(ierr); 362 ierr = PetscLayoutDestroy(&A->cmap);CHKERRQ(ierr); 363 ierr = PetscFunctionListDestroy(&((PetscObject)A)->qlist);CHKERRQ(ierr); 364 ierr = PetscObjectListDestroy(&((PetscObject)A)->olist);CHKERRQ(ierr); 365 366 /* copy C over to A */ 367 ierr = PetscMemcpy(A,*C,sizeof(struct _p_Mat));CHKERRQ(ierr); 368 369 /* return the parts of A we saved */ 370 ((PetscObject)A)->bops[0] = Abops; 371 A->ops[0] = Aops; 372 ((PetscObject)A)->refct = refct; 373 ((PetscObject)A)->type_name = mtype; 374 ((PetscObject)A)->name = mname; 375 ((PetscObject)A)->prefix = mprefix; 376 377 /* since these two are copied into A we do not want them destroyed in C */ 378 ((PetscObject)*C)->qlist = 0; 379 ((PetscObject)*C)->olist = 0; 380 381 ierr = PetscHeaderDestroy(C);CHKERRQ(ierr); 382 PetscFunctionReturn(0); 383 } 384 /* 385 Replace A's header with that of C; the C object is then destroyed 386 387 This is essentially code moved from MatDestroy() 388 389 This is somewhat different from MatHeaderMerge() it would be nice to merge the code 390 391 Used in DM hence is declared PETSC_EXTERN 392 */ 393 PETSC_EXTERN PetscErrorCode MatHeaderReplace(Mat A,Mat *C) 394 { 395 PetscErrorCode ierr; 396 PetscInt refct; 397 PetscObjectState state; 398 struct _p_Mat buffer; 399 400 PetscFunctionBegin; 401 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 402 PetscValidHeaderSpecific(*C,MAT_CLASSID,2); 403 if (A == *C) PetscFunctionReturn(0); 404 PetscCheckSameComm(A,1,*C,2); 405 if (((PetscObject)*C)->refct != 1) SETERRQ1(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Object C has refct %D > 1, would leave hanging reference",((PetscObject)*C)->refct); 406 407 /* swap C and A */ 408 refct = ((PetscObject)A)->refct; 409 state = ((PetscObject)A)->state; 410 ierr = PetscMemcpy(&buffer,A,sizeof(struct _p_Mat));CHKERRQ(ierr); 411 ierr = PetscMemcpy(A,*C,sizeof(struct _p_Mat));CHKERRQ(ierr); 412 ierr = PetscMemcpy(*C,&buffer,sizeof(struct _p_Mat));CHKERRQ(ierr); 413 ((PetscObject)A)->refct = refct; 414 ((PetscObject)A)->state = state + 1; 415 416 ((PetscObject)*C)->refct = 1; 417 ierr = MatDestroy(C);CHKERRQ(ierr); 418 PetscFunctionReturn(0); 419 } 420 421 /*@ 422 MatPinToCPU - marks a matrix to temporarily stay on the CPU and perform computations on the CPU 423 424 Input Parameters: 425 + A - the matrix 426 - flg - pin to the CPU if value of PETSC_TRUE 427 428 @*/ 429 PetscErrorCode MatPinToCPU(Mat A,PetscBool flg) 430 { 431 PetscFunctionBegin; 432 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 433 PetscErrorCode ierr; 434 435 if (A->pinnedtocpu == flg) return 0; 436 A->pinnedtocpu = flg; 437 if (A->ops->pintocpu) { 438 ierr = (*A->ops->pintocpu)(A,flg);CHKERRQ(ierr); 439 } 440 #endif 441 PetscFunctionReturn(0); 442 } 443