Actual source code: pinit.c
1: #define PETSC_DESIRE_FEATURE_TEST_MACROS
2: /*
3: This file defines the initialization of PETSc, including PetscInitialize()
4: */
5: #include <petsc/private/petscimpl.h>
6: #include <petscviewer.h>
8: #if !defined(PETSC_HAVE_WINDOWS_COMPILERS)
9: #include <petsc/private/valgrind/valgrind.h>
10: #endif
12: #if defined(PETSC_HAVE_FORTRAN)
13: #include <petsc/private/fortranimpl.h>
14: #endif
16: #if defined(PETSC_USE_GCOV)
17: EXTERN_C_BEGIN
18: void __gcov_flush(void);
19: EXTERN_C_END
20: #endif
22: #if defined(PETSC_SERIALIZE_FUNCTIONS)
23: PETSC_INTERN PetscFPT PetscFPTData;
24: PetscFPT PetscFPTData = 0;
25: #endif
27: #if PetscDefined(HAVE_SAWS)
28: #include <petscviewersaws.h>
29: #endif
31: /* -----------------------------------------------------------------------------------------*/
33: PETSC_INTERN FILE *petsc_history;
35: PETSC_INTERN PetscErrorCode PetscInitialize_DynamicLibraries(void);
36: PETSC_INTERN PetscErrorCode PetscFinalize_DynamicLibraries(void);
37: PETSC_INTERN PetscErrorCode PetscFunctionListPrintAll(void);
38: PETSC_INTERN PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm,int);
39: PETSC_INTERN PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm,int);
40: PETSC_INTERN PetscErrorCode PetscCloseHistoryFile(FILE**);
42: /* user may set these BEFORE calling PetscInitialize() */
43: MPI_Comm PETSC_COMM_WORLD = MPI_COMM_NULL;
44: #if PetscDefined(HAVE_MPI_INIT_THREAD)
45: PetscMPIInt PETSC_MPI_THREAD_REQUIRED = MPI_THREAD_FUNNELED;
46: #else
47: PetscMPIInt PETSC_MPI_THREAD_REQUIRED = 0;
48: #endif
50: PetscMPIInt Petsc_Counter_keyval = MPI_KEYVAL_INVALID;
51: PetscMPIInt Petsc_InnerComm_keyval = MPI_KEYVAL_INVALID;
52: PetscMPIInt Petsc_OuterComm_keyval = MPI_KEYVAL_INVALID;
53: PetscMPIInt Petsc_ShmComm_keyval = MPI_KEYVAL_INVALID;
55: /*
56: Declare and set all the string names of the PETSc enums
57: */
58: const char *const PetscBools[] = {"FALSE","TRUE","PetscBool","PETSC_",NULL};
59: const char *const PetscCopyModes[] = {"COPY_VALUES","OWN_POINTER","USE_POINTER","PetscCopyMode","PETSC_",NULL};
61: PetscBool PetscPreLoadingUsed = PETSC_FALSE;
62: PetscBool PetscPreLoadingOn = PETSC_FALSE;
64: PetscInt PetscHotRegionDepth;
66: PetscBool PETSC_RUNNING_ON_VALGRIND = PETSC_FALSE;
68: #if defined(PETSC_HAVE_THREADSAFETY)
69: PetscSpinlock PetscViewerASCIISpinLockOpen;
70: PetscSpinlock PetscViewerASCIISpinLockStdout;
71: PetscSpinlock PetscViewerASCIISpinLockStderr;
72: PetscSpinlock PetscCommSpinLock;
73: #endif
75: /*
76: PetscInitializeNoPointers - Calls PetscInitialize() from C/C++ without the pointers to argc and args
78: Collective
80: Level: advanced
82: Notes:
83: this is called only by the PETSc Julia interface. Even though it might start MPI it sets the flag to
84: indicate that it did NOT start MPI so that the PetscFinalize() does not end MPI, thus allowing PetscInitialize() to
85: be called multiple times from Julia without the problem of trying to initialize MPI more than once.
87: Developer Note: Turns off PETSc signal handling to allow Julia to manage signals
89: .seealso: PetscInitialize(), PetscInitializeFortran(), PetscInitializeNoArguments()
90: */
91: PetscErrorCode PetscInitializeNoPointers(int argc,char **args,const char *filename,const char *help)
92: {
93: int myargc = argc;
94: char **myargs = args;
96: PetscInitialize(&myargc,&myargs,filename,help);
97: PetscPopSignalHandler();
98: PetscBeganMPI = PETSC_FALSE;
99: return 0;
100: }
102: /*
103: Used by Julia interface to get communicator
104: */
105: PetscErrorCode PetscGetPETSC_COMM_SELF(MPI_Comm *comm)
106: {
108: *comm = PETSC_COMM_SELF;
109: return 0;
110: }
112: /*@C
113: PetscInitializeNoArguments - Calls PetscInitialize() from C/C++ without
114: the command line arguments.
116: Collective
118: Level: advanced
120: .seealso: PetscInitialize(), PetscInitializeFortran()
121: @*/
122: PetscErrorCode PetscInitializeNoArguments(void)
123: {
124: int argc = 0;
125: char **args = NULL;
127: PetscInitialize(&argc,&args,NULL,NULL);
128: return 0;
129: }
131: /*@
132: PetscInitialized - Determine whether PETSc is initialized.
134: Level: beginner
136: .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
137: @*/
138: PetscErrorCode PetscInitialized(PetscBool *isInitialized)
139: {
141: *isInitialized = PetscInitializeCalled;
142: return 0;
143: }
145: /*@
146: PetscFinalized - Determine whether PetscFinalize() has been called yet
148: Level: developer
150: .seealso: PetscInitialize(), PetscInitializeNoArguments(), PetscInitializeFortran()
151: @*/
152: PetscErrorCode PetscFinalized(PetscBool *isFinalized)
153: {
155: *isFinalized = PetscFinalizeCalled;
156: return 0;
157: }
159: PETSC_INTERN PetscErrorCode PetscOptionsCheckInitial_Private(const char []);
161: /*
162: This function is the MPI reduction operation used to compute the sum of the
163: first half of the datatype and the max of the second half.
164: */
165: MPI_Op MPIU_MAXSUM_OP = 0;
167: PETSC_INTERN void MPIAPI MPIU_MaxSum_Local(void *in,void *out,int *cnt,MPI_Datatype *datatype)
168: {
169: PetscInt *xin = (PetscInt*)in,*xout = (PetscInt*)out,i,count = *cnt;
171: if (*datatype != MPIU_2INT) {
172: (*PetscErrorPrintf)("Can only handle MPIU_2INT data types");
173: PETSCABORT(MPI_COMM_SELF,PETSC_ERR_ARG_WRONG);
174: }
176: for (i=0; i<count; i++) {
177: xout[2*i] = PetscMax(xout[2*i],xin[2*i]);
178: xout[2*i+1] += xin[2*i+1];
179: }
180: return;
181: }
183: /*
184: Returns the max of the first entry owned by this processor and the
185: sum of the second entry.
187: The reason sizes[2*i] contains lengths sizes[2*i+1] contains flag of 1 if length is nonzero
188: is so that the MPIU_MAXSUM_OP() can set TWO values, if we passed in only sizes[i] with lengths
189: there would be no place to store the both needed results.
190: */
191: PetscErrorCode PetscMaxSum(MPI_Comm comm,const PetscInt sizes[],PetscInt *max,PetscInt *sum)
192: {
193: #if defined(PETSC_HAVE_MPI_REDUCE_SCATTER_BLOCK)
194: {
195: struct {PetscInt max,sum;} work;
196: MPI_Reduce_scatter_block((void*)sizes,&work,1,MPIU_2INT,MPIU_MAXSUM_OP,comm);
197: *max = work.max;
198: *sum = work.sum;
199: }
200: #else
201: {
202: PetscMPIInt size,rank;
203: struct {PetscInt max,sum;} *work;
204: MPI_Comm_size(comm,&size);
205: MPI_Comm_rank(comm,&rank);
206: PetscMalloc1(size,&work);
207: MPIU_Allreduce((void*)sizes,work,size,MPIU_2INT,MPIU_MAXSUM_OP,comm);
208: *max = work[rank].max;
209: *sum = work[rank].sum;
210: PetscFree(work);
211: }
212: #endif
213: return 0;
214: }
216: /* ----------------------------------------------------------------------------*/
218: #if defined(PETSC_USE_REAL___FLOAT128) || defined(PETSC_USE_REAL___FP16)
219: MPI_Op MPIU_SUM = 0;
221: PETSC_EXTERN void MPIAPI PetscSum_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
222: {
223: PetscInt i,count = *cnt;
225: if (*datatype == MPIU_REAL) {
226: PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
227: for (i=0; i<count; i++) xout[i] += xin[i];
228: }
229: #if defined(PETSC_HAVE_COMPLEX)
230: else if (*datatype == MPIU_COMPLEX) {
231: PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
232: for (i=0; i<count; i++) xout[i] += xin[i];
233: }
234: #endif
235: else {
236: (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
237: PETSCABORT(MPI_COMM_SELF,PETSC_ERR_ARG_WRONG);
238: }
239: return;
240: }
241: #endif
243: #if defined(PETSC_USE_REAL___FLOAT128) || defined(PETSC_USE_REAL___FP16)
244: MPI_Op MPIU_MAX = 0;
245: MPI_Op MPIU_MIN = 0;
247: PETSC_EXTERN void MPIAPI PetscMax_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
248: {
249: PetscInt i,count = *cnt;
251: if (*datatype == MPIU_REAL) {
252: PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
253: for (i=0; i<count; i++) xout[i] = PetscMax(xout[i],xin[i]);
254: }
255: #if defined(PETSC_HAVE_COMPLEX)
256: else if (*datatype == MPIU_COMPLEX) {
257: PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
258: for (i=0; i<count; i++) {
259: xout[i] = PetscRealPartComplex(xout[i])<PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
260: }
261: }
262: #endif
263: else {
264: (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_COMPLEX data types");
265: PETSCABORT(MPI_COMM_SELF,PETSC_ERR_ARG_WRONG);
266: }
267: return;
268: }
270: PETSC_EXTERN void MPIAPI PetscMin_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
271: {
272: PetscInt i,count = *cnt;
274: if (*datatype == MPIU_REAL) {
275: PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
276: for (i=0; i<count; i++) xout[i] = PetscMin(xout[i],xin[i]);
277: }
278: #if defined(PETSC_HAVE_COMPLEX)
279: else if (*datatype == MPIU_COMPLEX) {
280: PetscComplex *xin = (PetscComplex*)in,*xout = (PetscComplex*)out;
281: for (i=0; i<count; i++) {
282: xout[i] = PetscRealPartComplex(xout[i])>PetscRealPartComplex(xin[i]) ? xin[i] : xout[i];
283: }
284: }
285: #endif
286: else {
287: (*PetscErrorPrintf)("Can only handle MPIU_REAL or MPIU_SCALAR data (i.e. double or complex) types");
288: PETSCABORT(MPI_COMM_SELF,PETSC_ERR_ARG_WRONG);
289: }
290: return;
291: }
292: #endif
294: /*
295: Private routine to delete internal tag/name counter storage when a communicator is freed.
297: This is called by MPI, not by users. This is called by MPI_Comm_free() when the communicator that has this data as an attribute is freed.
299: Note: this is declared extern "C" because it is passed to MPI_Comm_create_keyval()
301: */
302: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_Counter_Attr_Delete_Fn(MPI_Comm comm,PetscMPIInt keyval,void *count_val,void *extra_state)
303: {
304: PetscCommCounter *counter=(PetscCommCounter*)count_val;
305: struct PetscCommStash *comms = counter->comms, *pcomm;
307: PetscInfo(NULL,"Deleting counter data in an MPI_Comm %ld\n",(long)comm);
308: PetscFree(counter->iflags);
309: while (comms) {
310: MPI_Comm_free(&comms->comm);
311: pcomm = comms;
312: comms = comms->next;
313: PetscFree(pcomm);
314: }
315: PetscFree(counter);
316: return MPI_SUCCESS;
317: }
319: /*
320: This is invoked on the outer comm as a result of either PetscCommDestroy() (via MPI_Comm_delete_attr) or when the user
321: calls MPI_Comm_free().
323: This is the only entry point for breaking the links between inner and outer comms.
325: This is called by MPI, not by users. This is called when MPI_Comm_free() is called on the communicator.
327: Note: this is declared extern "C" because it is passed to MPI_Comm_create_keyval()
329: */
330: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_InnerComm_Attr_Delete_Fn(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
331: {
332: union {MPI_Comm comm; void *ptr;} icomm;
334: if (keyval != Petsc_InnerComm_keyval) SETERRMPI(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Unexpected keyval");
335: icomm.ptr = attr_val;
336: if (PetscDefined(USE_DEBUG)) {
337: /* Error out if the inner/outer comms are not correctly linked through their Outer/InnterComm attributes */
338: PetscMPIInt flg;
339: union {MPI_Comm comm; void *ptr;} ocomm;
340: MPI_Comm_get_attr(icomm.comm,Petsc_OuterComm_keyval,&ocomm,&flg);
341: if (!flg) SETERRMPI(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner comm does not have OuterComm attribute");
342: if (ocomm.comm != comm) SETERRMPI(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Inner comm's OuterComm attribute does not point to outer PETSc comm");
343: }
344: MPI_Comm_delete_attr(icomm.comm,Petsc_OuterComm_keyval);
345: PetscInfo(NULL,"User MPI_Comm %ld is being unlinked from inner PETSc comm %ld\n",(long)comm,(long)icomm.comm);
346: return MPI_SUCCESS;
347: }
349: /*
350: * This is invoked on the inner comm when Petsc_InnerComm_Attr_Delete_Fn calls MPI_Comm_delete_attr(). It should not be reached any other way.
351: */
352: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_OuterComm_Attr_Delete_Fn(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
353: {
354: PetscInfo(NULL,"Removing reference to PETSc communicator embedded in a user MPI_Comm %ld\n",(long)comm);
355: return MPI_SUCCESS;
356: }
358: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_ShmComm_Attr_Delete_Fn(MPI_Comm,PetscMPIInt,void *,void *);
360: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
361: PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype,MPI_Aint*,void*);
362: PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
363: PETSC_EXTERN PetscMPIInt PetscDataRep_write_conv_fn(void*, MPI_Datatype,PetscMPIInt,void*,MPI_Offset,void*);
364: #endif
366: PetscMPIInt PETSC_MPI_ERROR_CLASS=MPI_ERR_LASTCODE,PETSC_MPI_ERROR_CODE;
368: PETSC_INTERN int PetscGlobalArgc;
369: PETSC_INTERN char **PetscGlobalArgs;
370: int PetscGlobalArgc = 0;
371: char **PetscGlobalArgs = NULL;
372: PetscSegBuffer PetscCitationsList;
374: PetscErrorCode PetscCitationsInitialize(void)
375: {
376: PetscSegBufferCreate(1,10000,&PetscCitationsList);
378: PetscCall(PetscCitationsRegister("@TechReport{petsc-user-ref,\n\
379: Author = {Satish Balay and Shrirang Abhyankar and Mark~F. Adams and Steven Benson and Jed Brown\n\
380: and Peter Brune and Kris Buschelman and Emil Constantinescu and Lisandro Dalcin and Alp Dener\n\
381: and Victor Eijkhout and William~D. Gropp and V\'{a}clav Hapla and Tobin Isaac and Pierre Jolivet\n\
382: and Dmitry Karpeev and Dinesh Kaushik and Matthew~G. Knepley and Fande Kong and Scott Kruger\n\
383: and Dave~A. May and Lois Curfman McInnes and Richard Tran Mills and Lawrence Mitchell and Todd Munson\n\
384: and Jose~E. Roman and Karl Rupp and Patrick Sanan and Jason Sarich and Barry~F. Smith\n\
385: and Stefano Zampini and Hong Zhang and Hong Zhang and Junchao Zhang},\n\
386: Title = {{PETSc/TAO} Users Manual},\n\
387: Number = {ANL-21/39 - Revision 3.17},\n\
388: Institution = {Argonne National Laboratory},\n\
389: Year = {2022}\n}\n",NULL));
391: PetscCall(PetscCitationsRegister("@InProceedings{petsc-efficient,\n\
392: Author = {Satish Balay and William D. Gropp and Lois Curfman McInnes and Barry F. Smith},\n\
393: Title = {Efficient Management of Parallelism in Object Oriented Numerical Software Libraries},\n\
394: Booktitle = {Modern Software Tools in Scientific Computing},\n\
395: Editor = {E. Arge and A. M. Bruaset and H. P. Langtangen},\n\
396: Pages = {163--202},\n\
397: Publisher = {Birkh{\\\"{a}}user Press},\n\
398: Year = {1997}\n}\n",NULL));
400: return 0;
401: }
403: static char programname[PETSC_MAX_PATH_LEN] = ""; /* HP includes entire path in name */
405: PetscErrorCode PetscSetProgramName(const char name[])
406: {
407: PetscStrncpy(programname,name,sizeof(programname));
408: return 0;
409: }
411: /*@C
412: PetscGetProgramName - Gets the name of the running program.
414: Not Collective
416: Input Parameter:
417: . len - length of the string name
419: Output Parameter:
420: . name - the name of the running program
422: Level: advanced
424: Notes:
425: The name of the program is copied into the user-provided character
426: array of length len. On some machines the program name includes
427: its entire path, so one should generally set len >= PETSC_MAX_PATH_LEN.
428: @*/
429: PetscErrorCode PetscGetProgramName(char name[],size_t len)
430: {
431: PetscStrncpy(name,programname,len);
432: return 0;
433: }
435: /*@C
436: PetscGetArgs - Allows you to access the raw command line arguments anywhere
437: after PetscInitialize() is called but before PetscFinalize().
439: Not Collective
441: Output Parameters:
442: + argc - count of number of command line arguments
443: - args - the command line arguments
445: Level: intermediate
447: Notes:
448: This is usually used to pass the command line arguments into other libraries
449: that are called internally deep in PETSc or the application.
451: The first argument contains the program name as is normal for C arguments.
453: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArguments()
455: @*/
456: PetscErrorCode PetscGetArgs(int *argc,char ***args)
457: {
459: *argc = PetscGlobalArgc;
460: *args = PetscGlobalArgs;
461: return 0;
462: }
464: /*@C
465: PetscGetArguments - Allows you to access the command line arguments anywhere
466: after PetscInitialize() is called but before PetscFinalize().
468: Not Collective
470: Output Parameters:
471: . args - the command line arguments
473: Level: intermediate
475: Notes:
476: This does NOT start with the program name and IS null terminated (final arg is void)
478: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscFreeArguments()
480: @*/
481: PetscErrorCode PetscGetArguments(char ***args)
482: {
483: PetscInt i,argc = PetscGlobalArgc;
486: if (!argc) {*args = NULL; return 0;}
487: PetscMalloc1(argc,args);
488: for (i=0; i<argc-1; i++) PetscStrallocpy(PetscGlobalArgs[i+1],&(*args)[i]);
489: (*args)[argc-1] = NULL;
490: return 0;
491: }
493: /*@C
494: PetscFreeArguments - Frees the memory obtained with PetscGetArguments()
496: Not Collective
498: Output Parameters:
499: . args - the command line arguments
501: Level: intermediate
503: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscGetArguments()
505: @*/
506: PetscErrorCode PetscFreeArguments(char **args)
507: {
508: if (args) {
509: PetscInt i = 0;
511: while (args[i]) PetscFree(args[i++]);
512: PetscFree(args);
513: }
514: return 0;
515: }
517: #if PetscDefined(HAVE_SAWS)
518: #include <petscconfiginfo.h>
520: PETSC_INTERN PetscErrorCode PetscInitializeSAWs(const char help[])
521: {
522: if (!PetscGlobalRank) {
523: char cert[PETSC_MAX_PATH_LEN],root[PETSC_MAX_PATH_LEN],*intro,programname[64],*appline,*options,version[64];
524: int port;
525: PetscBool flg,rootlocal = PETSC_FALSE,flg2,selectport = PETSC_FALSE;
526: size_t applinelen,introlen;
527: char sawsurl[256];
529: PetscOptionsHasName(NULL,NULL,"-saws_log",&flg);
530: if (flg) {
531: char sawslog[PETSC_MAX_PATH_LEN];
533: PetscOptionsGetString(NULL,NULL,"-saws_log",sawslog,sizeof(sawslog),NULL);
534: if (sawslog[0]) {
535: PetscStackCallSAWs(SAWs_Set_Use_Logfile,(sawslog));
536: } else {
537: PetscStackCallSAWs(SAWs_Set_Use_Logfile,(NULL));
538: }
539: }
540: PetscOptionsGetString(NULL,NULL,"-saws_https",cert,sizeof(cert),&flg);
541: if (flg) {
542: PetscStackCallSAWs(SAWs_Set_Use_HTTPS,(cert));
543: }
544: PetscOptionsGetBool(NULL,NULL,"-saws_port_auto_select",&selectport,NULL);
545: if (selectport) {
546: PetscStackCallSAWs(SAWs_Get_Available_Port,(&port));
547: PetscStackCallSAWs(SAWs_Set_Port,(port));
548: } else {
549: PetscOptionsGetInt(NULL,NULL,"-saws_port",&port,&flg);
550: if (flg) {
551: PetscStackCallSAWs(SAWs_Set_Port,(port));
552: }
553: }
554: PetscOptionsGetString(NULL,NULL,"-saws_root",root,sizeof(root),&flg);
555: if (flg) {
556: PetscStackCallSAWs(SAWs_Set_Document_Root,(root));
557: PetscStrcmp(root,".",&rootlocal);
558: } else {
559: PetscOptionsHasName(NULL,NULL,"-saws_options",&flg);
560: if (flg) {
561: PetscStrreplace(PETSC_COMM_WORLD,"${PETSC_DIR}/share/petsc/saws",root,sizeof(root));
562: PetscStackCallSAWs(SAWs_Set_Document_Root,(root));
563: }
564: }
565: PetscOptionsHasName(NULL,NULL,"-saws_local",&flg2);
566: if (flg2) {
567: char jsdir[PETSC_MAX_PATH_LEN];
569: PetscSNPrintf(jsdir,sizeof(jsdir),"%s/js",root);
570: PetscTestDirectory(jsdir,'r',&flg);
572: PetscStackCallSAWs(SAWs_Push_Local_Header,());
573: }
574: PetscGetProgramName(programname,sizeof(programname));
575: PetscStrlen(help,&applinelen);
576: introlen = 4096 + applinelen;
577: applinelen += 1024;
578: PetscMalloc(applinelen,&appline);
579: PetscMalloc(introlen,&intro);
581: if (rootlocal) {
582: PetscSNPrintf(appline,applinelen,"%s.c.html",programname);
583: PetscTestFile(appline,'r',&rootlocal);
584: }
585: PetscOptionsGetAll(NULL,&options);
586: if (rootlocal && help) {
587: PetscSNPrintf(appline,applinelen,"<center> Running <a href=\"%s.c.html\">%s</a> %s</center><br><center><pre>%s</pre></center><br>\n",programname,programname,options,help);
588: } else if (help) {
589: PetscSNPrintf(appline,applinelen,"<center>Running %s %s</center><br><center><pre>%s</pre></center><br>",programname,options,help);
590: } else {
591: PetscSNPrintf(appline,applinelen,"<center> Running %s %s</center><br>\n",programname,options);
592: }
593: PetscFree(options);
594: PetscGetVersion(version,sizeof(version));
595: PetscCall(PetscSNPrintf(intro,introlen,"<body>\n"
596: "<center><h2> <a href=\"https://petsc.org/\">PETSc</a> Application Web server powered by <a href=\"https://bitbucket.org/saws/saws\">SAWs</a> </h2></center>\n"
597: "<center>This is the default PETSc application dashboard, from it you can access any published PETSc objects or logging data</center><br><center>%s configured with %s</center><br>\n"
598: "%s",version,petscconfigureoptions,appline));
599: PetscStackCallSAWs(SAWs_Push_Body,("index.html",0,intro));
600: PetscFree(intro);
601: PetscFree(appline);
602: if (selectport) {
603: PetscBool silent;
605: /* another process may have grabbed the port so keep trying */
606: while (SAWs_Initialize()) {
607: PetscStackCallSAWs(SAWs_Get_Available_Port,(&port));
608: PetscStackCallSAWs(SAWs_Set_Port,(port));
609: }
611: PetscOptionsGetBool(NULL,NULL,"-saws_port_auto_select_silent",&silent,NULL);
612: if (!silent) {
613: PetscStackCallSAWs(SAWs_Get_FullURL,(sizeof(sawsurl),sawsurl));
614: PetscPrintf(PETSC_COMM_WORLD,"Point your browser to %s for SAWs\n",sawsurl);
615: }
616: } else {
617: PetscStackCallSAWs(SAWs_Initialize,());
618: }
619: PetscCall(PetscCitationsRegister("@TechReport{ saws,\n"
620: " Author = {Matt Otten and Jed Brown and Barry Smith},\n"
621: " Title = {Scientific Application Web Server (SAWs) Users Manual},\n"
622: " Institution = {Argonne National Laboratory},\n"
623: " Year = 2013\n}\n",NULL));
624: }
625: return 0;
626: }
627: #endif
629: /* Things must be done before MPI_Init() when MPI is not yet initialized, and can be shared between C init and Fortran init */
630: PETSC_INTERN PetscErrorCode PetscPreMPIInit_Private(void)
631: {
632: #if defined(PETSC_HAVE_HWLOC_SOLARIS_BUG)
633: /* see MPI.py for details on this bug */
634: (void) setenv("HWLOC_COMPONENTS","-x86",1);
635: #endif
636: return 0;
637: }
639: #if PetscDefined(HAVE_ADIOS)
640: #include <adios.h>
641: #include <adios_read.h>
642: int64_t Petsc_adios_group;
643: #endif
644: #if PetscDefined(HAVE_OPENMP)
645: #include <omp.h>
646: PetscInt PetscNumOMPThreads;
647: #endif
649: #if PetscDefined(HAVE_DEVICE)
650: #include <petsc/private/deviceimpl.h>
651: # if PetscDefined(HAVE_CUDA)
652: // REMOVE ME
653: cudaStream_t PetscDefaultCudaStream = NULL;
654: # endif
655: # if PetscDefined(HAVE_HIP)
656: // REMOVE ME
657: hipStream_t PetscDefaultHipStream = NULL;
658: # endif
659: #endif
661: #if PetscDefined(HAVE_DLFCN_H)
662: #include <dlfcn.h>
663: #endif
664: #if PetscDefined(USE_LOG)
665: PETSC_INTERN PetscErrorCode PetscLogInitialize(void);
666: #endif
667: #if PetscDefined(HAVE_VIENNACL)
668: PETSC_EXTERN PetscErrorCode PetscViennaCLInit();
669: PetscBool PetscViennaCLSynchronize = PETSC_FALSE;
670: #endif
672: /*
673: PetscInitialize_Common - shared code between C and Fortran initialization
675: prog: program name
676: file: optional PETSc database file name. Might be in Fortran string format when 'ftn' is true
677: help: program help message
678: ftn: is it called from Fortran initilization (petscinitializef_)?
679: readarguments,len: used when fortran is true
680: */
681: PETSC_INTERN PetscErrorCode PetscInitialize_Common(const char* prog,const char* file,const char *help,PetscBool ftn,PetscBool readarguments,PetscInt len)
682: {
683: PetscMPIInt size;
684: PetscBool flg = PETSC_TRUE;
685: char hostname[256];
687: if (PetscInitializeCalled) return 0;
688: /* these must be initialized in a routine, not as a constant declaration */
689: PETSC_STDOUT = stdout;
690: PETSC_STDERR = stderr;
692: /* PetscCall can be used from now */
693: PetscErrorHandlingInitialized = PETSC_TRUE;
695: /*
696: The checking over compatible runtime libraries is complicated by the MPI ABI initiative
697: https://wiki.mpich.org/mpich/index.php/ABI_Compatibility_Initiative which started with
698: MPICH v3.1 (Released February 2014)
699: IBM MPI v2.1 (December 2014)
700: Intel MPI Library v5.0 (2014)
701: Cray MPT v7.0.0 (June 2014)
702: As of July 31, 2017 the ABI number still appears to be 12, that is all of the versions
703: listed above and since that time are compatible.
705: Unfortunately the MPI ABI initiative has not defined a way to determine the ABI number
706: at compile time or runtime. Thus we will need to systematically track the allowed versions
707: and how they are represented in the mpi.h and MPI_Get_library_version() output in order
708: to perform the checking.
710: Currently we only check for pre MPI ABI versions (and packages that do not follow the MPI ABI).
712: Questions:
714: Should the checks for ABI incompatibility be only on the major version number below?
715: Presumably the output to stderr will be removed before a release.
716: */
718: #if defined(PETSC_HAVE_MPI_GET_LIBRARY_VERSION)
719: {
720: char mpilibraryversion[MPI_MAX_LIBRARY_VERSION_STRING];
721: PetscMPIInt mpilibraryversionlength;
723: MPI_Get_library_version(mpilibraryversion,&mpilibraryversionlength);
724: /* check for MPICH versions before MPI ABI initiative */
725: #if defined(MPICH_VERSION)
726: #if MPICH_NUMVERSION < 30100000
727: {
728: char *ver,*lf;
729: PetscBool flg = PETSC_FALSE;
731: PetscStrstr(mpilibraryversion,"MPICH Version:",&ver);
732: if (ver) {
733: PetscStrchr(ver,'\n',&lf);
734: if (lf) {
735: *lf = 0;
736: PetscStrendswith(ver,MPICH_VERSION,&flg);
737: }
738: }
739: if (!flg) {
740: PetscInfo(NULL,"PETSc warning --- MPICH library version \n%s does not match what PETSc was compiled with %s.\n",mpilibraryversion,MPICH_VESION);
741: flg = PETSC_TRUE;
742: }
743: }
744: #endif
745: /* check for OpenMPI version, it is not part of the MPI ABI initiative (is it part of another initiative that needs to be handled?) */
746: #elif defined(OMPI_MAJOR_VERSION)
747: {
748: char *ver,bs[MPI_MAX_LIBRARY_VERSION_STRING],*bsf;
749: PetscBool flg = PETSC_FALSE;
750: #define PSTRSZ 2
751: char ompistr1[PSTRSZ][MPI_MAX_LIBRARY_VERSION_STRING] = {"Open MPI","FUJITSU MPI"};
752: char ompistr2[PSTRSZ][MPI_MAX_LIBRARY_VERSION_STRING] = {"v","Library "};
753: int i;
754: for (i=0; i<PSTRSZ; i++) {
755: PetscStrstr(mpilibraryversion,ompistr1[i],&ver);
756: if (ver) {
757: PetscSNPrintf(bs,MPI_MAX_LIBRARY_VERSION_STRING,"%s%d.%d",ompistr2[i],OMPI_MAJOR_VERSION,OMPI_MINOR_VERSION);
758: PetscStrstr(ver,bs,&bsf);
759: if (bsf) flg = PETSC_TRUE;
760: break;
761: }
762: }
763: if (!flg) {
764: PetscInfo(NULL,"PETSc warning --- Open MPI library version \n%s does not match what PETSc was compiled with %d.%d.\n",mpilibraryversion,OMPI_MAJOR_VERSION,OMPI_MINOR_VERSION);
765: flg = PETSC_TRUE;
766: }
767: }
768: #endif
769: }
770: #endif
772: #if PetscDefined(HAVE_DLSYM)
773: /* These symbols are currently in the OpenMPI and MPICH libraries; they may not always be, in that case the test will simply not detect the problem */
775: #endif
777: /* on Windows - set printf to default to printing 2 digit exponents */
778: #if defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
779: _set_output_format(_TWO_DIGIT_EXPONENT);
780: #endif
782: PetscOptionsCreateDefault();
784: PetscFinalizeCalled = PETSC_FALSE;
786: PetscSetProgramName(prog);
787: PetscSpinlockCreate(&PetscViewerASCIISpinLockOpen);
788: PetscSpinlockCreate(&PetscViewerASCIISpinLockStdout);
789: PetscSpinlockCreate(&PetscViewerASCIISpinLockStderr);
790: PetscSpinlockCreate(&PetscCommSpinLock);
792: if (PETSC_COMM_WORLD == MPI_COMM_NULL) PETSC_COMM_WORLD = MPI_COMM_WORLD;
793: MPI_Comm_set_errhandler(PETSC_COMM_WORLD,MPI_ERRORS_RETURN);
795: if (PETSC_MPI_ERROR_CLASS == MPI_ERR_LASTCODE) {
796: MPI_Add_error_class(&PETSC_MPI_ERROR_CLASS);
797: MPI_Add_error_code(PETSC_MPI_ERROR_CLASS,&PETSC_MPI_ERROR_CODE);
798: }
800: /* Done after init due to a bug in MPICH-GM? */
801: PetscErrorPrintfInitialize();
803: MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);
804: MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);
806: MPIU_BOOL = MPI_INT;
807: MPIU_ENUM = MPI_INT;
808: MPIU_FORTRANADDR = (sizeof(void*) == sizeof(int)) ? MPI_INT : MPIU_INT64;
809: if (sizeof(size_t) == sizeof(unsigned)) MPIU_SIZE_T = MPI_UNSIGNED;
810: else if (sizeof(size_t) == sizeof(unsigned long)) MPIU_SIZE_T = MPI_UNSIGNED_LONG;
811: #if defined(PETSC_SIZEOF_LONG_LONG)
812: else if (sizeof(size_t) == sizeof(unsigned long long)) MPIU_SIZE_T = MPI_UNSIGNED_LONG_LONG;
813: #endif
814: else SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS,"Could not find MPI type for size_t");
816: /*
817: Initialized the global complex variable; this is because with
818: shared libraries the constructors for global variables
819: are not called; at least on IRIX.
820: */
821: #if defined(PETSC_HAVE_COMPLEX)
822: {
823: #if defined(PETSC_CLANGUAGE_CXX) && !defined(PETSC_USE_REAL___FLOAT128)
824: PetscComplex ic(0.0,1.0);
825: PETSC_i = ic;
826: #else
827: PETSC_i = _Complex_I;
828: #endif
829: }
830: #endif /* PETSC_HAVE_COMPLEX */
832: /*
833: Create the PETSc MPI reduction operator that sums of the first
834: half of the entries and maxes the second half.
835: */
836: MPI_Op_create(MPIU_MaxSum_Local,1,&MPIU_MAXSUM_OP);
838: #if defined(PETSC_USE_REAL___FLOAT128)
839: MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128);
840: MPI_Type_commit(&MPIU___FLOAT128);
841: #if defined(PETSC_HAVE_COMPLEX)
842: MPI_Type_contiguous(4,MPI_DOUBLE,&MPIU___COMPLEX128);
843: MPI_Type_commit(&MPIU___COMPLEX128);
844: #endif
845: MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);
846: MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);
847: #elif defined(PETSC_USE_REAL___FP16)
848: MPI_Type_contiguous(2,MPI_CHAR,&MPIU___FP16);
849: MPI_Type_commit(&MPIU___FP16);
850: MPI_Op_create(PetscMax_Local,1,&MPIU_MAX);
851: MPI_Op_create(PetscMin_Local,1,&MPIU_MIN);
852: #endif
854: #if defined(PETSC_USE_REAL___FLOAT128) || defined(PETSC_USE_REAL___FP16)
855: MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);
856: #endif
858: MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR);
859: MPI_Type_commit(&MPIU_2SCALAR);
861: /* create datatypes used by MPIU_MAXLOC, MPIU_MINLOC and PetscSplitReduction_Op */
862: #if !defined(PETSC_HAVE_MPIUNI)
863: {
864: struct PetscRealInt { PetscReal v; PetscInt i; };
865: PetscMPIInt blockSizes[2] = {1,1};
866: MPI_Aint blockOffsets[2] = {offsetof(struct PetscRealInt,v),offsetof(struct PetscRealInt,i)};
867: MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, tmpStruct;
869: MPI_Type_create_struct(2,blockSizes,blockOffsets,blockTypes,&tmpStruct);
870: MPI_Type_create_resized(tmpStruct,0,sizeof(struct PetscRealInt),&MPIU_REAL_INT);
871: MPI_Type_free(&tmpStruct);
872: MPI_Type_commit(&MPIU_REAL_INT);
873: }
874: {
875: struct PetscScalarInt { PetscScalar v; PetscInt i; };
876: PetscMPIInt blockSizes[2] = {1,1};
877: MPI_Aint blockOffsets[2] = {offsetof(struct PetscScalarInt,v),offsetof(struct PetscScalarInt,i)};
878: MPI_Datatype blockTypes[2] = {MPIU_SCALAR,MPIU_INT}, tmpStruct;
880: MPI_Type_create_struct(2,blockSizes,blockOffsets,blockTypes,&tmpStruct);
881: MPI_Type_create_resized(tmpStruct,0,sizeof(struct PetscScalarInt),&MPIU_SCALAR_INT);
882: MPI_Type_free(&tmpStruct);
883: MPI_Type_commit(&MPIU_SCALAR_INT);
884: }
885: #endif
887: #if defined(PETSC_USE_64BIT_INDICES)
888: MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT);
889: MPI_Type_commit(&MPIU_2INT);
890: #endif
891: MPI_Type_contiguous(4,MPI_INT,&MPI_4INT);
892: MPI_Type_commit(&MPI_4INT);
893: MPI_Type_contiguous(4,MPIU_INT,&MPIU_4INT);
894: MPI_Type_commit(&MPIU_4INT);
896: /*
897: Attributes to be set on PETSc communicators
898: */
899: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_Counter_Attr_Delete_Fn,&Petsc_Counter_keyval,(void*)0);
900: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_InnerComm_Attr_Delete_Fn,&Petsc_InnerComm_keyval,(void*)0);
901: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_OuterComm_Attr_Delete_Fn,&Petsc_OuterComm_keyval,(void*)0);
902: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_ShmComm_Attr_Delete_Fn,&Petsc_ShmComm_keyval,(void*)0);
904: #if defined(PETSC_HAVE_FORTRAN)
905: if (ftn) PetscInitFortran_Private(readarguments,file,len);
906: else
907: #endif
908: PetscOptionsInsert(NULL,&PetscGlobalArgc,&PetscGlobalArgs,file);
910: /* call a second time so it can look in the options database */
911: PetscErrorPrintfInitialize();
913: /*
914: Check system options and print help
915: */
916: PetscOptionsCheckInitial_Private(help);
918: /*
919: Initialize PetscDevice and PetscDeviceContext
921: Note to any future devs thinking of moving this, proper initialization requires:
922: 1. MPI initialized
923: 2. Options DB initialized
924: 3. Petsc error handling initialized, specifically signal handlers. This expects to set up its own SIGSEV handler via
925: the push/pop interface.
926: */
927: #if (PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) || PetscDefined(HAVE_SYCL))
928: PetscDeviceInitializeFromOptions_Internal(PETSC_COMM_WORLD);
929: #endif
931: #if PetscDefined(HAVE_VIENNACL)
932: flg = PETSC_FALSE;
933: PetscOptionsHasName(NULL,NULL,"-log_summary",&flg);
934: if (!flg) PetscOptionsHasName(NULL,NULL,"-log_view",&flg);
935: if (!flg) PetscOptionsGetBool(NULL,NULL,"-viennacl_synchronize",&flg,NULL);
936: PetscViennaCLSynchronize = flg;
937: PetscViennaCLInit();
938: #endif
940: /*
941: Creates the logging data structures; this is enabled even if logging is not turned on
942: This is the last thing we do before returning to the user code to prevent having the
943: logging numbers contaminated by any startup time associated with MPI
944: */
945: #if defined(PETSC_USE_LOG)
946: PetscLogInitialize();
947: #endif
949: PetscCitationsInitialize();
951: #if defined(PETSC_HAVE_SAWS)
952: PetscInitializeSAWs(ftn ? NULL : help);
953: flg = PETSC_FALSE;
954: PetscOptionsHasName(NULL,NULL,"-stack_view",&flg);
955: if (flg) PetscStackViewSAWs();
956: #endif
958: /*
959: Load the dynamic libraries (on machines that support them), this registers all
960: the solvers etc. (On non-dynamic machines this initializes the PetscDraw and PetscViewer classes)
961: */
962: PetscInitialize_DynamicLibraries();
964: MPI_Comm_size(PETSC_COMM_WORLD,&size);
965: PetscInfo(NULL,"PETSc successfully started: number of processors = %d\n",size);
966: PetscGetHostName(hostname,256);
967: PetscInfo(NULL,"Running on machine: %s\n",hostname);
968: #if defined(PETSC_HAVE_OPENMP)
969: {
970: PetscBool omp_view_flag;
971: char *threads = getenv("OMP_NUM_THREADS");
972: PetscErrorCode ierr;
974: if (threads) {
975: PetscInfo(NULL,"Number of OpenMP threads %s (as given by OMP_NUM_THREADS)\n",threads);
976: (void) sscanf(threads, "%" PetscInt_FMT,&PetscNumOMPThreads);
977: } else {
978: PetscNumOMPThreads = (PetscInt) omp_get_max_threads();
979: PetscInfo(NULL,"Number of OpenMP threads %" PetscInt_FMT " (as given by omp_get_max_threads())\n",PetscNumOMPThreads);
980: }
981: PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"OpenMP options","Sys");
982: PetscOptionsInt("-omp_num_threads","Number of OpenMP threads to use (can also use environmental variable OMP_NUM_THREADS","None",PetscNumOMPThreads,&PetscNumOMPThreads,&flg);
983: PetscOptionsName("-omp_view","Display OpenMP number of threads",NULL,&omp_view_flag);
984: PetscOptionsEnd();
985: if (flg) {
986: PetscInfo(NULL,"Number of OpenMP theads %" PetscInt_FMT " (given by -omp_num_threads)\n",PetscNumOMPThreads);
987: omp_set_num_threads((int)PetscNumOMPThreads);
988: }
989: if (omp_view_flag) {
990: PetscPrintf(PETSC_COMM_WORLD,"OpenMP: number of threads %" PetscInt_FMT "\n",PetscNumOMPThreads);
991: }
992: }
993: #endif
995: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
996: /*
997: Tell MPI about our own data representation converter, this would/should be used if extern32 is not supported by the MPI
999: Currently not used because it is not supported by MPICH.
1000: */
1001: if (!PetscBinaryBigEndian()) MPI_Register_datarep((char*)"petsc",PetscDataRep_read_conv_fn,PetscDataRep_write_conv_fn,PetscDataRep_extent_fn,NULL);
1002: #endif
1004: #if defined(PETSC_SERIALIZE_FUNCTIONS)
1005: PetscFPTCreate(10000);
1006: #endif
1008: #if defined(PETSC_HAVE_HWLOC)
1009: {
1010: PetscViewer viewer;
1011: PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,NULL,"-process_view",&viewer,NULL,&flg);
1012: if (flg) {
1013: PetscProcessPlacementView(viewer);
1014: PetscViewerDestroy(&viewer);
1015: }
1016: }
1017: #endif
1019: flg = PETSC_TRUE;
1020: PetscOptionsGetBool(NULL,NULL,"-viewfromoptions",&flg,NULL);
1021: if (!flg) PetscOptionsPushGetViewerOff(PETSC_TRUE);
1023: #if defined(PETSC_HAVE_ADIOS)
1024: adios_init_noxml(PETSC_COMM_WORLD);
1025: adios_declare_group(&Petsc_adios_group,"PETSc","",adios_stat_default);
1026: adios_select_method(Petsc_adios_group,"MPI","","");
1027: adios_read_init_method(ADIOS_READ_METHOD_BP,PETSC_COMM_WORLD,"");
1028: #endif
1030: #if defined(__VALGRIND_H)
1031: PETSC_RUNNING_ON_VALGRIND = RUNNING_ON_VALGRIND? PETSC_TRUE: PETSC_FALSE;
1032: #if defined(PETSC_USING_DARWIN) && defined(PETSC_BLASLAPACK_SDOT_RETURNS_DOUBLE)
1033: if (PETSC_RUNNING_ON_VALGRIND) PetscPrintf(PETSC_COMM_WORLD,"WARNING: Running valgrind with the MacOS native BLAS and LAPACK can fail. If it fails suggest configuring with --download-fblaslapack or --download-f2cblaslapack");
1034: #endif
1035: #endif
1036: /*
1037: Set flag that we are completely initialized
1038: */
1039: PetscInitializeCalled = PETSC_TRUE;
1041: PetscOptionsHasName(NULL,NULL,"-python",&flg);
1042: if (flg) PetscPythonInitialize(NULL,NULL);
1043: return 0;
1044: }
1046: /*@C
1047: PetscInitialize - Initializes the PETSc database and MPI.
1048: PetscInitialize() calls MPI_Init() if that has yet to be called,
1049: so this routine should always be called near the beginning of
1050: your program -- usually the very first line!
1052: Collective on MPI_COMM_WORLD or PETSC_COMM_WORLD if it has been set
1054: Input Parameters:
1055: + argc - count of number of command line arguments
1056: . args - the command line arguments
1057: . file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format.
1058: Use NULL or empty string to not check for code specific file.
1059: Also checks ~/.petscrc, .petscrc and petscrc.
1060: Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
1061: - help - [optional] Help message to print, use NULL for no message
1063: If you wish PETSc code to run ONLY on a subcommunicator of MPI_COMM_WORLD, create that
1064: communicator first and assign it to PETSC_COMM_WORLD BEFORE calling PetscInitialize(). Thus if you are running a
1065: four process job and two processes will run PETSc and have PetscInitialize() and PetscFinalize() and two process will not,
1066: then do this. If ALL processes in the job are using PetscInitialize() and PetscFinalize() then you don't need to do this, even
1067: if different subcommunicators of the job are doing different things with PETSc.
1069: Options Database Keys:
1070: + -help [intro] - prints help method for each option; if intro is given the program stops after printing the introductory help message
1071: . -start_in_debugger [noxterm,dbx,xdb,gdb,...] - Starts program in debugger
1072: . -on_error_attach_debugger [noxterm,dbx,xdb,gdb,...] - Starts debugger when error detected
1073: . -on_error_emacs <machinename> - causes emacsclient to jump to error file
1074: . -on_error_abort - calls abort() when error detected (no traceback)
1075: . -on_error_mpiabort - calls MPI_abort() when error detected
1076: . -error_output_stderr - prints error messages to stderr instead of the default stdout
1077: . -error_output_none - does not print the error messages (but handles errors in the same way as if this was not called)
1078: . -debugger_ranks [rank1,rank2,...] - Indicates ranks to start in debugger
1079: . -debugger_pause [sleeptime] (in seconds) - Pauses debugger
1080: . -stop_for_debugger - Print message on how to attach debugger manually to
1081: process and wait (-debugger_pause) seconds for attachment
1082: . -malloc - Indicates use of PETSc error-checking malloc (on by default for debug version of libraries) (deprecated, use -malloc_debug)
1083: . -malloc no - Indicates not to use error-checking malloc (deprecated, use -malloc_debug no)
1084: . -malloc_debug - check for memory corruption at EVERY malloc or free, see PetscMallocSetDebug()
1085: . -malloc_dump - prints a list of all unfreed memory at the end of the run
1086: . -malloc_test - like -malloc_dump -malloc_debug, but only active for debugging builds, ignored in optimized build. May want to set in PETSC_OPTIONS environmental variable
1087: . -malloc_view - show a list of all allocated memory during PetscFinalize()
1088: . -malloc_view_threshold <t> - only list memory allocations of size greater than t with -malloc_view
1089: . -malloc_requested_size - malloc logging will record the requested size rather than size after alignment
1090: . -fp_trap - Stops on floating point exceptions
1091: . -no_signal_handler - Indicates not to trap error signals
1092: . -shared_tmp - indicates /tmp directory is shared by all processors
1093: . -not_shared_tmp - each processor has own /tmp
1094: . -tmp - alternative name of /tmp directory
1095: . -get_total_flops - returns total flops done by all processors
1096: - -memory_view - Print memory usage at end of run
1098: Options Database Keys for Option Database:
1099: + -skip_petscrc - skip the default option files ~/.petscrc, .petscrc, petscrc
1100: . -options_monitor - monitor all set options to standard output for the whole program run
1101: - -options_monitor_cancel - cancel options monitoring hard-wired using PetscOptionsMonitorSet()
1103: Options -options_monitor_{all,cancel} are
1104: position-independent and apply to all options set since the PETSc start.
1105: They can be used also in option files.
1107: See PetscOptionsMonitorSet() to do monitoring programmatically.
1109: Options Database Keys for Profiling:
1110: See Users-Manual: ch_profiling for details.
1111: + -info [filename][:[~]<list,of,classnames>[:[~]self]] - Prints verbose information. See PetscInfo().
1112: . -log_sync - Enable barrier synchronization for all events. This option is useful to debug imbalance within each event,
1113: however it slows things down and gives a distorted view of the overall runtime.
1114: . -log_trace [filename] - Print traces of all PETSc calls to the screen (useful to determine where a program
1115: hangs without running in the debugger). See PetscLogTraceBegin().
1116: . -log_view [:filename:format] - Prints summary of flop and timing information to screen or file, see PetscLogView().
1117: . -log_view_memory - Includes in the summary from -log_view the memory used in each method, see PetscLogView().
1118: . -log_summary [filename] - (Deprecated, use -log_view) Prints summary of flop and timing information to screen. If the filename is specified the
1119: summary is written to the file. See PetscLogView().
1120: . -log_exclude: <vec,mat,pc,ksp,snes> - excludes subset of object classes from logging
1121: . -log_all [filename] - Logs extensive profiling information See PetscLogDump().
1122: . -log [filename] - Logs basic profiline information See PetscLogDump().
1123: . -log_mpe [filename] - Creates a logfile viewable by the utility Jumpshot (in MPICH distribution)
1124: . -viewfromoptions on,off - Enable or disable XXXSetFromOptions() calls, for applications with many small solves turn this off
1125: - -check_pointer_intensity 0,1,2 - if pointers are checked for validity (debug version only), using 0 will result in faster code
1127: Only one of -log_trace, -log_view, -log_all, -log, or -log_mpe may be used at a time
1129: Options Database Keys for SAWs:
1130: + -saws_port <portnumber> - port number to publish SAWs data, default is 8080
1131: . -saws_port_auto_select - have SAWs select a new unique port number where it publishes the data, the URL is printed to the screen
1132: this is useful when you are running many jobs that utilize SAWs at the same time
1133: . -saws_log <filename> - save a log of all SAWs communication
1134: . -saws_https <certificate file> - have SAWs use HTTPS instead of HTTP
1135: - -saws_root <directory> - allow SAWs to have access to the given directory to search for requested resources and files
1137: Environmental Variables:
1138: + PETSC_TMP - alternative tmp directory
1139: . PETSC_SHARED_TMP - tmp is shared by all processes
1140: . PETSC_NOT_SHARED_TMP - each process has its own private tmp
1141: . PETSC_OPTIONS - a string containing additional options for petsc in the form of command line "-key value" pairs
1142: . PETSC_OPTIONS_YAML - (requires configuring PETSc to use libyaml) a string containing additional options for petsc in the form of a YAML document
1143: . PETSC_VIEWER_SOCKET_PORT - socket number to use for socket viewer
1144: - PETSC_VIEWER_SOCKET_MACHINE - machine to use for socket viewer to connect to
1146: Level: beginner
1148: Notes:
1149: If for some reason you must call MPI_Init() separately, call
1150: it before PetscInitialize().
1152: Fortran Version:
1153: In Fortran this routine has the format
1154: $ call PetscInitialize(file,ierr)
1156: + ierr - error return code
1157: - file - [optional] PETSc database file, also checks ~/.petscrc, .petscrc and petscrc.
1158: Use PETSC_NULL_CHARACTER to not check for code specific file.
1159: Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files.
1161: Important Fortran Note:
1162: In Fortran, you MUST use PETSC_NULL_CHARACTER to indicate a
1163: null character string; you CANNOT just use NULL as
1164: in the C version. See Users-Manual: ch_fortran for details.
1166: If your main program is C but you call Fortran code that also uses PETSc you need to call PetscInitializeFortran() soon after
1167: calling PetscInitialize().
1169: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()
1171: @*/
1172: PetscErrorCode PetscInitialize(int *argc,char ***args,const char file[],const char help[])
1173: {
1174: PetscMPIInt flag;
1175: const char *prog = "Unknown Name";
1177: if (PetscInitializeCalled) return 0;
1178: MPI_Initialized(&flag);
1179: if (!flag) {
1181: PetscPreMPIInit_Private();
1182: #if defined(PETSC_HAVE_MPI_INIT_THREAD)
1183: {
1184: PetscMPIInt PETSC_UNUSED provided;
1185: MPI_Init_thread(argc,args,PETSC_MPI_THREAD_REQUIRED,&provided);
1186: }
1187: #else
1188: MPI_Init(argc,args);
1189: #endif
1190: PetscBeganMPI = PETSC_TRUE;
1191: }
1193: if (argc && *argc) prog = **args;
1194: if (argc && args) {
1195: PetscGlobalArgc = *argc;
1196: PetscGlobalArgs = *args;
1197: }
1198: PetscInitialize_Common(prog,file,help,PETSC_FALSE/*C*/,PETSC_FALSE,0);
1199: return 0;
1200: }
1202: #if PetscDefined(USE_LOG)
1203: PETSC_INTERN PetscObject *PetscObjects;
1204: PETSC_INTERN PetscInt PetscObjectsCounts;
1205: PETSC_INTERN PetscInt PetscObjectsMaxCounts;
1206: PETSC_INTERN PetscBool PetscObjectsLog;
1207: #endif
1209: /*
1210: Frees all the MPI types and operations that PETSc may have created
1211: */
1212: PetscErrorCode PetscFreeMPIResources(void)
1213: {
1214: #if defined(PETSC_USE_REAL___FLOAT128)
1215: MPI_Type_free(&MPIU___FLOAT128);
1216: #if defined(PETSC_HAVE_COMPLEX)
1217: MPI_Type_free(&MPIU___COMPLEX128);
1218: #endif
1219: MPI_Op_free(&MPIU_MAX);
1220: MPI_Op_free(&MPIU_MIN);
1221: #elif defined(PETSC_USE_REAL___FP16)
1222: MPI_Type_free(&MPIU___FP16);
1223: MPI_Op_free(&MPIU_MAX);
1224: MPI_Op_free(&MPIU_MIN);
1225: #endif
1227: #if defined(PETSC_USE_REAL___FLOAT128) || defined(PETSC_USE_REAL___FP16)
1228: MPI_Op_free(&MPIU_SUM);
1229: #endif
1231: MPI_Type_free(&MPIU_2SCALAR);
1232: MPI_Type_free(&MPIU_REAL_INT);
1233: MPI_Type_free(&MPIU_SCALAR_INT);
1234: #if defined(PETSC_USE_64BIT_INDICES)
1235: MPI_Type_free(&MPIU_2INT);
1236: #endif
1237: MPI_Type_free(&MPI_4INT);
1238: MPI_Type_free(&MPIU_4INT);
1239: MPI_Op_free(&MPIU_MAXSUM_OP);
1240: return 0;
1241: }
1243: #if PetscDefined(USE_LOG)
1244: PETSC_INTERN PetscErrorCode PetscLogFinalize(void);
1245: #endif
1247: /*@C
1248: PetscFinalize - Checks for options to be called at the conclusion
1249: of the program. MPI_Finalize() is called only if the user had not
1250: called MPI_Init() before calling PetscInitialize().
1252: Collective on PETSC_COMM_WORLD
1254: Options Database Keys:
1255: + -options_view - Calls PetscOptionsView()
1256: . -options_left - Prints unused options that remain in the database
1257: . -objects_dump [all] - Prints list of objects allocated by the user that have not been freed, the option all cause all outstanding objects to be listed
1258: . -mpidump - Calls PetscMPIDump()
1259: . -malloc_dump <optional filename> - Calls PetscMallocDump(), displays all memory allocated that has not been freed
1260: . -malloc_info - Prints total memory usage
1261: - -malloc_view <optional filename> - Prints list of all memory allocated and where
1263: Level: beginner
1265: Note:
1266: See PetscInitialize() for more general runtime options.
1268: .seealso: PetscInitialize(), PetscOptionsView(), PetscMallocDump(), PetscMPIDump(), PetscEnd()
1269: @*/
1270: PetscErrorCode PetscFinalize(void)
1271: {
1272: PetscMPIInt rank;
1273: PetscInt nopt;
1274: PetscBool flg1 = PETSC_FALSE,flg2 = PETSC_FALSE,flg3 = PETSC_FALSE;
1275: PetscBool flg;
1276: #if defined(PETSC_USE_LOG)
1277: char mname[PETSC_MAX_PATH_LEN];
1278: #endif
1281: PetscInfo(NULL,"PetscFinalize() called\n");
1283: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
1284: #if defined(PETSC_HAVE_ADIOS)
1285: adios_read_finalize_method(ADIOS_READ_METHOD_BP_AGGREGATE);
1286: adios_finalize(rank);
1287: #endif
1288: PetscOptionsHasName(NULL,NULL,"-citations",&flg);
1289: if (flg) {
1290: char *cits, filename[PETSC_MAX_PATH_LEN];
1291: FILE *fd = PETSC_STDOUT;
1293: PetscOptionsGetString(NULL,NULL,"-citations",filename,sizeof(filename),NULL);
1294: if (filename[0]) {
1295: PetscFOpen(PETSC_COMM_WORLD,filename,"w",&fd);
1296: }
1297: PetscSegBufferGet(PetscCitationsList,1,&cits);
1298: cits[0] = 0;
1299: PetscSegBufferExtractAlloc(PetscCitationsList,&cits);
1300: PetscFPrintf(PETSC_COMM_WORLD,fd,"If you publish results based on this computation please cite the following:\n");
1301: PetscFPrintf(PETSC_COMM_WORLD,fd,"===========================================================================\n");
1302: PetscFPrintf(PETSC_COMM_WORLD,fd,"%s",cits);
1303: PetscFPrintf(PETSC_COMM_WORLD,fd,"===========================================================================\n");
1304: PetscFClose(PETSC_COMM_WORLD,fd);
1305: PetscFree(cits);
1306: }
1307: PetscSegBufferDestroy(&PetscCitationsList);
1309: #if defined(PETSC_HAVE_SSL) && defined(PETSC_USE_SOCKET_VIEWER)
1310: /* TextBelt is run for testing purposes only, please do not use this feature often */
1311: {
1312: PetscInt nmax = 2;
1313: char **buffs;
1314: PetscMalloc1(2,&buffs);
1315: PetscOptionsGetStringArray(NULL,NULL,"-textbelt",buffs,&nmax,&flg1);
1316: if (flg1) {
1318: if (nmax == 1) {
1319: PetscMalloc1(128,&buffs[1]);
1320: PetscGetProgramName(buffs[1],32);
1321: PetscStrcat(buffs[1]," has completed");
1322: }
1323: PetscTextBelt(PETSC_COMM_WORLD,buffs[0],buffs[1],NULL);
1324: PetscFree(buffs[0]);
1325: PetscFree(buffs[1]);
1326: }
1327: PetscFree(buffs);
1328: }
1329: {
1330: PetscInt nmax = 2;
1331: char **buffs;
1332: PetscMalloc1(2,&buffs);
1333: PetscOptionsGetStringArray(NULL,NULL,"-tellmycell",buffs,&nmax,&flg1);
1334: if (flg1) {
1336: if (nmax == 1) {
1337: PetscMalloc1(128,&buffs[1]);
1338: PetscGetProgramName(buffs[1],32);
1339: PetscStrcat(buffs[1]," has completed");
1340: }
1341: PetscTellMyCell(PETSC_COMM_WORLD,buffs[0],buffs[1],NULL);
1342: PetscFree(buffs[0]);
1343: PetscFree(buffs[1]);
1344: }
1345: PetscFree(buffs);
1346: }
1347: #endif
1349: #if defined(PETSC_SERIALIZE_FUNCTIONS)
1350: PetscFPTDestroy();
1351: #endif
1353: #if defined(PETSC_HAVE_SAWS)
1354: flg = PETSC_FALSE;
1355: PetscOptionsGetBool(NULL,NULL,"-saw_options",&flg,NULL);
1356: if (flg) {
1357: PetscOptionsSAWsDestroy();
1358: }
1359: #endif
1361: #if defined(PETSC_HAVE_X)
1362: flg1 = PETSC_FALSE;
1363: PetscOptionsGetBool(NULL,NULL,"-x_virtual",&flg1,NULL);
1364: if (flg1) {
1365: /* this is a crude hack, but better than nothing */
1366: PetscPOpen(PETSC_COMM_WORLD,NULL,"pkill -9 Xvfb","r",NULL);
1367: }
1368: #endif
1370: #if !defined(PETSC_HAVE_THREADSAFETY)
1371: PetscOptionsGetBool(NULL,NULL,"-malloc_info",&flg2,NULL);
1372: if (!flg2) {
1373: flg2 = PETSC_FALSE;
1374: PetscOptionsGetBool(NULL,NULL,"-memory_view",&flg2,NULL);
1375: }
1376: if (flg2) {
1377: PetscMemoryView(PETSC_VIEWER_STDOUT_WORLD,"Summary of Memory Usage in PETSc\n");
1378: }
1379: #endif
1381: #if defined(PETSC_USE_LOG)
1382: flg1 = PETSC_FALSE;
1383: PetscOptionsGetBool(NULL,NULL,"-get_total_flops",&flg1,NULL);
1384: if (flg1) {
1385: PetscLogDouble flops = 0;
1386: MPI_Reduce(&petsc_TotalFlops,&flops,1,MPI_DOUBLE,MPI_SUM,0,PETSC_COMM_WORLD);
1387: PetscPrintf(PETSC_COMM_WORLD,"Total flops over all processors %g\n",flops);
1388: }
1389: #endif
1391: #if defined(PETSC_USE_LOG)
1392: #if defined(PETSC_HAVE_MPE)
1393: mname[0] = 0;
1394: PetscOptionsGetString(NULL,NULL,"-log_mpe",mname,sizeof(mname),&flg1);
1395: if (flg1) {
1396: if (mname[0]) PetscLogMPEDump(mname);
1397: else PetscLogMPEDump(0);
1398: }
1399: #endif
1400: #endif
1402: /*
1403: Free all objects registered with PetscObjectRegisterDestroy() such as PETSC_VIEWER_XXX_().
1404: */
1405: PetscObjectRegisterDestroyAll();
1407: #if defined(PETSC_USE_LOG)
1408: PetscOptionsPushGetViewerOff(PETSC_FALSE);
1409: PetscLogViewFromOptions();
1410: PetscOptionsPopGetViewerOff();
1412: mname[0] = 0;
1413: PetscOptionsGetString(NULL,NULL,"-log_summary",mname,sizeof(mname),&flg1);
1414: if (flg1) {
1415: PetscViewer viewer;
1416: (*PetscHelpPrintf)(PETSC_COMM_WORLD,"\n\n WARNING: -log_summary is being deprecated; switch to -log_view\n\n\n");
1417: if (mname[0]) {
1418: PetscViewerASCIIOpen(PETSC_COMM_WORLD,mname,&viewer);
1419: PetscLogView(viewer);
1420: PetscViewerDestroy(&viewer);
1421: } else {
1422: viewer = PETSC_VIEWER_STDOUT_WORLD;
1423: PetscViewerPushFormat(viewer,PETSC_VIEWER_DEFAULT);
1424: PetscLogView(viewer);
1425: PetscViewerPopFormat(viewer);
1426: }
1427: }
1429: /*
1430: Free any objects created by the last block of code.
1431: */
1432: PetscObjectRegisterDestroyAll();
1434: mname[0] = 0;
1435: PetscOptionsGetString(NULL,NULL,"-log_all",mname,sizeof(mname),&flg1);
1436: PetscOptionsGetString(NULL,NULL,"-log",mname,sizeof(mname),&flg2);
1437: if (flg1 || flg2) PetscLogDump(mname);
1438: #endif
1440: flg1 = PETSC_FALSE;
1441: PetscOptionsGetBool(NULL,NULL,"-no_signal_handler",&flg1,NULL);
1442: if (!flg1) PetscPopSignalHandler();
1443: flg1 = PETSC_FALSE;
1444: PetscOptionsGetBool(NULL,NULL,"-mpidump",&flg1,NULL);
1445: if (flg1) {
1446: PetscMPIDump(stdout);
1447: }
1448: flg1 = PETSC_FALSE;
1449: flg2 = PETSC_FALSE;
1450: /* preemptive call to avoid listing this option in options table as unused */
1451: PetscOptionsHasName(NULL,NULL,"-malloc_dump",&flg1);
1452: PetscOptionsHasName(NULL,NULL,"-objects_dump",&flg1);
1453: PetscOptionsGetBool(NULL,NULL,"-options_view",&flg2,NULL);
1455: if (flg2) {
1456: PetscViewer viewer;
1457: PetscViewerCreate(PETSC_COMM_WORLD,&viewer);
1458: PetscViewerSetType(viewer,PETSCVIEWERASCII);
1459: PetscOptionsView(NULL,viewer);
1460: PetscViewerDestroy(&viewer);
1461: }
1463: /* to prevent PETSc -options_left from warning */
1464: PetscOptionsHasName(NULL,NULL,"-nox",&flg1);
1465: PetscOptionsHasName(NULL,NULL,"-nox_warning",&flg1);
1467: flg3 = PETSC_FALSE; /* default value is required */
1468: PetscOptionsGetBool(NULL,NULL,"-options_left",&flg3,&flg1);
1469: if (PetscUnlikelyDebug(!flg1)) flg3 = PETSC_TRUE;
1470: if (flg3) {
1471: if (!flg2 && flg1) { /* have not yet printed the options */
1472: PetscViewer viewer;
1473: PetscViewerCreate(PETSC_COMM_WORLD,&viewer);
1474: PetscViewerSetType(viewer,PETSCVIEWERASCII);
1475: PetscOptionsView(NULL,viewer);
1476: PetscViewerDestroy(&viewer);
1477: }
1478: PetscOptionsAllUsed(NULL,&nopt);
1479: if (nopt) {
1480: PetscPrintf(PETSC_COMM_WORLD,"WARNING! There are options you set that were not used!\n");
1481: PetscPrintf(PETSC_COMM_WORLD,"WARNING! could be spelling mistake, etc!\n");
1482: if (nopt == 1) {
1483: PetscPrintf(PETSC_COMM_WORLD,"There is one unused database option. It is:\n");
1484: } else {
1485: PetscPrintf(PETSC_COMM_WORLD,"There are %" PetscInt_FMT " unused database options. They are:\n",nopt);
1486: }
1487: } else if (flg3 && flg1) {
1488: PetscPrintf(PETSC_COMM_WORLD,"There are no unused options.\n");
1489: }
1490: PetscOptionsLeft(NULL);
1491: }
1493: #if defined(PETSC_HAVE_SAWS)
1494: if (!PetscGlobalRank) {
1495: PetscStackSAWsViewOff();
1496: PetscStackCallSAWs(SAWs_Finalize,());
1497: }
1498: #endif
1500: #if defined(PETSC_USE_LOG)
1501: /*
1502: List all objects the user may have forgot to free
1503: */
1504: if (PetscObjectsLog) {
1505: PetscOptionsHasName(NULL,NULL,"-objects_dump",&flg1);
1506: if (flg1) {
1507: MPI_Comm local_comm;
1508: char string[64];
1510: PetscOptionsGetString(NULL,NULL,"-objects_dump",string,sizeof(string),NULL);
1511: MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
1512: PetscSequentialPhaseBegin_Private(local_comm,1);
1513: PetscObjectsDump(stdout,(string[0] == 'a') ? PETSC_TRUE : PETSC_FALSE);
1514: PetscSequentialPhaseEnd_Private(local_comm,1);
1515: MPI_Comm_free(&local_comm);
1516: }
1517: }
1518: #endif
1520: #if defined(PETSC_USE_LOG)
1521: PetscObjectsCounts = 0;
1522: PetscObjectsMaxCounts = 0;
1523: PetscFree(PetscObjects);
1524: #endif
1526: /*
1527: Destroy any packages that registered a finalize
1528: */
1529: PetscRegisterFinalizeAll();
1531: #if defined(PETSC_USE_LOG)
1532: PetscLogFinalize();
1533: #endif
1535: /*
1536: Print PetscFunctionLists that have not been properly freed
1538: PetscFunctionListPrintAll();
1539: */
1541: if (petsc_history) {
1542: PetscCloseHistoryFile(&petsc_history);
1543: petsc_history = NULL;
1544: }
1545: PetscOptionsHelpPrintedDestroy(&PetscOptionsHelpPrintedSingleton);
1546: PetscInfoDestroy();
1548: #if !defined(PETSC_HAVE_THREADSAFETY)
1549: if (!(PETSC_RUNNING_ON_VALGRIND)) {
1550: char fname[PETSC_MAX_PATH_LEN];
1551: char sname[PETSC_MAX_PATH_LEN];
1552: FILE *fd;
1553: int err;
1555: flg2 = PETSC_FALSE;
1556: flg3 = PETSC_FALSE;
1557: if (PetscDefined(USE_DEBUG)) PetscOptionsGetBool(NULL,NULL,"-malloc_test",&flg2,NULL);
1558: PetscOptionsGetBool(NULL,NULL,"-malloc_debug",&flg3,NULL);
1559: fname[0] = 0;
1560: PetscOptionsGetString(NULL,NULL,"-malloc_dump",fname,sizeof(fname),&flg1);
1561: if (flg1 && fname[0]) {
1563: PetscSNPrintf(sname,sizeof(sname),"%s_%d",fname,rank);
1565: PetscMallocDump(fd);
1566: err = fclose(fd);
1568: } else if (flg1 || flg2 || flg3) {
1569: MPI_Comm local_comm;
1571: MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
1572: PetscSequentialPhaseBegin_Private(local_comm,1);
1573: PetscMallocDump(stdout);
1574: PetscSequentialPhaseEnd_Private(local_comm,1);
1575: MPI_Comm_free(&local_comm);
1576: }
1577: fname[0] = 0;
1578: PetscOptionsGetString(NULL,NULL,"-malloc_view",fname,sizeof(fname),&flg1);
1579: if (flg1 && fname[0]) {
1581: PetscSNPrintf(sname,sizeof(sname),"%s_%d",fname,rank);
1583: PetscMallocView(fd);
1584: err = fclose(fd);
1586: } else if (flg1) {
1587: MPI_Comm local_comm;
1589: MPI_Comm_dup(MPI_COMM_WORLD,&local_comm);
1590: PetscSequentialPhaseBegin_Private(local_comm,1);
1591: PetscMallocView(stdout);
1592: PetscSequentialPhaseEnd_Private(local_comm,1);
1593: MPI_Comm_free(&local_comm);
1594: }
1595: }
1596: #endif
1598: /*
1599: Close any open dynamic libraries
1600: */
1601: PetscFinalize_DynamicLibraries();
1603: /* Can be destroyed only after all the options are used */
1604: PetscOptionsDestroyDefault();
1606: PetscGlobalArgc = 0;
1607: PetscGlobalArgs = NULL;
1609: #if defined(PETSC_HAVE_KOKKOS)
1610: if (PetscBeganKokkos) {
1611: PetscKokkosFinalize_Private();
1612: PetscBeganKokkos = PETSC_FALSE;
1613: PetscKokkosInitialized = PETSC_FALSE;
1614: }
1615: #endif
1617: #if defined(PETSC_HAVE_NVSHMEM)
1618: if (PetscBeganNvshmem) {
1619: PetscNvshmemFinalize();
1620: PetscBeganNvshmem = PETSC_FALSE;
1621: }
1622: #endif
1624: PetscFreeMPIResources();
1626: /*
1627: Destroy any known inner MPI_Comm's and attributes pointing to them
1628: Note this will not destroy any new communicators the user has created.
1630: If all PETSc objects were not destroyed those left over objects will have hanging references to
1631: the MPI_Comms that were freed; but that is ok because those PETSc objects will never be used again
1632: */
1633: {
1634: PetscCommCounter *counter;
1635: PetscMPIInt flg;
1636: MPI_Comm icomm;
1637: union {MPI_Comm comm; void *ptr;} ucomm;
1638: MPI_Comm_get_attr(PETSC_COMM_SELF,Petsc_InnerComm_keyval,&ucomm,&flg);
1639: if (flg) {
1640: icomm = ucomm.comm;
1641: MPI_Comm_get_attr(icomm,Petsc_Counter_keyval,&counter,&flg);
1644: MPI_Comm_delete_attr(PETSC_COMM_SELF,Petsc_InnerComm_keyval);
1645: MPI_Comm_delete_attr(icomm,Petsc_Counter_keyval);
1646: MPI_Comm_free(&icomm);
1647: }
1648: MPI_Comm_get_attr(PETSC_COMM_WORLD,Petsc_InnerComm_keyval,&ucomm,&flg);
1649: if (flg) {
1650: icomm = ucomm.comm;
1651: MPI_Comm_get_attr(icomm,Petsc_Counter_keyval,&counter,&flg);
1654: MPI_Comm_delete_attr(PETSC_COMM_WORLD,Petsc_InnerComm_keyval);
1655: MPI_Comm_delete_attr(icomm,Petsc_Counter_keyval);
1656: MPI_Comm_free(&icomm);
1657: }
1658: }
1660: MPI_Comm_free_keyval(&Petsc_Counter_keyval);
1661: MPI_Comm_free_keyval(&Petsc_InnerComm_keyval);
1662: MPI_Comm_free_keyval(&Petsc_OuterComm_keyval);
1663: MPI_Comm_free_keyval(&Petsc_ShmComm_keyval);
1665: PetscSpinlockDestroy(&PetscViewerASCIISpinLockOpen);
1666: PetscSpinlockDestroy(&PetscViewerASCIISpinLockStdout);
1667: PetscSpinlockDestroy(&PetscViewerASCIISpinLockStderr);
1668: PetscSpinlockDestroy(&PetscCommSpinLock);
1670: if (PetscBeganMPI) {
1671: PetscMPIInt flag;
1672: MPI_Finalized(&flag);
1674: /* wait until the very last moment to disable error handling */
1675: PetscErrorHandlingInitialized = PETSC_FALSE;
1676: MPI_Finalize();
1677: } else PetscErrorHandlingInitialized = PETSC_FALSE;
1679: /*
1681: Note: In certain cases PETSC_COMM_WORLD is never MPI_Comm_free()ed because
1682: the communicator has some outstanding requests on it. Specifically if the
1683: flag PETSC_HAVE_BROKEN_REQUEST_FREE is set (for IBM MPI implementation). See
1684: src/vec/utils/vpscat.c. Due to this the memory allocated in PetscCommDuplicate()
1685: is never freed as it should be. Thus one may obtain messages of the form
1686: [ 1] 8 bytes PetscCommDuplicate() line 645 in src/sys/mpiu.c indicating the
1687: memory was not freed.
1689: */
1690: PetscMallocClear();
1691: PetscStackReset();
1693: PetscInitializeCalled = PETSC_FALSE;
1694: PetscFinalizeCalled = PETSC_TRUE;
1695: #if defined(PETSC_USE_GCOV)
1696: /*
1697: flush gcov, otherwise during CI the flushing continues into the next pipeline resulting in git not being able to delete directories since the
1698: gcov files are still being added to the directories as git tries to remove the directories.
1699: */
1700: __gcov_flush();
1701: #endif
1703: PetscStackClearTop;
1704: return 0;
1705: }
1707: #if defined(PETSC_MISSING_LAPACK_lsame_)
1708: PETSC_EXTERN int lsame_(char *a,char *b)
1709: {
1710: if (*a == *b) return 1;
1711: if (*a + 32 == *b) return 1;
1712: if (*a - 32 == *b) return 1;
1713: return 0;
1714: }
1715: #endif
1717: #if defined(PETSC_MISSING_LAPACK_lsame)
1718: PETSC_EXTERN int lsame(char *a,char *b)
1719: {
1720: if (*a == *b) return 1;
1721: if (*a + 32 == *b) return 1;
1722: if (*a - 32 == *b) return 1;
1723: return 0;
1724: }
1725: #endif