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 extern PetscErrorCode PetscCUBLASInitializeHandle(void); 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) MPI_Abort(*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 - do the initialization in PetscInitialize() 207 . -cuda_view - view information about the CUDA devices 208 . -cuda_synchronize - wait at the end of asynchronize CUDA calls so that their time gets credited to the current event; default with -log_view 209 - -cuda_set_device <gpu> - integer number of the device 210 211 Notes: 212 Initializing cuBLAS takes about 1/2 second there it is done by default in PetscInitialize() before logging begins 213 214 @*/ 215 PetscErrorCode PetscCUDAInitialize(MPI_Comm comm) 216 { 217 PetscErrorCode ierr; 218 PetscInt deviceOpt = 0; 219 PetscBool cuda_view_flag = PETSC_FALSE,flg; 220 struct cudaDeviceProp prop; 221 int devCount,device,devicecnt; 222 cudaError_t err = cudaSuccess; 223 PetscMPIInt rank,size; 224 225 PetscFunctionBegin; 226 /* 227 If collecting logging information, by default, wait for GPU to complete its operations 228 before returning to the CPU in order to get accurate timings of each event 229 */ 230 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&PetscCUDASynchronize);CHKERRQ(ierr); 231 if (!PetscCUDASynchronize) { 232 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&PetscCUDASynchronize);CHKERRQ(ierr); 233 } 234 235 ierr = PetscOptionsBegin(comm,NULL,"CUDA options","Sys");CHKERRQ(ierr); 236 ierr = PetscOptionsInt("-cuda_set_device","Set all MPI ranks to use the specified CUDA device",NULL,deviceOpt,&deviceOpt,&flg);CHKERRQ(ierr); 237 device = (int)deviceOpt; 238 ierr = PetscOptionsBool("-cuda_synchronize","Wait for the GPU to complete operations before returning to the CPU",NULL,PetscCUDASynchronize,&PetscCUDASynchronize,NULL);CHKERRQ(ierr); 239 ierr = PetscOptionsDeprecated("-cuda_show_devices","-cuda_view","3.12",NULL);CHKERRQ(ierr); 240 ierr = PetscOptionsName("-cuda_view","Display CUDA device information and assignments",NULL,&cuda_view_flag);CHKERRQ(ierr); 241 ierr = PetscOptionsEnd();CHKERRQ(ierr); 242 if (!PetscCUDAInitialized) { 243 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 244 245 if (size>1 && !flg) { 246 /* check to see if we force multiple ranks to hit the same GPU */ 247 /* we're not using the same GPU on multiple MPI threads. So try to allocated different GPUs to different processes */ 248 249 /* First get the device count */ 250 err = cudaGetDeviceCount(&devCount); 251 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err)); 252 253 /* next determine the rank and then set the device via a mod */ 254 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 255 device = rank % devCount; 256 } 257 err = cudaSetDevice(device); 258 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDevice %s",cudaGetErrorString(err)); 259 260 /* set the device flags so that it can map host memory */ 261 err = cudaSetDeviceFlags(cudaDeviceMapHost); 262 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaSetDeviceFlags %s",cudaGetErrorString(err)); 263 264 ierr = PetscCUBLASInitializeHandle();CHKERRQ(ierr); 265 PetscCUDAInitialized = PETSC_TRUE; 266 } 267 if (cuda_view_flag) { 268 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 269 err = cudaGetDeviceCount(&devCount); 270 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err)); 271 for (devicecnt = 0; devicecnt < devCount; ++devicecnt) { 272 err = cudaGetDeviceProperties(&prop,devicecnt); 273 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceProperties %s",cudaGetErrorString(err)); 274 ierr = PetscPrintf(comm, "CUDA device %d: %s\n", devicecnt, prop.name);CHKERRQ(ierr); 275 } 276 ierr = PetscSynchronizedPrintf(comm,"[%d] Using CUDA device %d.\n",rank,device);CHKERRQ(ierr); 277 ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 278 } 279 PetscFunctionReturn(0); 280 } 281 #endif 282 283 /*@C 284 PetscEnd - Calls PetscFinalize() and then ends the program. This is useful if one 285 wishes a clean exit somewhere deep in the program. 286 287 Collective on PETSC_COMM_WORLD 288 289 Options Database Keys are the same as for PetscFinalize() 290 291 Level: advanced 292 293 Note: 294 See PetscInitialize() for more general runtime options. 295 296 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscFinalize() 297 @*/ 298 PetscErrorCode PetscEnd(void) 299 { 300 PetscFunctionBegin; 301 PetscFinalize(); 302 exit(0); 303 return 0; 304 } 305 306 PetscBool PetscOptionsPublish = PETSC_FALSE; 307 PETSC_INTERN PetscErrorCode PetscSetUseHBWMalloc_Private(void); 308 PETSC_INTERN PetscBool petscsetmallocvisited; 309 static char emacsmachinename[256]; 310 311 PetscErrorCode (*PetscExternalVersionFunction)(MPI_Comm) = 0; 312 PetscErrorCode (*PetscExternalHelpFunction)(MPI_Comm) = 0; 313 314 /*@C 315 PetscSetHelpVersionFunctions - Sets functions that print help and version information 316 before the PETSc help and version information is printed. Must call BEFORE PetscInitialize(). 317 This routine enables a "higher-level" package that uses PETSc to print its messages first. 318 319 Input Parameter: 320 + help - the help function (may be NULL) 321 - version - the version function (may be NULL) 322 323 Level: developer 324 325 @*/ 326 PetscErrorCode PetscSetHelpVersionFunctions(PetscErrorCode (*help)(MPI_Comm),PetscErrorCode (*version)(MPI_Comm)) 327 { 328 PetscFunctionBegin; 329 PetscExternalHelpFunction = help; 330 PetscExternalVersionFunction = version; 331 PetscFunctionReturn(0); 332 } 333 334 #if defined(PETSC_USE_LOG) 335 PETSC_INTERN PetscBool PetscObjectsLog; 336 #endif 337 338 PETSC_INTERN PetscErrorCode PetscOptionsCheckInitial_Private(void) 339 { 340 char string[64],mname[PETSC_MAX_PATH_LEN],*f; 341 MPI_Comm comm = PETSC_COMM_WORLD; 342 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flag; 343 PetscErrorCode ierr; 344 PetscReal si; 345 PetscInt intensity; 346 int i; 347 PetscMPIInt rank; 348 char version[256],helpoptions[256]; 349 #if defined(PETSC_USE_LOG) 350 PetscViewerFormat format; 351 PetscBool flg4 = PETSC_FALSE; 352 #endif 353 #if defined(PETSC_HAVE_CUDA) 354 PetscBool initCuda = PETSC_TRUE; 355 #endif 356 357 PetscFunctionBegin; 358 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 359 360 #if !defined(PETSC_HAVE_THREADSAFETY) 361 if (!(PETSC_RUNNING_ON_VALGRIND)) { 362 /* 363 Setup the memory management; support for tracing malloc() usage 364 */ 365 PetscBool mdebug = PETSC_FALSE, eachcall = PETSC_FALSE, initializenan = PETSC_FALSE, dump = PETSC_FALSE, mlog = PETSC_FALSE; 366 367 #if defined(PETSC_USE_DEBUG) 368 mdebug = PETSC_TRUE; 369 initializenan = PETSC_TRUE; 370 ierr = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr); 371 #else 372 /* don't warn about unused option */ 373 ierr = PetscOptionsHasName(NULL,NULL,"-malloc_test",&flg1);CHKERRQ(ierr); 374 flg1 = PETSC_FALSE; 375 #endif 376 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_debug",&flg2,NULL);CHKERRQ(ierr); 377 if (flg1 || flg2) { 378 mdebug = PETSC_TRUE; 379 eachcall = PETSC_TRUE; 380 initializenan = PETSC_TRUE; 381 dump = PETSC_TRUE; 382 } 383 384 ierr = PetscOptionsHasName(NULL,NULL,"-malloc_view",&mlog);CHKERRQ(ierr); 385 if (mlog) { 386 mdebug = PETSC_TRUE; 387 } 388 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc",&mdebug,NULL);CHKERRQ(ierr); 389 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_dump",&mdebug,NULL);CHKERRQ(ierr); 390 ierr = PetscOptionsGetBool(NULL,NULL,"-log_view_memory",&mdebug,NULL);CHKERRQ(ierr); 391 if (mdebug) { 392 ierr = PetscMallocSetDebug(eachcall,initializenan);CHKERRQ(ierr); 393 } 394 if (mlog) { 395 PetscReal logthreshold = 0; 396 ierr = PetscOptionsGetReal(NULL,NULL,"-malloc_view_threshold",&logthreshold,NULL);CHKERRQ(ierr); 397 ierr = PetscMallocViewSet(logthreshold);CHKERRQ(ierr); 398 } 399 } 400 401 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_coalesce",&flg1,&flg2);CHKERRQ(ierr); 402 if (flg2) {ierr = PetscMallocSetCoalesce(flg1);CHKERRQ(ierr);} 403 flg1 = PETSC_FALSE; 404 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_hbw",&flg1,NULL);CHKERRQ(ierr); 405 /* ignore this option if malloc is already set */ 406 if (flg1 && !petscsetmallocvisited) {ierr = PetscSetUseHBWMalloc_Private();CHKERRQ(ierr);} 407 408 flg1 = PETSC_FALSE; 409 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_info",&flg1,NULL);CHKERRQ(ierr); 410 if (!flg1) { 411 flg1 = PETSC_FALSE; 412 ierr = PetscOptionsGetBool(NULL,NULL,"-memory_view",&flg1,NULL);CHKERRQ(ierr); 413 } 414 if (flg1) { 415 ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 416 } 417 #endif 418 419 #if defined(PETSC_USE_LOG) 420 ierr = PetscOptionsHasName(NULL,NULL,"-objects_dump",&PetscObjectsLog);CHKERRQ(ierr); 421 #endif 422 423 /* 424 Set the display variable for graphics 425 */ 426 ierr = PetscSetDisplay();CHKERRQ(ierr); 427 428 /* 429 Print the PETSc version information 430 */ 431 ierr = PetscOptionsHasName(NULL,NULL,"-v",&flg1);CHKERRQ(ierr); 432 ierr = PetscOptionsHasName(NULL,NULL,"-version",&flg2);CHKERRQ(ierr); 433 ierr = PetscOptionsHasHelp(NULL,&flg3);CHKERRQ(ierr); 434 if (flg1 || flg2 || flg3) { 435 436 /* 437 Print "higher-level" package version message 438 */ 439 if (PetscExternalVersionFunction) { 440 ierr = (*PetscExternalVersionFunction)(comm);CHKERRQ(ierr); 441 } 442 443 ierr = PetscGetVersion(version,256);CHKERRQ(ierr); 444 ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr); 445 ierr = (*PetscHelpPrintf)(comm,"%s\n",version);CHKERRQ(ierr); 446 ierr = (*PetscHelpPrintf)(comm,"%s",PETSC_AUTHOR_INFO);CHKERRQ(ierr); 447 ierr = (*PetscHelpPrintf)(comm,"See docs/changes/index.html for recent updates.\n");CHKERRQ(ierr); 448 ierr = (*PetscHelpPrintf)(comm,"See docs/faq.html for problems.\n");CHKERRQ(ierr); 449 ierr = (*PetscHelpPrintf)(comm,"See docs/manualpages/index.html for help. \n");CHKERRQ(ierr); 450 ierr = (*PetscHelpPrintf)(comm,"Libraries linked from %s\n",PETSC_LIB_DIR);CHKERRQ(ierr); 451 ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr); 452 } 453 454 /* 455 Print "higher-level" package help message 456 */ 457 if (flg3) { 458 if (PetscExternalHelpFunction) { 459 ierr = (*PetscExternalHelpFunction)(comm);CHKERRQ(ierr); 460 } 461 } 462 463 ierr = PetscOptionsGetString(NULL,NULL,"-help",helpoptions,sizeof(helpoptions),&flg1);CHKERRQ(ierr); 464 if (flg1) { 465 ierr = PetscStrcmp(helpoptions,"intro",&flg2);CHKERRQ(ierr); 466 if (flg2) { 467 ierr = PetscOptionsDestroyDefault();CHKERRQ(ierr); 468 ierr = PetscFreeMPIResources();CHKERRQ(ierr); 469 ierr = MPI_Finalize();CHKERRQ(ierr); 470 exit(0); 471 } 472 } 473 474 /* 475 Setup the error handling 476 */ 477 flg1 = PETSC_FALSE; 478 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_abort",&flg1,NULL);CHKERRQ(ierr); 479 if (flg1) { 480 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_ARE_FATAL);CHKERRQ(ierr); 481 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr); 482 } 483 flg1 = PETSC_FALSE; 484 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_mpiabort",&flg1,NULL);CHKERRQ(ierr); 485 if (flg1) { ierr = PetscPushErrorHandler(PetscMPIAbortErrorHandler,0);CHKERRQ(ierr);} 486 flg1 = PETSC_FALSE; 487 ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_on_error",&flg1,NULL);CHKERRQ(ierr); 488 if (flg1) { 489 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);CHKERRQ(ierr); 490 } 491 flg1 = PETSC_FALSE; 492 ierr = PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr); 493 if (!flg1) {ierr = PetscPushSignalHandler(PetscSignalHandlerDefault,(void*)0);CHKERRQ(ierr);} 494 flg1 = PETSC_FALSE; 495 ierr = PetscOptionsGetBool(NULL,NULL,"-fp_trap",&flg1,NULL);CHKERRQ(ierr); 496 if (flg1) {ierr = PetscSetFPTrap(PETSC_FP_TRAP_ON);CHKERRQ(ierr);} 497 ierr = PetscOptionsGetInt(NULL,NULL,"-check_pointer_intensity",&intensity,&flag);CHKERRQ(ierr); 498 if (flag) {ierr = PetscCheckPointerSetIntensity(intensity);CHKERRQ(ierr);} 499 500 /* 501 Setup debugger information 502 */ 503 ierr = PetscSetDefaultDebugger();CHKERRQ(ierr); 504 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_attach_debugger",string,64,&flg1);CHKERRQ(ierr); 505 if (flg1) { 506 MPI_Errhandler err_handler; 507 508 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 509 ierr = MPI_Comm_create_errhandler(Petsc_MPI_DebuggerOnError,&err_handler);CHKERRQ(ierr); 510 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 511 ierr = PetscPushErrorHandler(PetscAttachDebuggerErrorHandler,0);CHKERRQ(ierr); 512 } 513 ierr = PetscOptionsGetString(NULL,NULL,"-debug_terminal",string,64,&flg1);CHKERRQ(ierr); 514 if (flg1) { ierr = PetscSetDebugTerminal(string);CHKERRQ(ierr); } 515 ierr = PetscOptionsGetString(NULL,NULL,"-start_in_debugger",string,64,&flg1);CHKERRQ(ierr); 516 ierr = PetscOptionsGetString(NULL,NULL,"-stop_for_debugger",string,64,&flg2);CHKERRQ(ierr); 517 if (flg1 || flg2) { 518 PetscMPIInt size; 519 PetscInt lsize,*nodes; 520 MPI_Errhandler err_handler; 521 /* 522 we have to make sure that all processors have opened 523 connections to all other processors, otherwise once the 524 debugger has stated it is likely to receive a SIGUSR1 525 and kill the program. 526 */ 527 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 528 if (size > 2) { 529 PetscMPIInt dummy = 0; 530 MPI_Status status; 531 for (i=0; i<size; i++) { 532 if (rank != i) { 533 ierr = MPI_Send(&dummy,1,MPI_INT,i,109,comm);CHKERRQ(ierr); 534 } 535 } 536 for (i=0; i<size; i++) { 537 if (rank != i) { 538 ierr = MPI_Recv(&dummy,1,MPI_INT,i,109,comm,&status);CHKERRQ(ierr); 539 } 540 } 541 } 542 /* check if this processor node should be in debugger */ 543 ierr = PetscMalloc1(size,&nodes);CHKERRQ(ierr); 544 lsize = size; 545 ierr = PetscOptionsGetIntArray(NULL,NULL,"-debugger_nodes",nodes,&lsize,&flag);CHKERRQ(ierr); 546 if (flag) { 547 for (i=0; i<lsize; i++) { 548 if (nodes[i] == rank) { flag = PETSC_FALSE; break; } 549 } 550 } 551 if (!flag) { 552 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 553 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr); 554 if (flg1) { 555 ierr = PetscAttachDebugger();CHKERRQ(ierr); 556 } else { 557 ierr = PetscStopForDebugger();CHKERRQ(ierr); 558 } 559 ierr = MPI_Comm_create_errhandler(Petsc_MPI_AbortOnError,&err_handler);CHKERRQ(ierr); 560 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 561 } 562 ierr = PetscFree(nodes);CHKERRQ(ierr); 563 } 564 565 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_emacs",emacsmachinename,128,&flg1);CHKERRQ(ierr); 566 if (flg1 && !rank) {ierr = PetscPushErrorHandler(PetscEmacsClientErrorHandler,emacsmachinename);CHKERRQ(ierr);} 567 568 /* 569 Setup profiling and logging 570 */ 571 #if defined(PETSC_USE_INFO) 572 { 573 char logname[PETSC_MAX_PATH_LEN]; logname[0] = 0; 574 ierr = PetscOptionsGetString(NULL,NULL,"-info",logname,250,&flg1);CHKERRQ(ierr); 575 if (flg1 && logname[0]) { 576 ierr = PetscInfoAllow(PETSC_TRUE,logname);CHKERRQ(ierr); 577 } else if (flg1) { 578 ierr = PetscInfoAllow(PETSC_TRUE,NULL);CHKERRQ(ierr); 579 } 580 } 581 #endif 582 #if defined(PETSC_USE_LOG) 583 mname[0] = 0; 584 ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 585 if (flg1) { 586 if (mname[0]) { 587 ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr); 588 } else { 589 ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr); 590 } 591 } 592 593 ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr); 594 595 #if defined(PETSC_HAVE_MPE) 596 flg1 = PETSC_FALSE; 597 ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr); 598 if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);} 599 #endif 600 flg1 = PETSC_FALSE; 601 flg3 = PETSC_FALSE; 602 ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr); 603 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 604 if (flg1) { ierr = PetscLogAllBegin();CHKERRQ(ierr); } 605 else if (flg3) { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 606 607 ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,250,&flg1);CHKERRQ(ierr); 608 if (flg1) { 609 char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN]; 610 FILE *file; 611 if (mname[0]) { 612 PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank); 613 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 614 file = fopen(fname,"w"); 615 if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname); 616 } else file = PETSC_STDOUT; 617 ierr = PetscLogTraceBegin(file);CHKERRQ(ierr); 618 } 619 620 ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr); 621 if (flg4) { 622 if (format == PETSC_VIEWER_ASCII_XML) { 623 ierr = PetscLogNestedBegin();CHKERRQ(ierr); 624 } else { 625 ierr = PetscLogDefaultBegin();CHKERRQ(ierr); 626 } 627 } 628 if (flg4 && format == PETSC_VIEWER_ASCII_XML) { 629 PetscReal threshold = PetscRealConstant(0.01); 630 ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr); 631 if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);} 632 } 633 #endif 634 635 ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr); 636 637 #if defined(PETSC_HAVE_CUDA) 638 ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr); 639 ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCuda,&initCuda,NULL);CHKERRQ(ierr); 640 ierr = PetscOptionsEnd();CHKERRQ(ierr); 641 if (initCuda) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);} 642 #endif 643 644 /* 645 Print basic help message 646 */ 647 ierr = PetscOptionsHasHelp(NULL,&flg1);CHKERRQ(ierr); 648 if (flg1) { 649 ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr); 650 ierr = (*PetscHelpPrintf)(comm," -help: prints help method for each option\n");CHKERRQ(ierr); 651 ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr); 652 ierr = (*PetscHelpPrintf)(comm," only when run in the debugger\n");CHKERRQ(ierr); 653 ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 654 ierr = (*PetscHelpPrintf)(comm," start the debugger in new xterm\n");CHKERRQ(ierr); 655 ierr = (*PetscHelpPrintf)(comm," unless noxterm is given\n");CHKERRQ(ierr); 656 ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 657 ierr = (*PetscHelpPrintf)(comm," start all processes in the debugger\n");CHKERRQ(ierr); 658 ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr); 659 ierr = (*PetscHelpPrintf)(comm," emacs jumps to error file\n");CHKERRQ(ierr); 660 ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr); 661 ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr); 662 ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr); 663 ierr = (*PetscHelpPrintf)(comm," waits the delay for you to attach\n");CHKERRQ(ierr); 664 ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr); 665 ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr); 666 ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr); 667 ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr); 668 ierr = (*PetscHelpPrintf)(comm," note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr); 669 ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr); 670 ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecaited, use -malloc_debug)\n");CHKERRQ(ierr); 671 ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecaited, use -malloc_debug)\n");CHKERRQ(ierr); 672 ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr); 673 ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr); 674 ierr = (*PetscHelpPrintf)(comm," -malloc_debug: enables extended checking for memory corruption\n");CHKERRQ(ierr); 675 ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr); 676 ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr); 677 ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr); 678 ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr); 679 ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr); 680 ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr); 681 ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr); 682 #if defined(PETSC_USE_LOG) 683 ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr); 684 ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr); 685 ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr); 686 #if defined(PETSC_HAVE_MPE) 687 ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr); 688 #endif 689 ierr = (*PetscHelpPrintf)(comm," -info <optional filename>: print informative messages about the calculations\n");CHKERRQ(ierr); 690 #endif 691 ierr = (*PetscHelpPrintf)(comm," -v: prints PETSc version number and release date\n");CHKERRQ(ierr); 692 ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr); 693 ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr); 694 ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr); 695 } 696 697 #if defined(PETSC_HAVE_POPEN) 698 { 699 char machine[128]; 700 ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,128,&flg1);CHKERRQ(ierr); 701 if (flg1) { 702 ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr); 703 } 704 } 705 #endif 706 707 ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr); 708 if (flg1) { 709 ierr = PetscSleep(si);CHKERRQ(ierr); 710 } 711 712 ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 713 if (flg1) { 714 ierr = PetscStrstr(mname,"null",&f);CHKERRQ(ierr); 715 if (f) { 716 ierr = PetscInfoDeactivateClass(0);CHKERRQ(ierr); 717 } 718 } 719 720 #if defined(PETSC_HAVE_VIENNACL) 721 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 722 if (!flg3) { 723 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr); 724 } 725 ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr); 726 PetscViennaCLSynchronize = flg3; 727 ierr = PetscViennaCLInit();CHKERRQ(ierr); 728 #endif 729 730 /* 731 Creates the logging data structures; this is enabled even if logging is not turned on 732 This is the last thing we do before returning to the user code to prevent having the 733 logging numbers contaminated by any startup time associated with MPI and the GPUs 734 */ 735 #if defined(PETSC_USE_LOG) 736 ierr = PetscLogInitialize();CHKERRQ(ierr); 737 #endif 738 739 PetscFunctionReturn(0); 740 } 741