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: }