Date: 2023-09-05T10:17:41+00:00

Actual source code: slepcimpl.h
slepc-3.19.2 2023-09-05
Report Typos and Errors

      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: #if !defined(SLEPCIMPL_H)
     12: #define SLEPCIMPL_H

     14: #include <slepcsys.h>
     15: #include <petsc/private/petscimpl.h>

     17: /* SUBMANSEC = sys */

     19: SLEPC_INTERN PetscBool SlepcBeganPetsc;

     21: /*@C
     22:     SlepcHeaderCreate - Creates a SLEPc object

     24:     Input Parameters:
     25: +   classid - the classid associated with this object
     26: .   class_name - string name of class; should be static
     27: .   descr - string containing short description; should be static
     28: .   mansec - string indicating section in manual pages; should be static
     29: .   comm - the MPI Communicator
     30: .   destroy - the destroy routine for this object
     31: -   view - the view routine for this object

     33:     Output Parameter:
     34: .   h - the newly created object

     36:     Note:
     37:     This is equivalent to PetscHeaderCreate but makes sure that SlepcInitialize
     38:     has been called.

     40:     Level: developer
     41: @*/
     42: #define SlepcHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
     43:     ((PetscErrorCode)((!SlepcInitializeCalled && \
     44:                        PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,PETSC_ERR_ORDER,PETSC_ERROR_INITIAL, \
     45:                                   "Must call SlepcInitialize instead of PetscInitialize to use SLEPc classes")) || \
     46:                       PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view)))

     48: /* context for monitors of type XXXMonitorConverged */
     49: struct _n_SlepcConvMon {
     50:   void     *ctx;
     51:   PetscInt oldnconv;  /* previous value of nconv */
     52: };

     54: /*
     55:   SlepcPrintEigenvalueASCII - Print an eigenvalue on an ASCII viewer.
     56: */
     57: static inline PetscErrorCode SlepcPrintEigenvalueASCII(PetscViewer viewer,PetscScalar eigr,PetscScalar eigi)
     58: {
     59:   PetscReal      re,im;

     61:   PetscFunctionBegin;
     62: #if defined(PETSC_USE_COMPLEX)
     63:   re = PetscRealPart(eigr);
     64:   im = PetscImaginaryPart(eigr);
     65:   (void)eigi;
     66: #else
     67:   re = eigr;
     68:   im = eigi;
     69: #endif
     70:   /* print zero instead of tiny value */
     71:   if (PetscAbs(im) && PetscAbs(re)/PetscAbs(im)<PETSC_SMALL) re = 0.0;
     72:   if (PetscAbs(re) && PetscAbs(im)/PetscAbs(re)<PETSC_SMALL) im = 0.0;
     73:   /* print as real if imaginary part is zero */
     74:   if (im!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%.5f%+.5fi",(double)re,(double)im));
     75:   else PetscCall(PetscViewerASCIIPrintf(viewer,"%.5f",(double)re));
     76:   PetscFunctionReturn(PETSC_SUCCESS);
     77: }

     79: /*
     80:   SlepcViewEigenvector - Outputs an eigenvector xr,xi to a viewer.
     81:   In complex scalars only xr is written.
     82:   The name of xr,xi is set before writing, based on the label, the index, and the name of obj.
     83: */
     84: static inline PetscErrorCode SlepcViewEigenvector(PetscViewer viewer,Vec xr,Vec xi,const char *label,PetscInt index,PetscObject obj)
     85: {
     86:   size_t         count;
     87:   char           vname[30];
     88:   const char     *pname;

     90:   PetscFunctionBegin;
     91:   PetscCall(PetscObjectGetName(obj,&pname));
     92:   PetscCall(PetscSNPrintfCount(vname,sizeof(vname),"%s%s",&count,label,PetscDefined(USE_COMPLEX)?"":"r"));
     93:   count--;
     94:   PetscCall(PetscSNPrintf(vname+count,sizeof(vname)-count,"%" PetscInt_FMT "_%s",index,pname));
     95:   PetscCall(PetscObjectSetName((PetscObject)xr,vname));
     96:   PetscCall(VecView(xr,viewer));
     97: #if !defined(PETSC_USE_COMPLEX)
     98:   vname[count-1] = 'i';
     99:   PetscCall(PetscObjectSetName((PetscObject)xi,vname));
    100:   PetscCall(VecView(xi,viewer));
    101: #else
    102:   (void)xi;
    103: #endif
    104:   PetscFunctionReturn(PETSC_SUCCESS);
    105: }

    107: /* Macros for strings with different value in real and complex */
    108: #if defined(PETSC_USE_COMPLEX)
    109: #define SLEPC_STRING_HERMITIAN "hermitian"
    110: #else
    111: #define SLEPC_STRING_HERMITIAN "symmetric"
    112: #endif

    114: /* Private functions that are shared by several classes */
    115: SLEPC_EXTERN PetscErrorCode SlepcBasisReference_Private(PetscInt,Vec*,PetscInt*,Vec**);
    116: SLEPC_EXTERN PetscErrorCode SlepcBasisDestroy_Private(PetscInt*,Vec**);
    117: SLEPC_EXTERN PetscErrorCode SlepcMonitorMakeKey_Internal(const char[],PetscViewerType,PetscViewerFormat,char[]);
    118: SLEPC_EXTERN PetscErrorCode PetscViewerAndFormatCreate_Internal(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);

    120: SLEPC_INTERN PetscErrorCode SlepcCitationsInitialize(void);
    121: SLEPC_INTERN PetscErrorCode SlepcInitialize_DynamicLibraries(void);
    122: SLEPC_INTERN PetscErrorCode SlepcInitialize_Packages(void);

    124: /* Definitions needed to work with CUDA kernels */
    125: #if defined(PETSC_HAVE_CUDA)
    126: #include <petscdevice_cuda.h>

    128: #define X_AXIS 0
    129: #define Y_AXIS 1

    131: #define SLEPC_TILE_SIZE_X  32
    132: #define SLEPC_BLOCK_SIZE_X 128
    133: #define SLEPC_TILE_SIZE_Y  32
    134: #define SLEPC_BLOCK_SIZE_Y 128

    136: static inline PetscErrorCode SlepcKernelSetGrid1D(PetscInt rows,dim3 *dimGrid,dim3 *dimBlock,PetscInt *dimGrid_xcount)
    137: {
    138:   int                   card;
    139:   struct cudaDeviceProp devprop;

    141:   PetscFunctionBegin;
    142:   PetscCallCUDA(cudaGetDevice(&card));
    143:   PetscCallCUDA(cudaGetDeviceProperties(&devprop,card));
    144:   *dimGrid_xcount = 1;

    146:   /* X axis */
    147:   dimGrid->x  = 1;
    148:   dimBlock->x = SLEPC_BLOCK_SIZE_X;
    149:   if (rows>SLEPC_BLOCK_SIZE_X) dimGrid->x = (rows+SLEPC_BLOCK_SIZE_X-1)/SLEPC_BLOCK_SIZE_X;
    150:   else dimBlock->x = rows;
    151:   if (dimGrid->x>(unsigned)devprop.maxGridSize[X_AXIS]) {
    152:     *dimGrid_xcount = (dimGrid->x+(devprop.maxGridSize[X_AXIS]-1))/devprop.maxGridSize[X_AXIS];
    153:     dimGrid->x = devprop.maxGridSize[X_AXIS];
    154:   }
    155:   PetscFunctionReturn(PETSC_SUCCESS);
    156: }

    158: static inline PetscErrorCode SlepcKernelSetGrid2DTiles(PetscInt rows,PetscInt cols,dim3 *dimGrid,dim3 *dimBlock,PetscInt *dimGrid_xcount,PetscInt *dimGrid_ycount)
    159: {
    160:   int                   card;
    161:   struct cudaDeviceProp devprop;

    163:   PetscFunctionBegin;
    164:   PetscCallCUDA(cudaGetDevice(&card));
    165:   PetscCallCUDA(cudaGetDeviceProperties(&devprop,card));
    166:   *dimGrid_xcount = *dimGrid_ycount = 1;

    168:   /* X axis */
    169:   dimGrid->x  = 1;
    170:   dimBlock->x = SLEPC_BLOCK_SIZE_X;
    171:   if (rows>SLEPC_BLOCK_SIZE_X*SLEPC_TILE_SIZE_X) dimGrid->x = (rows+SLEPC_BLOCK_SIZE_X*SLEPC_TILE_SIZE_X-1)/(SLEPC_BLOCK_SIZE_X*SLEPC_TILE_SIZE_X);
    172:   else dimBlock->x = (rows+SLEPC_TILE_SIZE_X-1)/SLEPC_TILE_SIZE_X;
    173:   if (dimGrid->x>(unsigned)devprop.maxGridSize[X_AXIS]) {
    174:     *dimGrid_xcount = (dimGrid->x+(devprop.maxGridSize[X_AXIS]-1))/devprop.maxGridSize[X_AXIS];
    175:     dimGrid->x = devprop.maxGridSize[X_AXIS];
    176:   }

    178:   /* Y axis */
    179:   dimGrid->y  = 1;
    180:   dimBlock->y = SLEPC_BLOCK_SIZE_Y;
    181:   if (cols>SLEPC_BLOCK_SIZE_Y*SLEPC_TILE_SIZE_Y) dimGrid->y = (cols+SLEPC_BLOCK_SIZE_Y*SLEPC_TILE_SIZE_Y-1)/(SLEPC_BLOCK_SIZE_Y*SLEPC_TILE_SIZE_Y);
    182:   else dimBlock->y = (cols+SLEPC_TILE_SIZE_Y-1)/SLEPC_TILE_SIZE_Y;
    183:   if (dimGrid->y>(unsigned)devprop.maxGridSize[Y_AXIS]) {
    184:     *dimGrid_ycount = (dimGrid->y+(devprop.maxGridSize[Y_AXIS]-1))/devprop.maxGridSize[Y_AXIS];
    185:     dimGrid->y = devprop.maxGridSize[Y_AXIS];
    186:   }
    187:   PetscFunctionReturn(PETSC_SUCCESS);
    188: }
    189: #undef X_AXIS
    190: #undef Y_AXIS
    191: #endif

    193: #endif