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