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