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