LCOV - code coverage report
Current view: top level - svd/impls/external/primme - svdprimme.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 212 234 90.6 %
Date: 2020-05-28 03:14:05 Functions: 18 20 90.0 %

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-2020, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : /*
      11             :    This file implements a wrapper to the PRIMME SVD solver
      12             : */
      13             : 
      14             : #include <slepc/private/svdimpl.h>    /*I "slepcsvd.h" I*/
      15             : 
      16             : #include <primme.h>
      17             : 
      18             : #if defined(PETSC_USE_COMPLEX)
      19             : #if defined(PETSC_USE_REAL_SINGLE)
      20             : #define PRIMME_DRIVER cprimme_svds
      21             : #else
      22             : #define PRIMME_DRIVER zprimme_svds
      23             : #endif
      24             : #else
      25             : #if defined(PETSC_USE_REAL_SINGLE)
      26             : #define PRIMME_DRIVER sprimme_svds
      27             : #else
      28             : #define PRIMME_DRIVER dprimme_svds
      29             : #endif
      30             : #endif
      31             : 
      32             : #if defined(PRIMME_VERSION_MAJOR) && PRIMME_VERSION_MAJOR*100+PRIMME_VERSION_MINOR >= 202
      33             : #define SLEPC_HAVE_PRIMME2p2
      34             : #endif
      35             : 
      36             : typedef struct {
      37             :   primme_svds_params        primme;   /* param struct */
      38             :   PetscInt                  bs;       /* block size */
      39             :   primme_svds_preset_method method;   /* primme method */
      40             :   SVD                       svd;      /* reference to the solver */
      41             :   Vec                       x,y;      /* auxiliary vectors */
      42             : } SVD_PRIMME;
      43             : 
      44             : static void multMatvec_PRIMME(void*,PRIMME_INT*,void*,PRIMME_INT*,int*,int*,struct primme_svds_params*,int*);
      45             : 
      46          30 : static void par_GlobalSumReal(void *sendBuf,void *recvBuf,int *count,primme_svds_params *primme,int *ierr)
      47             : {
      48          30 :   if (sendBuf == recvBuf) {
      49          60 :     *ierr = MPI_Allreduce(MPI_IN_PLACE,recvBuf,*count,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)primme->commInfo));CHKERRABORT(PetscObjectComm((PetscObject)primme->commInfo),*ierr);
      50             :   } else {
      51           0 :     *ierr = MPI_Allreduce(sendBuf,recvBuf,*count,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)primme->commInfo));CHKERRABORT(PetscObjectComm((PetscObject)primme->commInfo),*ierr);
      52             :   }
      53          30 : }
      54             : 
      55             : #if defined(SLEPC_HAVE_PRIMME3)
      56           0 : static void par_broadcastReal(void *buf,int *count,primme_svds_params *primme,int *ierr)
      57             : {
      58           0 :   *ierr = MPI_Bcast(buf,*count,MPIU_REAL,0/*root*/,PetscObjectComm((PetscObject)primme->commInfo));CHKERRABORT(PetscObjectComm((PetscObject)primme->commInfo),*ierr);
      59           0 : }
      60             : #endif
      61             : 
      62             : #if defined(SLEPC_HAVE_PRIMME2p2)
      63         551 : static void convTestFun(double *sval,void *leftsvec,void *rightsvec,double *resNorm,
      64             : #if defined(SLEPC_HAVE_PRIMME3)
      65             :                         int *method,
      66             : #endif
      67             :                         int *isconv,struct primme_svds_params *primme,int *err)
      68             : {
      69             :   PetscErrorCode ierr;
      70         551 :   SVD            svd = (SVD)primme->commInfo;
      71         551 :   PetscReal      sigma = sval?*sval:0.0;
      72         551 :   PetscReal      r = resNorm?*resNorm:HUGE_VAL,errest;
      73             : 
      74         551 :   *err = 1;
      75         551 :   ierr = (*svd->converged)(svd,sigma,r,&errest,svd->convergedctx);CHKERRABORT(PetscObjectComm((PetscObject)svd),ierr);
      76         551 :   *isconv = (errest<=svd->tol?1:0);
      77         551 :   *err = 0;
      78         551 : }
      79             : 
      80         474 : static void monitorFun(void *basisSvals,int *basisSize,int *basisFlags,int *iblock,int *blockSize,void *basisNorms,int *numConverged,void *lockedSvals,int *numLocked,int *lockedFlags,void *lockedNorms,int *inner_its,void *LSRes,
      81             : #if defined(SLEPC_HAVE_PRIMME3)
      82             :                        const char *msg,double *time,
      83             : #endif
      84             :                        primme_event *event,int *stage,struct primme_svds_params *primme,int *err)
      85             : {
      86             : 
      87             :   PetscErrorCode ierr;
      88         474 :   SVD            svd = (SVD)primme->commInfo;
      89             :   PetscInt       i,k,nerrest;
      90             : 
      91         474 :   *err = 1;
      92         474 :   switch (*event) {
      93             :     case primme_event_outer_iteration:
      94             :       /* Update SVD */
      95          87 :       svd->its = primme->stats.numOuterIterations;
      96          87 :       if (numConverged) svd->nconv = *numConverged;
      97          87 :       k = 0;
      98          87 :       if (lockedSvals && numLocked) for (i=0; i<*numLocked && k<svd->ncv; i++) svd->sigma[k++] = ((PetscReal*)lockedSvals)[i];
      99          87 :       nerrest = k;
     100          87 :       if (iblock && blockSize) {
     101         128 :         for (i=0; i<*blockSize && k+iblock[i]<svd->ncv; i++) svd->errest[k+iblock[i]] = ((PetscReal*)basisNorms)[i];
     102          87 :         nerrest = k+(*blockSize>0?1+iblock[*blockSize-1]:0);
     103             :       }
     104          87 :       if (basisSvals && basisSize) for (i=0; i<*basisSize && k<svd->ncv; i++) svd->sigma[k++] = ((PetscReal*)basisSvals)[i];
     105             :       /* Show progress */
     106          87 :       ierr = SVDMonitor(svd,svd->its,numConverged?*numConverged:0,svd->sigma,svd->errest,nerrest);CHKERRABORT(PetscObjectComm((PetscObject)svd),ierr);
     107             :       break;
     108             : #if defined(SLEPC_HAVE_PRIMME3)
     109             :     case primme_event_message:
     110             :       /* Print PRIMME information messages */
     111           0 :       ierr = PetscInfo(svd,msg);CHKERRABORT(PetscObjectComm((PetscObject)svd),ierr);
     112             :       break;
     113             : #endif
     114             :     default:
     115             :       break;
     116             :   }
     117         474 :   *err = 0;
     118         474 : }
     119             : #endif /* SLEPC_HAVE_PRIMME2p2 */
     120             : 
     121         930 : static void multMatvec_PRIMME(void *xa,PRIMME_INT *ldx,void *ya,PRIMME_INT *ldy,int *blockSize,int *transpose,struct primme_svds_params *primme,int *ierr)
     122             : {
     123             :   PetscInt   i;
     124         930 :   SVD_PRIMME *ops = (SVD_PRIMME*)primme->matrix;
     125         930 :   Vec        x = ops->x,y = ops->y;
     126         930 :   SVD        svd = ops->svd;
     127             : 
     128         930 :   PetscFunctionBegin;
     129        1256 :   for (i=0;i<*blockSize;i++) {
     130        1256 :     if (*transpose) {
     131         616 :       *ierr = VecPlaceArray(y,(PetscScalar*)xa+(*ldx)*i);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     132         616 :       *ierr = VecPlaceArray(x,(PetscScalar*)ya+(*ldy)*i);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     133         616 :       *ierr = SVDMatMult(svd,PETSC_TRUE,y,x);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     134             :     } else {
     135         640 :       *ierr = VecPlaceArray(x,(PetscScalar*)xa+(*ldx)*i);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     136         640 :       *ierr = VecPlaceArray(y,(PetscScalar*)ya+(*ldy)*i);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     137         640 :       *ierr = SVDMatMult(svd,PETSC_FALSE,x,y);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     138             :     }
     139        1256 :     *ierr = VecResetArray(x);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     140        1256 :     *ierr = VecResetArray(y);CHKERRABORT(PetscObjectComm((PetscObject)svd),*ierr);
     141             :   }
     142         930 :   PetscFunctionReturnVoid();
     143             : }
     144             : 
     145           6 : PetscErrorCode SVDSetUp_PRIMME(SVD svd)
     146             : {
     147             :   PetscErrorCode     ierr;
     148             :   PetscMPIInt        numProcs,procID;
     149             :   PetscInt           n,m,nloc,mloc;
     150           6 :   SVD_PRIMME         *ops = (SVD_PRIMME*)svd->data;
     151           6 :   primme_svds_params *primme = &ops->primme;
     152             : 
     153           6 :   PetscFunctionBegin;
     154           6 :   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)svd),&numProcs);CHKERRQ(ierr);
     155           6 :   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)svd),&procID);CHKERRQ(ierr);
     156             : 
     157             :   /* Check some constraints and set some default values */
     158           6 :   ierr = SVDMatGetSize(svd,&m,&n);CHKERRQ(ierr);
     159           6 :   ierr = SVDMatGetLocalSize(svd,&mloc,&nloc);CHKERRQ(ierr);
     160           6 :   ierr = SVDSetDimensions_Default(svd);CHKERRQ(ierr);
     161           6 :   if (svd->max_it==PETSC_DEFAULT) svd->max_it = PETSC_MAX_INT;
     162           6 :   svd->leftbasis = PETSC_TRUE;
     163           6 :   SVDCheckUnsupported(svd,SVD_FEATURE_STOPPING);
     164             : #if !defined(SLEPC_HAVE_PRIMME2p2)
     165             :   if (svd->converged != SVDConvergedAbsolute) { ierr = PetscInfo(svd,"Warning: using absolute convergence test\n");CHKERRQ(ierr); }
     166             : #endif
     167             : 
     168             :   /* Transfer SLEPc options to PRIMME options */
     169           6 :   primme_svds_free(primme);
     170           6 :   primme_svds_initialize(primme);
     171           6 :   primme->m             = m;
     172           6 :   primme->n             = n;
     173           6 :   primme->mLocal        = mloc;
     174           6 :   primme->nLocal        = nloc;
     175           6 :   primme->numSvals      = svd->nsv;
     176           6 :   primme->matrix        = ops;
     177           6 :   primme->commInfo      = svd;
     178           6 :   primme->maxMatvecs    = svd->max_it;
     179             : #if !defined(SLEPC_HAVE_PRIMME2p2)
     180             :   primme->eps           = svd->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:svd->tol;
     181             : #endif
     182           6 :   primme->numProcs      = numProcs;
     183           6 :   primme->procID        = procID;
     184           6 :   primme->printLevel    = 1;
     185           6 :   primme->matrixMatvec  = multMatvec_PRIMME;
     186           6 :   primme->globalSumReal = par_GlobalSumReal;
     187             : #if defined(SLEPC_HAVE_PRIMME3)
     188           6 :   primme->broadcastReal = par_broadcastReal;
     189             : #endif
     190             : #if defined(SLEPC_HAVE_PRIMME2p2)
     191           6 :   primme->convTestFun   = convTestFun;
     192           6 :   primme->monitorFun    = monitorFun;
     193             : #endif
     194           6 :   if (ops->bs > 0) primme->maxBlockSize = ops->bs;
     195             : 
     196           6 :   switch (svd->which) {
     197             :     case SVD_LARGEST:
     198           5 :       primme->target = primme_svds_largest;
     199           5 :       break;
     200             :     case SVD_SMALLEST:
     201           1 :       primme->target = primme_svds_smallest;
     202           1 :       break;
     203             :     default:
     204           0 :       SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_SUP,"'which' value not supported by PRIMME");
     205             :       break;
     206             :   }
     207             : 
     208             :   /* If user sets mpd or ncv, maxBasisSize is modified */
     209           6 :   if (svd->mpd!=PETSC_DEFAULT) {
     210           6 :     primme->maxBasisSize = svd->mpd;
     211           6 :     if (svd->ncv!=PETSC_DEFAULT) { ierr = PetscInfo(svd,"Warning: 'ncv' is ignored by PRIMME\n");CHKERRQ(ierr); }
     212           0 :   } else if (svd->ncv!=PETSC_DEFAULT) primme->maxBasisSize = svd->ncv;
     213             : 
     214           6 :   if (primme_svds_set_method(ops->method,(primme_preset_method)EPS_PRIMME_DEFAULT_MIN_TIME,PRIMME_DEFAULT_METHOD,primme) < 0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_SUP,"PRIMME method not valid");
     215             : 
     216           6 :   svd->mpd = primme->maxBasisSize;
     217           6 :   svd->ncv = (primme->locking?svd->nsv:0)+primme->maxBasisSize;
     218           6 :   ops->bs  = primme->maxBlockSize;
     219             : 
     220             :   /* Set workspace */
     221           6 :   ierr = SVDAllocateSolution(svd,0);CHKERRQ(ierr);
     222             : 
     223             :   /* Prepare auxiliary vectors */
     224           6 :   if (!ops->x) {
     225           5 :     ierr = MatCreateVecsEmpty(svd->A,&ops->x,&ops->y);CHKERRQ(ierr);
     226           5 :     ierr = PetscLogObjectParent((PetscObject)svd,(PetscObject)ops->x);CHKERRQ(ierr);
     227           5 :     ierr = PetscLogObjectParent((PetscObject)svd,(PetscObject)ops->y);CHKERRQ(ierr);
     228             :   }
     229           6 :   PetscFunctionReturn(0);
     230             : }
     231             : 
     232           6 : PetscErrorCode SVDSolve_PRIMME(SVD svd)
     233             : {
     234             :   PetscErrorCode ierr;
     235           6 :   SVD_PRIMME     *ops = (SVD_PRIMME*)svd->data;
     236             :   PetscScalar    *svecs, *a;
     237             :   PetscInt       i,ierrprimme;
     238             :   PetscReal      *svals,*rnorms;
     239             : 
     240           6 :   PetscFunctionBegin;
     241             :   /* Reset some parameters left from previous runs */
     242           6 :   ops->primme.aNorm    = 0.0;
     243           6 :   ops->primme.initSize = svd->nini;
     244           6 :   ops->primme.iseed[0] = -1;
     245           6 :   ops->primme.iseed[1] = -1;
     246           6 :   ops->primme.iseed[2] = -1;
     247           6 :   ops->primme.iseed[3] = -1;
     248             : 
     249             :   /* Allocating left and right singular vectors contiguously */
     250           6 :   ierr = PetscCalloc1(ops->primme.numSvals*(ops->primme.mLocal+ops->primme.nLocal),&svecs);CHKERRQ(ierr);
     251           6 :   ierr = PetscLogObjectMemory((PetscObject)svd,sizeof(PetscReal)*ops->primme.numSvals*(ops->primme.mLocal+ops->primme.nLocal));CHKERRQ(ierr);
     252             : 
     253             :   /* Call PRIMME solver */
     254           6 :   ierr = PetscMalloc2(svd->ncv,&svals,svd->ncv,&rnorms);CHKERRQ(ierr);
     255           6 :   ierrprimme = PRIMME_DRIVER(svals,svecs,rnorms,&ops->primme);
     256           6 :   for (i=0;i<svd->ncv;i++) svd->sigma[i] = svals[i];
     257          88 :   for (i=0;i<svd->ncv;i++) svd->errest[i] = rnorms[i];
     258           6 :   ierr = PetscFree2(svals,rnorms);CHKERRQ(ierr);
     259             : 
     260             :   /* Copy left and right singular vectors into svd */
     261           6 :   ierr = BVGetArray(svd->U,&a);CHKERRQ(ierr);
     262           6 :   ierr = PetscArraycpy(a,svecs,ops->primme.mLocal*ops->primme.initSize);CHKERRQ(ierr);
     263           6 :   ierr = BVRestoreArray(svd->U,&a);CHKERRQ(ierr);
     264             : 
     265           6 :   ierr = BVGetArray(svd->V,&a);CHKERRQ(ierr);
     266           6 :   ierr = PetscArraycpy(a,svecs+ops->primme.mLocal*ops->primme.initSize,ops->primme.nLocal*ops->primme.initSize);CHKERRQ(ierr);
     267           6 :   ierr = BVRestoreArray(svd->V,&a);CHKERRQ(ierr);
     268             : 
     269           6 :   ierr = PetscFree(svecs);CHKERRQ(ierr);
     270             : 
     271           6 :   svd->nconv  = ops->primme.initSize >= 0 ? ops->primme.initSize : 0;
     272           6 :   svd->reason = svd->nconv >= svd->nsv ? SVD_CONVERGED_TOL: SVD_DIVERGED_ITS;
     273           6 :   svd->its    = ops->primme.stats.numOuterIterations;
     274             : 
     275             :   /* Process PRIMME error code */
     276           6 :   if (ierrprimme == 0) {
     277             :     /* no error */
     278           0 :   } else if (ierrprimme%100 == -1) SETERRQ1(PetscObjectComm((PetscObject)svd),PETSC_ERR_LIB,"PRIMME library failed with error code=%d: unexpected error",ierrprimme);
     279           0 :   else if (ierrprimme%100 == -2) SETERRQ1(PetscObjectComm((PetscObject)svd),PETSC_ERR_LIB,"PRIMME library failed with error code=%d: allocation error",ierrprimme);
     280           0 :   else if (ierrprimme%100 == -3) {
     281             :     /* stop by maximum number of iteration or matvecs */
     282           0 :   } else if (ierrprimme%100 >= -39) SETERRQ1(PetscObjectComm((PetscObject)svd),PETSC_ERR_LIB,"PRIMME library failed with error code=%d: configuration error; check PRIMME's manual",ierrprimme);
     283           0 :   else SETERRQ1(PetscObjectComm((PetscObject)svd),PETSC_ERR_LIB,"PRIMME library failed with error code=%d: runtime error; check PRIMME's manual",ierrprimme);
     284           6 :   PetscFunctionReturn(0);
     285             : }
     286             : 
     287           5 : PetscErrorCode SVDReset_PRIMME(SVD svd)
     288             : {
     289             :   PetscErrorCode ierr;
     290           5 :   SVD_PRIMME     *ops = (SVD_PRIMME*)svd->data;
     291             : 
     292           5 :   PetscFunctionBegin;
     293           5 :   primme_svds_free(&ops->primme);
     294           5 :   ierr = VecDestroy(&ops->x);CHKERRQ(ierr);
     295           5 :   ierr = VecDestroy(&ops->y);CHKERRQ(ierr);
     296           5 :   PetscFunctionReturn(0);
     297             : }
     298             : 
     299           5 : PetscErrorCode SVDDestroy_PRIMME(SVD svd)
     300             : {
     301             :   PetscErrorCode ierr;
     302             : 
     303           5 :   PetscFunctionBegin;
     304           5 :   ierr = PetscFree(svd->data);CHKERRQ(ierr);
     305           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMESetBlockSize_C",NULL);CHKERRQ(ierr);
     306           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMEGetBlockSize_C",NULL);CHKERRQ(ierr);
     307           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMESetMethod_C",NULL);CHKERRQ(ierr);
     308           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMEGetMethod_C",NULL);CHKERRQ(ierr);
     309           5 :   PetscFunctionReturn(0);
     310             : }
     311             : 
     312           0 : PetscErrorCode SVDView_PRIMME(SVD svd,PetscViewer viewer)
     313             : {
     314             :   PetscErrorCode ierr;
     315             :   PetscBool      isascii;
     316           0 :   SVD_PRIMME     *ctx = (SVD_PRIMME*)svd->data;
     317             :   PetscMPIInt    rank;
     318             : 
     319           0 :   PetscFunctionBegin;
     320           0 :   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
     321           0 :   if (isascii) {
     322           0 :     ierr = PetscViewerASCIIPrintf(viewer,"  block size=%D\n",ctx->bs);CHKERRQ(ierr);
     323           0 :     ierr = PetscViewerASCIIPrintf(viewer,"  solver method: %s\n",SVDPRIMMEMethods[(SVDPRIMMEMethod)ctx->method]);CHKERRQ(ierr);
     324             : 
     325             :     /* Display PRIMME params */
     326           0 :     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)svd),&rank);CHKERRQ(ierr);
     327           0 :     if (!rank) primme_svds_display_params(ctx->primme);
     328             :   }
     329           0 :   PetscFunctionReturn(0);
     330             : }
     331             : 
     332           4 : PetscErrorCode SVDSetFromOptions_PRIMME(PetscOptionItems *PetscOptionsObject,SVD svd)
     333             : {
     334             :   PetscErrorCode  ierr;
     335           4 :   SVD_PRIMME      *ctx = (SVD_PRIMME*)svd->data;
     336             :   PetscInt        bs;
     337             :   SVDPRIMMEMethod meth;
     338             :   PetscBool       flg;
     339             : 
     340           4 :   PetscFunctionBegin;
     341           4 :   ierr = PetscOptionsHead(PetscOptionsObject,"SVD PRIMME Options");CHKERRQ(ierr);
     342             : 
     343           4 :     ierr = PetscOptionsInt("-svd_primme_blocksize","Maximum block size","SVDPRIMMESetBlockSize",ctx->bs,&bs,&flg);CHKERRQ(ierr);
     344           4 :     if (flg) { ierr = SVDPRIMMESetBlockSize(svd,bs);CHKERRQ(ierr); }
     345             : 
     346           4 :     ierr = PetscOptionsEnum("-svd_primme_method","Method for solving the singular value problem","SVDPRIMMESetMethod",SVDPRIMMEMethods,(PetscEnum)ctx->method,(PetscEnum*)&meth,&flg);CHKERRQ(ierr);
     347           4 :     if (flg) { ierr = SVDPRIMMESetMethod(svd,meth);CHKERRQ(ierr); }
     348             : 
     349           4 :   ierr = PetscOptionsTail();CHKERRQ(ierr);
     350           4 :   PetscFunctionReturn(0);
     351             : }
     352             : 
     353           2 : static PetscErrorCode SVDPRIMMESetBlockSize_PRIMME(SVD svd,PetscInt bs)
     354             : {
     355           2 :   SVD_PRIMME *ops = (SVD_PRIMME*)svd->data;
     356             : 
     357           2 :   PetscFunctionBegin;
     358           2 :   if (bs == PETSC_DEFAULT) ops->bs = 0;
     359           2 :   else if (bs <= 0) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"PRIMME: block size must be positive");
     360           2 :   else ops->bs = bs;
     361           2 :   PetscFunctionReturn(0);
     362             : }
     363             : 
     364             : /*@
     365             :    SVDPRIMMESetBlockSize - The maximum block size that PRIMME will try to use.
     366             : 
     367             :    Logically Collective on svd
     368             : 
     369             :    Input Parameters:
     370             : +  svd - the singular value solver context
     371             : -  bs - block size
     372             : 
     373             :    Options Database Key:
     374             : .  -svd_primme_blocksize - Sets the max allowed block size value
     375             : 
     376             :    Notes:
     377             :    If the block size is not set, the value established by primme_svds_initialize
     378             :    is used.
     379             : 
     380             :    The user should set the block size based on the architecture specifics
     381             :    of the target computer, as well as any a priori knowledge of multiplicities.
     382             :    The code does NOT require bs > 1 to find multiple eigenvalues. For some
     383             :    methods, keeping bs = 1 yields the best overall performance.
     384             : 
     385             :    Level: advanced
     386             : 
     387             : .seealso: SVDPRIMMEGetBlockSize()
     388             : @*/
     389           2 : PetscErrorCode SVDPRIMMESetBlockSize(SVD svd,PetscInt bs)
     390             : {
     391             :   PetscErrorCode ierr;
     392             : 
     393           2 :   PetscFunctionBegin;
     394           2 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     395           4 :   PetscValidLogicalCollectiveInt(svd,bs,2);
     396           2 :   ierr = PetscTryMethod(svd,"SVDPRIMMESetBlockSize_C",(SVD,PetscInt),(svd,bs));CHKERRQ(ierr);
     397           4 :   PetscFunctionReturn(0);
     398             : }
     399             : 
     400           1 : static PetscErrorCode SVDPRIMMEGetBlockSize_PRIMME(SVD svd,PetscInt *bs)
     401             : {
     402           1 :   SVD_PRIMME *ops = (SVD_PRIMME*)svd->data;
     403             : 
     404           1 :   PetscFunctionBegin;
     405           1 :   *bs = ops->bs;
     406           1 :   PetscFunctionReturn(0);
     407             : }
     408             : 
     409             : /*@
     410             :    SVDPRIMMEGetBlockSize - Get the maximum block size the code will try to use.
     411             : 
     412             :    Not Collective
     413             : 
     414             :    Input Parameter:
     415             : .  svd - the singular value solver context
     416             : 
     417             :    Output Parameter:
     418             : .  bs - returned block size
     419             : 
     420             :    Level: advanced
     421             : 
     422             : .seealso: SVDPRIMMESetBlockSize()
     423             : @*/
     424           1 : PetscErrorCode SVDPRIMMEGetBlockSize(SVD svd,PetscInt *bs)
     425             : {
     426             :   PetscErrorCode ierr;
     427             : 
     428           1 :   PetscFunctionBegin;
     429           1 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     430           1 :   PetscValidIntPointer(bs,2);
     431           1 :   ierr = PetscUseMethod(svd,"SVDPRIMMEGetBlockSize_C",(SVD,PetscInt*),(svd,bs));CHKERRQ(ierr);
     432           2 :   PetscFunctionReturn(0);
     433             : }
     434             : 
     435           2 : static PetscErrorCode SVDPRIMMESetMethod_PRIMME(SVD svd,SVDPRIMMEMethod method)
     436             : {
     437           2 :   SVD_PRIMME *ops = (SVD_PRIMME*)svd->data;
     438             : 
     439           2 :   PetscFunctionBegin;
     440           2 :   ops->method = (primme_svds_preset_method)method;
     441           2 :   PetscFunctionReturn(0);
     442             : }
     443             : 
     444             : /*@
     445             :    SVDPRIMMESetMethod - Sets the method for the PRIMME SVD solver.
     446             : 
     447             :    Logically Collective on svd
     448             : 
     449             :    Input Parameters:
     450             : +  svd - the singular value solver context
     451             : -  method - method that will be used by PRIMME
     452             : 
     453             :    Options Database Key:
     454             : .  -svd_primme_method - Sets the method for the PRIMME SVD solver
     455             : 
     456             :    Note:
     457             :    If not set, the method defaults to SVD_PRIMME_HYBRID.
     458             : 
     459             :    Level: advanced
     460             : 
     461             : .seealso: SVDPRIMMEGetMethod(), SVDPRIMMEMethod
     462             : @*/
     463           2 : PetscErrorCode SVDPRIMMESetMethod(SVD svd,SVDPRIMMEMethod method)
     464             : {
     465             :   PetscErrorCode ierr;
     466             : 
     467           2 :   PetscFunctionBegin;
     468           2 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     469           4 :   PetscValidLogicalCollectiveEnum(svd,method,2);
     470           2 :   ierr = PetscTryMethod(svd,"SVDPRIMMESetMethod_C",(SVD,SVDPRIMMEMethod),(svd,method));CHKERRQ(ierr);
     471           4 :   PetscFunctionReturn(0);
     472             : }
     473             : 
     474           1 : static PetscErrorCode SVDPRIMMEGetMethod_PRIMME(SVD svd,SVDPRIMMEMethod *method)
     475             : {
     476           1 :   SVD_PRIMME *ops = (SVD_PRIMME*)svd->data;
     477             : 
     478           1 :   PetscFunctionBegin;
     479           1 :   *method = (SVDPRIMMEMethod)ops->method;
     480           1 :   PetscFunctionReturn(0);
     481             : }
     482             : 
     483             : /*@
     484             :    SVDPRIMMEGetMethod - Gets the method for the PRIMME SVD solver.
     485             : 
     486             :    Not Collective
     487             : 
     488             :    Input Parameter:
     489             : .  svd - the singular value solver context
     490             : 
     491             :    Output Parameter:
     492             : .  method - method that will be used by PRIMME
     493             : 
     494             :    Level: advanced
     495             : 
     496             : .seealso: SVDPRIMMESetMethod(), SVDPRIMMEMethod
     497             : @*/
     498           1 : PetscErrorCode SVDPRIMMEGetMethod(SVD svd,SVDPRIMMEMethod *method)
     499             : {
     500             :   PetscErrorCode ierr;
     501             : 
     502           1 :   PetscFunctionBegin;
     503           1 :   PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
     504           1 :   PetscValidPointer(method,2);
     505           1 :   ierr = PetscUseMethod(svd,"SVDPRIMMEGetMethod_C",(SVD,SVDPRIMMEMethod*),(svd,method));CHKERRQ(ierr);
     506           2 :   PetscFunctionReturn(0);
     507             : }
     508             : 
     509           5 : SLEPC_EXTERN PetscErrorCode SVDCreate_PRIMME(SVD svd)
     510             : {
     511             :   PetscErrorCode ierr;
     512             :   SVD_PRIMME     *primme;
     513             : 
     514           5 :   PetscFunctionBegin;
     515           5 :   ierr = PetscNewLog(svd,&primme);CHKERRQ(ierr);
     516           5 :   svd->data = (void*)primme;
     517             : 
     518           5 :   primme_svds_initialize(&primme->primme);
     519           5 :   primme->bs = 0;
     520           5 :   primme->method = (primme_svds_preset_method)SVD_PRIMME_HYBRID;
     521           5 :   primme->svd = svd;
     522             : 
     523           5 :   svd->ops->solve          = SVDSolve_PRIMME;
     524           5 :   svd->ops->setup          = SVDSetUp_PRIMME;
     525           5 :   svd->ops->setfromoptions = SVDSetFromOptions_PRIMME;
     526           5 :   svd->ops->destroy        = SVDDestroy_PRIMME;
     527           5 :   svd->ops->reset          = SVDReset_PRIMME;
     528           5 :   svd->ops->view           = SVDView_PRIMME;
     529             : 
     530           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMESetBlockSize_C",SVDPRIMMESetBlockSize_PRIMME);CHKERRQ(ierr);
     531           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMEGetBlockSize_C",SVDPRIMMEGetBlockSize_PRIMME);CHKERRQ(ierr);
     532           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMESetMethod_C",SVDPRIMMESetMethod_PRIMME);CHKERRQ(ierr);
     533           5 :   ierr = PetscObjectComposeFunction((PetscObject)svd,"SVDPRIMMEGetMethod_C",SVDPRIMMEGetMethod_PRIMME);CHKERRQ(ierr);
     534           5 :   PetscFunctionReturn(0);
     535             : }
     536             : 

Generated by: LCOV version 1.13