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