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