1 /* 2 3 This file defines part of the initialization of PETSc 4 5 This file uses regular malloc and free because it cannot known 6 what malloc is being used until it has already processed the input. 7 */ 8 9 #include <petscsys.h> /*I "petscsys.h" I*/ 10 #include <petsc/private/petscimpl.h> 11 #include <petscvalgrind.h> 12 #include <petscviewer.h> 13 #if defined(PETSC_USE_LOG) 14 PETSC_INTERN PetscErrorCode PetscLogInitialize(void); 15 #endif 16 17 #if defined(PETSC_HAVE_SYS_SYSINFO_H) 18 #include <sys/sysinfo.h> 19 #endif 20 #if defined(PETSC_HAVE_UNISTD_H) 21 #include <unistd.h> 22 #endif 23 #if defined(PETSC_HAVE_CUDA) 24 #include <cuda_runtime.h> 25 #include <petsccublas.h> 26 #endif 27 28 #if defined(PETSC_HAVE_VIENNACL) 29 PETSC_EXTERN PetscErrorCode PetscViennaCLInit(); 30 #endif 31 32 /* ------------------------Nasty global variables -------------------------------*/ 33 /* 34 Indicates if PETSc started up MPI, or it was 35 already started before PETSc was initialized. 36 */ 37 PetscBool PetscBeganMPI = PETSC_FALSE; 38 PetscBool PetscInitializeCalled = PETSC_FALSE; 39 PetscBool PetscFinalizeCalled = PETSC_FALSE; 40 PetscBool PetscCUDAInitialized = PETSC_FALSE; 41 42 PetscMPIInt PetscGlobalRank = -1; 43 PetscMPIInt PetscGlobalSize = -1; 44 45 #if defined(PETSC_HAVE_COMPLEX) 46 #if defined(PETSC_COMPLEX_INSTANTIATE) 47 template <> class std::complex<double>; /* instantiate complex template class */ 48 #endif 49 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 50 MPI_Datatype MPIU_C_DOUBLE_COMPLEX; 51 MPI_Datatype MPIU_C_COMPLEX; 52 #endif 53 54 /*MC 55 PETSC_i - the imaginary number i 56 57 Synopsis: 58 #include <petscsys.h> 59 PetscComplex PETSC_i; 60 61 Level: beginner 62 63 Note: 64 Complex numbers are automatically available if PETSc located a working complex implementation 65 66 .seealso: PetscRealPart(), PetscImaginaryPart(), PetscRealPartComplex(), PetscImaginaryPartComplex() 67 M*/ 68 PetscComplex PETSC_i; 69 #endif 70 #if defined(PETSC_USE_REAL___FLOAT128) 71 MPI_Datatype MPIU___FLOAT128 = 0; 72 #if defined(PETSC_HAVE_COMPLEX) 73 MPI_Datatype MPIU___COMPLEX128 = 0; 74 #endif 75 #elif defined(PETSC_USE_REAL___FP16) 76 MPI_Datatype MPIU___FP16 = 0; 77 #endif 78 MPI_Datatype MPIU_2SCALAR = 0; 79 #if defined(PETSC_USE_64BIT_INDICES) 80 MPI_Datatype MPIU_2INT = 0; 81 #endif 82 MPI_Datatype MPIU_BOOL; 83 MPI_Datatype MPIU_ENUM; 84 MPI_Datatype MPIU_FORTRANADDR; 85 MPI_Datatype MPIU_SIZE_T; 86 87 /* 88 Function that is called to display all error messages 89 */ 90 PetscErrorCode (*PetscErrorPrintf)(const char [],...) = PetscErrorPrintfDefault; 91 PetscErrorCode (*PetscHelpPrintf)(MPI_Comm,const char [],...) = PetscHelpPrintfDefault; 92 PetscErrorCode (*PetscVFPrintf)(FILE*,const char[],va_list) = PetscVFPrintfDefault; 93 /* 94 This is needed to turn on/off GPU synchronization 95 */ 96 PetscBool PetscViennaCLSynchronize = PETSC_FALSE; 97 PetscBool PetscCUDASynchronize = PETSC_FALSE; 98 99 /* ------------------------------------------------------------------------------*/ 100 /* 101 Optional file where all PETSc output from various prints is saved 102 */ 103 PETSC_INTERN FILE *petsc_history; 104 FILE *petsc_history = NULL; 105 106 PetscErrorCode PetscOpenHistoryFile(const char filename[],FILE **fd) 107 { 108 PetscErrorCode ierr; 109 PetscMPIInt rank,size; 110 char pfile[PETSC_MAX_PATH_LEN],pname[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN],date[64]; 111 char version[256]; 112 113 PetscFunctionBegin; 114 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 115 if (!rank) { 116 char arch[10]; 117 int err; 118 119 ierr = PetscGetArchType(arch,10);CHKERRQ(ierr); 120 ierr = PetscGetDate(date,64);CHKERRQ(ierr); 121 ierr = PetscGetVersion(version,256);CHKERRQ(ierr); 122 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 123 if (filename) { 124 ierr = PetscFixFilename(filename,fname);CHKERRQ(ierr); 125 } else { 126 ierr = PetscGetHomeDirectory(pfile,240);CHKERRQ(ierr); 127 ierr = PetscStrcat(pfile,"/.petschistory");CHKERRQ(ierr); 128 ierr = PetscFixFilename(pfile,fname);CHKERRQ(ierr); 129 } 130 131 *fd = fopen(fname,"a"); 132 if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file: %s",fname); 133 134 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr); 135 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"%s %s\n",version,date);CHKERRQ(ierr); 136 ierr = PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 137 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"%s on a %s, %d proc. with options:\n",pname,arch,size);CHKERRQ(ierr); 138 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr); 139 140 err = fflush(*fd); 141 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 142 } 143 PetscFunctionReturn(0); 144 } 145 146 PETSC_INTERN PetscErrorCode PetscCloseHistoryFile(FILE **fd) 147 { 148 PetscErrorCode ierr; 149 PetscMPIInt rank; 150 char date[64]; 151 int err; 152 153 PetscFunctionBegin; 154 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 155 if (!rank) { 156 ierr = PetscGetDate(date,64);CHKERRQ(ierr); 157 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr); 158 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"Finished at %s\n",date);CHKERRQ(ierr); 159 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"---------------------------------------------------------\n");CHKERRQ(ierr); 160 err = fflush(*fd); 161 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 162 err = fclose(*fd); 163 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 164 } 165 PetscFunctionReturn(0); 166 } 167 168 /* ------------------------------------------------------------------------------*/ 169 170 /* 171 This is ugly and probably belongs somewhere else, but I want to 172 be able to put a true MPI abort error handler with command line args. 173 174 This is so MPI errors in the debugger will leave all the stack 175 frames. The default MP_Abort() cleans up and exits thus providing no useful information 176 in the debugger hence we call abort() instead of MPI_Abort(). 177 */ 178 179 void Petsc_MPI_AbortOnError(MPI_Comm *comm,PetscMPIInt *flag,...) 180 { 181 PetscFunctionBegin; 182 (*PetscErrorPrintf)("MPI error %d\n",*flag); 183 abort(); 184 } 185 186 void Petsc_MPI_DebuggerOnError(MPI_Comm *comm,PetscMPIInt *flag,...) 187 { 188 PetscErrorCode ierr; 189 190 PetscFunctionBegin; 191 (*PetscErrorPrintf)("MPI error %d\n",*flag); 192 ierr = PetscAttachDebugger(); 193 if (ierr) PETSCABORT(*comm,*flag); /* hopeless so get out */ 194 } 195 196 #if defined(PETSC_HAVE_CUDA) 197 /*@C 198 PetscCUDAInitialize - Initializes the CUDA device and cuBLAS on the device 199 200 Logically collective 201 202 Input Parameter: 203 comm - the MPI communicator that will utilize the CUDA devices 204 205 Options Database: 206 + -cuda_initialize <default yes,no> - do the initialization in PetscInitialize(). If -cuda_initialize no is used then the default initialization is done automatically 207 when the first CUDA call is made unless you call PetscCUDAInitialize() before any CUDA operations are performed 208 . -cuda_view - view information about the CUDA devices 209 . -cuda_synchronize - wait at the end of asynchronize CUDA calls so that their time gets credited to the current event; default with -log_view 210 - -cuda_set_device <gpu> - integer number of the device 211 212 Level: beginner 213 214 Notes: 215 Initializing cuBLAS takes about 1/2 second there it is done by default in PetscInitialize() before logging begins 216 217 @*/ 218 PetscErrorCode PetscCUDAInitialize(MPI_Comm comm) 219 { 220 PetscErrorCode ierr; 221 PetscInt deviceOpt = 0; 222 PetscBool cuda_view_flag = PETSC_FALSE,flg; 223 struct cudaDeviceProp prop; 224 int devCount,device,devicecnt; 225 cudaError_t err = cudaSuccess; 226 PetscMPIInt rank,size; 227 228 PetscFunctionBegin; 229 /* 230 If collecting logging information, by default, wait for GPU to complete its operations 231 before returning to the CPU in order to get accurate timings of each event 232 */ 233 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&PetscCUDASynchronize);CHKERRQ(ierr); 234 if (!PetscCUDASynchronize) { 235 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&PetscCUDASynchronize);CHKERRQ(ierr); 236 } 237 238 ierr = PetscOptionsBegin(comm,NULL,"CUDA options","Sys");CHKERRQ(ierr); 239 ierr = PetscOptionsInt("-cuda_set_device","Set all MPI ranks to use the specified CUDA device",NULL,deviceOpt,&deviceOpt,&flg);CHKERRQ(ierr); 240 device = (int)deviceOpt; 241 ierr = PetscOptionsBool("-cuda_synchronize","Wait for the GPU to complete operations before returning to the CPU",NULL,PetscCUDASynchronize,&PetscCUDASynchronize,NULL);CHKERRQ(ierr); 242 ierr = PetscOptionsDeprecated("-cuda_show_devices","-cuda_view","3.12",NULL);CHKERRQ(ierr); 243 ierr = PetscOptionsName("-cuda_view","Display CUDA device information and assignments",NULL,&cuda_view_flag);CHKERRQ(ierr); 244 ierr = PetscOptionsEnd();CHKERRQ(ierr); 245 if (!PetscCUDAInitialized) { 246 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 247 248 if (size>1 && !flg) { 249 /* check to see if we force multiple ranks to hit the same GPU */ 250 /* we're not using the same GPU on multiple MPI threads. So try to allocated different GPUs to different processes */ 251 252 /* First get the device count */ 253 err = cudaGetDeviceCount(&devCount); 254 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err)); 255 256 /* next determine the rank and then set the device via a mod */ 257 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 258 device = rank % devCount; 259 } 260 err = cudaSetDevice(device); 261 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDevice %s",cudaGetErrorString(err)); 262 263 /* set the device flags so that it can map host memory */ 264 err = cudaSetDeviceFlags(cudaDeviceMapHost); 265 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDeviceFlags %s",cudaGetErrorString(err)); 266 267 ierr = PetscCUBLASInitializeHandle();CHKERRQ(ierr); 268 ierr = PetscCUSOLVERDnInitializeHandle();CHKERRQ(ierr); 269 PetscCUDAInitialized = PETSC_TRUE; 270 } 271 if (cuda_view_flag) { 272 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 273 err = cudaGetDeviceCount(&devCount); 274 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err)); 275 for (devicecnt = 0; devicecnt < devCount; ++devicecnt) { 276 err = cudaGetDeviceProperties(&prop,devicecnt); 277 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceProperties %s",cudaGetErrorString(err)); 278 ierr = PetscPrintf(comm, "CUDA device %d: %s\n", devicecnt, prop.name);CHKERRQ(ierr); 279 } 280 ierr = PetscSynchronizedPrintf(comm,"[%d] Using CUDA device %d.\n",rank,device);CHKERRQ(ierr); 281 ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 282 } 283 PetscFunctionReturn(0); 284 } 285 #endif 286 287 /*@C 288 PetscEnd - Calls PetscFinalize() and then ends the program. This is useful if one 289 wishes a clean exit somewhere deep in the program. 290 291 Collective on PETSC_COMM_WORLD 292 293 Options Database Keys are the same as for PetscFinalize() 294 295 Level: advanced 296 297 Note: 298 See PetscInitialize() for more general runtime options. 299 300 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscFinalize() 301 @*/ 302 PetscErrorCode PetscEnd(void) 303 { 304 PetscFunctionBegin; 305 PetscFinalize(); 306 exit(0); 307 return 0; 308 } 309 310 PetscBool PetscOptionsPublish = PETSC_FALSE; 311 PETSC_INTERN PetscErrorCode PetscSetUseHBWMalloc_Private(void); 312 PETSC_INTERN PetscBool petscsetmallocvisited; 313 static char emacsmachinename[256]; 314 315 PetscErrorCode (*PetscExternalVersionFunction)(MPI_Comm) = NULL; 316 PetscErrorCode (*PetscExternalHelpFunction)(MPI_Comm) = NULL; 317 318 /*@C 319 PetscSetHelpVersionFunctions - Sets functions that print help and version information 320 before the PETSc help and version information is printed. Must call BEFORE PetscInitialize(). 321 This routine enables a "higher-level" package that uses PETSc to print its messages first. 322 323 Input Parameter: 324 + help - the help function (may be NULL) 325 - version - the version function (may be NULL) 326 327 Level: developer 328 329 @*/ 330 PetscErrorCode PetscSetHelpVersionFunctions(PetscErrorCode (*help)(MPI_Comm),PetscErrorCode (*version)(MPI_Comm)) 331 { 332 PetscFunctionBegin; 333 PetscExternalHelpFunction = help; 334 PetscExternalVersionFunction = version; 335 PetscFunctionReturn(0); 336 } 337 338 #if defined(PETSC_USE_LOG) 339 PETSC_INTERN PetscBool PetscObjectsLog; 340 #endif 341 342 void PetscMPI_Comm_eh(MPI_Comm *comm, PetscMPIInt *err, ...) 343 { 344 if (PetscUnlikely(*err)) { 345 PetscMPIInt len; 346 char errstring[MPI_MAX_ERROR_STRING]; 347 348 MPI_Error_string(*err,errstring,&len); 349 PetscError(MPI_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,PETSC_MPI_ERROR_CODE,PETSC_ERROR_INITIAL,"Internal error in MPI: %s",errstring); 350 } 351 return; 352 } 353 354 PETSC_INTERN PetscErrorCode PetscOptionsCheckInitial_Private(void) 355 { 356 char string[64],mname[PETSC_MAX_PATH_LEN]; 357 MPI_Comm comm = PETSC_COMM_WORLD; 358 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flag; 359 PetscErrorCode ierr; 360 PetscReal si; 361 PetscInt intensity; 362 int i; 363 PetscMPIInt rank; 364 char version[256],helpoptions[256]; 365 #if defined(PETSC_USE_LOG) 366 PetscViewerFormat format; 367 PetscBool flg4 = PETSC_FALSE; 368 #endif 369 #if defined(PETSC_HAVE_CUDA) 370 PetscBool initCUDA = PETSC_TRUE; 371 #endif 372 373 PetscFunctionBegin; 374 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 375 376 #if !defined(PETSC_HAVE_THREADSAFETY) 377 if (!(PETSC_RUNNING_ON_VALGRIND)) { 378 /* 379 Setup the memory management; support for tracing malloc() usage 380 */ 381 PetscBool mdebug = PETSC_FALSE, eachcall = PETSC_FALSE, initializenan = PETSC_FALSE, mlog = PETSC_FALSE; 382 383 #if defined(PETSC_USE_DEBUG) 384 mdebug = PETSC_TRUE; 385 initializenan = PETSC_TRUE; 386 ierr = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr); 387 #else 388 /* don't warn about unused option */ 389 ierr = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr); 390 flg1 = PETSC_FALSE; 391 #endif 392 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_debug",&flg2,&flg3);CHKERRQ(ierr); 393 if (flg1 || flg2) { 394 mdebug = PETSC_TRUE; 395 eachcall = PETSC_TRUE; 396 initializenan = PETSC_TRUE; 397 } else if (flg3 && !flg2) { 398 mdebug = PETSC_FALSE; 399 eachcall = PETSC_FALSE; 400 initializenan = PETSC_FALSE; 401 } 402 403 ierr = PetscOptionsHasName(NULL,NULL,"-malloc_view",&mlog);CHKERRQ(ierr); 404 if (mlog) { 405 mdebug = PETSC_TRUE; 406 } 407 /* the next line is deprecated */ 408 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc",&mdebug,NULL);CHKERRQ(ierr); 409 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_dump",&mdebug,NULL);CHKERRQ(ierr); 410 ierr = PetscOptionsGetBool(NULL,NULL,"-log_view_memory",&mdebug,NULL);CHKERRQ(ierr); 411 if (mdebug) { 412 ierr = PetscMallocSetDebug(eachcall,initializenan);CHKERRQ(ierr); 413 } 414 if (mlog) { 415 PetscReal logthreshold = 0; 416 ierr = PetscOptionsGetReal(NULL,NULL,"-malloc_view_threshold",&logthreshold,NULL);CHKERRQ(ierr); 417 ierr = PetscMallocViewSet(logthreshold);CHKERRQ(ierr); 418 } 419 #if defined(PETSC_USE_LOG) 420 ierr = PetscOptionsGetBool(NULL,NULL,"-log_view_memory",&PetscLogMemory,NULL);CHKERRQ(ierr); 421 #endif 422 } 423 424 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_coalesce",&flg1,&flg2);CHKERRQ(ierr); 425 if (flg2) {ierr = PetscMallocSetCoalesce(flg1);CHKERRQ(ierr);} 426 flg1 = PETSC_FALSE; 427 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_hbw",&flg1,NULL);CHKERRQ(ierr); 428 /* ignore this option if malloc is already set */ 429 if (flg1 && !petscsetmallocvisited) {ierr = PetscSetUseHBWMalloc_Private();CHKERRQ(ierr);} 430 431 flg1 = PETSC_FALSE; 432 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_info",&flg1,NULL);CHKERRQ(ierr); 433 if (!flg1) { 434 flg1 = PETSC_FALSE; 435 ierr = PetscOptionsGetBool(NULL,NULL,"-memory_view",&flg1,NULL);CHKERRQ(ierr); 436 } 437 if (flg1) { 438 ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 439 } 440 #endif 441 442 #if defined(PETSC_USE_LOG) 443 ierr = PetscOptionsHasName(NULL,NULL,"-objects_dump",&PetscObjectsLog);CHKERRQ(ierr); 444 #endif 445 446 /* 447 Set the display variable for graphics 448 */ 449 ierr = PetscSetDisplay();CHKERRQ(ierr); 450 451 /* 452 Print the PETSc version information 453 */ 454 ierr = PetscOptionsHasName(NULL,NULL,"-v",&flg1);CHKERRQ(ierr); 455 ierr = PetscOptionsHasName(NULL,NULL,"-version",&flg2);CHKERRQ(ierr); 456 ierr = PetscOptionsHasHelp(NULL,&flg3);CHKERRQ(ierr); 457 if (flg1 || flg2 || flg3) { 458 459 /* 460 Print "higher-level" package version message 461 */ 462 if (PetscExternalVersionFunction) { 463 ierr = (*PetscExternalVersionFunction)(comm);CHKERRQ(ierr); 464 } 465 466 ierr = PetscGetVersion(version,256);CHKERRQ(ierr); 467 ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr); 468 ierr = (*PetscHelpPrintf)(comm,"%s\n",version);CHKERRQ(ierr); 469 ierr = (*PetscHelpPrintf)(comm,"%s",PETSC_AUTHOR_INFO);CHKERRQ(ierr); 470 ierr = (*PetscHelpPrintf)(comm,"See docs/changes/index.html for recent updates.\n");CHKERRQ(ierr); 471 ierr = (*PetscHelpPrintf)(comm,"See docs/faq.html for problems.\n");CHKERRQ(ierr); 472 ierr = (*PetscHelpPrintf)(comm,"See docs/manualpages/index.html for help. \n");CHKERRQ(ierr); 473 ierr = (*PetscHelpPrintf)(comm,"Libraries linked from %s\n",PETSC_LIB_DIR);CHKERRQ(ierr); 474 ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr); 475 } 476 477 /* 478 Print "higher-level" package help message 479 */ 480 if (flg3) { 481 if (PetscExternalHelpFunction) { 482 ierr = (*PetscExternalHelpFunction)(comm);CHKERRQ(ierr); 483 } 484 } 485 486 ierr = PetscOptionsGetString(NULL,NULL,"-help",helpoptions,sizeof(helpoptions),&flg1);CHKERRQ(ierr); 487 if (flg1) { 488 ierr = PetscStrcmp(helpoptions,"intro",&flg2);CHKERRQ(ierr); 489 if (flg2) { 490 ierr = PetscOptionsDestroyDefault();CHKERRQ(ierr); 491 ierr = PetscFreeMPIResources();CHKERRQ(ierr); 492 ierr = MPI_Finalize();CHKERRQ(ierr); 493 exit(0); 494 } 495 } 496 497 /* 498 Setup the error handling 499 */ 500 flg1 = PETSC_FALSE; 501 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_abort",&flg1,NULL);CHKERRQ(ierr); 502 if (flg1) { 503 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_ARE_FATAL);CHKERRQ(ierr); 504 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,NULL);CHKERRQ(ierr); 505 } 506 flg1 = PETSC_FALSE; 507 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_mpiabort",&flg1,NULL);CHKERRQ(ierr); 508 if (flg1) { ierr = PetscPushErrorHandler(PetscMPIAbortErrorHandler,NULL);CHKERRQ(ierr);} 509 flg1 = PETSC_FALSE; 510 ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_on_error",&flg1,NULL);CHKERRQ(ierr); 511 if (flg1) { 512 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);CHKERRQ(ierr); 513 } 514 /* experimental */ 515 flg1 = PETSC_FALSE; 516 ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_error_string",&flg1,NULL);CHKERRQ(ierr); 517 if (flg1) { 518 MPI_Errhandler eh; 519 520 ierr = MPI_Comm_create_errhandler(PetscMPI_Comm_eh,&eh);CHKERRQ(ierr); 521 ierr = MPI_Comm_set_errhandler(comm,eh);CHKERRQ(ierr); 522 ierr = MPI_Errhandler_free(&eh);CHKERRQ(ierr); 523 } 524 flg1 = PETSC_FALSE; 525 ierr = PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr); 526 if (!flg1) {ierr = PetscPushSignalHandler(PetscSignalHandlerDefault,(void*)0);CHKERRQ(ierr);} 527 flg1 = PETSC_FALSE; 528 ierr = PetscOptionsGetBool(NULL,NULL,"-fp_trap",&flg1,&flag);CHKERRQ(ierr); 529 if (flag) {ierr = PetscSetFPTrap((PetscFPTrap)flg1);CHKERRQ(ierr);} 530 ierr = PetscOptionsGetInt(NULL,NULL,"-check_pointer_intensity",&intensity,&flag);CHKERRQ(ierr); 531 if (flag) {ierr = PetscCheckPointerSetIntensity(intensity);CHKERRQ(ierr);} 532 533 /* 534 Setup debugger information 535 */ 536 ierr = PetscSetDefaultDebugger();CHKERRQ(ierr); 537 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_attach_debugger",string,64,&flg1);CHKERRQ(ierr); 538 if (flg1) { 539 MPI_Errhandler err_handler; 540 541 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 542 ierr = MPI_Comm_create_errhandler(Petsc_MPI_DebuggerOnError,&err_handler);CHKERRQ(ierr); 543 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 544 ierr = PetscPushErrorHandler(PetscAttachDebuggerErrorHandler,NULL);CHKERRQ(ierr); 545 } 546 ierr = PetscOptionsGetString(NULL,NULL,"-debug_terminal",string,64,&flg1);CHKERRQ(ierr); 547 if (flg1) { ierr = PetscSetDebugTerminal(string);CHKERRQ(ierr); } 548 ierr = PetscOptionsGetString(NULL,NULL,"-start_in_debugger",string,64,&flg1);CHKERRQ(ierr); 549 ierr = PetscOptionsGetString(NULL,NULL,"-stop_for_debugger",string,64,&flg2);CHKERRQ(ierr); 550 if (flg1 || flg2) { 551 PetscMPIInt size; 552 PetscInt lsize,*nodes; 553 MPI_Errhandler err_handler; 554 /* 555 we have to make sure that all processors have opened 556 connections to all other processors, otherwise once the 557 debugger has stated it is likely to receive a SIGUSR1 558 and kill the program. 559 */ 560 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 561 if (size > 2) { 562 PetscMPIInt dummy = 0; 563 MPI_Status status; 564 for (i=0; i<size; i++) { 565 if (rank != i) { 566 ierr = MPI_Send(&dummy,1,MPI_INT,i,109,comm);CHKERRQ(ierr); 567 } 568 } 569 for (i=0; i<size; i++) { 570 if (rank != i) { 571 ierr = MPI_Recv(&dummy,1,MPI_INT,i,109,comm,&status);CHKERRQ(ierr); 572 } 573 } 574 } 575 /* check if this processor node should be in debugger */ 576 ierr = PetscMalloc1(size,&nodes);CHKERRQ(ierr); 577 lsize = size; 578 ierr = PetscOptionsGetIntArray(NULL,NULL,"-debugger_nodes",nodes,&lsize,&flag);CHKERRQ(ierr); 579 if (flag) { 580 for (i=0; i<lsize; i++) { 581 if (nodes[i] == rank) { flag = PETSC_FALSE; break; } 582 } 583 } 584 if (!flag) { 585 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 586 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,NULL);CHKERRQ(ierr); 587 if (flg1) { 588 ierr = PetscAttachDebugger();CHKERRQ(ierr); 589 } else { 590 ierr = PetscStopForDebugger();CHKERRQ(ierr); 591 } 592 ierr = MPI_Comm_create_errhandler(Petsc_MPI_AbortOnError,&err_handler);CHKERRQ(ierr); 593 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 594 } 595 ierr = PetscFree(nodes);CHKERRQ(ierr); 596 } 597 598 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_emacs",emacsmachinename,128,&flg1);CHKERRQ(ierr); 599 if (flg1 && !rank) {ierr = PetscPushErrorHandler(PetscEmacsClientErrorHandler,emacsmachinename);CHKERRQ(ierr);} 600 601 /* 602 Setup profiling and logging 603 */ 604 #if defined(PETSC_USE_INFO) 605 { 606 ierr = PetscInfoSetFromOptions(NULL);CHKERRQ(ierr); 607 } 608 #endif 609 #if defined(PETSC_USE_LOG) 610 mname[0] = 0; 611 ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 612 if (flg1) { 613 if (mname[0]) { 614 ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr); 615 } else { 616 ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr); 617 } 618 } 619 620 ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr); 621 622 #if defined(PETSC_HAVE_MPE) 623 flg1 = PETSC_FALSE; 624 ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr); 625 if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);} 626 #endif 627 flg1 = PETSC_FALSE; 628 flg3 = PETSC_FALSE; 629 ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr); 630 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 631 if (flg1) { ierr = PetscLogAllBegin();CHKERRQ(ierr); } 632 else if (flg3) { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 633 634 ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,250,&flg1);CHKERRQ(ierr); 635 if (flg1) { 636 char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN]; 637 FILE *file; 638 if (mname[0]) { 639 PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank); 640 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 641 file = fopen(fname,"w"); 642 if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname); 643 } else file = PETSC_STDOUT; 644 ierr = PetscLogTraceBegin(file);CHKERRQ(ierr); 645 } 646 647 ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr); 648 if (flg4) { 649 if (format == PETSC_VIEWER_ASCII_XML) { 650 ierr = PetscLogNestedBegin();CHKERRQ(ierr); 651 } else { 652 ierr = PetscLogDefaultBegin();CHKERRQ(ierr); 653 } 654 } 655 if (flg4 && format == PETSC_VIEWER_ASCII_XML) { 656 PetscReal threshold = PetscRealConstant(0.01); 657 ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr); 658 if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);} 659 } 660 #endif 661 662 ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr); 663 664 #if defined(PETSC_HAVE_CUDA) 665 ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr); 666 ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCUDA,&initCUDA,NULL);CHKERRQ(ierr); 667 ierr = PetscOptionsEnd();CHKERRQ(ierr); 668 if (initCUDA) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);} 669 #endif 670 671 /* 672 Print basic help message 673 */ 674 ierr = PetscOptionsHasHelp(NULL,&flg1);CHKERRQ(ierr); 675 if (flg1) { 676 ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr); 677 ierr = (*PetscHelpPrintf)(comm," -help: prints help method for each option\n");CHKERRQ(ierr); 678 ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr); 679 ierr = (*PetscHelpPrintf)(comm," only when run in the debugger\n");CHKERRQ(ierr); 680 ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 681 ierr = (*PetscHelpPrintf)(comm," start the debugger in new xterm\n");CHKERRQ(ierr); 682 ierr = (*PetscHelpPrintf)(comm," unless noxterm is given\n");CHKERRQ(ierr); 683 ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 684 ierr = (*PetscHelpPrintf)(comm," start all processes in the debugger\n");CHKERRQ(ierr); 685 ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr); 686 ierr = (*PetscHelpPrintf)(comm," emacs jumps to error file\n");CHKERRQ(ierr); 687 ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr); 688 ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr); 689 ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr); 690 ierr = (*PetscHelpPrintf)(comm," waits the delay for you to attach\n");CHKERRQ(ierr); 691 ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr); 692 ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr); 693 ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr); 694 ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr); 695 ierr = (*PetscHelpPrintf)(comm," note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr); 696 ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr); 697 ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecated, use -malloc_debug)\n");CHKERRQ(ierr); 698 ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecated, use -malloc_debug no)\n");CHKERRQ(ierr); 699 ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr); 700 ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr); 701 ierr = (*PetscHelpPrintf)(comm," -malloc_debug <true or false>: enables or disables extended checking for memory corruption\n");CHKERRQ(ierr); 702 ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr); 703 ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr); 704 ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr); 705 ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr); 706 ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr); 707 ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr); 708 ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr); 709 #if defined(PETSC_USE_LOG) 710 ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr); 711 ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr); 712 ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr); 713 #if defined(PETSC_HAVE_MPE) 714 ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr); 715 #endif 716 #endif 717 #if defined(PETSC_USE_INFO) 718 ierr = (*PetscHelpPrintf)(comm," -info [filename][:[[~]list,of,classnames][:[[~]'self']]]: print informative messages\n");CHKERRQ(ierr); 719 #endif 720 ierr = (*PetscHelpPrintf)(comm," -v: prints PETSc version number and release date\n");CHKERRQ(ierr); 721 ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr); 722 ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr); 723 ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr); 724 } 725 726 #if defined(PETSC_HAVE_POPEN) 727 { 728 char machine[128]; 729 ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,128,&flg1);CHKERRQ(ierr); 730 if (flg1) { 731 ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr); 732 } 733 } 734 #endif 735 736 ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr); 737 if (flg1) { 738 ierr = PetscSleep(si);CHKERRQ(ierr); 739 } 740 741 #if defined(PETSC_HAVE_VIENNACL) 742 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 743 if (!flg3) { 744 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr); 745 } 746 ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr); 747 PetscViennaCLSynchronize = flg3; 748 ierr = PetscViennaCLInit();CHKERRQ(ierr); 749 #endif 750 751 /* 752 Creates the logging data structures; this is enabled even if logging is not turned on 753 This is the last thing we do before returning to the user code to prevent having the 754 logging numbers contaminated by any startup time associated with MPI and the GPUs 755 */ 756 #if defined(PETSC_USE_LOG) 757 ierr = PetscLogInitialize();CHKERRQ(ierr); 758 #endif 759 760 PetscFunctionReturn(0); 761 } 762