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