1 2 /* 3 This file defines the initialization of PETSc, including PetscInitialize() 4 */ 5 #define PETSC_DESIRE_COMPLEX 6 #include <petscsys.h> /*I "petscsys.h" I*/ 7 8 #if defined(PETSC_HAVE_CUDA) 9 #include <cublas.h> 10 #endif 11 12 #include <petscthreadcomm.h> 13 14 #if defined(PETSC_USE_LOG) 15 extern PetscErrorCode PetscLogBegin_Private(void); 16 #endif 17 extern PetscBool PetscHMPIWorker; 18 19 20 #if defined(PETSC_SERIALIZE_FUNCTIONS) 21 PetscFPT PetscFPTData = 0; 22 #endif 23 24 /* -----------------------------------------------------------------------------------------*/ 25 26 extern FILE *petsc_history; 27 28 extern PetscErrorCode PetscInitialize_DynamicLibraries(void); 29 extern PetscErrorCode PetscFinalize_DynamicLibraries(void); 30 extern PetscErrorCode PetscFListDestroyAll(void); 31 extern PetscErrorCode PetscOpFListDestroyAll(void); 32 extern PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int); 33 extern PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int); 34 extern PetscErrorCode PetscCloseHistoryFile(FILE **); 35 36 /* user may set this BEFORE calling PetscInitialize() */ 37 MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL; 38 39 PetscMPIInt Petsc_Counter_keyval = MPI_KEYVAL_INVALID; 40 PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID; 41 PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID; 42 43 /* 44 Declare and set all the string names of the PETSc enums 45 */ 46 const char *const PetscBools[] = {"FALSE","TRUE","PetscBool","PETSC_",0}; 47 const char *const PetscCopyModes[] = {"COPY_VALUES","OWN_POINTER","USE_POINTER","PetscCopyMode","PETSC_",0}; 48 const char *const PetscDataTypes[] = {"INT","DOUBLE","COMPLEX","LONG","SHORT","FLOAT", 49 "CHAR","LOGICAL","ENUM","BOOL","LONGDOUBLE","OBJECT","FUNCTION","PetscDataType","PETSC_",0}; 50 51 PetscBool PetscPreLoadingUsed = PETSC_FALSE; 52 PetscBool PetscPreLoadingOn = PETSC_FALSE; 53 54 /* pthread_key for PetscStack */ 55 #if defined(PETSC_HAVE_PTHREADCLASSES) && !defined(PETSC_PTHREAD_LOCAL) 56 pthread_key_t petscstack; 57 #endif 58 59 /* 60 Checks the options database for initializations related to the 61 PETSc components 62 */ 63 #undef __FUNCT__ 64 #define __FUNCT__ "PetscOptionsCheckInitial_Components" 65 PetscErrorCode PetscOptionsCheckInitial_Components(void) 66 { 67 PetscBool flg1; 68 PetscErrorCode ierr; 69 70 PetscFunctionBegin; 71 ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg1);CHKERRQ(ierr); 72 if (flg1) { 73 #if defined (PETSC_USE_LOG) 74 MPI_Comm comm = PETSC_COMM_WORLD; 75 ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr); 76 ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr); 77 ierr = (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr); 78 ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr); 79 #endif 80 } 81 PetscFunctionReturn(0); 82 } 83 84 extern PetscBool PetscBeganMPI; 85 86 #undef __FUNCT__ 87 #define __FUNCT__ "PetscInitializeNoPointers" 88 /* 89 PetscInitializeNoPointers - Calls PetscInitialize() from C/C++ without the pointers to argc and args 90 91 Collective 92 93 Level: advanced 94 95 Notes: this is called only by the PETSc MATLAB and Julia interface. Even though it might start MPI it sets the flag to 96 indicate that it did NOT start MPI so that the PetscFinalize() does not end MPI, thus allowing PetscInitialize() to 97 be called multiple times from MATLAB and Julia without the problem of trying to initialize MPI more than once. 98 99 Turns off PETSc signal handling because that can interact with MATLAB's signal handling causing random crashes. 100 101 .seealso: PetscInitialize(), PetscInitializeFortran(), PetscInitializeNoArguments() 102 */ 103 PetscErrorCode PetscInitializeNoPointers(int argc,char **args,const char *filename,const char *help) 104 { 105 PetscErrorCode ierr; 106 int myargc = argc; 107 char **myargs = args; 108 109 PetscFunctionBegin; 110 ierr = PetscInitialize(&myargc,&myargs,filename,help); 111 ierr = PetscPopSignalHandler();CHKERRQ(ierr); 112 PetscBeganMPI = PETSC_FALSE; 113 PetscFunctionReturn(ierr); 114 } 115 116 #undef __FUNCT__ 117 #define __FUNCT__ "PetscGetPETSC_COMM_SELF" 118 /* 119 Used by MATLAB and Julia interface to get communicator 120 */ 121 PetscErrorCode PetscGetPETSC_COMM_SELF(MPI_Comm *comm) 122 { 123 PetscFunctionBegin; 124 *comm = PETSC_COMM_SELF; 125 PetscFunctionReturn(0); 126 } 127 128 #undef __FUNCT__ 129 #define __FUNCT__ "PetscInitializeNoArguments" 130 /*@C 131 PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without 132 the command line arguments. 133 134 Collective 135 136 Level: advanced 137 138 .seealso: PetscInitialize(), PetscInitializeFortran() 139 @*/ 140 PetscErrorCode PetscInitializeNoArguments(void) 141 { 142 PetscErrorCode ierr; 143 int argc = 0; 144 char **args = 0; 145 146 PetscFunctionBegin; 147 ierr = PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL); 148 PetscFunctionReturn(ierr); 149 } 150 151 #undef __FUNCT__ 152 #define __FUNCT__ "PetscInitialized" 153 /*@ 154 PetscInitialized - Determine whether PETSc is initialized. 155 156 7 Level: beginner 157 158 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran() 159 @*/ 160 PetscErrorCode PetscInitialized(PetscBool *isInitialized) 161 { 162 PetscFunctionBegin; 163 PetscValidPointer(isInitialized, 1); 164 *isInitialized = PetscInitializeCalled; 165 PetscFunctionReturn(0); 166 } 167 168 #undef __FUNCT__ 169 #define __FUNCT__ "PetscFinalized" 170 /*@ 171 PetscFinalized - Determine whether PetscFinalize() has been called yet 172 173 Level: developer 174 175 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran() 176 @*/ 177 PetscErrorCode PetscFinalized(PetscBool *isFinalized) 178 { 179 PetscFunctionBegin; 180 PetscValidPointer(isFinalized, 1); 181 *isFinalized = PetscFinalizeCalled; 182 PetscFunctionReturn(0); 183 } 184 185 extern PetscErrorCode PetscOptionsCheckInitial_Private(void); 186 extern PetscBool PetscBeganMPI; 187 188 /* 189 This function is the MPI reduction operation used to compute the sum of the 190 first half of the datatype and the max of the second half. 191 */ 192 MPI_Op PetscMaxSum_Op = 0; 193 194 EXTERN_C_BEGIN 195 #undef __FUNCT__ 196 #define __FUNCT__ "PetscMaxSum_Local" 197 void MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype) 198 { 199 PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt; 200 201 PetscFunctionBegin; 202 if (*datatype != MPIU_2INT) { 203 (*PetscErrorPrintf)("Can only handle MPIU_2INT data types"); 204 MPI_Abort(MPI_COMM_WORLD,1); 205 } 206 207 for (i=0; i<count; i++) { 208 xout[2*i] = PetscMax(xout[2*i],xin[2*i]); 209 xout[2*i+1] += xin[2*i+1]; 210 } 211 PetscFunctionReturnVoid(); 212 } 213 EXTERN_C_END 214 215 /* 216 Returns the max of the first entry owned by this processor and the 217 sum of the second entry. 218 219 The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero 220 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths 221 there would be no place to store the both needed results. 222 */ 223 #undef __FUNCT__ 224 #define __FUNCT__ "PetscMaxSum" 225 PetscErrorCode PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum) 226 { 227 PetscMPIInt size,rank; 228 struct {PetscInt max,sum;} *work; 229 PetscErrorCode ierr; 230 231 PetscFunctionBegin; 232 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 233 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 234 ierr = PetscMalloc(size*sizeof(*work),&work);CHKERRQ(ierr); 235 ierr = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 236 *max = work[rank].max; 237 *sum = work[rank].sum; 238 ierr = PetscFree(work);CHKERRQ(ierr); 239 PetscFunctionReturn(0); 240 } 241 242 /* ----------------------------------------------------------------------------*/ 243 MPI_Op PetscADMax_Op = 0; 244 245 EXTERN_C_BEGIN 246 #undef __FUNCT__ 247 #define __FUNCT__ "PetscADMax_Local" 248 void MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 249 { 250 PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out; 251 PetscInt i,count = *cnt; 252 253 PetscFunctionBegin; 254 if (*datatype != MPIU_2SCALAR) { 255 (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types"); 256 MPI_Abort(MPI_COMM_WORLD,1); 257 } 258 259 for (i=0; i<count; i++) { 260 if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) { 261 xout[2*i] = xin[2*i]; 262 xout[2*i+1] = xin[2*i+1]; 263 } 264 } 265 PetscFunctionReturnVoid(); 266 } 267 EXTERN_C_END 268 269 MPI_Op PetscADMin_Op = 0; 270 271 EXTERN_C_BEGIN 272 #undef __FUNCT__ 273 #define __FUNCT__ "PetscADMin_Local" 274 void MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 275 { 276 PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out; 277 PetscInt i,count = *cnt; 278 279 PetscFunctionBegin; 280 if (*datatype != MPIU_2SCALAR) { 281 (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types"); 282 MPI_Abort(MPI_COMM_WORLD,1); 283 } 284 285 for (i=0; i<count; i++) { 286 if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) { 287 xout[2*i] = xin[2*i]; 288 xout[2*i+1] = xin[2*i+1]; 289 } 290 } 291 PetscFunctionReturnVoid(); 292 } 293 EXTERN_C_END 294 /* ---------------------------------------------------------------------------------------*/ 295 296 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128) 297 MPI_Op MPIU_SUM = 0; 298 299 #undef __FUNCT__ 300 #define __FUNCT__ "PetscSum_Local" 301 PETSC_EXTERN_C void PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 302 { 303 PetscInt i,count = *cnt; 304 305 PetscFunctionBegin; 306 if (*datatype == MPIU_REAL) { 307 PetscReal *xin = (PetscReal *)in,*xout = (PetscReal*)out; 308 for (i=0; i<count; i++) { 309 xout[i] += xin[i]; 310 } 311 } 312 #if defined(PETSC_HAVE_COMPLEX) 313 else if (*datatype == MPIU_COMPLEX) { 314 PetscComplex *xin = (PetscComplex *)in,*xout = (PetscComplex*)out; 315 for (i=0; i<count; i++) { 316 xout[i] += xin[i]; 317 } 318 } 319 #endif 320 else { 321 (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types"); 322 MPI_Abort(MPI_COMM_WORLD,1); 323 } 324 PetscFunctionReturnVoid(); 325 } 326 #endif 327 328 #if defined(PETSC_USE_REAL___FLOAT128) 329 MPI_Op MPIU_MAX = 0; 330 MPI_Op MPIU_MIN = 0; 331 332 #undef __FUNCT__ 333 #define __FUNCT__ "PetscMax_Local" 334 PETSC_EXTERN_C void PetscMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 335 { 336 PetscInt i,count = *cnt; 337 338 PetscFunctionBegin; 339 if (*datatype == MPIU_REAL) { 340 PetscReal *xin = (PetscReal *)in,*xout = (PetscReal*)out; 341 for (i=0; i<count; i++) { 342 xout[i] = PetscMax(xout[i],xin[i]); 343 } 344 } 345 #if defined(PETSC_HAVE_COMPLEX) 346 else if (*datatype == MPIU_COMPLEX) { 347 PetscComplex *xin = (PetscComplex *)in,*xout = (PetscComplex*)out; 348 for (i=0; i<count; i++) { 349 xout[i] = PetscRealPartComplex(xout[i])<PetscRealPartComplex(xin[i])? xin[i]: xout[i]; 350 } 351 } 352 #endif 353 else { 354 (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types"); 355 MPI_Abort(MPI_COMM_WORLD,1); 356 } 357 PetscFunctionReturnVoid(); 358 } 359 360 #undef __FUNCT__ 361 #define __FUNCT__ "PetscMin_Local" 362 PETSC_EXTERN_C void PetscMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 363 { 364 PetscInt i,count = *cnt; 365 366 PetscFunctionBegin; 367 if (*datatype == MPIU_REAL) { 368 PetscReal *xin = (PetscReal *)in,*xout = (PetscReal*)out; 369 for (i=0; i<count; i++) { 370 xout[i] = PetscMin(xout[i],xin[i]); 371 } 372 } 373 #if defined(PETSC_HAVE_COMPLEX) 374 else if (*datatype == MPIU_COMPLEX) { 375 PetscComplex *xin = (PetscComplex *)in,*xout = (PetscComplex*)out; 376 for (i=0; i<count; i++) { 377 xout[i] = PetscRealPartComplex(xout[i])>PetscRealPartComplex(xin[i])? xin[i]: xout[i]; 378 } 379 } 380 #endif 381 else { 382 (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_SCALAR data (i.e. double or complex) types"); 383 MPI_Abort(MPI_COMM_WORLD,1); 384 } 385 PetscFunctionReturnVoid(); 386 } 387 #endif 388 389 EXTERN_C_BEGIN 390 #undef __FUNCT__ 391 #define __FUNCT__ "Petsc_DelCounter" 392 /* 393 Private routine to delete internal tag/name counter storage when a communicator is freed. 394 395 This is called by MPI, not by users. This is called by MPI_Comm_free() when the communicator that has this data as an attribute is freed. 396 397 Note: this is declared extern "C" because it is passed to MPI_Keyval_create() 398 399 */ 400 PetscMPIInt MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state) 401 { 402 PetscErrorCode ierr; 403 404 PetscFunctionBegin; 405 ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 406 ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 407 PetscFunctionReturn(MPI_SUCCESS); 408 } 409 EXTERN_C_END 410 411 EXTERN_C_BEGIN 412 #undef __FUNCT__ 413 #define __FUNCT__ "Petsc_DelComm" 414 /* 415 This does not actually free anything, it simply marks when a reference count to an internal or external MPI_Comm reaches zero and the 416 the external MPI_Comm drops its reference to the internal or external MPI_Comm 417 418 This is called by MPI, not by users. This is called when MPI_Comm_free() is called on the communicator. 419 420 Note: this is declared extern "C" because it is passed to MPI_Keyval_create() 421 422 */ 423 PetscMPIInt MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state) 424 { 425 PetscErrorCode ierr; 426 PetscMPIInt flg; 427 MPI_Comm icomm; 428 void *ptr; 429 430 PetscFunctionBegin; 431 ierr = MPI_Attr_get(comm,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr); 432 if (flg) { 433 /* Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers */ 434 ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr); 435 ierr = MPI_Attr_get(icomm,Petsc_OuterComm_keyval,&ptr,&flg);CHKERRQ(ierr); 436 if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected reference to outer comm"); 437 ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr); 438 ierr = PetscInfo1(0,"User MPI_Comm m %ld is being freed, removing reference from inner PETSc comm to this outer comm\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 439 } else { 440 ierr = PetscInfo1(0,"Removing reference to PETSc communicator imbedded in a user MPI_Comm m %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 441 } 442 PetscFunctionReturn(MPI_SUCCESS); 443 } 444 EXTERN_C_END 445 446 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32) 447 #if !defined(PETSC_WORDS_BIGENDIAN) 448 EXTERN_C_BEGIN 449 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*); 450 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*); 451 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*); 452 EXTERN_C_END 453 #endif 454 #endif 455 456 int PetscGlobalArgc = 0; 457 char **PetscGlobalArgs = 0; 458 459 #undef __FUNCT__ 460 #define __FUNCT__ "PetscGetArgs" 461 /*@C 462 PetscGetArgs - Allows you to access the raw command line arguments anywhere 463 after PetscInitialize() is called but before PetscFinalize(). 464 465 Not Collective 466 467 Output Parameters: 468 + argc - count of number of command line arguments 469 - args - the command line arguments 470 471 Level: intermediate 472 473 Notes: 474 This is usually used to pass the command line arguments into other libraries 475 that are called internally deep in PETSc or the application. 476 477 The first argument contains the program name as is normal for C arguments. 478 479 Concepts: command line arguments 480 481 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments() 482 483 @*/ 484 PetscErrorCode PetscGetArgs(int *argc,char ***args) 485 { 486 PetscFunctionBegin; 487 if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()"); 488 *argc = PetscGlobalArgc; 489 *args = PetscGlobalArgs; 490 PetscFunctionReturn(0); 491 } 492 493 #undef __FUNCT__ 494 #define __FUNCT__ "PetscGetArguments" 495 /*@C 496 PetscGetArguments - Allows you to access the command line arguments anywhere 497 after PetscInitialize() is called but before PetscFinalize(). 498 499 Not Collective 500 501 Output Parameters: 502 . args - the command line arguments 503 504 Level: intermediate 505 506 Notes: 507 This does NOT start with the program name and IS null terminated (final arg is void) 508 509 Concepts: command line arguments 510 511 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments() 512 513 @*/ 514 PetscErrorCode PetscGetArguments(char ***args) 515 { 516 PetscInt i,argc = PetscGlobalArgc; 517 PetscErrorCode ierr; 518 519 PetscFunctionBegin; 520 if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()"); 521 if (!argc) {*args = 0; PetscFunctionReturn(0);} 522 ierr = PetscMalloc(argc*sizeof(char*),args);CHKERRQ(ierr); 523 for (i=0; i<argc-1; i++) { 524 ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr); 525 } 526 (*args)[argc-1] = 0; 527 PetscFunctionReturn(0); 528 } 529 530 #undef __FUNCT__ 531 #define __FUNCT__ "PetscFreeArguments" 532 /*@C 533 PetscFreeArguments - Frees the memory obtained with PetscGetArguments() 534 535 Not Collective 536 537 Output Parameters: 538 . args - the command line arguments 539 540 Level: intermediate 541 542 Concepts: command line arguments 543 544 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments() 545 546 @*/ 547 PetscErrorCode PetscFreeArguments(char **args) 548 { 549 PetscInt i = 0; 550 PetscErrorCode ierr; 551 552 PetscFunctionBegin; 553 if (!args) {PetscFunctionReturn(0);} 554 while (args[i]) { 555 ierr = PetscFree(args[i]);CHKERRQ(ierr); 556 i++; 557 } 558 ierr = PetscFree(args);CHKERRQ(ierr); 559 PetscFunctionReturn(0); 560 } 561 562 #undef __FUNCT__ 563 #define __FUNCT__ "PetscInitialize" 564 /*@C 565 PetscInitialize - Initializes the PETSc database and MPI. 566 PetscInitialize() calls MPI_Init() if that has yet to be called, 567 so this routine should always be called near the beginning of 568 your program -- usually the very first line! 569 570 Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set 571 572 Input Parameters: 573 + argc - count of number of command line arguments 574 . args - the command line arguments 575 . file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL to not check for 576 code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files 577 - help - [optional] Help message to print, use PETSC_NULL for no message 578 579 If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that 580 communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a 581 four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not, 582 then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even 583 if different subcommunicators of the job are doing different things with PETSc. 584 585 Options Database Keys: 586 + -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger 587 . -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected 588 . -on_error_emacs <machinename> causes emacsclient to jump to error file 589 . -on_error_abort calls abort() when error detected (no traceback) 590 . -on_error_mpiabort calls MPI_abort() when error detected 591 . -error_output_stderr prints error messages to stderr instead of the default stdout 592 . -error_output_none does not print the error messages (but handles errors in the same way as if this was not called) 593 . -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger 594 . -debugger_pause [sleeptime] (in seconds) - Pauses debugger 595 . -stop_for_debugger - Print message on how to attach debugger manually to 596 process and wait (-debugger_pause) seconds for attachment 597 . -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries) 598 . -malloc no - Indicates not to use error-checking malloc 599 . -malloc_debug - check for memory corruption at EVERY malloc or free 600 . -malloc_test - like -malloc_dump -malloc_debug, but only active for debugging builds 601 . -fp_trap - Stops on floating point exceptions (Note that on the 602 IBM RS6000 this slows code by at least a factor of 10.) 603 . -no_signal_handler - Indicates not to trap error signals 604 . -shared_tmp - indicates /tmp directory is shared by all processors 605 . -not_shared_tmp - each processor has own /tmp 606 . -tmp - alternative name of /tmp directory 607 . -get_total_flops - returns total flops done by all processors 608 . -memory_info - Print memory usage at end of run 609 - -server <port> - start PETSc webserver (default port is 8080) 610 611 Options Database Keys for Profiling: 612 See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details. 613 + -log_trace [filename] - Print traces of all PETSc calls 614 to the screen (useful to determine where a program 615 hangs without running in the debugger). See PetscLogTraceBegin(). 616 . -info <optional filename> - Prints verbose information to the screen 617 - -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages 618 619 Environmental Variables: 620 + PETSC_TMP - alternative tmp directory 621 . PETSC_SHARED_TMP - tmp is shared by all processes 622 . PETSC_NOT_SHARED_TMP - each process has its own private tmp 623 . PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer 624 - PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to 625 626 627 Level: beginner 628 629 Notes: 630 If for some reason you must call MPI_Init() separately, call 631 it before PetscInitialize(). 632 633 Fortran Version: 634 In Fortran this routine has the format 635 $ call PetscInitialize(file,ierr) 636 637 + ierr - error return code 638 - file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for 639 code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files 640 641 Important Fortran Note: 642 In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a 643 null character string; you CANNOT just use PETSC_NULL as 644 in the C version. See the <a href="../../docs/manual.pdf">users manual</a> for details. 645 646 If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after 647 calling PetscInitialize(). 648 649 Concepts: initializing PETSc 650 651 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments() 652 653 @*/ 654 PetscErrorCode PetscInitialize(int *argc,char ***args,const char file[],const char help[]) 655 { 656 PetscErrorCode ierr; 657 PetscMPIInt flag, size; 658 PetscInt nodesize; 659 PetscBool flg; 660 char hostname[256]; 661 662 PetscFunctionBegin; 663 if (PetscInitializeCalled) PetscFunctionReturn(0); 664 665 /* these must be initialized in a routine, not as a constant declaration*/ 666 PETSC_STDOUT = stdout; 667 PETSC_STDERR = stderr; 668 669 ierr = PetscOptionsCreate();CHKERRQ(ierr); 670 671 /* 672 We initialize the program name here (before MPI_Init()) because MPICH has a bug in 673 it that it sets args[0] on all processors to be args[0] on the first processor. 674 */ 675 if (argc && *argc) { 676 ierr = PetscSetProgramName(**args);CHKERRQ(ierr); 677 } else { 678 ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr); 679 } 680 681 ierr = MPI_Initialized(&flag);CHKERRQ(ierr); 682 if (!flag) { 683 if (PETSC_COMM_WORLD != MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You cannot set PETSC_COMM_WORLD if you have not initialized MPI first"); 684 #if defined(PETSC_HAVE_MPI_INIT_THREAD) 685 { 686 PetscMPIInt provided; 687 ierr = MPI_Init_thread(argc,args,MPI_THREAD_FUNNELED,&provided);CHKERRQ(ierr); 688 } 689 #else 690 ierr = MPI_Init(argc,args);CHKERRQ(ierr); 691 #endif 692 PetscBeganMPI = PETSC_TRUE; 693 } 694 if (argc && args) { 695 PetscGlobalArgc = *argc; 696 PetscGlobalArgs = *args; 697 } 698 PetscFinalizeCalled = PETSC_FALSE; 699 700 if (PETSC_COMM_WORLD == MPI_COMM_NULL) { 701 PETSC_COMM_WORLD = MPI_COMM_WORLD; 702 } 703 ierr = MPI_Errhandler_set(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);CHKERRQ(ierr); 704 705 /* Done after init due to a bug in MPICH-GM? */ 706 ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr); 707 708 ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr); 709 ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr); 710 711 /* 712 Initialized the global complex variable; this is because with 713 shared libraries the constructors for global variables 714 are not called; at least on IRIX. 715 */ 716 #if defined(PETSC_HAVE_COMPLEX) 717 { 718 #if defined(PETSC_CLANGUAGE_CXX) 719 PetscComplex ic(0.0,1.0); 720 PETSC_i = ic; 721 #elif defined(PETSC_CLANGUAGE_C) 722 PETSC_i = _Complex_I; 723 #endif 724 } 725 726 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 727 ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr); 728 ierr = MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr); 729 ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX);CHKERRQ(ierr); 730 ierr = MPI_Type_commit(&MPIU_C_COMPLEX);CHKERRQ(ierr); 731 #endif 732 #endif /* PETSC_HAVE_COMPLEX */ 733 734 /* 735 Create the PETSc MPI reduction operator that sums of the first 736 half of the entries and maxes the second half. 737 */ 738 ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr); 739 740 #if defined(PETSC_USE_REAL___FLOAT128) 741 ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr); 742 ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr); 743 #if defined(PETSC_HAVE_COMPLEX) 744 ierr = MPI_Type_contiguous(4,MPI_DOUBLE,&MPIU___COMPLEX128);CHKERRQ(ierr); 745 ierr = MPI_Type_commit(&MPIU___COMPLEX128);CHKERRQ(ierr); 746 #endif 747 ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);CHKERRQ(ierr); 748 ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);CHKERRQ(ierr); 749 #endif 750 751 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128) 752 ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr); 753 #endif 754 755 ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr); 756 ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr); 757 ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr); 758 ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr); 759 760 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT) 761 ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr); 762 ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr); 763 #endif 764 765 /* 766 Attributes to be set on PETSc communicators 767 */ 768 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr); 769 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr); 770 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr); 771 772 /* 773 Build the options database 774 */ 775 ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr); 776 777 778 /* 779 Print main application help message 780 */ 781 ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 782 if (help && flg) { 783 ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr); 784 } 785 ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr); 786 787 /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */ 788 #if defined(PETSC_USE_LOG) 789 ierr = PetscLogBegin_Private();CHKERRQ(ierr); 790 #endif 791 792 /* 793 Load the dynamic libraries (on machines that support them), this registers all 794 the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes) 795 */ 796 ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr); 797 798 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 799 ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr); 800 ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr); 801 ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr); 802 803 ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr); 804 /* Check the options database for options related to the options database itself */ 805 ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr); 806 807 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32) 808 /* 809 Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI 810 811 Currently not used because it is not supported by MPICH. 812 */ 813 #if !defined(PETSC_WORDS_BIGENDIAN) 814 ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr); 815 #endif 816 #endif 817 818 ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_spawn_size",&nodesize,&flg);CHKERRQ(ierr); 819 if (flg) { 820 #if defined(PETSC_HAVE_MPI_COMM_SPAWN) 821 ierr = PetscHMPISpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */ 822 #else 823 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -hmpi_merge_size instead"); 824 #endif 825 } else { 826 ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_merge_size",&nodesize,&flg);CHKERRQ(ierr); 827 if (flg) { 828 ierr = PetscHMPIMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 829 if (PetscHMPIWorker) { /* if worker then never enter user code */ 830 PetscInitializeCalled = PETSC_TRUE; 831 ierr = PetscEnd(); 832 } 833 } 834 } 835 836 #if defined(PETSC_HAVE_CUDA) 837 { 838 PetscMPIInt p; 839 for (p = 0; p < PetscGlobalSize; ++p) { 840 if (p == PetscGlobalRank) {cublasInit();} 841 ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); 842 } 843 } 844 #endif 845 846 #if defined(PETSC_HAVE_AMS) 847 ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr); 848 if (flg) { 849 PetscAMSPublishAll = PETSC_TRUE; 850 } 851 #endif 852 853 ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr); 854 if (flg) { 855 PetscInitializeCalled = PETSC_TRUE; 856 ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 857 } 858 859 ierr = PetscThreadCommInitializePackage(PETSC_NULL);CHKERRQ(ierr); 860 861 #if defined(PETSC_USE_DEBUG) 862 PetscThreadLocalRegister(&petscstack); /* Creates petscstack_key if needed */ 863 ierr = PetscStackCreate();CHKERRQ(ierr); 864 #endif 865 866 #if defined(PETSC_SERIALIZE_FUNCTIONS) 867 ierr = PetscFPTCreate(10000);CHKERRQ(ierr); 868 #endif 869 870 /* 871 Once we are completedly initialized then we can set this variables 872 */ 873 PetscInitializeCalled = PETSC_TRUE; 874 PetscFunctionReturn(0); 875 } 876 877 extern PetscObject *PetscObjects; 878 extern PetscInt PetscObjectsCounts, PetscObjectsMaxCounts; 879 880 #undef __FUNCT__ 881 #define __FUNCT__ "PetscFinalize" 882 /*@C 883 PetscFinalize - Checks for options to be called at the conclusion 884 of the program. MPI_Finalize() is called only if the user had not 885 called MPI_Init() before calling PetscInitialize(). 886 887 Collective on PETSC_COMM_WORLD 888 889 Options Database Keys: 890 + -options_table - Calls PetscOptionsView() 891 . -options_left - Prints unused options that remain in the database 892 . -objects_dump [all] - Prints list of objects allocated by the user that have not been freed, the option all cause all outstanding objects to be listed 893 . -mpidump - Calls PetscMPIDump() 894 . -malloc_dump - Calls PetscMallocDump() 895 . -malloc_info - Prints total memory usage 896 - -malloc_log - Prints summary of memory usage 897 898 Options Database Keys for Profiling: 899 See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details. 900 + -log_summary [filename] - Prints summary of flop and timing 901 information to screen. If the filename is specified the 902 summary is written to the file. See PetscLogView(). 903 . -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen. 904 See PetscLogPrintSViewPython(). 905 . -log_all [filename] - Logs extensive profiling information 906 See PetscLogDump(). 907 . -log [filename] - Logs basic profiline information See PetscLogDump(). 908 . -log_sync - Log the synchronization in scatters, inner products 909 and norms 910 - -log_mpe [filename] - Creates a logfile viewable by the 911 utility Upshot/Nupshot (in MPICH distribution) 912 913 Level: beginner 914 915 Note: 916 See PetscInitialize() for more general runtime options. 917 918 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd() 919 @*/ 920 PetscErrorCode PetscFinalize(void) 921 { 922 PetscErrorCode ierr; 923 PetscMPIInt rank; 924 PetscInt nopt; 925 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE; 926 #if defined(PETSC_HAVE_AMS) 927 PetscBool flg = PETSC_FALSE; 928 #endif 929 #if defined(PETSC_USE_LOG) 930 char mname[PETSC_MAX_PATH_LEN]; 931 #endif 932 933 PetscFunctionBegin; 934 935 if (!PetscInitializeCalled) { 936 printf("PetscInitialize() must be called before PetscFinalize()\n"); 937 PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE); 938 } 939 ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n");CHKERRQ(ierr); 940 941 #if defined(PETSC_SERIALIZE_FUNCTIONS) 942 ierr = PetscFPTDestroy();CHKERRQ(ierr); 943 #endif 944 945 946 #if defined(PETSC_HAVE_AMS) 947 ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr); 948 if (flg) { 949 ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr); 950 } 951 #endif 952 953 ierr = PetscHMPIFinalize();CHKERRQ(ierr); 954 955 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 956 ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr); 957 if (!flg2) { 958 flg2 = PETSC_FALSE; 959 ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr); 960 } 961 if (flg2) { 962 ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr); 963 } 964 965 #if defined(PETSC_USE_LOG) 966 flg1 = PETSC_FALSE; 967 ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr); 968 if (flg1) { 969 PetscLogDouble flops = 0; 970 ierr = MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr); 971 ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr); 972 } 973 #endif 974 975 976 #if defined(PETSC_USE_LOG) 977 #if defined(PETSC_HAVE_MPE) 978 mname[0] = 0; 979 ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 980 if (flg1){ 981 if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);} 982 else {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);} 983 } 984 #endif 985 mname[0] = 0; 986 ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 987 if (flg1) { 988 PetscViewer viewer; 989 if (mname[0]) { 990 ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr); 991 ierr = PetscLogView(viewer);CHKERRQ(ierr); 992 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 993 } else { 994 viewer = PETSC_VIEWER_STDOUT_WORLD; 995 ierr = PetscLogView(viewer);CHKERRQ(ierr); 996 } 997 } 998 999 mname[0] = 0; 1000 ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 1001 if (flg1) { 1002 PetscViewer viewer; 1003 if (mname[0]) { 1004 ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr); 1005 ierr = PetscLogViewPython(viewer);CHKERRQ(ierr); 1006 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1007 } else { 1008 viewer = PETSC_VIEWER_STDOUT_WORLD; 1009 ierr = PetscLogViewPython(viewer);CHKERRQ(ierr); 1010 } 1011 } 1012 1013 ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 1014 if (flg1) { 1015 if (mname[0]) {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);} 1016 else {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);} 1017 } 1018 1019 mname[0] = 0; 1020 ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 1021 ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr); 1022 if (flg1 || flg2){ 1023 if (mname[0]) PetscLogDump(mname); 1024 else PetscLogDump(0); 1025 } 1026 #endif 1027 1028 /* 1029 Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_(). 1030 */ 1031 ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr); 1032 1033 #if defined(PETSC_USE_DEBUG) 1034 ierr = PetscStackDestroy();CHKERRQ(ierr); 1035 #endif 1036 1037 flg1 = PETSC_FALSE; 1038 ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr); 1039 if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);} 1040 flg1 = PETSC_FALSE; 1041 ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr); 1042 if (flg1) { 1043 ierr = PetscMPIDump(stdout);CHKERRQ(ierr); 1044 } 1045 flg1 = PETSC_FALSE; 1046 flg2 = PETSC_FALSE; 1047 /* preemptive call to avoid listing this option in options table as unused */ 1048 ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr); 1049 ierr = PetscOptionsHasName(PETSC_NULL,"-objects_dump",&flg1);CHKERRQ(ierr); 1050 ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr); 1051 1052 if (flg2) { 1053 ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 1054 } 1055 1056 /* to prevent PETSc -options_left from warning */ 1057 ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr); 1058 ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr); 1059 1060 if (!PetscHMPIWorker) { /* worker processes skip this because they do not usually process options */ 1061 flg3 = PETSC_FALSE; /* default value is required */ 1062 ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr); 1063 ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr); 1064 if (flg3) { 1065 if (!flg2) { /* have not yet printed the options */ 1066 ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 1067 } 1068 if (!nopt) { 1069 ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr); 1070 } else if (nopt == 1) { 1071 ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr); 1072 } else { 1073 ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %D unused database options. They are:\n",nopt);CHKERRQ(ierr); 1074 } 1075 } 1076 #if defined(PETSC_USE_DEBUG) 1077 if (nopt && !flg3 && !flg1) { 1078 ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr); 1079 ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr); 1080 ierr = PetscOptionsLeft();CHKERRQ(ierr); 1081 } else if (nopt && flg3) { 1082 #else 1083 if (nopt && flg3) { 1084 #endif 1085 ierr = PetscOptionsLeft();CHKERRQ(ierr); 1086 } 1087 } 1088 1089 /* 1090 List all objects the user may have forgot to free 1091 */ 1092 ierr = PetscOptionsHasName(PETSC_NULL,"-objects_dump",&flg1);CHKERRQ(ierr); 1093 if (flg1) { 1094 MPI_Comm local_comm; 1095 char string[64]; 1096 1097 ierr = PetscOptionsGetString(PETSC_NULL,"-objects_dump",string,64,PETSC_NULL);CHKERRQ(ierr); 1098 ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr); 1099 ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr); 1100 ierr = PetscObjectsDump(stdout,(string[0] == 'a') ? PETSC_TRUE : PETSC_FALSE);CHKERRQ(ierr); 1101 ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr); 1102 ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr); 1103 } 1104 PetscObjectsCounts = 0; 1105 PetscObjectsMaxCounts = 0; 1106 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 1107 1108 1109 #if defined(PETSC_USE_LOG) 1110 ierr = PetscLogDestroy();CHKERRQ(ierr); 1111 #endif 1112 1113 /* 1114 Free all the registered create functions, such as KSPList, VecList, SNESList, etc 1115 */ 1116 ierr = PetscFListDestroyAll();CHKERRQ(ierr); 1117 1118 /* 1119 Free all the registered op functions, such as MatOpList, etc 1120 */ 1121 ierr = PetscOpFListDestroyAll();CHKERRQ(ierr); 1122 1123 /* 1124 Destroy any packages that registered a finalize 1125 */ 1126 ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr); 1127 1128 /* 1129 Destroy all the function registration lists created 1130 */ 1131 ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr); 1132 1133 if (petsc_history) { 1134 ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr); 1135 petsc_history = 0; 1136 } 1137 1138 ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr); 1139 1140 { 1141 char fname[PETSC_MAX_PATH_LEN]; 1142 FILE *fd; 1143 int err; 1144 1145 fname[0] = 0; 1146 ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr); 1147 flg2 = PETSC_FALSE; 1148 ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_test",&flg2,PETSC_NULL);CHKERRQ(ierr); 1149 #if defined(PETSC_USE_DEBUG) 1150 if (PETSC_RUNNING_ON_VALGRIND) flg2 = PETSC_FALSE; 1151 #else 1152 flg2 = PETSC_FALSE; /* Skip reporting for optimized builds regardless of -malloc_test */ 1153 #endif 1154 if (flg1 && fname[0]) { 1155 char sname[PETSC_MAX_PATH_LEN]; 1156 1157 sprintf(sname,"%s_%d",fname,rank); 1158 fd = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname); 1159 ierr = PetscMallocDump(fd);CHKERRQ(ierr); 1160 err = fclose(fd); 1161 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 1162 } else if (flg1 || flg2) { 1163 MPI_Comm local_comm; 1164 1165 ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr); 1166 ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr); 1167 ierr = PetscMallocDump(stdout);CHKERRQ(ierr); 1168 ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr); 1169 ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr); 1170 } 1171 } 1172 1173 { 1174 char fname[PETSC_MAX_PATH_LEN]; 1175 FILE *fd = PETSC_NULL; 1176 1177 fname[0] = 0; 1178 ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr); 1179 ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_log_threshold",&flg2);CHKERRQ(ierr); 1180 if (flg1 && fname[0]) { 1181 int err; 1182 1183 if (!rank) { 1184 fd = fopen(fname,"w"); 1185 if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",fname); 1186 } 1187 ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr); 1188 if (fd) { 1189 err = fclose(fd); 1190 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 1191 } 1192 } else if (flg1 || flg2) { 1193 ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr); 1194 } 1195 } 1196 /* Can be destroyed only after all the options are used */ 1197 ierr = PetscOptionsDestroy();CHKERRQ(ierr); 1198 1199 PetscGlobalArgc = 0; 1200 PetscGlobalArgs = 0; 1201 1202 #if defined(PETSC_USE_REAL___FLOAT128) 1203 ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr); 1204 #if defined(PETSC_HAVE_COMPLEX) 1205 ierr = MPI_Type_free(&MPIU___COMPLEX128);CHKERRQ(ierr); 1206 #endif 1207 ierr = MPI_Op_free(&MPIU_MAX);CHKERRQ(ierr); 1208 ierr = MPI_Op_free(&MPIU_MIN);CHKERRQ(ierr); 1209 #endif 1210 1211 #if defined(PETSC_HAVE_COMPLEX) 1212 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 1213 ierr = MPI_Type_free(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr); 1214 ierr = MPI_Type_free(&MPIU_C_COMPLEX);CHKERRQ(ierr); 1215 #endif 1216 #endif 1217 1218 #if (defined(PETSC_HAVE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128) 1219 ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr); 1220 #endif 1221 1222 ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr); 1223 #if defined(PETSC_USE_64BIT_INDICES) || !defined(MPI_2INT) 1224 ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr); 1225 #endif 1226 ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr); 1227 ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr); 1228 ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr); 1229 1230 /* 1231 Destroy any known inner MPI_Comm's and attributes pointing to them 1232 Note this will not destroy any new communicators the user has created. 1233 1234 If all PETSc objects were not destroyed those left over objects will have hanging references to 1235 the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again 1236 */ 1237 { 1238 PetscCommCounter *counter; 1239 PetscMPIInt flg; 1240 MPI_Comm icomm; 1241 void *ptr; 1242 ierr = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr); 1243 if (flg) { 1244 /* Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers */ 1245 ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr); 1246 ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr); 1247 if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory"); 1248 1249 ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr); 1250 ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr); 1251 ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr); 1252 } 1253 ierr = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr); 1254 if (flg) { 1255 /* Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers */ 1256 ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr); 1257 ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr); 1258 if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory"); 1259 1260 ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr); 1261 ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr); 1262 ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr); 1263 } 1264 } 1265 1266 ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr); 1267 ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr); 1268 ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr); 1269 1270 #if defined(PETSC_HAVE_CUDA) 1271 { 1272 PetscInt p; 1273 for (p = 0; p < PetscGlobalSize; ++p) { 1274 if (p == PetscGlobalRank) {cublasShutdown();} 1275 ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); 1276 } 1277 } 1278 #endif 1279 1280 if (PetscBeganMPI) { 1281 #if defined(PETSC_HAVE_MPI_FINALIZED) 1282 PetscMPIInt flag; 1283 ierr = MPI_Finalized(&flag);CHKERRQ(ierr); 1284 if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()"); 1285 #endif 1286 ierr = MPI_Finalize();CHKERRQ(ierr); 1287 } 1288 /* 1289 1290 Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because 1291 the communicator has some outstanding requests on it. Specifically if the 1292 flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See 1293 src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate() 1294 is never freed as it should be. Thus one may obtain messages of the form 1295 [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the 1296 memory was not freed. 1297 1298 */ 1299 ierr = PetscMallocClear();CHKERRQ(ierr); 1300 PetscInitializeCalled = PETSC_FALSE; 1301 PetscFinalizeCalled = PETSC_TRUE; 1302 PetscFunctionReturn(ierr); 1303 } 1304 1305 #if defined(PETSC_MISSING_LAPACK_lsame_) 1306 EXTERN_C_BEGIN 1307 int lsame_(char *a,char *b) 1308 { 1309 if (*a == *b) return 1; 1310 if (*a + 32 == *b) return 1; 1311 if (*a - 32 == *b) return 1; 1312 return 0; 1313 } 1314 EXTERN_C_END 1315 #endif 1316 1317 #if defined(PETSC_MISSING_LAPACK_lsame) 1318 EXTERN_C_BEGIN 1319 int lsame(char *a,char *b) 1320 { 1321 if (*a == *b) return 1; 1322 if (*a + 32 == *b) return 1; 1323 if (*a - 32 == *b) return 1; 1324 return 0; 1325 } 1326 EXTERN_C_END 1327 #endif 1328