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