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],*f; 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 char logname[PETSC_MAX_PATH_LEN]; logname[0] = 0; 607 ierr = PetscOptionsGetString(NULL,NULL,"-info",logname,250,&flg1);CHKERRQ(ierr); 608 if (flg1 && logname[0]) { 609 ierr = PetscInfoAllow(PETSC_TRUE,logname);CHKERRQ(ierr); 610 } else if (flg1) { 611 ierr = PetscInfoAllow(PETSC_TRUE,NULL);CHKERRQ(ierr); 612 } 613 } 614 #endif 615 #if defined(PETSC_USE_LOG) 616 mname[0] = 0; 617 ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 618 if (flg1) { 619 if (mname[0]) { 620 ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr); 621 } else { 622 ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr); 623 } 624 } 625 626 ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr); 627 628 #if defined(PETSC_HAVE_MPE) 629 flg1 = PETSC_FALSE; 630 ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr); 631 if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);} 632 #endif 633 flg1 = PETSC_FALSE; 634 flg3 = PETSC_FALSE; 635 ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr); 636 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 637 if (flg1) { ierr = PetscLogAllBegin();CHKERRQ(ierr); } 638 else if (flg3) { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 639 640 ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,250,&flg1);CHKERRQ(ierr); 641 if (flg1) { 642 char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN]; 643 FILE *file; 644 if (mname[0]) { 645 PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank); 646 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 647 file = fopen(fname,"w"); 648 if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname); 649 } else file = PETSC_STDOUT; 650 ierr = PetscLogTraceBegin(file);CHKERRQ(ierr); 651 } 652 653 ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr); 654 if (flg4) { 655 if (format == PETSC_VIEWER_ASCII_XML) { 656 ierr = PetscLogNestedBegin();CHKERRQ(ierr); 657 } else { 658 ierr = PetscLogDefaultBegin();CHKERRQ(ierr); 659 } 660 } 661 if (flg4 && format == PETSC_VIEWER_ASCII_XML) { 662 PetscReal threshold = PetscRealConstant(0.01); 663 ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr); 664 if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);} 665 } 666 #endif 667 668 ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr); 669 670 #if defined(PETSC_HAVE_CUDA) 671 ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr); 672 ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCuda,&initCuda,NULL);CHKERRQ(ierr); 673 ierr = PetscOptionsEnd();CHKERRQ(ierr); 674 if (initCuda) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);} 675 #endif 676 677 /* 678 Print basic help message 679 */ 680 ierr = PetscOptionsHasHelp(NULL,&flg1);CHKERRQ(ierr); 681 if (flg1) { 682 ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr); 683 ierr = (*PetscHelpPrintf)(comm," -help: prints help method for each option\n");CHKERRQ(ierr); 684 ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr); 685 ierr = (*PetscHelpPrintf)(comm," only when run in the debugger\n");CHKERRQ(ierr); 686 ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 687 ierr = (*PetscHelpPrintf)(comm," start the debugger in new xterm\n");CHKERRQ(ierr); 688 ierr = (*PetscHelpPrintf)(comm," unless noxterm is given\n");CHKERRQ(ierr); 689 ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 690 ierr = (*PetscHelpPrintf)(comm," start all processes in the debugger\n");CHKERRQ(ierr); 691 ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr); 692 ierr = (*PetscHelpPrintf)(comm," emacs jumps to error file\n");CHKERRQ(ierr); 693 ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr); 694 ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr); 695 ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr); 696 ierr = (*PetscHelpPrintf)(comm," waits the delay for you to attach\n");CHKERRQ(ierr); 697 ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr); 698 ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr); 699 ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr); 700 ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr); 701 ierr = (*PetscHelpPrintf)(comm," note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr); 702 ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr); 703 ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecated, use -malloc_debug)\n");CHKERRQ(ierr); 704 ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecated, use -malloc_debug no)\n");CHKERRQ(ierr); 705 ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr); 706 ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr); 707 ierr = (*PetscHelpPrintf)(comm," -malloc_debug <true or false>: enables or disables extended checking for memory corruption\n");CHKERRQ(ierr); 708 ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr); 709 ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr); 710 ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr); 711 ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr); 712 ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr); 713 ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr); 714 ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr); 715 #if defined(PETSC_USE_LOG) 716 ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr); 717 ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr); 718 ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr); 719 #if defined(PETSC_HAVE_MPE) 720 ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr); 721 #endif 722 ierr = (*PetscHelpPrintf)(comm," -info <optional filename>: print informative messages about the calculations\n");CHKERRQ(ierr); 723 #endif 724 ierr = (*PetscHelpPrintf)(comm," -v: prints PETSc version number and release date\n");CHKERRQ(ierr); 725 ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr); 726 ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr); 727 ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr); 728 } 729 730 #if defined(PETSC_HAVE_POPEN) 731 { 732 char machine[128]; 733 ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,128,&flg1);CHKERRQ(ierr); 734 if (flg1) { 735 ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr); 736 } 737 } 738 #endif 739 740 ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr); 741 if (flg1) { 742 ierr = PetscSleep(si);CHKERRQ(ierr); 743 } 744 745 ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 746 if (flg1) { 747 ierr = PetscStrstr(mname,"null",&f);CHKERRQ(ierr); 748 if (f) { 749 ierr = PetscInfoDeactivateClass(0);CHKERRQ(ierr); 750 } 751 } 752 753 #if defined(PETSC_HAVE_VIENNACL) 754 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 755 if (!flg3) { 756 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr); 757 } 758 ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr); 759 PetscViennaCLSynchronize = flg3; 760 ierr = PetscViennaCLInit();CHKERRQ(ierr); 761 #endif 762 763 /* 764 Creates the logging data structures; this is enabled even if logging is not turned on 765 This is the last thing we do before returning to the user code to prevent having the 766 logging numbers contaminated by any startup time associated with MPI and the GPUs 767 */ 768 #if defined(PETSC_USE_LOG) 769 ierr = PetscLogInitialize();CHKERRQ(ierr); 770 #endif 771 772 PetscFunctionReturn(0); 773 } 774