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