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) = 0; 316 PetscErrorCode (*PetscExternalHelpFunction)(MPI_Comm) = 0; 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 } 420 421 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_coalesce",&flg1,&flg2);CHKERRQ(ierr); 422 if (flg2) {ierr = PetscMallocSetCoalesce(flg1);CHKERRQ(ierr);} 423 flg1 = PETSC_FALSE; 424 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_hbw",&flg1,NULL);CHKERRQ(ierr); 425 /* ignore this option if malloc is already set */ 426 if (flg1 && !petscsetmallocvisited) {ierr = PetscSetUseHBWMalloc_Private();CHKERRQ(ierr);} 427 428 flg1 = PETSC_FALSE; 429 ierr = PetscOptionsGetBool(NULL,NULL,"-malloc_info",&flg1,NULL);CHKERRQ(ierr); 430 if (!flg1) { 431 flg1 = PETSC_FALSE; 432 ierr = PetscOptionsGetBool(NULL,NULL,"-memory_view",&flg1,NULL);CHKERRQ(ierr); 433 } 434 if (flg1) { 435 ierr = PetscMemorySetGetMaximumUsage();CHKERRQ(ierr); 436 } 437 #endif 438 439 #if defined(PETSC_USE_LOG) 440 ierr = PetscOptionsHasName(NULL,NULL,"-objects_dump",&PetscObjectsLog);CHKERRQ(ierr); 441 #endif 442 443 /* 444 Set the display variable for graphics 445 */ 446 ierr = PetscSetDisplay();CHKERRQ(ierr); 447 448 /* 449 Print the PETSc version information 450 */ 451 ierr = PetscOptionsHasName(NULL,NULL,"-v",&flg1);CHKERRQ(ierr); 452 ierr = PetscOptionsHasName(NULL,NULL,"-version",&flg2);CHKERRQ(ierr); 453 ierr = PetscOptionsHasHelp(NULL,&flg3);CHKERRQ(ierr); 454 if (flg1 || flg2 || flg3) { 455 456 /* 457 Print "higher-level" package version message 458 */ 459 if (PetscExternalVersionFunction) { 460 ierr = (*PetscExternalVersionFunction)(comm);CHKERRQ(ierr); 461 } 462 463 ierr = PetscGetVersion(version,256);CHKERRQ(ierr); 464 ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr); 465 ierr = (*PetscHelpPrintf)(comm,"%s\n",version);CHKERRQ(ierr); 466 ierr = (*PetscHelpPrintf)(comm,"%s",PETSC_AUTHOR_INFO);CHKERRQ(ierr); 467 ierr = (*PetscHelpPrintf)(comm,"See docs/changes/index.html for recent updates.\n");CHKERRQ(ierr); 468 ierr = (*PetscHelpPrintf)(comm,"See docs/faq.html for problems.\n");CHKERRQ(ierr); 469 ierr = (*PetscHelpPrintf)(comm,"See docs/manualpages/index.html for help. \n");CHKERRQ(ierr); 470 ierr = (*PetscHelpPrintf)(comm,"Libraries linked from %s\n",PETSC_LIB_DIR);CHKERRQ(ierr); 471 ierr = (*PetscHelpPrintf)(comm,"--------------------------------------------------------------------------\n");CHKERRQ(ierr); 472 } 473 474 /* 475 Print "higher-level" package help message 476 */ 477 if (flg3) { 478 if (PetscExternalHelpFunction) { 479 ierr = (*PetscExternalHelpFunction)(comm);CHKERRQ(ierr); 480 } 481 } 482 483 ierr = PetscOptionsGetString(NULL,NULL,"-help",helpoptions,sizeof(helpoptions),&flg1);CHKERRQ(ierr); 484 if (flg1) { 485 ierr = PetscStrcmp(helpoptions,"intro",&flg2);CHKERRQ(ierr); 486 if (flg2) { 487 ierr = PetscOptionsDestroyDefault();CHKERRQ(ierr); 488 ierr = PetscFreeMPIResources();CHKERRQ(ierr); 489 ierr = MPI_Finalize();CHKERRQ(ierr); 490 exit(0); 491 } 492 } 493 494 /* 495 Setup the error handling 496 */ 497 flg1 = PETSC_FALSE; 498 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_abort",&flg1,NULL);CHKERRQ(ierr); 499 if (flg1) { 500 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_ARE_FATAL);CHKERRQ(ierr); 501 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr); 502 } 503 flg1 = PETSC_FALSE; 504 ierr = PetscOptionsGetBool(NULL,NULL,"-on_error_mpiabort",&flg1,NULL);CHKERRQ(ierr); 505 if (flg1) { ierr = PetscPushErrorHandler(PetscMPIAbortErrorHandler,0);CHKERRQ(ierr);} 506 flg1 = PETSC_FALSE; 507 ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_on_error",&flg1,NULL);CHKERRQ(ierr); 508 if (flg1) { 509 ierr = MPI_Comm_set_errhandler(comm,MPI_ERRORS_RETURN);CHKERRQ(ierr); 510 } 511 /* experimental */ 512 flg1 = PETSC_FALSE; 513 ierr = PetscOptionsGetBool(NULL,NULL,"-mpi_return_error_string",&flg1,NULL);CHKERRQ(ierr); 514 if (flg1) { 515 MPI_Errhandler eh; 516 517 ierr = MPI_Comm_create_errhandler(PetscMPI_Comm_eh,&eh);CHKERRQ(ierr); 518 ierr = MPI_Comm_set_errhandler(comm,eh);CHKERRQ(ierr); 519 ierr = MPI_Errhandler_free(&eh);CHKERRQ(ierr); 520 } 521 flg1 = PETSC_FALSE; 522 ierr = PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);CHKERRQ(ierr); 523 if (!flg1) {ierr = PetscPushSignalHandler(PetscSignalHandlerDefault,(void*)0);CHKERRQ(ierr);} 524 flg1 = PETSC_FALSE; 525 ierr = PetscOptionsGetBool(NULL,NULL,"-fp_trap",&flg1,&flag);CHKERRQ(ierr); 526 if (flag) {ierr = PetscSetFPTrap((PetscFPTrap)flg1);CHKERRQ(ierr);} 527 ierr = PetscOptionsGetInt(NULL,NULL,"-check_pointer_intensity",&intensity,&flag);CHKERRQ(ierr); 528 if (flag) {ierr = PetscCheckPointerSetIntensity(intensity);CHKERRQ(ierr);} 529 530 /* 531 Setup debugger information 532 */ 533 ierr = PetscSetDefaultDebugger();CHKERRQ(ierr); 534 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_attach_debugger",string,64,&flg1);CHKERRQ(ierr); 535 if (flg1) { 536 MPI_Errhandler err_handler; 537 538 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 539 ierr = MPI_Comm_create_errhandler(Petsc_MPI_DebuggerOnError,&err_handler);CHKERRQ(ierr); 540 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 541 ierr = PetscPushErrorHandler(PetscAttachDebuggerErrorHandler,0);CHKERRQ(ierr); 542 } 543 ierr = PetscOptionsGetString(NULL,NULL,"-debug_terminal",string,64,&flg1);CHKERRQ(ierr); 544 if (flg1) { ierr = PetscSetDebugTerminal(string);CHKERRQ(ierr); } 545 ierr = PetscOptionsGetString(NULL,NULL,"-start_in_debugger",string,64,&flg1);CHKERRQ(ierr); 546 ierr = PetscOptionsGetString(NULL,NULL,"-stop_for_debugger",string,64,&flg2);CHKERRQ(ierr); 547 if (flg1 || flg2) { 548 PetscMPIInt size; 549 PetscInt lsize,*nodes; 550 MPI_Errhandler err_handler; 551 /* 552 we have to make sure that all processors have opened 553 connections to all other processors, otherwise once the 554 debugger has stated it is likely to receive a SIGUSR1 555 and kill the program. 556 */ 557 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 558 if (size > 2) { 559 PetscMPIInt dummy = 0; 560 MPI_Status status; 561 for (i=0; i<size; i++) { 562 if (rank != i) { 563 ierr = MPI_Send(&dummy,1,MPI_INT,i,109,comm);CHKERRQ(ierr); 564 } 565 } 566 for (i=0; i<size; i++) { 567 if (rank != i) { 568 ierr = MPI_Recv(&dummy,1,MPI_INT,i,109,comm,&status);CHKERRQ(ierr); 569 } 570 } 571 } 572 /* check if this processor node should be in debugger */ 573 ierr = PetscMalloc1(size,&nodes);CHKERRQ(ierr); 574 lsize = size; 575 ierr = PetscOptionsGetIntArray(NULL,NULL,"-debugger_nodes",nodes,&lsize,&flag);CHKERRQ(ierr); 576 if (flag) { 577 for (i=0; i<lsize; i++) { 578 if (nodes[i] == rank) { flag = PETSC_FALSE; break; } 579 } 580 } 581 if (!flag) { 582 ierr = PetscSetDebuggerFromString(string);CHKERRQ(ierr); 583 ierr = PetscPushErrorHandler(PetscAbortErrorHandler,0);CHKERRQ(ierr); 584 if (flg1) { 585 ierr = PetscAttachDebugger();CHKERRQ(ierr); 586 } else { 587 ierr = PetscStopForDebugger();CHKERRQ(ierr); 588 } 589 ierr = MPI_Comm_create_errhandler(Petsc_MPI_AbortOnError,&err_handler);CHKERRQ(ierr); 590 ierr = MPI_Comm_set_errhandler(comm,err_handler);CHKERRQ(ierr); 591 } 592 ierr = PetscFree(nodes);CHKERRQ(ierr); 593 } 594 595 ierr = PetscOptionsGetString(NULL,NULL,"-on_error_emacs",emacsmachinename,128,&flg1);CHKERRQ(ierr); 596 if (flg1 && !rank) {ierr = PetscPushErrorHandler(PetscEmacsClientErrorHandler,emacsmachinename);CHKERRQ(ierr);} 597 598 /* 599 Setup profiling and logging 600 */ 601 #if defined(PETSC_USE_INFO) 602 { 603 char logname[PETSC_MAX_PATH_LEN]; logname[0] = 0; 604 ierr = PetscOptionsGetString(NULL,NULL,"-info",logname,250,&flg1);CHKERRQ(ierr); 605 if (flg1 && logname[0]) { 606 ierr = PetscInfoAllow(PETSC_TRUE,logname);CHKERRQ(ierr); 607 } else if (flg1) { 608 ierr = PetscInfoAllow(PETSC_TRUE,NULL);CHKERRQ(ierr); 609 } 610 } 611 #endif 612 #if defined(PETSC_USE_LOG) 613 mname[0] = 0; 614 ierr = PetscOptionsGetString(NULL,NULL,"-history",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 615 if (flg1) { 616 if (mname[0]) { 617 ierr = PetscOpenHistoryFile(mname,&petsc_history);CHKERRQ(ierr); 618 } else { 619 ierr = PetscOpenHistoryFile(NULL,&petsc_history);CHKERRQ(ierr); 620 } 621 } 622 623 ierr = PetscOptionsGetBool(NULL,NULL,"-log_sync",&PetscLogSyncOn,NULL);CHKERRQ(ierr); 624 625 #if defined(PETSC_HAVE_MPE) 626 flg1 = PETSC_FALSE; 627 ierr = PetscOptionsHasName(NULL,NULL,"-log_mpe",&flg1);CHKERRQ(ierr); 628 if (flg1) {ierr = PetscLogMPEBegin();CHKERRQ(ierr);} 629 #endif 630 flg1 = PETSC_FALSE; 631 flg3 = PETSC_FALSE; 632 ierr = PetscOptionsGetBool(NULL,NULL,"-log_all",&flg1,NULL);CHKERRQ(ierr); 633 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 634 if (flg1) { ierr = PetscLogAllBegin();CHKERRQ(ierr); } 635 else if (flg3) { ierr = PetscLogDefaultBegin();CHKERRQ(ierr);} 636 637 ierr = PetscOptionsGetString(NULL,NULL,"-log_trace",mname,250,&flg1);CHKERRQ(ierr); 638 if (flg1) { 639 char name[PETSC_MAX_PATH_LEN],fname[PETSC_MAX_PATH_LEN]; 640 FILE *file; 641 if (mname[0]) { 642 PetscSNPrintf(name,PETSC_MAX_PATH_LEN,"%s.%d",mname,rank); 643 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr); 644 file = fopen(fname,"w"); 645 if (!file) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open trace file: %s",fname); 646 } else file = PETSC_STDOUT; 647 ierr = PetscLogTraceBegin(file);CHKERRQ(ierr); 648 } 649 650 ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-log_view",NULL,&format,&flg4);CHKERRQ(ierr); 651 if (flg4) { 652 if (format == PETSC_VIEWER_ASCII_XML) { 653 ierr = PetscLogNestedBegin();CHKERRQ(ierr); 654 } else { 655 ierr = PetscLogDefaultBegin();CHKERRQ(ierr); 656 } 657 } 658 if (flg4 && format == PETSC_VIEWER_ASCII_XML) { 659 PetscReal threshold = PetscRealConstant(0.01); 660 ierr = PetscOptionsGetReal(NULL,NULL,"-log_threshold",&threshold,&flg1);CHKERRQ(ierr); 661 if (flg1) {ierr = PetscLogSetThreshold((PetscLogDouble)threshold,NULL);CHKERRQ(ierr);} 662 } 663 #endif 664 665 ierr = PetscOptionsGetBool(NULL,NULL,"-saws_options",&PetscOptionsPublish,NULL);CHKERRQ(ierr); 666 667 #if defined(PETSC_HAVE_CUDA) 668 ierr = PetscOptionsBegin(comm,NULL,"CUDA initialize","Sys");CHKERRQ(ierr); 669 ierr = PetscOptionsBool("-cuda_initialize","Initialize the CUDA devices and cuBLAS during PetscInitialize()",NULL,initCuda,&initCuda,NULL);CHKERRQ(ierr); 670 ierr = PetscOptionsEnd();CHKERRQ(ierr); 671 if (initCuda) {ierr = PetscCUDAInitialize(PETSC_COMM_WORLD);CHKERRQ(ierr);} 672 #endif 673 674 /* 675 Print basic help message 676 */ 677 ierr = PetscOptionsHasHelp(NULL,&flg1);CHKERRQ(ierr); 678 if (flg1) { 679 ierr = (*PetscHelpPrintf)(comm,"Options for all PETSc programs:\n");CHKERRQ(ierr); 680 ierr = (*PetscHelpPrintf)(comm," -help: prints help method for each option\n");CHKERRQ(ierr); 681 ierr = (*PetscHelpPrintf)(comm," -on_error_abort: cause an abort when an error is detected. Useful \n ");CHKERRQ(ierr); 682 ierr = (*PetscHelpPrintf)(comm," only when run in the debugger\n");CHKERRQ(ierr); 683 ierr = (*PetscHelpPrintf)(comm," -on_error_attach_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 684 ierr = (*PetscHelpPrintf)(comm," start the debugger in new xterm\n");CHKERRQ(ierr); 685 ierr = (*PetscHelpPrintf)(comm," unless noxterm is given\n");CHKERRQ(ierr); 686 ierr = (*PetscHelpPrintf)(comm," -start_in_debugger [gdb,dbx,xxgdb,ups,noxterm]\n");CHKERRQ(ierr); 687 ierr = (*PetscHelpPrintf)(comm," start all processes in the debugger\n");CHKERRQ(ierr); 688 ierr = (*PetscHelpPrintf)(comm," -on_error_emacs <machinename>\n");CHKERRQ(ierr); 689 ierr = (*PetscHelpPrintf)(comm," emacs jumps to error file\n");CHKERRQ(ierr); 690 ierr = (*PetscHelpPrintf)(comm," -debugger_nodes [n1,n2,..] Nodes to start in debugger\n");CHKERRQ(ierr); 691 ierr = (*PetscHelpPrintf)(comm," -debugger_pause [m] : delay (in seconds) to attach debugger\n");CHKERRQ(ierr); 692 ierr = (*PetscHelpPrintf)(comm," -stop_for_debugger : prints message on how to attach debugger manually\n");CHKERRQ(ierr); 693 ierr = (*PetscHelpPrintf)(comm," waits the delay for you to attach\n");CHKERRQ(ierr); 694 ierr = (*PetscHelpPrintf)(comm," -display display: Location where X window graphics and debuggers are displayed\n");CHKERRQ(ierr); 695 ierr = (*PetscHelpPrintf)(comm," -no_signal_handler: do not trap error signals\n");CHKERRQ(ierr); 696 ierr = (*PetscHelpPrintf)(comm," -mpi_return_on_error: MPI returns error code, rather than abort on internal error\n");CHKERRQ(ierr); 697 ierr = (*PetscHelpPrintf)(comm," -fp_trap: stop on floating point exceptions\n");CHKERRQ(ierr); 698 ierr = (*PetscHelpPrintf)(comm," note on IBM RS6000 this slows run greatly\n");CHKERRQ(ierr); 699 ierr = (*PetscHelpPrintf)(comm," -malloc_dump <optional filename>: dump list of unfreed memory at conclusion\n");CHKERRQ(ierr); 700 ierr = (*PetscHelpPrintf)(comm," -malloc: use PETSc error checking malloc (deprecated, use -malloc_debug)\n");CHKERRQ(ierr); 701 ierr = (*PetscHelpPrintf)(comm," -malloc no: don't use PETSc error checking malloc (deprecated, use -malloc_debug no)\n");CHKERRQ(ierr); 702 ierr = (*PetscHelpPrintf)(comm," -malloc_info: prints total memory usage\n");CHKERRQ(ierr); 703 ierr = (*PetscHelpPrintf)(comm," -malloc_view <optional filename>: keeps log of all memory allocations, displays in PetscFinalize()\n");CHKERRQ(ierr); 704 ierr = (*PetscHelpPrintf)(comm," -malloc_debug <true or false>: enables or disables extended checking for memory corruption\n");CHKERRQ(ierr); 705 ierr = (*PetscHelpPrintf)(comm," -options_view: dump list of options inputted\n");CHKERRQ(ierr); 706 ierr = (*PetscHelpPrintf)(comm," -options_left: dump list of unused options\n");CHKERRQ(ierr); 707 ierr = (*PetscHelpPrintf)(comm," -options_left no: don't dump list of unused options\n");CHKERRQ(ierr); 708 ierr = (*PetscHelpPrintf)(comm," -tmp tmpdir: alternative /tmp directory\n");CHKERRQ(ierr); 709 ierr = (*PetscHelpPrintf)(comm," -shared_tmp: tmp directory is shared by all processors\n");CHKERRQ(ierr); 710 ierr = (*PetscHelpPrintf)(comm," -not_shared_tmp: each processor has separate tmp directory\n");CHKERRQ(ierr); 711 ierr = (*PetscHelpPrintf)(comm," -memory_view: print memory usage at end of run\n");CHKERRQ(ierr); 712 #if defined(PETSC_USE_LOG) 713 ierr = (*PetscHelpPrintf)(comm," -get_total_flops: total flops over all processors\n");CHKERRQ(ierr); 714 ierr = (*PetscHelpPrintf)(comm," -log_view [:filename:[format]]: logging objects and events\n");CHKERRQ(ierr); 715 ierr = (*PetscHelpPrintf)(comm," -log_trace [filename]: prints trace of all PETSc calls\n");CHKERRQ(ierr); 716 #if defined(PETSC_HAVE_MPE) 717 ierr = (*PetscHelpPrintf)(comm," -log_mpe: Also create logfile viewable through Jumpshot\n");CHKERRQ(ierr); 718 #endif 719 ierr = (*PetscHelpPrintf)(comm," -info <optional filename>: print informative messages about the calculations\n");CHKERRQ(ierr); 720 #endif 721 ierr = (*PetscHelpPrintf)(comm," -v: prints PETSc version number and release date\n");CHKERRQ(ierr); 722 ierr = (*PetscHelpPrintf)(comm," -options_file <file>: reads options from file\n");CHKERRQ(ierr); 723 ierr = (*PetscHelpPrintf)(comm," -petsc_sleep n: sleeps n seconds before running program\n");CHKERRQ(ierr); 724 ierr = (*PetscHelpPrintf)(comm,"-----------------------------------------------\n");CHKERRQ(ierr); 725 } 726 727 #if defined(PETSC_HAVE_POPEN) 728 { 729 char machine[128]; 730 ierr = PetscOptionsGetString(NULL,NULL,"-popen_machine",machine,128,&flg1);CHKERRQ(ierr); 731 if (flg1) { 732 ierr = PetscPOpenSetMachine(machine);CHKERRQ(ierr); 733 } 734 } 735 #endif 736 737 ierr = PetscOptionsGetReal(NULL,NULL,"-petsc_sleep",&si,&flg1);CHKERRQ(ierr); 738 if (flg1) { 739 ierr = PetscSleep(si);CHKERRQ(ierr); 740 } 741 742 ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",mname,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr); 743 if (flg1) { 744 ierr = PetscStrstr(mname,"null",&f);CHKERRQ(ierr); 745 if (f) { 746 ierr = PetscInfoDeactivateClass(0);CHKERRQ(ierr); 747 } 748 } 749 750 #if defined(PETSC_HAVE_VIENNACL) 751 ierr = PetscOptionsHasName(NULL,NULL,"-log_summary",&flg3);CHKERRQ(ierr); 752 if (!flg3) { 753 ierr = PetscOptionsHasName(NULL,NULL,"-log_view",&flg3);CHKERRQ(ierr); 754 } 755 ierr = PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg3,NULL);CHKERRQ(ierr); 756 PetscViennaCLSynchronize = flg3; 757 ierr = PetscViennaCLInit();CHKERRQ(ierr); 758 #endif 759 760 /* 761 Creates the logging data structures; this is enabled even if logging is not turned on 762 This is the last thing we do before returning to the user code to prevent having the 763 logging numbers contaminated by any startup time associated with MPI and the GPUs 764 */ 765 #if defined(PETSC_USE_LOG) 766 ierr = PetscLogInitialize();CHKERRQ(ierr); 767 #endif 768 769 PetscFunctionReturn(0); 770 } 771