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