1 /* 2 3 This file defines part of the initialization of PETSc 4 5 This file uses regular malloc and free because it cannot be 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 #if defined(PETSC_HAVE_OMPI_MAJOR_VERSION) 27 #include "mpi-ext.h" /* Needed for OpenMPI CUDA-aware check */ 28 #endif 29 #endif 30 31 #if defined(PETSC_HAVE_VIENNACL) 32 PETSC_EXTERN PetscErrorCode PetscViennaCLInit(); 33 #endif 34 35 /* ------------------------Nasty global variables -------------------------------*/ 36 /* 37 Indicates if PETSc started up MPI, or it was 38 already started before PETSc was initialized. 39 */ 40 PetscBool PetscBeganMPI = PETSC_FALSE; 41 PetscBool PetscErrorHandlingInitialized = PETSC_FALSE; 42 PetscBool PetscInitializeCalled = PETSC_FALSE; 43 PetscBool PetscFinalizeCalled = PETSC_FALSE; 44 PetscBool PetscCUDAInitialized = PETSC_FALSE; 45 46 PetscMPIInt PetscGlobalRank = -1; 47 PetscMPIInt PetscGlobalSize = -1; 48 49 PetscBool use_gpu_aware_mpi = PETSC_TRUE; 50 51 #if defined(PETSC_HAVE_COMPLEX) 52 #if defined(PETSC_COMPLEX_INSTANTIATE) 53 template <> class std::complex<double>; /* instantiate complex template class */ 54 #endif 55 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 56 MPI_Datatype MPIU_C_DOUBLE_COMPLEX; 57 MPI_Datatype MPIU_C_COMPLEX; 58 #endif 59 60 /*MC 61 PETSC_i - the imaginary number i 62 63 Synopsis: 64 #include <petscsys.h> 65 PetscComplex PETSC_i; 66 67 Level: beginner 68 69 Note: 70 Complex numbers are automatically available if PETSc located a working complex implementation 71 72 .seealso: PetscRealPart(), PetscImaginaryPart(), PetscRealPartComplex(), PetscImaginaryPartComplex() 73 M*/ 74 PetscComplex PETSC_i; 75 #endif 76 #if defined(PETSC_USE_REAL___FLOAT128) 77 MPI_Datatype MPIU___FLOAT128 = 0; 78 #if defined(PETSC_HAVE_COMPLEX) 79 MPI_Datatype MPIU___COMPLEX128 = 0; 80 #endif 81 #elif defined(PETSC_USE_REAL___FP16) 82 MPI_Datatype MPIU___FP16 = 0; 83 #endif 84 MPI_Datatype MPIU_2SCALAR = 0; 85 #if defined(PETSC_USE_64BIT_INDICES) 86 MPI_Datatype MPIU_2INT = 0; 87 #endif 88 MPI_Datatype MPIU_BOOL; 89 MPI_Datatype MPIU_ENUM; 90 MPI_Datatype MPIU_FORTRANADDR; 91 MPI_Datatype MPIU_SIZE_T; 92 93 /* 94 Function that is called to display all error messages 95 */ 96 PetscErrorCode (*PetscErrorPrintf)(const char [],...) = PetscErrorPrintfDefault; 97 PetscErrorCode (*PetscHelpPrintf)(MPI_Comm,const char [],...) = PetscHelpPrintfDefault; 98 PetscErrorCode (*PetscVFPrintf)(FILE*,const char[],va_list) = PetscVFPrintfDefault; 99 /* 100 This is needed to turn on/off GPU synchronization 101 */ 102 PetscBool PetscViennaCLSynchronize = PETSC_FALSE; 103 PetscBool PetscCUDASynchronize = PETSC_FALSE; 104 105 /* ------------------------------------------------------------------------------*/ 106 /* 107 Optional file where all PETSc output from various prints is saved 108 */ 109 PETSC_INTERN FILE *petsc_history; 110 FILE *petsc_history = NULL; 111 112 PetscErrorCode PetscOpenHistoryFile(const char filename[],FILE **fd) 113 { 114 PetscErrorCode ierr; 115 PetscMPIInt rank,size; 116 char pfile[PETSC_MAX_PATH_LEN],pname[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN],date[64]; 117 char version[256]; 118 119 PetscFunctionBegin; 120 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 121 if (!rank) { 122 char arch[10]; 123 int err; 124 125 ierr = PetscGetArchType(arch,10);CHKERRQ(ierr); 126 ierr = PetscGetDate(date,64);CHKERRQ(ierr); 127 ierr = PetscGetVersion(version,256);CHKERRQ(ierr); 128 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 129 if (filename) { 130 ierr = PetscFixFilename(filename,fname);CHKERRQ(ierr); 131 } else { 132 ierr = PetscGetHomeDirectory(pfile,sizeof(pfile));CHKERRQ(ierr); 133 ierr = PetscStrlcat(pfile,"/.petschistory",sizeof(pfile));CHKERRQ(ierr); 134 ierr = PetscFixFilename(pfile,fname);CHKERRQ(ierr); 135 } 136 137 *fd = fopen(fname,"a"); 138 if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file: %s",fname); 139 140 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"----------------------------------------\n");CHKERRQ(ierr); 141 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"%s %s\n",version,date);CHKERRQ(ierr); 142 ierr = PetscGetProgramName(pname,sizeof(pname));CHKERRQ(ierr); 143 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"%s on a %s, %d proc. with options:\n",pname,arch,size);CHKERRQ(ierr); 144 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"----------------------------------------\n");CHKERRQ(ierr); 145 146 err = fflush(*fd); 147 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 148 } 149 PetscFunctionReturn(0); 150 } 151 152 PETSC_INTERN PetscErrorCode PetscCloseHistoryFile(FILE **fd) 153 { 154 PetscErrorCode ierr; 155 PetscMPIInt rank; 156 char date[64]; 157 int err; 158 159 PetscFunctionBegin; 160 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 161 if (!rank) { 162 ierr = PetscGetDate(date,64);CHKERRQ(ierr); 163 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"----------------------------------------\n");CHKERRQ(ierr); 164 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"Finished at %s\n",date);CHKERRQ(ierr); 165 ierr = PetscFPrintf(PETSC_COMM_SELF,*fd,"----------------------------------------\n");CHKERRQ(ierr); 166 err = fflush(*fd); 167 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file"); 168 err = fclose(*fd); 169 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 170 } 171 PetscFunctionReturn(0); 172 } 173 174 /* ------------------------------------------------------------------------------*/ 175 176 /* 177 This is ugly and probably belongs somewhere else, but I want to 178 be able to put a true MPI abort error handler with command line args. 179 180 This is so MPI errors in the debugger will leave all the stack 181 frames. The default MP_Abort() cleans up and exits thus providing no useful information 182 in the debugger hence we call abort() instead of MPI_Abort(). 183 */ 184 185 void Petsc_MPI_AbortOnError(MPI_Comm *comm,PetscMPIInt *flag,...) 186 { 187 PetscFunctionBegin; 188 (*PetscErrorPrintf)("MPI error %d\n",*flag); 189 abort(); 190 } 191 192 void Petsc_MPI_DebuggerOnError(MPI_Comm *comm,PetscMPIInt *flag,...) 193 { 194 PetscErrorCode ierr; 195 196 PetscFunctionBegin; 197 (*PetscErrorPrintf)("MPI error %d\n",*flag); 198 ierr = PetscAttachDebugger(); 199 if (ierr) PETSCABORT(*comm,*flag); /* hopeless so get out */ 200 } 201 202 #if defined(PETSC_HAVE_CUDA) 203 /*@C 204 PetscCUDAInitialize - Initializes the CUDA device and cuBLAS on the device 205 206 Logically collective 207 208 Input Parameter: 209 comm - the MPI communicator that will utilize the CUDA devices 210 211 Options Database: 212 + -cuda_initialize <yes,no> - Default no. Do the initialization in PetscInitialize(). If -cuda_initialize no is used then the default initialization is done automatically 213 when the first CUDA call is made unless you call PetscCUDAInitialize() before any CUDA operations are performed 214 . -cuda_view - view information about the CUDA devices 215 . -cuda_synchronize - wait at the end of asynchronize CUDA calls so that their time gets credited to the current event; default with -log_view 216 . -cuda_set_device <gpu> - integer number of the device 217 - -use_gpu_aware_mpi - Assume the MPI is GPU-aware when communicating data on GPU 218 219 Level: beginner 220 221 Notes: 222 Initializing cuBLAS takes about 1/2 second there it is done by default in PetscInitialize() before logging begins 223 224 @*/ 225 PetscErrorCode PetscCUDAInitialize(MPI_Comm comm) 226 { 227 PetscErrorCode ierr; 228 PetscInt deviceOpt = 0; 229 PetscBool cuda_view_flag = PETSC_FALSE,flg; 230 struct cudaDeviceProp prop; 231 int devCount,device,devicecnt; 232 cudaError_t err = cudaSuccess; 233 PetscMPIInt rank,size; 234 235 PetscFunctionBegin; 236 ierr = PetscOptionsBegin(comm,NULL,"CUDA options","Sys");CHKERRQ(ierr); 237 ierr = PetscOptionsInt("-cuda_set_device","Set all MPI ranks to use the specified CUDA device",NULL,deviceOpt,&deviceOpt,&flg);CHKERRQ(ierr); 238 device = (int)deviceOpt; 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 ierr = PetscCUSOLVERDnInitializeHandle();CHKERRQ(ierr); 266 PetscCUDAInitialized = PETSC_TRUE; 267 } 268 if (cuda_view_flag) { 269 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 270 err = cudaGetDeviceCount(&devCount); 271 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceCount %s",cudaGetErrorString(err)); 272 for (devicecnt = 0; devicecnt < devCount; ++devicecnt) { 273 err = cudaGetDeviceProperties(&prop,devicecnt); 274 if (err != cudaSuccess) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"error in cudaGetDeviceProperties %s",cudaGetErrorString(err)); 275 ierr = PetscPrintf(comm, "CUDA device %d: %s\n", devicecnt, prop.name);CHKERRQ(ierr); 276 } 277 ierr = PetscSynchronizedPrintf(comm,"[%d] Using CUDA device %d.\n",rank,device);CHKERRQ(ierr); 278 ierr = PetscSynchronizedFlush(comm,PETSC_STDOUT);CHKERRQ(ierr); 279 } 280 PetscFunctionReturn(0); 281 } 282 #endif 283 284 /*@C 285 PetscEnd - Calls PetscFinalize() and then ends the program. This is useful if one 286 wishes a clean exit somewhere deep in the program. 287 288 Collective on PETSC_COMM_WORLD 289 290 Options Database Keys are the same as for PetscFinalize() 291 292 Level: advanced 293 294 Note: 295 See PetscInitialize() for more general runtime options. 296 297 .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscFinalize() 298 @*/ 299 PetscErrorCode PetscEnd(void) 300 { 301 PetscFunctionBegin; 302 PetscFinalize(); 303 exit(0); 304 return 0; 305 } 306 307 PetscBool PetscOptionsPublish = PETSC_FALSE; 308 PETSC_INTERN PetscErrorCode PetscSetUseHBWMalloc_Private(void); 309 PETSC_INTERN PetscBool petscsetmallocvisited; 310 static char emacsmachinename[256]; 311 312 PetscErrorCode (*PetscExternalVersionFunction)(MPI_Comm) = NULL; 313 PetscErrorCode (*PetscExternalHelpFunction)(MPI_Comm) = NULL; 314 315 /*@C 316 PetscSetHelpVersionFunctions - Sets functions that print help and version information 317 before the PETSc help and version information is printed. Must call BEFORE PetscInitialize(). 318 This routine enables a "higher-level" package that uses PETSc to print its messages first. 319 320 Input Parameter: 321 + help - the help function (may be NULL) 322 - version - the version function (may be NULL) 323 324 Level: developer 325 326 @*/ 327 PetscErrorCode PetscSetHelpVersionFunctions(PetscErrorCode (*help)(MPI_Comm),PetscErrorCode (*version)(MPI_Comm)) 328 { 329 PetscFunctionBegin; 330 PetscExternalHelpFunction = help; 331 PetscExternalVersionFunction = version; 332 PetscFunctionReturn(0); 333 } 334 335 #if defined(PETSC_USE_LOG) 336 PETSC_INTERN PetscBool PetscObjectsLog; 337 #endif 338 339 void PetscMPI_Comm_eh(MPI_Comm *comm, PetscMPIInt *err, ...) 340 { 341 if (PetscUnlikely(*err)) { 342 PetscMPIInt len; 343 char errstring[MPI_MAX_ERROR_STRING]; 344 345 MPI_Error_string(*err,errstring,&len); 346 PetscError(MPI_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,PETSC_MPI_ERROR_CODE,PETSC_ERROR_INITIAL,"Internal error in MPI: %s",errstring); 347 } 348 return; 349 } 350 351 PETSC_INTERN PetscErrorCode PetscOptionsCheckInitial_Private(const char help[]) 352 { 353 char string[64]; 354 MPI_Comm comm = PETSC_COMM_WORLD; 355 PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE,flag,hasHelp; 356 PetscErrorCode ierr; 357 PetscReal si; 358 PetscInt intensity; 359 int i; 360 PetscMPIInt rank; 361 char version[256]; 362 #if defined(PETSC_USE_LOG) 363 char mname[PETSC_MAX_PATH_LEN]; 364 PetscViewerFormat format; 365 PetscBool flg4 = PETSC_FALSE; 366 #endif 367 #if defined(PETSC_HAVE_CUDA) 368 PetscBool initCUDA = PETSC_FALSE,mpi_gpu_awareness; 369 cudaError_t cerr; 370 int devCount = 0; 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 (PetscDefined(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 } 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 main application help message 453 */ 454 ierr = PetscOptionsHasHelp(NULL,&hasHelp);CHKERRQ(ierr); 455 if (help && hasHelp) { 456 ierr = PetscPrintf(comm,help);CHKERRQ(ierr); 457 ierr = PetscPrintf(comm,"----------------------------------------\n");CHKERRQ(ierr); 458 } 459 460 /* 461 Print the PETSc version information 462 */ 463 ierr = PetscOptionsHasName(NULL,NULL,"-version",&flg1);CHKERRQ(ierr); 464 if (flg1 || hasHelp) { 465 /* 466 Print "higher-level" package version message 467 */ 468 if (PetscExternalVersionFunction) { 469 ierr = (*PetscExternalVersionFunction)(comm);CHKERRQ(ierr); 470 } 471 472 ierr = PetscGetVersion(version,256);CHKERRQ(ierr); 473 ierr = (*PetscHelpPrintf)(comm,"%s\n",version);CHKERRQ(ierr); 474 ierr = (*PetscHelpPrintf)(comm,"%s",PETSC_AUTHOR_INFO);CHKERRQ(ierr); 475 ierr = (*PetscHelpPrintf)(comm,"See docs/changes/index.html for recent updates.\n");CHKERRQ(ierr); 476 ierr = (*PetscHelpPrintf)(comm,"See docs/faq.html for problems.\n");CHKERRQ(ierr); 477 ierr = (*PetscHelpPrintf)(comm,"See docs/manualpages/index.html for help. \n");CHKERRQ(ierr); 478 ierr = (*PetscHelpPrintf)(comm,"Libraries linked from %s\n",PETSC_LIB_DIR);CHKERRQ(ierr); 479 ierr = (*PetscHelpPrintf)(comm,"----------------------------------------\n");CHKERRQ(ierr); 480 } 481 482 /* 483 Print "higher-level" package help message 484 */ 485 if (hasHelp) { 486 PetscBool hasHelpIntro; 487 488 if (PetscExternalHelpFunction) { 489 ierr = (*PetscExternalHelpFunction)(comm);CHKERRQ(ierr); 490 } 491 ierr = PetscOptionsHasHelpIntro_Internal(NULL,&hasHelpIntro);CHKERRQ(ierr); 492 if (hasHelpIntro) { 493 ierr = PetscOptionsDestroyDefault();CHKERRQ(ierr); 494 ierr = PetscFreeMPIResources();CHKERRQ(ierr); 495 ierr = MPI_Finalize();CHKERRQ(ierr); 496 exit(0); 497 } 498 } 499 500 /* 501 Setup the error handling 502 */ 503 flg1 = PETSC_FALSE; 504 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_abort",&flg1,NULL);CHKERRQ(ierr); 505 if (flg1) { 506 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_ARE_FATAL);CHKERRQ(ierr); 507 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,NULL);CHKERRQ(ierr); 508 } 509 flg1 = PETSC_FALSE; 510 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_mpiabort",&flg1,NULL);CHKERRQ(ierr); 511 if (flg1) { ierr = PetscPushErrorHandler(PetscMPIAbortErrorHandler,NULL);CHKERRQ(ierr);} 512 flg1 = PETSC_FALSE; 513 ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_on_error",&flg1,NULL);CHKERRQ(ierr); 514 if (flg1) { 515 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);CHKERRQ(ierr); 516 } 517 /* experimental */ 518 flg1 = PETSC_FALSE; 519 ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_error_string",&flg1,NULL);CHKERRQ(ierr); 520 if (flg1) { 521 MPI_Errhandler eh; 522 523 ierr = MPI_Comm_create_errhandler(PetscMPI_Comm_eh,&eh);CHKERRQ(ierr); 524 ierr = MPI_Comm_set_errhandler(comm,eh);CHKERRQ(ierr); 525 ierr = MPI_Errhandler_free(&eh);CHKERRQ(ierr); 526 } 527 flg1 = PETSC_FALSE; 528 ierr = PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr); 529 if (!flg1) {ierr = PetscPushSignalHandler(PetscSignalHandlerDefault,(void*)0);CHKERRQ(ierr);} 530 531 /* 532 Setup debugger information 533 */ 534 ierr = PetscSetDefaultDebugger();CHKERRQ(ierr); 535 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_attach_debugger",string,sizeof(string),&flg1);CHKERRQ(ierr); 536 if (flg1) { 537 MPI_Errhandler err_handler; 538 539 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 540 ierr = MPI_Comm_create_errhandler(Petsc_MPI_DebuggerOnError,&err_handler);CHKERRQ(ierr); 541 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 542 ierr = PetscPushErrorHandler(PetscAttachDebuggerErrorHandler,NULL);CHKERRQ(ierr); 543 } 544 ierr = PetscOptionsGetString(NULL,NULL,"-debug_terminal",string,sizeof(string),&flg1);CHKERRQ(ierr); 545 if (flg1) { ierr = PetscSetDebugTerminal(string);CHKERRQ(ierr); } 546 ierr = PetscOptionsGetString(NULL,NULL,"-start_in_debugger",string,sizeof(string),&flg1);CHKERRQ(ierr); 547 ierr = PetscOptionsGetString(NULL,NULL,"-stop_for_debugger",string,sizeof(string),&flg2);CHKERRQ(ierr); 548 if (flg1 || flg2) { 549 PetscMPIInt size; 550 PetscInt lsize,*nodes; 551 MPI_Errhandler err_handler; 552 /* 553 we have to make sure that all processors have opened 554 connections to all other processors, otherwise once the 555 debugger has stated it is likely to receive a SIGUSR1 556 and kill the program. 557 */ 558 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 559 if (size > 2) { 560 PetscMPIInt dummy = 0; 561 MPI_Status status; 562 for (i=0; i<size; i++) { 563 if (rank != i) { 564 ierr = MPI_Send(&dummy,1,MPI_INT,i,109,comm);CHKERRQ(ierr); 565 } 566 } 567 for (i=0; i<size; i++) { 568 if (rank != i) { 569 ierr = MPI_Recv(&dummy,1,MPI_INT,i,109,comm,&status);CHKERRQ(ierr); 570 } 571 } 572 } 573 /* check if this processor node should be in debugger */ 574 ierr = PetscMalloc1(size,&nodes);CHKERRQ(ierr); 575 lsize = size; 576 ierr = PetscOptionsGetIntArray(NULL,NULL,"-debugger_nodes",nodes,&lsize,&flag);CHKERRQ(ierr); 577 if (flag) { 578 for (i=0; i<lsize; i++) { 579 if (nodes[i] == rank) { flag = PETSC_FALSE; break; } 580 } 581 } 582 if (!flag) { 583 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 584 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,NULL);CHKERRQ(ierr); 585 if (flg1) { 586 ierr = PetscAttachDebugger();CHKERRQ(ierr); 587 } else { 588 ierr = PetscStopForDebugger();CHKERRQ(ierr); 589 } 590 ierr = MPI_Comm_create_errhandler(Petsc_MPI_AbortOnError,&err_handler);CHKERRQ(ierr); 591 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 592 } 593 ierr = PetscFree(nodes);CHKERRQ(ierr); 594 } 595 596 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_emacs",emacsmachinename,sizeof(emacsmachinename),&flg1);CHKERRQ(ierr); 597 if (flg1 && !rank) {ierr = PetscPushErrorHandler(PetscEmacsClientErrorHandler,emacsmachinename);CHKERRQ(ierr);} 598 599 /* 600 Setup profiling and logging 601 */ 602 #if defined(PETSC_USE_INFO) 603 { 604 ierr = PetscInfoSetFromOptions(NULL);CHKERRQ(ierr); 605 } 606 #endif 607 ierr = PetscDetermineInitialFPTrap(); 608 flg1 = PETSC_FALSE; 609 ierr = PetscOptionsGetBool(NULL,NULL,"-fp_trap",&flg1,&flag);CHKERRQ(ierr); 610 if (flag) {ierr = PetscSetFPTrap((PetscFPTrap)flg1);CHKERRQ(ierr);} 611 ierr = PetscOptionsGetInt(NULL,NULL,"-check_pointer_intensity",&intensity,&flag);CHKERRQ(ierr); 612 if (flag) {ierr = PetscCheckPointerSetIntensity(intensity);CHKERRQ(ierr);} 613 #if defined(PETSC_USE_LOG) 614 mname[0] = 0; 615 ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,sizeof(mname),&flg1);CHKERRQ(ierr); 616 if (flg1) { 617 if (mname[0]) { 618 ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr); 619 } else { 620 ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr); 621 } 622 } 623 624 ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr); 625 626 #if defined(PETSC_HAVE_MPE) 627 flg1 = PETSC_FALSE; 628 ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr); 629 if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);} 630 #endif 631 flg1 = PETSC_FALSE; 632 flg3 = PETSC_FALSE; 633 ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr); 634 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 635 if (flg1) { ierr = PetscLogAllBegin();CHKERRQ(ierr); } 636 else if (flg3) { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 637 638 ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,sizeof(mname),&flg1);CHKERRQ(ierr); 639 if (flg1) { 640 char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN]; 641 FILE *file; 642 if (mname[0]) { 643 PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank); 644 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 645 file = fopen(fname,"w"); 646 if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname); 647 } else file = PETSC_STDOUT; 648 ierr = PetscLogTraceBegin(file);CHKERRQ(ierr); 649 } 650 651 ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr); 652 if (flg4) { 653 if (format == PETSC_VIEWER_ASCII_XML) { 654 ierr = PetscLogNestedBegin();CHKERRQ(ierr); 655 } else { 656 ierr = PetscLogDefaultBegin();CHKERRQ(ierr); 657 } 658 } 659 if (flg4 && format == PETSC_VIEWER_ASCII_XML) { 660 PetscReal threshold = PetscRealConstant(0.01); 661 ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr); 662 if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);} 663 } 664 #endif 665 666 ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr); 667 668 #if defined(PETSC_HAVE_CUDA) 669 /* 670 If collecting logging information, by default, wait for GPU to complete its operations 671 before returning to the CPU in order to get accurate timings of each event 672 */ 673 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&PetscCUDASynchronize);CHKERRQ(ierr); 674 if (!PetscCUDASynchronize) { 675 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&PetscCUDASynchronize);CHKERRQ(ierr); 676 } 677 678 ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr); 679 ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCUDA,&initCUDA,NULL);CHKERRQ(ierr); 680 ierr = PetscOptionsBool("-cuda_synchronize","Wait for the GPU to complete operations before returning to the CPU (on by default with -log_summary or -log_view)",NULL,PetscCUDASynchronize,&PetscCUDASynchronize,NULL);CHKERRQ(ierr); 681 ierr = PetscOptionsBool("-use_gpu_aware_mpi","Use GPU-aware MPI",NULL,use_gpu_aware_mpi,&use_gpu_aware_mpi,NULL);CHKERRQ(ierr); 682 ierr = PetscOptionsEnd();CHKERRQ(ierr); 683 if (initCUDA) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);} 684 if (use_gpu_aware_mpi) { 685 cerr = cudaGetDeviceCount(&devCount);{if (cerr != cudaErrorNoDevice) CHKERRCUDA(cerr);} /* Catch other errors */ 686 if (cerr == cudaErrorNoDevice) devCount = 0; /* CUDA does not say what devCount is under this error */ 687 } 688 if (devCount > 0 && use_gpu_aware_mpi) { /* Only do the MPI GPU awareness check when there are GPU(s) */ 689 #if defined(PETSC_HAVE_OMPI_MAJOR_VERSION) && defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT 690 /* Trust OpenMPI's compile time cuda query interface */ 691 mpi_gpu_awareness = PETSC_TRUE; 692 #else 693 /* For other MPI implementations without cuda query API, we do a GPU MPI call to see if it segfaults. 694 Note that Spectrum MPI sets OMPI_MAJOR_VERSION and is CUDA-aware, but does not have MPIX_CUDA_AWARE_SUPPORT. 695 */ 696 mpi_gpu_awareness = PetscCheckMpiGpuAwareness(); 697 #endif 698 if (!mpi_gpu_awareness) { 699 (*PetscErrorPrintf)("PETSc is configured with GPU support, but your MPI is not GPU-aware. For better performance, please use a GPU-aware MPI.\n"); 700 (*PetscErrorPrintf)("For IBM Spectrum MPI on OLCF Summit, you may need jsrun --smpiargs=-gpu.\n"); 701 (*PetscErrorPrintf)("For OpenMPI, you need to configure it --with-cuda (https://www.open-mpi.org/faq/?category=buildcuda)\n"); 702 (*PetscErrorPrintf)("For MVAPICH2-GDR, you need to set MV2_USE_CUDA=1 (http://mvapich.cse.ohio-state.edu/userguide/gdr/)\n"); 703 (*PetscErrorPrintf)("For Cray-MPICH, you need to set MPICH_RDMA_ENABLED_CUDA=1 (https://www.olcf.ornl.gov/tutorials/gpudirect-mpich-enabled-cuda/)\n"); 704 (*PetscErrorPrintf)("If you do not care, use option -use_gpu_aware_mpi 0, then PETSc will copy data from GPU to CPU for communication.\n"); 705 PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_LIB); 706 } 707 } 708 #endif 709 710 /* 711 Print basic help message 712 */ 713 if (hasHelp) { 714 ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr); 715 ierr = (*PetscHelpPrintf)(comm," -version: prints PETSc version\n");CHKERRQ(ierr); 716 ierr = (*PetscHelpPrintf)(comm," -help intro: prints example description and PETSc version, and exits\n");CHKERRQ(ierr); 717 ierr = (*PetscHelpPrintf)(comm," -help: prints example description, PETSc version, and available options for used routines\n");CHKERRQ(ierr); 718 ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr); 719 ierr = (*PetscHelpPrintf)(comm," only when run in the debugger\n");CHKERRQ(ierr); 720 ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 721 ierr = (*PetscHelpPrintf)(comm," start the debugger in new xterm\n");CHKERRQ(ierr); 722 ierr = (*PetscHelpPrintf)(comm," unless noxterm is given\n");CHKERRQ(ierr); 723 ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 724 ierr = (*PetscHelpPrintf)(comm," start all processes in the debugger\n");CHKERRQ(ierr); 725 ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr); 726 ierr = (*PetscHelpPrintf)(comm," emacs jumps to error file\n");CHKERRQ(ierr); 727 ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr); 728 ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr); 729 ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr); 730 ierr = (*PetscHelpPrintf)(comm," waits the delay for you to attach\n");CHKERRQ(ierr); 731 ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr); 732 ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr); 733 ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr); 734 ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr); 735 ierr = (*PetscHelpPrintf)(comm," note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr); 736 ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr); 737 ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecated, use -malloc_debug)\n");CHKERRQ(ierr); 738 ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecated, use -malloc_debug no)\n");CHKERRQ(ierr); 739 ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr); 740 ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr); 741 ierr = (*PetscHelpPrintf)(comm," -malloc_debug <true or false>: enables or disables extended checking for memory corruption\n");CHKERRQ(ierr); 742 ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr); 743 ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr); 744 ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr); 745 ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr); 746 ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr); 747 ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr); 748 ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr); 749 #if defined(PETSC_USE_LOG) 750 ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr); 751 ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr); 752 ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr); 753 ierr = (*PetscHelpPrintf)(comm," -log_exclude <list,of,classnames>: exclude given classes from logging\n");CHKERRQ(ierr); 754 #if defined(PETSC_HAVE_MPE) 755 ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr); 756 #endif 757 #endif 758 #if defined(PETSC_USE_INFO) 759 ierr = (*PetscHelpPrintf)(comm," -info [filename][:[~]<list,of,classnames>[:[~]self]]: print verbose information\n");CHKERRQ(ierr); 760 #endif 761 ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr); 762 ierr = (*PetscHelpPrintf)(comm," -options_monitor: monitor options to standard output, including that set previously e.g. in option files\n");CHKERRQ(ierr); 763 ierr = (*PetscHelpPrintf)(comm," -options_monitor_cancel: cancels all hardwired option monitors\n");CHKERRQ(ierr); 764 ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr); 765 } 766 767 #if defined(PETSC_HAVE_POPEN) 768 { 769 char machine[128]; 770 ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,sizeof(machine),&flg1);CHKERRQ(ierr); 771 if (flg1) { 772 ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr); 773 } 774 } 775 #endif 776 777 ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr); 778 if (flg1) { 779 ierr = PetscSleep(si);CHKERRQ(ierr); 780 } 781 782 #if defined(PETSC_HAVE_VIENNACL) 783 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 784 if (!flg3) { 785 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr); 786 } 787 ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr); 788 PetscViennaCLSynchronize = flg3; 789 ierr = PetscViennaCLInit();CHKERRQ(ierr); 790 #endif 791 792 /* 793 Creates the logging data structures; this is enabled even if logging is not turned on 794 This is the last thing we do before returning to the user code to prevent having the 795 logging numbers contaminated by any startup time associated with MPI and the GPUs 796 */ 797 #if defined(PETSC_USE_LOG) 798 ierr = PetscLogInitialize();CHKERRQ(ierr); 799 #endif 800 801 PetscFunctionReturn(0); 802 } 803