1 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 #if defined(PETSC_USE_SCALAR___FLOAT128) 670 ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);CHKERRQ(ierr); 671 ierr = MPI_Type_commit(&MPIU___FLOAT128);CHKERRQ(ierr); 672 #endif 673 674 ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);CHKERRQ(ierr); 675 ierr = MPI_Type_commit(&MPIU_2SCALAR);CHKERRQ(ierr); 676 ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op);CHKERRQ(ierr); 677 ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op);CHKERRQ(ierr); 678 679 ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);CHKERRQ(ierr); 680 ierr = MPI_Type_commit(&MPIU_2INT);CHKERRQ(ierr); 681 682 /* 683 Attributes to be set on PETSc communicators 684 */ 685 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0);CHKERRQ(ierr); 686 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0);CHKERRQ(ierr); 687 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0);CHKERRQ(ierr); 688 689 /* 690 Build the options database 691 */ 692 ierr = PetscOptionsInsert(argc,args,file);CHKERRQ(ierr); 693 694 695 /* 696 Print main application help message 697 */ 698 ierr = PetscOptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 699 if (help && flg) { 700 ierr = PetscPrintf(PETSC_COMM_WORLD,help);CHKERRQ(ierr); 701 } 702 ierr = PetscOptionsCheckInitial_Private();CHKERRQ(ierr); 703 704 /* SHOULD PUT IN GUARDS: Make sure logging is initialized, even if we do not print it out */ 705 #if defined(PETSC_USE_LOG) 706 ierr = PetscLogBegin_Private();CHKERRQ(ierr); 707 #endif 708 709 /* 710 Load the dynamic libraries (on machines that support them), this registers all 711 the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes) 712 */ 713 ierr = PetscInitialize_DynamicLibraries();CHKERRQ(ierr); 714 715 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 716 ierr = PetscInfo1(0,"PETSc successfully started: number of processors = %d\n",size);CHKERRQ(ierr); 717 ierr = PetscGetHostName(hostname,256);CHKERRQ(ierr); 718 ierr = PetscInfo1(0,"Running on machine: %s\n",hostname);CHKERRQ(ierr); 719 720 ierr = PetscOptionsCheckInitial_Components();CHKERRQ(ierr); 721 /* Check the options database for options related to the options database itself */ 722 ierr = PetscOptionsSetFromOptions();CHKERRQ(ierr); 723 724 #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32) 725 /* 726 Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI 727 728 Currently not used because it is not supported by MPICH. 729 */ 730 #if !defined(PETSC_WORDS_BIGENDIAN) 731 ierr = MPI_Register_datarep((char *)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,PETSC_NULL);CHKERRQ(ierr); 732 #endif 733 #endif 734 735 ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_spawn_size",&nodesize,&flg);CHKERRQ(ierr); 736 if (flg) { 737 #if defined(PETSC_HAVE_MPI_COMM_SPAWN) 738 ierr = PetscOpenMPSpawn((PetscMPIInt) nodesize);CHKERRQ(ierr); /* worker nodes never return from here; they go directly to PetscEnd() */ 739 #else 740 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -openmp_merge_size instead"); 741 #endif 742 } else { 743 ierr = PetscOptionsGetInt(PETSC_NULL,"-openmp_merge_size",&nodesize,&flg);CHKERRQ(ierr); 744 if (flg) { 745 ierr = PetscOpenMPMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 746 if (PetscOpenMPWorker) { /* if worker then never enter user code */ 747 ierr = PetscEnd(); 748 } 749 } 750 } 751 752 #if defined(PETSC_HAVE_CUDA) 753 cublasInit(); 754 #endif 755 756 #if defined(PETSC_HAVE_AMS) 757 ierr = PetscOptionsHasName(PETSC_NULL,"-ams_publish_objects",&flg);CHKERRQ(ierr); 758 if (flg) { 759 PetscAMSPublishAll = PETSC_TRUE; 760 } 761 #endif 762 763 ierr = PetscOptionsHasName(PETSC_NULL,"-python",&flg);CHKERRQ(ierr); 764 if (flg) { 765 PetscInitializeCalled = PETSC_TRUE; 766 ierr = PetscPythonInitialize(PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 767 } 768 769 /* 770 Once we are completedly initialized then we can set this variables 771 */ 772 PetscInitializeCalled = PETSC_TRUE; 773 PetscFunctionReturn(0); 774 } 775 776 extern PetscObject *PetscObjects; 777 extern PetscInt PetscObjectsCounts, PetscObjectsMaxCounts; 778 779 #undef __FUNCT__ 780 #define __FUNCT__ "PetscFinalize" 781 /*@C 782 PetscFinalize - Checks for options to be called at the conclusion 783 of the program. MPI_Finalize() is called only if the user had not 784 called MPI_Init() before calling PetscInitialize(). 785 786 Collective on PETSC_COMM_WORLD 787 788 Options Database Keys: 789 + -options_table - Calls PetscOptionsView() 790 . -options_left - Prints unused options that remain in the database 791 . -objects_left - Prints list of all objects that have not been freed 792 . -mpidump - Calls PetscMPIDump() 793 . -malloc_dump - Calls PetscMallocDump() 794 . -malloc_info - Prints total memory usage 795 - -malloc_log - Prints summary of memory usage 796 797 Options Database Keys for Profiling: 798 See the <a href="../../docs/manual.pdf#nameddest=ch_profiling">profiling chapter of the users manual</a> for details. 799 + -log_summary [filename] - Prints summary of flop and timing 800 information to screen. If the filename is specified the 801 summary is written to the file. See PetscLogView(). 802 . -log_summary_python [filename] - Prints data on of flop and timing usage to a file or screen. 803 See PetscLogPrintSViewPython(). 804 . -log_all [filename] - Logs extensive profiling information 805 See PetscLogDump(). 806 . -log [filename] - Logs basic profiline information See PetscLogDump(). 807 . -log_sync - Log the synchronization in scatters, inner products 808 and norms 809 - -log_mpe [filename] - Creates a logfile viewable by the 810 utility Upshot/Nupshot (in MPICH distribution) 811 812 Level: beginner 813 814 Note: 815 See PetscInitialize() for more general runtime options. 816 817 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd() 818 @*/ 819 PetscErrorCode PetscFinalize(void) 820 { 821 PetscErrorCode ierr; 822 PetscMPIInt rank; 823 PetscInt i,nopt; 824 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,objects_left = PETSC_FALSE; 825 #if defined(PETSC_HAVE_AMS) 826 PetscBool flg = PETSC_FALSE; 827 #endif 828 #if defined(PETSC_USE_LOG) 829 char mname[PETSC_MAX_PATH_LEN]; 830 #endif 831 832 PetscFunctionBegin; 833 834 if (!PetscInitializeCalled) { 835 printf("PetscInitialize() must be called before PetscFinalize()\n"); 836 PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE); 837 } 838 ierr = PetscInfo(PETSC_NULL,"PetscFinalize() called\n"); 839 840 #if defined(PETSC_HAVE_AMS) 841 ierr = PetscOptionsGetBool(PETSC_NULL,"-options_gui",&flg,PETSC_NULL);CHKERRQ(ierr); 842 if (flg) { 843 ierr = PetscOptionsAMSDestroy();CHKERRQ(ierr); 844 } 845 #endif 846 847 ierr = PetscOpenMPFinalize();CHKERRQ(ierr); 848 849 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 850 ierr = PetscOptionsGetBool(PETSC_NULL,"-malloc_info",&flg2,PETSC_NULL);CHKERRQ(ierr); 851 if (!flg2) { 852 flg2 = PETSC_FALSE; 853 ierr = PetscOptionsGetBool(PETSC_NULL,"-memory_info",&flg2,PETSC_NULL);CHKERRQ(ierr); 854 } 855 if (flg2) { 856 ierr = PetscMemoryShowUsage(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");CHKERRQ(ierr); 857 } 858 859 #if defined(PETSC_USE_LOG) 860 flg1 = PETSC_FALSE; 861 ierr = PetscOptionsGetBool(PETSC_NULL,"-get_total_flops",&flg1,PETSC_NULL);CHKERRQ(ierr); 862 if (flg1) { 863 PetscLogDouble flops = 0; 864 ierr = MPI_Reduce(&_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);CHKERRQ(ierr); 865 ierr = PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);CHKERRQ(ierr); 866 } 867 #endif 868 869 870 #if defined(PETSC_USE_LOG) 871 #if defined(PETSC_HAVE_MPE) 872 mname[0] = 0; 873 ierr = PetscOptionsGetString(PETSC_NULL,"-log_mpe",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 874 if (flg1){ 875 if (mname[0]) {ierr = PetscLogMPEDump(mname);CHKERRQ(ierr);} 876 else {ierr = PetscLogMPEDump(0);CHKERRQ(ierr);} 877 } 878 #endif 879 mname[0] = 0; 880 ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 881 if (flg1) { 882 PetscViewer viewer; 883 if (mname[0]) { 884 ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr); 885 ierr = PetscLogView(viewer);CHKERRQ(ierr); 886 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 887 } else { 888 viewer = PETSC_VIEWER_STDOUT_WORLD; 889 ierr = PetscLogView(viewer);CHKERRQ(ierr); 890 } 891 } 892 893 mname[0] = 0; 894 ierr = PetscOptionsGetString(PETSC_NULL,"-log_summary_python",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 895 if (flg1) { 896 PetscViewer viewer; 897 if (mname[0]) { 898 ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);CHKERRQ(ierr); 899 ierr = PetscLogViewPython(viewer);CHKERRQ(ierr); 900 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 901 } else { 902 viewer = PETSC_VIEWER_STDOUT_WORLD; 903 ierr = PetscLogViewPython(viewer);CHKERRQ(ierr); 904 } 905 } 906 907 ierr = PetscOptionsGetString(PETSC_NULL,"-log_detailed",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 908 if (flg1) { 909 if (mname[0]) {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,mname);CHKERRQ(ierr);} 910 else {ierr = PetscLogPrintDetailed(PETSC_COMM_WORLD,0);CHKERRQ(ierr);} 911 } 912 913 mname[0] = 0; 914 ierr = PetscOptionsGetString(PETSC_NULL,"-log_all",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 915 ierr = PetscOptionsGetString(PETSC_NULL,"-log",mname,PETSC_MAX_PATH_LEN,&flg2);CHKERRQ(ierr); 916 if (flg1 || flg2){ 917 if (mname[0]) PetscLogDump(mname); 918 else PetscLogDump(0); 919 } 920 #endif 921 922 #if defined(PETSC_USE_DEBUG) && !defined(PETSC_USE_PTHREAD) 923 if (PetscStackActive) { 924 ierr = PetscStackDestroy();CHKERRQ(ierr); 925 } 926 #endif 927 928 flg1 = PETSC_FALSE; 929 ierr = PetscOptionsGetBool(PETSC_NULL,"-no_signal_handler",&flg1,PETSC_NULL);CHKERRQ(ierr); 930 if (!flg1) { ierr = PetscPopSignalHandler();CHKERRQ(ierr);} 931 flg1 = PETSC_FALSE; 932 ierr = PetscOptionsGetBool(PETSC_NULL,"-mpidump",&flg1,PETSC_NULL);CHKERRQ(ierr); 933 if (flg1) { 934 ierr = PetscMPIDump(stdout);CHKERRQ(ierr); 935 } 936 flg1 = PETSC_FALSE; 937 flg2 = PETSC_FALSE; 938 /* preemptive call to avoid listing this option in options table as unused */ 939 ierr = PetscOptionsHasName(PETSC_NULL,"-malloc_dump",&flg1);CHKERRQ(ierr); 940 ierr = PetscOptionsGetBool(PETSC_NULL,"-options_table",&flg2,PETSC_NULL);CHKERRQ(ierr); 941 942 if (flg2) { 943 if (!rank) {ierr = PetscOptionsView(PETSC_NULL);CHKERRQ(ierr);} 944 } 945 946 /* to prevent PETSc -options_left from warning */ 947 ierr = PetscOptionsHasName(PETSC_NULL,"-nox",&flg1);CHKERRQ(ierr); 948 ierr = PetscOptionsHasName(PETSC_NULL,"-nox_warning",&flg1);CHKERRQ(ierr); 949 ierr = PetscOptionsGetBool(PETSC_NULL,"-objects_left",&objects_left,PETSC_NULL);CHKERRQ(ierr); 950 951 if (!PetscOpenMPWorker) { /* worker processes skip this because they do not usually process options */ 952 flg3 = PETSC_FALSE; /* default value is required */ 953 ierr = PetscOptionsGetBool(PETSC_NULL,"-options_left",&flg3,&flg1);CHKERRQ(ierr); 954 ierr = PetscOptionsAllUsed(&nopt);CHKERRQ(ierr); 955 if (flg3) { 956 if (!flg2) { /* have not yet printed the options */ 957 ierr = PetscOptionsView(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 958 } 959 if (!nopt) { 960 ierr = PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");CHKERRQ(ierr); 961 } else if (nopt == 1) { 962 ierr = PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");CHKERRQ(ierr); 963 } else { 964 ierr = PetscPrintf(PETSC_COMM_WORLD,"There are %d unused database options. They are:\n",nopt);CHKERRQ(ierr); 965 } 966 } 967 #if defined(PETSC_USE_DEBUG) 968 if (nopt && !flg3 && !flg1) { 969 ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");CHKERRQ(ierr); 970 ierr = PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");CHKERRQ(ierr); 971 ierr = PetscOptionsLeft();CHKERRQ(ierr); 972 } else if (nopt && flg3) { 973 #else 974 if (nopt && flg3) { 975 #endif 976 ierr = PetscOptionsLeft();CHKERRQ(ierr); 977 } 978 } 979 980 /* 981 Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_(). 982 */ 983 ierr = PetscObjectRegisterDestroyAll();CHKERRQ(ierr); 984 985 /* 986 List all objects the user may have forgot to free 987 */ 988 if (objects_left && PetscObjectsCounts) { 989 ierr = PetscPrintf(PETSC_COMM_WORLD,"The following objects %D were never freed\n",PetscObjectsCounts); 990 } 991 for (i=0; i<PetscObjectsMaxCounts; i++) { 992 if (PetscObjects[i]) { 993 if (objects_left) { 994 ierr = PetscPrintf(PETSC_COMM_WORLD," %s %s %s\n",PetscObjects[i]->class_name,PetscObjects[i]->type_name,PetscObjects[i]->name);CHKERRQ(ierr); 995 } 996 } 997 } 998 /* cannot actually destroy the left over objects, but destroy the list */ 999 PetscObjectsCounts = 0; 1000 PetscObjectsMaxCounts = 0; 1001 ierr = PetscFree(PetscObjects);CHKERRQ(ierr); 1002 1003 1004 #if defined(PETSC_USE_LOG) 1005 ierr = PetscLogDestroy();CHKERRQ(ierr); 1006 #endif 1007 1008 /* 1009 Free all the registered create functions, such as KSPList, VecList, SNESList, etc 1010 */ 1011 ierr = PetscFListDestroyAll();CHKERRQ(ierr); 1012 1013 /* 1014 Destroy any packages that registered a finalize 1015 */ 1016 ierr = PetscRegisterFinalizeAll();CHKERRQ(ierr); 1017 1018 /* 1019 Destroy all the function registration lists created 1020 */ 1021 ierr = PetscFinalize_DynamicLibraries();CHKERRQ(ierr); 1022 1023 if (petsc_history) { 1024 ierr = PetscCloseHistoryFile(&petsc_history);CHKERRQ(ierr); 1025 petsc_history = 0; 1026 } 1027 1028 ierr = PetscInfoAllow(PETSC_FALSE,PETSC_NULL);CHKERRQ(ierr); 1029 1030 { 1031 char fname[PETSC_MAX_PATH_LEN]; 1032 FILE *fd; 1033 int err; 1034 1035 fname[0] = 0; 1036 ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_dump",fname,250,&flg1);CHKERRQ(ierr); 1037 if (flg1 && fname[0]) { 1038 char sname[PETSC_MAX_PATH_LEN]; 1039 1040 sprintf(sname,"%s_%d",fname,rank); 1041 fd = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname); 1042 ierr = PetscMallocDump(fd);CHKERRQ(ierr); 1043 err = fclose(fd); 1044 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 1045 } else if (flg1) { 1046 MPI_Comm local_comm; 1047 1048 ierr = MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);CHKERRQ(ierr); 1049 ierr = PetscSequentialPhaseBegin_Private(local_comm,1);CHKERRQ(ierr); 1050 ierr = PetscMallocDump(stdout);CHKERRQ(ierr); 1051 ierr = PetscSequentialPhaseEnd_Private(local_comm,1);CHKERRQ(ierr); 1052 ierr = MPI_Comm_free(&local_comm);CHKERRQ(ierr); 1053 } 1054 } 1055 { 1056 char fname[PETSC_MAX_PATH_LEN]; 1057 FILE *fd; 1058 1059 fname[0] = 0; 1060 ierr = PetscOptionsGetString(PETSC_NULL,"-malloc_log",fname,250,&flg1);CHKERRQ(ierr); 1061 if (flg1 && fname[0]) { 1062 char sname[PETSC_MAX_PATH_LEN]; 1063 int err; 1064 1065 sprintf(sname,"%s_%d",fname,rank); 1066 fd = fopen(sname,"w"); if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open log file: %s",sname); 1067 ierr = PetscMallocDumpLog(fd);CHKERRQ(ierr); 1068 err = fclose(fd); 1069 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 1070 } else if (flg1) { 1071 ierr = PetscMallocDumpLog(stdout);CHKERRQ(ierr); 1072 } 1073 } 1074 /* Can be destroyed only after all the options are used */ 1075 ierr = PetscOptionsDestroy();CHKERRQ(ierr); 1076 1077 PetscGlobalArgc = 0; 1078 PetscGlobalArgs = 0; 1079 1080 #if defined(PETSC_USE_SCALAR___FLOAT128) 1081 ierr = MPI_Type_free(&MPIU___FLOAT128);CHKERRQ(ierr); 1082 #endif 1083 1084 #if defined(PETSC_USE_COMPLEX) 1085 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 1086 ierr = MPI_Op_free(&MPIU_SUM);CHKERRQ(ierr); 1087 ierr = MPI_Type_free(&MPI_C_DOUBLE_COMPLEX);CHKERRQ(ierr); 1088 ierr = MPI_Type_free(&MPI_C_COMPLEX);CHKERRQ(ierr); 1089 #endif 1090 #endif 1091 ierr = MPI_Type_free(&MPIU_2SCALAR);CHKERRQ(ierr); 1092 ierr = MPI_Type_free(&MPIU_2INT);CHKERRQ(ierr); 1093 ierr = MPI_Op_free(&PetscMaxSum_Op);CHKERRQ(ierr); 1094 ierr = MPI_Op_free(&PetscADMax_Op);CHKERRQ(ierr); 1095 ierr = MPI_Op_free(&PetscADMin_Op);CHKERRQ(ierr); 1096 1097 /* 1098 Destroy any known inner communicators and attributes pointing to them 1099 Note this will not destroy any new communicators the user has created 1100 */ 1101 { 1102 PetscCommCounter *counter; 1103 PetscMPIInt flg; 1104 MPI_Comm icomm; 1105 void *ptr; 1106 ierr = MPI_Attr_get(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr); 1107 if (flg) { 1108 /* Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers */ 1109 ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr); 1110 ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr); 1111 if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory"); 1112 1113 ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr); 1114 ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr); 1115 ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr); 1116 ierr = MPI_Attr_delete(PETSC_COMM_SELF,Petsc_InnerComm_keyval);CHKERRQ(ierr); 1117 } 1118 ierr = MPI_Attr_get(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr); 1119 if (flg) { 1120 /* Use PetscMemcpy() because casting from pointer to integer of different size is not allowed with some compilers */ 1121 ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr); 1122 ierr = MPI_Attr_get(icomm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr); 1123 if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_CORRUPT,"Inner MPI_Comm does not have expected tag/name counter, problem with corrupted memory"); 1124 1125 ierr = MPI_Attr_delete(icomm,Petsc_Counter_keyval);CHKERRQ(ierr); 1126 ierr = MPI_Attr_delete(icomm,Petsc_OuterComm_keyval);CHKERRQ(ierr); 1127 ierr = MPI_Comm_free(&icomm);CHKERRQ(ierr); 1128 ierr = MPI_Attr_delete(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);CHKERRQ(ierr); 1129 } 1130 } 1131 1132 ierr = MPI_Keyval_free(&Petsc_Counter_keyval);CHKERRQ(ierr); 1133 ierr = MPI_Keyval_free(&Petsc_InnerComm_keyval);CHKERRQ(ierr); 1134 ierr = MPI_Keyval_free(&Petsc_OuterComm_keyval);CHKERRQ(ierr); 1135 1136 ierr = PetscInfo(0,"PETSc successfully ended!\n");CHKERRQ(ierr); 1137 if (PetscBeganMPI) { 1138 #if defined(PETSC_HAVE_MPI_FINALIZED) 1139 PetscMPIInt flag; 1140 ierr = MPI_Finalized(&flag);CHKERRQ(ierr); 1141 if (flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI_Finalize() has already been called, even though MPI_Init() was called by PetscInitialize()"); 1142 #endif 1143 ierr = MPI_Finalize();CHKERRQ(ierr); 1144 } 1145 1146 if (PETSC_ZOPEFD){ 1147 if (PETSC_ZOPEFD != PETSC_STDOUT) fprintf(PETSC_ZOPEFD, "<<<end>>>"); 1148 else fprintf(PETSC_STDOUT, "<<<end>>>"); 1149 } 1150 1151 #if defined(PETSC_HAVE_CUDA) 1152 cublasShutdown(); 1153 #endif 1154 /* 1155 1156 Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because 1157 the communicator has some outstanding requests on it. Specifically if the 1158 flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See 1159 src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate() 1160 is never freed as it should be. Thus one may obtain messages of the form 1161 [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the 1162 memory was not freed. 1163 1164 */ 1165 ierr = PetscMallocClear();CHKERRQ(ierr); 1166 PetscInitializeCalled = PETSC_FALSE; 1167 PetscFinalizeCalled = PETSC_TRUE; 1168 PetscFunctionReturn(ierr); 1169 } 1170 1171