1 #define PETSC_DLL 2 /* 3 This file defines the initialization of PETSc, including PetscInitialize() 4 */ 5 6 #include "petscsys.h" /*I "petscsys.h" I*/ 7 8 #if defined(PETSC_HAVE_CUDA) 9 10 EXTERN void cublasInit_Public(void); 11 EXTERN void cublasShutdown_Public(void); 12 #endif 13 14 #if defined(PETSC_USE_LOG) 15 EXTERN PetscErrorCode PetscLogBegin_Private(void); 16 #endif 17 extern PetscTruth PetscOpenMPWorker; 18 19 /* -----------------------------------------------------------------------------------------*/ 20 21 extern FILE *petsc_history; 22 23 EXTERN PetscErrorCode PetscInitialize_DynamicLibraries(void); 24 EXTERN PetscErrorCode PetscFinalize_DynamicLibraries(void); 25 EXTERN PetscErrorCode PetscFListDestroyAll(void); 26 EXTERN PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int); 27 EXTERN PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int); 28 EXTERN PetscErrorCode PetscLogCloseHistoryFile(FILE **); 29 30 /* this is used by the _, __, and ___ macros (see include/petscerror.h) */ 31 PetscErrorCode __gierr = 0; 32 33 /* user may set this BEFORE calling PetscInitialize() */ 34 MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL; 35 36 PetscMPIInt Petsc_Counter_keyval = MPI_KEYVAL_INVALID; 37 PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID; 38 PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID; 39 40 /* 41 Declare and set all the string names of the PETSc enums 42 */ 43 const char *PetscTruths[] = {"FALSE","TRUE","PetscTruth","PETSC_",0}; 44 const char *PetscDataTypes[] = {"INT", "DOUBLE", "COMPLEX", 45 "LONG","SHORT", "FLOAT", 46 "CHAR","LOGICAL","ENUM","TRUTH","LONGDOUBLE","PetscDataType","PETSC_",0}; 47 48 PetscTruth PetscPreLoadingUsed = PETSC_FALSE; 49 PetscTruth PetscPreLoadingOn = PETSC_FALSE; 50 51 /* 52 Checks the options database for initializations related to the 53 PETSc components 54 */ 55 #undef __FUNCT__ 56 #define __FUNCT__ "PetscOptionsCheckInitial_Components" 57 PetscErrorCode PETSC_DLLEXPORT PetscOptionsCheckInitial_Components(void) 58 { 59 PetscTruth flg1; 60 PetscErrorCode ierr; 61 62 PetscFunctionBegin; 63 ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg1);CHKERRQ(ierr); 64 if (flg1) { 65 #if defined (PETSC_USE_LOG) 66 MPI_Comm comm = PETSC_COMM_WORLD; 67 ierr = (*PetscHelpPrintf)(comm,"------Additional PETSc component options--------\n");CHKERRQ(ierr); 68 ierr = (*PetscHelpPrintf)(comm," -log_summary_exclude: <vec,mat,pc.ksp,snes>\n");CHKERRQ(ierr); 69 ierr = (*PetscHelpPrintf)(comm," -info_exclude: <null,vec,mat,pc,ksp,snes,ts>\n");CHKERRQ(ierr); 70 ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr); 71 #endif 72 } 73 PetscFunctionReturn(0); 74 } 75 76 #undef __FUNCT__ 77 #define __FUNCT__ "PetscInitializeNoArguments" 78 /*@C 79 PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without 80 the command line arguments. 81 82 Collective 83 84 Level: advanced 85 86 .seealso: PetscInitialize(), PetscInitializeFortran() 87 @*/ 88 PetscErrorCode PETSC_DLLEXPORT PetscInitializeNoArguments(void) 89 { 90 PetscErrorCode ierr; 91 int argc = 0; 92 char **args = 0; 93 94 PetscFunctionBegin; 95 ierr = PetscInitialize(&argc,&args,PETSC_NULL,PETSC_NULL); 96 PetscFunctionReturn(ierr); 97 } 98 99 #undef __FUNCT__ 100 #define __FUNCT__ "PetscInitialized" 101 /*@ 102 PetscInitialized - Determine whether PETSc is initialized. 103 104 7 Level: beginner 105 106 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran() 107 @*/ 108 PetscErrorCode PETSC_DLLEXPORT PetscInitialized(PetscTruth *isInitialized) 109 { 110 PetscFunctionBegin; 111 PetscValidPointer(isInitialized, 1); 112 *isInitialized = PetscInitializeCalled; 113 PetscFunctionReturn(0); 114 } 115 116 #undef __FUNCT__ 117 #define __FUNCT__ "PetscFinalized" 118 /*@ 119 PetscFinalized - Determine whether PetscFinalize() has been called yet 120 121 Level: developer 122 123 .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran() 124 @*/ 125 PetscErrorCode PETSC_DLLEXPORT PetscFinalized(PetscTruth *isFinalized) 126 { 127 PetscFunctionBegin; 128 PetscValidPointer(isFinalized, 1); 129 *isFinalized = PetscFinalizeCalled; 130 PetscFunctionReturn(0); 131 } 132 133 EXTERN PetscErrorCode PetscOptionsCheckInitial_Private(void); 134 extern PetscTruth PetscBeganMPI; 135 136 /* 137 This function is the MPI reduction operation used to compute the sum of the 138 first half of the datatype and the max of the second half. 139 */ 140 MPI_Op PetscMaxSum_Op = 0; 141 142 EXTERN_C_BEGIN 143 #undef __FUNCT__ 144 #define __FUNCT__ "PetscMaxSum_Local" 145 void PETSC_DLLEXPORT MPIAPI PetscMaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype) 146 { 147 PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt; 148 149 PetscFunctionBegin; 150 if (*datatype != MPIU_2INT) { 151 (*PetscErrorPrintf)("Can only handle MPIU_2INT data types"); 152 MPI_Abort(MPI_COMM_WORLD,1); 153 } 154 155 for (i=0; i<count; i++) { 156 xout[2*i] = PetscMax(xout[2*i],xin[2*i]); 157 xout[2*i+1] += xin[2*i+1]; 158 } 159 PetscStackPop; 160 return; 161 } 162 EXTERN_C_END 163 164 /* 165 Returns the max of the first entry owned by this processor and the 166 sum of the second entry. 167 168 The reason nprocs[2*i] contains lengths nprocs[2*i+1] contains flag of 1 if length is nonzero 169 is so that the PetscMaxSum_Op() can set TWO values, if we passed in only nprocs[i] with lengths 170 there would be no place to store the both needed results. 171 */ 172 #undef __FUNCT__ 173 #define __FUNCT__ "PetscMaxSum" 174 PetscErrorCode PETSC_DLLEXPORT PetscMaxSum(MPI_Comm comm,const PetscInt nprocs[],PetscInt *max,PetscInt *sum) 175 { 176 PetscMPIInt size,rank; 177 PetscInt *work; 178 PetscErrorCode ierr; 179 180 PetscFunctionBegin; 181 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 182 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 183 ierr = PetscMalloc(2*size*sizeof(PetscInt),&work);CHKERRQ(ierr); 184 ierr = MPI_Allreduce((void*)nprocs,work,size,MPIU_2INT,PetscMaxSum_Op,comm);CHKERRQ(ierr); 185 *max = work[2*rank]; 186 *sum = work[2*rank+1]; 187 ierr = PetscFree(work);CHKERRQ(ierr); 188 PetscFunctionReturn(0); 189 } 190 191 /* ----------------------------------------------------------------------------*/ 192 MPI_Op PETSC_DLLEXPORT PetscADMax_Op = 0; 193 194 EXTERN_C_BEGIN 195 #undef __FUNCT__ 196 #define __FUNCT__ "PetscADMax_Local" 197 void PETSC_DLLEXPORT MPIAPI PetscADMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 198 { 199 PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out; 200 PetscInt i,count = *cnt; 201 202 PetscFunctionBegin; 203 if (*datatype != MPIU_2SCALAR) { 204 (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types"); 205 MPI_Abort(MPI_COMM_WORLD,1); 206 } 207 208 for (i=0; i<count; i++) { 209 if (PetscRealPart(xout[2*i]) < PetscRealPart(xin[2*i])) { 210 xout[2*i] = xin[2*i]; 211 xout[2*i+1] = xin[2*i+1]; 212 } 213 } 214 215 PetscStackPop; 216 return; 217 } 218 EXTERN_C_END 219 220 MPI_Op PETSC_DLLEXPORT PetscADMin_Op = 0; 221 222 EXTERN_C_BEGIN 223 #undef __FUNCT__ 224 #define __FUNCT__ "PetscADMin_Local" 225 void PETSC_DLLEXPORT MPIAPI PetscADMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 226 { 227 PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out; 228 PetscInt i,count = *cnt; 229 230 PetscFunctionBegin; 231 if (*datatype != MPIU_2SCALAR) { 232 (*PetscErrorPrintf)("Can only handle MPIU_2SCALAR data (i.e. double or complex) types"); 233 MPI_Abort(MPI_COMM_WORLD,1); 234 } 235 236 for (i=0; i<count; i++) { 237 if (PetscRealPart(xout[2*i]) > PetscRealPart(xin[2*i])) { 238 xout[2*i] = xin[2*i]; 239 xout[2*i+1] = xin[2*i+1]; 240 } 241 } 242 243 PetscStackPop; 244 return; 245 } 246 EXTERN_C_END 247 /* ---------------------------------------------------------------------------------------*/ 248 249 #if defined(PETSC_USE_COMPLEX) 250 251 /* 252 This operation is only needed when using complex numbers with older MPI that does not support complex numbers 253 */ 254 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 255 MPI_Op MPIU_SUM = 0; 256 257 EXTERN_C_BEGIN 258 #undef __FUNCT__ 259 #define __FUNCT__ "PetscSum_Local" 260 void PETSC_DLLEXPORT PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype) 261 { 262 PetscScalar *xin = (PetscScalar *)in,*xout = (PetscScalar*)out; 263 PetscInt i,count = *cnt; 264 265 PetscFunctionBegin; 266 if (*datatype != MPIU_SCALAR) { 267 (*PetscErrorPrintf)("Can only handle MPIU_SCALAR data (i.e. double or complex) types"); 268 MPI_Abort(MPI_COMM_WORLD,1); 269 } 270 271 for (i=0; i<count; i++) { 272 xout[i] += xin[i]; 273 } 274 275 PetscStackPop; 276 return; 277 } 278 EXTERN_C_END 279 #endif 280 #endif 281 282 EXTERN_C_BEGIN 283 #undef __FUNCT__ 284 #define __FUNCT__ "Petsc_DelCounter" 285 /* 286 Private routine to delete internal tag/name counter storage when a communicator is freed. 287 288 This is called by MPI, not by users. 289 290 Note: this is declared extern "C" because it is passed to MPI_Keyval_create() 291 292 */ 293 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelCounter(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state) 294 { 295 PetscErrorCode ierr; 296 297 PetscFunctionBegin; 298 ierr = PetscInfo1(0,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 299 ierr = PetscFree(count_val);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 300 PetscFunctionReturn(MPI_SUCCESS); 301 } 302 EXTERN_C_END 303 304 EXTERN_C_BEGIN 305 #undef __FUNCT__ 306 #define __FUNCT__ "Petsc_DelComm" 307 /* 308 This does not actually free anything, it simply marks when a reference count to an internal MPI_Comm reaches zero and the 309 the external MPI_Comm drops its reference to the internal MPI_Comm 310 311 This is called by MPI, not by users. 312 313 Note: this is declared extern "C" because it is passed to MPI_Keyval_create() 314 315 */ 316 PetscMPIInt PETSC_DLLEXPORT MPIAPI Petsc_DelComm(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state) 317 { 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 ierr = PetscInfo1(0,"Deleting PETSc communicator imbedded in a user MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 322 /* actually don't delete anything because we cannot increase the reference count of the communicator anyways */ 323 PetscFunctionReturn(MPI_SUCCESS); 324 } 325 EXTERN_C_END 326 327 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32) 328 #if !defined(PETSC_WORDS_BIGENDIAN) 329 EXTERN_C_BEGIN 330 extern PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*); 331 extern PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*); 332 extern PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*); 333 EXTERN_C_END 334 #endif 335 #endif 336 337 int PetscGlobalArgc = 0; 338 char **PetscGlobalArgs = 0; 339 340 #undef __FUNCT__ 341 #define __FUNCT__ "PetscGetArgs" 342 /*@C 343 PetscGetArgs - Allows you to access the raw command line arguments anywhere 344 after PetscInitialize() is called but before PetscFinalize(). 345 346 Not Collective 347 348 Output Parameters: 349 + argc - count of number of command line arguments 350 - args - the command line arguments 351 352 Level: intermediate 353 354 Notes: 355 This is usually used to pass the command line arguments into other libraries 356 that are called internally deep in PETSc or the application. 357 358 The first argument contains the program name as is normal for C arguments. 359 360 Concepts: command line arguments 361 362 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments() 363 364 @*/ 365 PetscErrorCode PETSC_DLLEXPORT PetscGetArgs(int *argc,char ***args) 366 { 367 PetscFunctionBegin; 368 if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()"); 369 *argc = PetscGlobalArgc; 370 *args = PetscGlobalArgs; 371 PetscFunctionReturn(0); 372 } 373 374 #undef __FUNCT__ 375 #define __FUNCT__ "PetscGetArguments" 376 /*@C 377 PetscGetArguments - Allows you to access the command line arguments anywhere 378 after PetscInitialize() is called but before PetscFinalize(). 379 380 Not Collective 381 382 Output Parameters: 383 . args - the command line arguments 384 385 Level: intermediate 386 387 Notes: 388 This does NOT start with the program name and IS null terminated (final arg is void) 389 390 Concepts: command line arguments 391 392 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments() 393 394 @*/ 395 PetscErrorCode PETSC_DLLEXPORT PetscGetArguments(char ***args) 396 { 397 PetscInt i,argc = PetscGlobalArgc; 398 PetscErrorCode ierr; 399 400 PetscFunctionBegin; 401 if (!PetscInitializeCalled && PetscFinalizeCalled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call after PetscInitialize() but before PetscFinalize()"); 402 if (!argc) {*args = 0; PetscFunctionReturn(0);} 403 ierr = PetscMalloc(argc*sizeof(char*),args);CHKERRQ(ierr); 404 for (i=0; i<argc-1; i++) { 405 ierr = PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);CHKERRQ(ierr); 406 } 407 (*args)[argc-1] = 0; 408 PetscFunctionReturn(0); 409 } 410 411 #undef __FUNCT__ 412 #define __FUNCT__ "PetscFreeArguments" 413 /*@C 414 PetscFreeArguments - Frees the memory obtained with PetscGetArguments() 415 416 Not Collective 417 418 Output Parameters: 419 . args - the command line arguments 420 421 Level: intermediate 422 423 Concepts: command line arguments 424 425 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments() 426 427 @*/ 428 PetscErrorCode PETSC_DLLEXPORT PetscFreeArguments(char **args) 429 { 430 PetscInt i = 0; 431 PetscErrorCode ierr; 432 433 PetscFunctionBegin; 434 if (!args) {PetscFunctionReturn(0);} 435 while (args[i]) { 436 ierr = PetscFree(args[i]);CHKERRQ(ierr); 437 i++; 438 } 439 ierr = PetscFree(args);CHKERRQ(ierr); 440 PetscFunctionReturn(0); 441 } 442 443 #undef __FUNCT__ 444 #define __FUNCT__ "PetscInitialize" 445 /*@C 446 PetscInitialize - Initializes the PETSc database and MPI. 447 PetscInitialize() calls MPI_Init() if that has yet to be called, 448 so this routine should always be called near the beginning of 449 your program -- usually the very first line! 450 451 Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set 452 453 Input Parameters: 454 + argc - count of number of command line arguments 455 . args - the command line arguments 456 . file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL to not check for 457 code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files 458 - help - [optional] Help message to print, use PETSC_NULL for no message 459 460 If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that 461 communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a 462 four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not, 463 then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even 464 if different subcommunicators of the job are doing different things with PETSc. 465 466 Options Database Keys: 467 + -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger 468 . -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected 469 . -on_error_emacs <machinename> causes emacsclient to jump to error file 470 . -on_error_abort calls abort() when error detected (no traceback) 471 . -on_error_mpiabort calls MPI_abort() when error detected 472 . -error_output_stderr prints error messages to stderr instead of the default stdout 473 . -error_output_none does not print the error messages (but handles errors in the same way as if this was not called) 474 . -debugger_nodes [node1,node2,...] - Indicates nodes to start in debugger 475 . -debugger_pause [sleeptime] (in seconds) - Pauses debugger 476 . -stop_for_debugger - Print message on how to attach debugger manually to 477 process and wait (-debugger_pause) seconds for attachment 478 . -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries) 479 . -malloc no - Indicates not to use error-checking malloc 480 . -malloc_debug - check for memory corruption at EVERY malloc or free 481 . -fp_trap - Stops on floating point exceptions (Note that on the 482 IBM RS6000 this slows code by at least a factor of 10.) 483 . -no_signal_handler - Indicates not to trap error signals 484 . -shared_tmp - indicates /tmp directory is shared by all processors 485 . -not_shared_tmp - each processor has own /tmp 486 . -tmp - alternative name of /tmp directory 487 . -get_total_flops - returns total flops done by all processors 488 - -memory_info - Print memory usage at end of run 489 490 Options Database Keys for Profiling: 491 See the Profiling chapter of the users manual for details. 492 + -log_trace [filename] - Print traces of all PETSc calls 493 to the screen (useful to determine where a program 494 hangs without running in the debugger). See PetscLogTraceBegin(). 495 . -info <optional filename> - Prints verbose information to the screen 496 - -info_exclude <null,vec,mat,pc,ksp,snes,ts> - Excludes some of the verbose messages 497 498 Environmental Variables: 499 + PETSC_TMP - alternative tmp directory 500 . PETSC_SHARED_TMP - tmp is shared by all processes 501 . PETSC_NOT_SHARED_TMP - each process has its own private tmp 502 . PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer 503 - PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to 504 505 506 Level: beginner 507 508 Notes: 509 If for some reason you must call MPI_Init() separately, call 510 it before PetscInitialize(). 511 512 Fortran Version: 513 In Fortran this routine has the format 514 $ call PetscInitialize(file,ierr) 515 516 + ierr - error return code 517 - file - [optional] PETSc database file, also checks ~username/.petscrc and .petscrc use PETSC_NULL_CHARACTER to not check for 518 code specific file. Use -skip_petscrc in the code specific file to skip the .petscrc files 519 520 Important Fortran Note: 521 In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a 522 null character string; you CANNOT just use PETSC_NULL as 523 in the C version. See the users manual for details. 524 525 If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after 526 calling PetscInitialize(). 527 528 Concepts: initializing PETSc 529 530 .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments() 531 532 @*/ 533 PetscErrorCode PETSC_DLLEXPORT PetscInitialize(int *argc,char ***args,const char file[],const char help[]) 534 { 535 PetscErrorCode ierr; 536 PetscMPIInt flag, size; 537 PetscInt nodesize; 538 PetscTruth flg; 539 char hostname[256]; 540 541 PetscFunctionBegin; 542 if (PetscInitializeCalled) PetscFunctionReturn(0); 543 544 /* these must be initialized in a routine, not as a constant declaration*/ 545 PETSC_STDOUT = stdout; 546 PETSC_STDERR = stderr; 547 548 ierr = PetscOptionsCreate();CHKERRQ(ierr); 549 550 /* 551 We initialize the program name here (before MPI_Init()) because MPICH has a bug in 552 it that it sets args[0] on all processors to be args[0] on the first processor. 553 */ 554 if (argc && *argc) { 555 ierr = PetscSetProgramName(**args);CHKERRQ(ierr); 556 } else { 557 ierr = PetscSetProgramName("Unknown Name");CHKERRQ(ierr); 558 } 559 560 ierr = MPI_Initialized(&flag);CHKERRQ(ierr); 561 if (!flag) { 562 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"); 563 ierr = MPI_Init(argc,args);CHKERRQ(ierr); 564 PetscBeganMPI = PETSC_TRUE; 565 } 566 if (argc && args) { 567 PetscGlobalArgc = *argc; 568 PetscGlobalArgs = *args; 569 } 570 PetscFinalizeCalled = PETSC_FALSE; 571 572 if (PETSC_COMM_WORLD == MPI_COMM_NULL) { 573 PETSC_COMM_WORLD = MPI_COMM_WORLD; 574 } 575 576 /* Done after init due to a bug in MPICH-GM? */ 577 ierr = PetscErrorPrintfInitialize();CHKERRQ(ierr); 578 579 ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr); 580 ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr); 581 582 #if defined(PETSC_USE_COMPLEX) 583 /* 584 Initialized the global complex variable; this is because with 585 shared libraries the constructors for global variables 586 are not called; at least on IRIX. 587 */ 588 { 589 #if defined(PETSC_CLANGUAGE_CXX) 590 PetscScalar ic(0.0,1.0); 591 PETSC_i = ic; 592 #else 593 PETSC_i = I; 594 #endif 595 } 596 597 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 598 ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr); 599 ierr = MPI_Type_commit(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr); 600 ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPI_C_COMPLEX);CHKERRQ(ierr); 601 ierr = MPI_Type_commit(&MPI_C_COMPLEX);CHKERRQ(ierr); 602 ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr); 603 #endif 604 #endif 605 606 /* 607 Create the PETSc MPI reduction operator that sums of the first 608 half of the entries and maxes the second half. 609 */ 610 ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op);CHKERRQ(ierr); 611 612 ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr); 613 ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr); 614 ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr); 615 ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr); 616 617 ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr); 618 ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr); 619 620 /* 621 Attributes to be set on PETSc communicators 622 */ 623 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr); 624 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr); 625 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr); 626 627 /* 628 Build the options database 629 */ 630 ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr); 631 632 633 /* 634 Print main application help message 635 */ 636 ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 637 if (help && flg) { 638 ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr); 639 } 640 ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr); 641 642 /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */ 643 #if defined(PETSC_USE_LOG) 644 ierr = PetscLogBegin_Private();CHKERRQ(ierr); 645 #endif 646 647 /* 648 Load the dynamic libraries (on machines that support them), this registers all 649 the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes) 650 */ 651 ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr); 652 653 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 654 ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr); 655 ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr); 656 ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr); 657 658 ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr); 659 /* Check the options database for options related to the options database itself */ 660 ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr); 661 662 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32) 663 /* 664 Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI 665 666 Currently not used because it is not supported by MPICH. 667 */ 668 #if !defined(PETSC_WORDS_BIGENDIAN) 669 ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr); 670 #endif 671 #endif 672 673 ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr); 674 if (flg) { 675 #if defined(PETSC_HAVE_MPI_COMM_SPAWN) 676 ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */ 677 #else 678 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead"); 679 #endif 680 } else { 681 ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr); 682 if (flg) { 683 ierr = PetscOpenMPMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 684 if (PetscOpenMPWorker) { /* if worker then never enter user code */ 685 ierr = PetscEnd(); 686 } 687 } 688 } 689 flg = PETSC_FALSE; 690 ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg,PETSC_NULL);CHKERRQ(ierr); 691 if (flg) {ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 692 693 #if defined(PETSC_HAVE_CUDA) 694 cublasInit_Public(); 695 #endif 696 /* 697 Once we are completedly initialized then we can set this variables 698 */ 699 PetscInitializeCalled = PETSC_TRUE; 700 PetscFunctionReturn(0); 701 } 702 703 704 #undef __FUNCT__ 705 #define __FUNCT__ "PetscFinalize" 706 /*@C 707 PetscFinalize - Checks for options to be called at the conclusion 708 of the program. MPI_Finalize() is called only if the user had not 709 called MPI_Init() before calling PetscInitialize(). 710 711 Collective on PETSC_COMM_WORLD 712 713 Options Database Keys: 714 + -options_table - Calls PetscOptionsPrint() 715 . -options_left - Prints unused options that remain in the database 716 . -options_left no - Does not print unused options that remain in the database 717 . -mpidump - Calls PetscMPIDump() 718 . -malloc_dump - Calls PetscMallocDump() 719 . -malloc_info - Prints total memory usage 720 - -malloc_log - Prints summary of memory usage 721 722 Options Database Keys for Profiling: 723 See the Profiling chapter of the users manual for details. 724 + -log_summary [filename] - Prints summary of flop and timing 725 information to screen. If the filename is specified the 726 summary is written to the file. (for code compiled with 727 PETSC_USE_LOG). See PetscLogPrintSummary(). 728 . -log_all [filename] - Logs extensive profiling information 729 (for code compiled with PETSC_USE_LOG). See PetscLogDump(). 730 . -log [filename] - Logs basic profiline information (for 731 code compiled with PETSC_USE_LOG). See PetscLogDump(). 732 . -log_sync - Log the synchronization in scatters, inner products 733 and norms 734 - -log_mpe [filename] - Creates a logfile viewable by the 735 utility Upshot/Nupshot (in MPICH distribution) 736 737 Level: beginner 738 739 Note: 740 See PetscInitialize() for more general runtime options. 741 742 .seealso: PetscInitialize(), PetscOptionsPrint(), PetscMallocDump(), PetscMPIDump(), PetscEnd() 743 @*/ 744 PetscErrorCode PETSC_DLLEXPORT PetscFinalize(void) 745 { 746 PetscErrorCode ierr; 747 PetscMPIInt rank; 748 int nopt; 749 PetscTruth flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE; 750 #if defined(PETSC_HAVE_AMS) 751 PetscTruth flg = PETSC_FALSE; 752 #endif 753 754 PetscFunctionBegin; 755 756 if (!PetscInitializeCalled) { 757 (*PetscErrorPrintf)("PetscInitialize() must be called before PetscFinalize()\n"); 758 PetscFunctionReturn(0); 759 } 760 ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n"); 761 762 #if defined(PETSC_HAVE_AMS) 763 ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr); 764 if (flg) { 765 ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr); 766 } 767 #endif 768 769 ierr = PetscOpenMPFinalize();CHKERRQ(ierr); 770 771 ierr = PetscOptionsGetTruth(PETSC_NULL,"-python",&flg1,PETSC_NULL);CHKERRQ(ierr); 772 if (flg1) {ierr = PetscPythonFinalize();CHKERRQ(ierr);} 773 774 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 775 ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr); 776 if (!flg2) { 777 flg2 = PETSC_FALSE; 778 ierr = PetscOptionsGetTruth(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr); 779 } 780 if (flg2) { 781 ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr); 782 } 783 784 /* 785 Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_(). 786 */ 787 ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr); 788 789 /* 790 Free all the registered create functions, such as KSPList, VecList, SNESList, etc 791 */ 792 ierr = PetscFListDestroyAll();CHKERRQ(ierr); 793 794 /* 795 Destroy any packages that registered a finalize 796 */ 797 ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr); 798 799 /* 800 Destroy all the function registration lists created 801 */ 802 ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr); 803 804 #if defined(PETSC_USE_LOG) 805 flg1 = PETSC_FALSE; 806 ierr = PetscOptionsGetTruth(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr); 807 if (flg1) { 808 PetscLogDouble flops = 0; 809 ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr); 810 ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr); 811 } 812 #endif 813 814 #if defined(PETSC_USE_DEBUG) 815 if (PetscStackActive) { 816 ierr = PetscStackDestroy();CHKERRQ(ierr); 817 } 818 #endif 819 820 #if defined(PETSC_USE_LOG) 821 { 822 char mname[PETSC_MAX_PATH_LEN]; 823 #if defined(PETSC_HAVE_MPE) 824 mname[0] = 0; 825 ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 826 if (flg1){ 827 if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);} 828 else {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);} 829 } 830 #endif 831 mname[0] = 0; 832 ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 833 if (flg1) { 834 if (mname[0]) {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);} 835 else {ierr = PetscLogPrintSummary(PETSC_COMM_WORLD,0);CHKERRQ(ierr);} 836 } 837 838 ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 839 if (flg1) { 840 if (mname[0]) {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);} 841 else {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);} 842 } 843 844 mname[0] = 0; 845 ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 846 ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr); 847 if (flg1 || flg2){ 848 if (mname[0]) PetscLogDump(mname); 849 else PetscLogDump(0); 850 } 851 ierr = PetscLogDestroy();CHKERRQ(ierr); 852 } 853 #endif 854 flg1 = PETSC_FALSE; 855 ierr = PetscOptionsGetTruth(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr); 856 if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);} 857 flg1 = PETSC_FALSE; 858 ierr = PetscOptionsGetTruth(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr); 859 if (flg1) { 860 ierr = PetscMPIDump(stdout);CHKERRQ(ierr); 861 } 862 flg1 = PETSC_FALSE; 863 flg2 = PETSC_FALSE; 864 ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr); 865 ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr); 866 if (flg2) { 867 if (!rank) {ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr);} 868 } 869 870 /* to prevent PETSc -options_left from warning */ 871 ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr); 872 ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr); 873 874 if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */ 875 flg3 = PETSC_FALSE; /* default value is required */ 876 ierr = PetscOptionsGetTruth(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr); 877 ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr); 878 if (flg3) { 879 if (!flg2) { /* have not yet printed the options */ 880 ierr = PetscOptionsPrint(stdout);CHKERRQ(ierr); 881 } 882 if (!nopt) { 883 ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr); 884 } else if (nopt == 1) { 885 ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr); 886 } else { 887 ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr); 888 } 889 } 890 #if defined(PETSC_USE_DEBUG) 891 if (nopt && !flg3 && !flg1) { 892 ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr); 893 ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr); 894 ierr = PetscOptionsLeft();CHKERRQ(ierr); 895 } else if (nopt && flg3) { 896 #else 897 if (nopt && flg3) { 898 #endif 899 ierr = PetscOptionsLeft();CHKERRQ(ierr); 900 } 901 } 902 903 flg1 = PETSC_FALSE; 904 ierr = PetscOptionsGetTruth(PETSC_NULL,"-log_history",&flg1,PETSC_NULL);CHKERRQ(ierr); 905 if (flg1) { 906 ierr = PetscLogCloseHistoryFile(&petsc_history);CHKERRQ(ierr); 907 petsc_history = 0; 908 } 909 910 ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr); 911 912 flg1 = PETSC_FALSE; 913 flg3 = PETSC_FALSE; 914 ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_dump",&flg1,PETSC_NULL);CHKERRQ(ierr); 915 ierr = PetscOptionsGetTruth(PETSC_NULL,"-malloc_log",&flg3,PETSC_NULL);CHKERRQ(ierr); 916 if (flg1) { 917 char fname[PETSC_MAX_PATH_LEN]; 918 FILE *fd; 919 int err; 920 921 fname[0] = 0; 922 ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr); 923 if (flg1 && fname[0]) { 924 char sname[PETSC_MAX_PATH_LEN]; 925 926 sprintf(sname,"%s_%d",fname,rank); 927 fd = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname); 928 ierr = PetscMallocDump(fd);CHKERRQ(ierr); 929 err = fclose(fd); 930 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 931 } else { 932 MPI_Comm local_comm; 933 934 ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr); 935 ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr); 936 ierr = PetscMallocDump(stdout);CHKERRQ(ierr); 937 ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr); 938 ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr); 939 } 940 } 941 if (flg3) { 942 char fname[PETSC_MAX_PATH_LEN]; 943 FILE *fd; 944 945 fname[0] = 0; 946 ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr); 947 if (flg1 && fname[0]) { 948 char sname[PETSC_MAX_PATH_LEN]; 949 int err; 950 951 sprintf(sname,"%s_%d",fname,rank); 952 fd = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname); 953 ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr); 954 err = fclose(fd); 955 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 956 } else { 957 ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr); 958 } 959 } 960 /* Can be destroyed only after all the options are used */ 961 ierr = PetscOptionsDestroy();CHKERRQ(ierr); 962 963 PetscGlobalArgc = 0; 964 PetscGlobalArgs = 0; 965 966 #if defined(PETSC_USE_COMPLEX) 967 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 968 ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr); 969 ierr = MPI_Type_free(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr); 970 ierr = MPI_Type_free(&MPI_C_COMPLEX);CHKERRQ(ierr); 971 #endif 972 #endif 973 ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr); 974 ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr); 975 ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr); 976 ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr); 977 ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr); 978 979 ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr); 980 ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr); 981 ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr); 982 983 ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr); 984 if (PetscBeganMPI) { 985 #if defined(PETSC_HAVE_MPI_FINALIZED) 986 PetscMPIInt flag; 987 ierr = MPI_Finalized(&flag);CHKERRQ(ierr); 988 if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()"); 989 #endif 990 ierr = MPI_Finalize();CHKERRQ(ierr); 991 } 992 993 if (PETSC_ZOPEFD){ 994 if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>"); 995 else fprintf(PETSC_STDOUT, "<<<end>>>"); 996 } 997 998 #if defined(PETSC_HAVE_CUDA) 999 cublasShutdown_Public(); 1000 #endif 1001 /* 1002 1003 Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because 1004 the communicator has some outstanding requests on it. Specifically if the 1005 flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See 1006 src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate() 1007 is never freed as it should be. Thus one may obtain messages of the form 1008 [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the 1009 memory was not freed. 1010 1011 */ 1012 ierr = PetscMallocClear();CHKERRQ(ierr); 1013 PetscInitializeCalled = PETSC_FALSE; 1014 PetscFinalizeCalled = PETSC_TRUE; 1015 PetscFunctionReturn(ierr); 1016 } 1017 1018