Actual source code: slepcinit.c
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7: SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9: */
11: #include <slepc/private/slepcimpl.h>
12: #include <slepcconfiginfo.h>
14: #if defined(SLEPC_HAVE_HPDDM)
15: #include <petscksp.h>
16: SLEPC_EXTERN PetscErrorCode KSPCreate_HPDDM(KSP);
17: SLEPC_EXTERN PetscErrorCode PCCreate_HPDDM(PC);
18: #endif
20: /*@
21: SlepcGetVersion - Gets the SLEPc version information in a string.
23: Not Collective
25: Input Parameter:
26: . len - length of the string
28: Output Parameter:
29: . version - version string
31: Level: intermediate
33: .seealso: [](sec:writing-prog), `SlepcGetVersionNumber()`
34: @*/
35: PetscErrorCode SlepcGetVersion(char version[],size_t len)
36: {
37: PetscFunctionBegin;
38: #if (SLEPC_VERSION_RELEASE == 1)
39: PetscCall(PetscSNPrintf(version,len,"SLEPc Release Version %d.%d.%d, %s",SLEPC_VERSION_MAJOR,SLEPC_VERSION_MINOR,SLEPC_VERSION_SUBMINOR,SLEPC_VERSION_DATE));
40: #else
41: PetscCall(PetscSNPrintf(version,len,"SLEPc Development Git Revision: %s Git Date: %s",SLEPC_VERSION_GIT,SLEPC_VERSION_DATE_GIT));
42: #endif
43: PetscFunctionReturn(PETSC_SUCCESS);
44: }
46: /*@
47: SlepcGetVersionNumber - Gets the SLEPc version information from the library.
49: Not Collective
51: Output Parameters:
52: + major - the major version
53: . minor - the minor version
54: . subminor - the subminor version (patch number)
55: - release - indicates the library is from a release
57: Notes:
58: Pass `NULL` in any argument that is not requested.
60: The C macros `SLEPC_VERSION_MAJOR`, `SLEPC_VERSION_MINOR`, `SLEPC_VERSION_SUBMINOR`,
61: `SLEPC_VERSION_RELEASE` provide the information at compile time. This can be used to confirm
62: that the shared library being loaded at runtime has the appropriate version updates.
64: This function can be called before `SlepcInitialize()`.
66: Level: intermediate
68: .seealso: [](sec:writing-prog), `SlepcGetVersion()`, `SlepcInitialize()`
69: @*/
70: PetscErrorCode SlepcGetVersionNumber(PetscInt *major,PetscInt *minor,PetscInt *subminor,PetscInt *release)
71: {
72: if (major) *major = SLEPC_VERSION_MAJOR;
73: if (minor) *minor = SLEPC_VERSION_MINOR;
74: if (subminor) *subminor = SLEPC_VERSION_SUBMINOR;
75: if (release) *release = SLEPC_VERSION_RELEASE;
76: return PETSC_SUCCESS;
77: }
79: /*@
80: SlepcGetConfiguration - Gets the SLEPc configuration information in a string.
82: Not Collective
84: Output Parameter:
85: . configuration - configuration string
87: Level: developer
89: .seealso: `SlepcGetVersionNumber()`
90: @*/
91: PetscErrorCode SlepcGetConfiguration(const char *configuration[])
92: {
93: PetscFunctionBegin;
94: *configuration = slepcconfigureoptions;
95: PetscFunctionReturn(PETSC_SUCCESS);
96: }
98: /*
99: SlepcPrintVersion - Prints SLEPc version info.
101: Collective
102: */
103: static PetscErrorCode SlepcPrintVersion(MPI_Comm comm)
104: {
105: char version[256];
107: PetscFunctionBegin;
108: PetscCall(SlepcGetVersion(version,256));
109: PetscCall((*PetscHelpPrintf)(comm,"%s\n",version));
110: PetscCall((*PetscHelpPrintf)(comm,SLEPC_AUTHOR_INFO));
111: PetscCall((*PetscHelpPrintf)(comm,"See https://slepc.upv.es/documentation/ for help.\n"));
112: PetscCall((*PetscHelpPrintf)(comm,"SLEPc libraries linked from %s\n",SLEPC_LIB_DIR));
113: PetscFunctionReturn(PETSC_SUCCESS);
114: }
116: /*
117: SlepcPrintHelpIntro - Prints introductory SLEPc help info.
119: Collective
120: */
121: static PetscErrorCode SlepcPrintHelpIntro(MPI_Comm comm)
122: {
123: PetscFunctionBegin;
124: PetscCall((*PetscHelpPrintf)(comm,"SLEPc help information includes that for the PETSc libraries, which provide\n"));
125: PetscCall((*PetscHelpPrintf)(comm,"low-level system infrastructure and linear algebra tools.\n"));
126: PetscCall((*PetscHelpPrintf)(comm,"----------------------------------------\n"));
127: PetscFunctionReturn(PETSC_SUCCESS);
128: }
130: /* ------------------------Nasty global variables -------------------------------*/
131: /*
132: Indicates whether SLEPc started PETSc, or whether it was
133: already started before SLEPc was initialized.
134: */
135: PetscBool SlepcBeganPetsc = PETSC_FALSE;
136: PetscBool SlepcInitializeCalled = PETSC_FALSE;
137: PetscBool SlepcFinalizeCalled = PETSC_FALSE;
139: #if PetscDefined(HAVE_DYNAMIC_LIBRARIES) && PetscDefined(USE_SHARED_LIBRARIES)
140: static PetscErrorCode SlepcLoadDynamicLibrary(const char *name,PetscBool *found)
141: {
142: char libs[PETSC_MAX_PATH_LEN],dlib[PETSC_MAX_PATH_LEN];
144: PetscFunctionBegin;
145: PetscCall(PetscStrcpy(libs,SLEPC_LIB_DIR));
146: PetscCall(PetscStrlcat(libs,"/libslepc",sizeof(libs)));
147: PetscCall(PetscStrlcat(libs,name,sizeof(libs)));
148: #if defined(PETSC_LIB_NAME_SUFFIX)
149: PetscCall(PetscStrlcat(libs,PETSC_LIB_NAME_SUFFIX,sizeof(libs)));
150: #endif
151: PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,sizeof(dlib),found));
152: if (*found) PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib));
153: PetscFunctionReturn(PETSC_SUCCESS);
154: }
155: #endif
157: #if PetscDefined(USE_SINGLE_LIBRARY) && !(PetscDefined(HAVE_DYNAMIC_LIBRARIES) && PetscDefined(USE_SHARED_LIBRARIES))
158: SLEPC_EXTERN PetscErrorCode STInitializePackage(void);
159: SLEPC_EXTERN PetscErrorCode DSInitializePackage(void);
160: SLEPC_EXTERN PetscErrorCode FNInitializePackage(void);
161: SLEPC_EXTERN PetscErrorCode BVInitializePackage(void);
162: SLEPC_EXTERN PetscErrorCode RGInitializePackage(void);
163: SLEPC_EXTERN PetscErrorCode EPSInitializePackage(void);
164: SLEPC_EXTERN PetscErrorCode SVDInitializePackage(void);
165: SLEPC_EXTERN PetscErrorCode PEPInitializePackage(void);
166: SLEPC_EXTERN PetscErrorCode NEPInitializePackage(void);
167: SLEPC_EXTERN PetscErrorCode MFNInitializePackage(void);
168: SLEPC_EXTERN PetscErrorCode LMEInitializePackage(void);
169: #endif
171: /*
172: SlepcInitialize_DynamicLibraries - Adds the default dynamic link libraries to the
173: search path.
174: */
175: PetscErrorCode SlepcInitialize_DynamicLibraries(void)
176: {
177: PetscBool preload = PETSC_FALSE;
179: PetscFunctionBegin;
180: #if PetscDefined(HAVE_THREADSAFETY)
181: /* These must be all initialized here because it is not safe for individual threads to call these initialize routines */
182: preload = PETSC_TRUE;
183: #endif
185: PetscCall(PetscOptionsGetBool(NULL,NULL,"-library_preload",&preload,NULL));
186: if (preload) {
187: #if PetscDefined(HAVE_DYNAMIC_LIBRARIES) && PetscDefined(USE_SHARED_LIBRARIES)
188: PetscBool found;
189: #if PetscDefined(USE_SINGLE_LIBRARY)
190: PetscCall(SlepcLoadDynamicLibrary("",&found));
191: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc dynamic library. You cannot move the dynamic libraries!");
192: #else
193: PetscCall(SlepcLoadDynamicLibrary("sys",&found));
194: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc sys dynamic library. You cannot move the dynamic libraries!");
195: PetscCall(SlepcLoadDynamicLibrary("eps",&found));
196: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc EPS dynamic library. You cannot move the dynamic libraries!");
197: PetscCall(SlepcLoadDynamicLibrary("pep",&found));
198: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc PEP dynamic library. You cannot move the dynamic libraries!");
199: PetscCall(SlepcLoadDynamicLibrary("nep",&found));
200: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc NEP dynamic library. You cannot move the dynamic libraries!");
201: PetscCall(SlepcLoadDynamicLibrary("svd",&found));
202: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc SVD dynamic library. You cannot move the dynamic libraries!");
203: PetscCall(SlepcLoadDynamicLibrary("mfn",&found));
204: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc MFN dynamic library. You cannot move the dynamic libraries!");
205: PetscCall(SlepcLoadDynamicLibrary("lme",&found));
206: PetscCheck(found,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate SLEPc LME dynamic library. You cannot move the dynamic libraries!");
207: #endif
208: #else /* PetscDefined(HAVE_DYNAMIC_LIBRARIES) && PetscDefined(USE_SHARED_LIBRARIES) */
209: #if PetscDefined(USE_SINGLE_LIBRARY)
210: PetscCall(STInitializePackage());
211: PetscCall(DSInitializePackage());
212: PetscCall(FNInitializePackage());
213: PetscCall(BVInitializePackage());
214: PetscCall(RGInitializePackage());
215: PetscCall(EPSInitializePackage());
216: PetscCall(SVDInitializePackage());
217: PetscCall(PEPInitializePackage());
218: PetscCall(NEPInitializePackage());
219: PetscCall(MFNInitializePackage());
220: PetscCall(LMEInitializePackage());
221: #else
222: SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Cannot use -library_preload with multiple static SLEPc libraries");
223: #endif
224: #endif /* PetscDefined(HAVE_DYNAMIC_LIBRARIES) && PetscDefined(USE_SHARED_LIBRARIES) */
225: }
227: #if defined(SLEPC_HAVE_HPDDM)
228: PetscCall(KSPRegister(KSPHPDDM,KSPCreate_HPDDM));
229: PetscCall(PCRegister(PCHPDDM,PCCreate_HPDDM));
230: #endif
231: PetscFunctionReturn(PETSC_SUCCESS);
232: }
234: PetscErrorCode SlepcCitationsInitialize(void)
235: {
236: PetscFunctionBegin;
237: PetscCall(PetscCitationsRegister("@Article{slepc-toms,\n"
238: " author = \"Vicente Hernandez and Jose E. Roman and Vicente Vidal\",\n"
239: " title = \"{SLEPc}: A Scalable and Flexible Toolkit for the Solution of Eigenvalue Problems\",\n"
240: " journal = \"{ACM} Trans. Math. Software\",\n"
241: " volume = \"31\",\n"
242: " number = \"3\",\n"
243: " pages = \"351--362\",\n"
244: " year = \"2005\",\n"
245: " doi = \"https://doi.org/10.1145/1089014.1089019\"\n"
246: "}\n",NULL));
247: PetscCall(PetscCitationsRegister("@TechReport{slepc-manual,\n"
248: " author = \"J. E. Roman and C. Campos and L. Dalcin and E. Romero and A. Tomas\",\n"
249: " title = \"{SLEPc} Users Manual\",\n"
250: " number = \"DSIC-II/24/02 - Revision 3.26\",\n"
251: " institution = \"D. Sistemes Inform\\`atics i Computaci\\'o, Universitat Polit\\`ecnica de Val\\`encia\",\n"
252: " year = \"2026\"\n"
253: "}\n",NULL));
254: PetscFunctionReturn(PETSC_SUCCESS);
255: }
257: /*@
258: SlepcInitialize - Initializes the SLEPc library. `SlepcInitialize()` calls
259: `PetscInitialize()` if it has not been called yet, so this function should
260: always be called near the beginning of your program.
262: Collective on `MPI_COMM_WORLD` or `PETSC_COMM_WORLD` if it has been set
264: Input Parameters:
265: + argc - count of number of command line arguments
266: . args - the command line arguments
267: . file - [optional] PETSc database file
268: - help - [optional] Help message to print, use `NULL` for no message
270: Note:
271: Works in the same way as `PetscInitialize()`, but in addition initializes SLEPc.
272: The same considerations apply with respect to command line options and
273: environment variables.
275: Fortran Notes:
276: In Fortran this routine can be called with
277: .vb
278: call SlepcInitialize(ierr)
279: .ve
280: .vb
281: call SlepcInitialize(file,ierr)
282: .ve
283: or
284: .vb
285: call SlepcInitialize(file,help,ierr)
286: .ve
288: If your main program is C but you call Fortran code that also uses SLEPc you need
289: to call `SlepcInitializeFortran()` soon after calling `SlepcInitialize()`.
291: Level: beginner
293: .seealso: [](sec:writing-prog), `SlepcFinalize()`, `PetscInitialize()`, `SlepcInitializeFortran()`
294: @*/
295: PetscErrorCode SlepcInitialize(int *argc,char ***args,const char file[],const char help[])
296: {
297: PetscBool flg;
299: PetscFunctionBegin;
300: if (SlepcInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
301: PetscCall(PetscSetHelpVersionFunctions(SlepcPrintHelpIntro,SlepcPrintVersion));
302: PetscCall(PetscInitialized(&flg));
303: if (!flg) {
304: PetscCall(PetscInitialize(argc,args,file,help));
305: SlepcBeganPetsc = PETSC_TRUE;
306: }
308: PetscCall(SlepcCitationsInitialize());
310: /* Load the dynamic libraries (on machines that support them), this registers all the solvers etc. */
311: PetscCall(SlepcInitialize_DynamicLibraries());
313: SlepcInitializeCalled = PETSC_TRUE;
314: SlepcFinalizeCalled = PETSC_FALSE;
315: PetscCall(PetscInfo(0,"SLEPc successfully started\n"));
316: PetscFunctionReturn(PETSC_SUCCESS);
317: }
319: /*@
320: SlepcFinalize - Checks for options to be called at the conclusion
321: of the SLEPc program and calls `PetscFinalize()`.
323: Collective on `PETSC_COMM_WORLD`
325: Level: beginner
327: .seealso: [](sec:writing-prog), `SlepcInitialize()`, `PetscFinalize()`
328: @*/
329: PetscErrorCode SlepcFinalize(void)
330: {
331: PetscFunctionBegin;
332: if (PetscUnlikely(!SlepcInitializeCalled)) {
333: fprintf(PETSC_STDOUT,"SlepcInitialize() must be called before SlepcFinalize()\n");
334: PetscStackClearTop;
335: return PETSC_ERR_ARG_WRONGSTATE;
336: }
337: PetscCall(PetscInfo(NULL,"SlepcFinalize() called\n"));
338: if (SlepcBeganPetsc) {
339: PetscCall(PetscFinalize());
340: SlepcBeganPetsc = PETSC_FALSE;
341: }
342: SlepcInitializeCalled = PETSC_FALSE;
343: SlepcFinalizeCalled = PETSC_TRUE;
344: PetscStackClearTop;
345: return PETSC_SUCCESS;
346: }
348: /*@
349: SlepcInitializeNoArguments - Calls `SlepcInitialize()` from C/C++ without
350: the command line arguments.
352: Collective
354: Level: advanced
356: .seealso: [](sec:writing-prog), `SlepcInitialize()`, `SlepcInitializeFortran()`
357: @*/
358: PetscErrorCode SlepcInitializeNoArguments(void) PeNS
359: {
360: int argc = 0;
361: char **args = NULL;
363: PetscFunctionBegin;
364: PetscCall(SlepcInitialize(&argc,&args,NULL,NULL));
365: PetscFunctionReturn(PETSC_SUCCESS);
366: }
368: /*@
369: SlepcInitialized - Determine whether SLEPc is initialized.
371: Output Parameter:
372: . isInitialized - the result
374: Level: beginner
376: .seealso: [](sec:writing-prog), `SlepcInitialize()`, `SlepcInitializeFortran()`
377: @*/
378: PetscErrorCode SlepcInitialized(PetscBool *isInitialized)
379: {
380: PetscFunctionBegin;
381: *isInitialized = SlepcInitializeCalled;
382: PetscFunctionReturn(PETSC_SUCCESS);
383: }
385: /*@
386: SlepcFinalized - Determine whether `SlepcFinalize()` has been called.
388: Output Parameter:
389: . isFinalized - the result
391: Level: beginner
393: .seealso: [](sec:writing-prog), `SlepcFinalize()`
394: @*/
395: PetscErrorCode SlepcFinalized(PetscBool *isFinalized)
396: {
397: PetscFunctionBegin;
398: *isFinalized = SlepcFinalizeCalled;
399: PetscFunctionReturn(PETSC_SUCCESS);
400: }
402: PETSC_EXTERN PetscBool PetscBeganMPI;
404: /*@
405: SlepcInitializeNoPointers - Calls `SlepcInitialize()` from C/C++ without the pointers
406: to `argc` and `args`.
408: Collective
410: Input Parameters:
411: + argc - count of number of command line arguments
412: . args - the command line arguments
413: . file - [optional] PETSc database file
414: - help - [optional] Help message to print, use `NULL` for no message
416: Note:
417: Check the manual page of `PetscInitializeNoPointers()` for an explanation.
419: Level: advanced
421: .seealso: [](sec:writing-prog), `SlepcInitialize()`
422: @*/
423: PetscErrorCode SlepcInitializeNoPointers(int argc,char **args,const char *file,const char *help)
424: {
425: int myargc = argc;
426: char **myargs = args;
428: PetscFunctionBegin;
429: PetscCall(SlepcInitialize(&myargc,&myargs,file,help));
430: PetscCall(PetscPopSignalHandler());
431: PetscBeganMPI = PETSC_FALSE;
432: PetscFunctionReturn(PETSC_SUCCESS);
433: }