LCOV - code coverage report
Current view: top level - sys/classes/bv/impls/svec - svec.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 355 362 98.1 %
Date: 2024-11-23 00:39:48 Functions: 24 24 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, 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             :    BV implemented as a single Vec
      12             : */
      13             : 
      14             : #include <slepc/private/bvimpl.h>
      15             : #include "svec.h"
      16             : 
      17          98 : static PetscErrorCode BVMult_Svec(BV Y,PetscScalar alpha,PetscScalar beta,BV X,Mat Q)
      18             : {
      19          98 :   BV_SVEC           *y = (BV_SVEC*)Y->data,*x = (BV_SVEC*)X->data;
      20          98 :   const PetscScalar *px,*q;
      21          98 :   PetscScalar       *py;
      22          98 :   PetscInt          ldq;
      23             : 
      24          98 :   PetscFunctionBegin;
      25          98 :   PetscCall(VecGetArrayRead(x->v,&px));
      26          98 :   PetscCall(VecGetArray(y->v,&py));
      27          98 :   if (Q) {
      28          78 :     PetscCall(MatDenseGetLDA(Q,&ldq));
      29          78 :     PetscCall(MatDenseGetArrayRead(Q,&q));
      30          78 :     PetscCall(BVMult_BLAS_Private(Y,Y->n,Y->k-Y->l,X->k-X->l,alpha,px+(X->nc+X->l)*X->ld,X->ld,q+Y->l*ldq+X->l,ldq,beta,py+(Y->nc+Y->l)*Y->ld,Y->ld));
      31          78 :     PetscCall(MatDenseRestoreArrayRead(Q,&q));
      32          20 :   } else PetscCall(BVAXPY_BLAS_Private(Y,Y->n,Y->k-Y->l,alpha,px+(X->nc+X->l)*X->ld,X->ld,beta,py+(Y->nc+Y->l)*Y->ld,Y->ld));
      33          98 :   PetscCall(VecRestoreArrayRead(x->v,&px));
      34          98 :   PetscCall(VecRestoreArray(y->v,&py));
      35          98 :   PetscFunctionReturn(PETSC_SUCCESS);
      36             : }
      37             : 
      38         357 : static PetscErrorCode BVMultVec_Svec(BV X,PetscScalar alpha,PetscScalar beta,Vec y,PetscScalar *q)
      39             : {
      40         357 :   BV_SVEC        *x = (BV_SVEC*)X->data;
      41         357 :   PetscScalar    *px,*py,*qq=q;
      42             : 
      43         357 :   PetscFunctionBegin;
      44         357 :   PetscCall(VecGetArray(x->v,&px));
      45         357 :   PetscCall(VecGetArray(y,&py));
      46         357 :   if (!q) PetscCall(VecGetArray(X->buffer,&qq));
      47         357 :   PetscCall(BVMultVec_BLAS_Private(X,X->n,X->k-X->l,alpha,px+(X->nc+X->l)*X->ld,X->ld,qq,beta,py));
      48         357 :   if (!q) PetscCall(VecRestoreArray(X->buffer,&qq));
      49         357 :   PetscCall(VecRestoreArray(x->v,&px));
      50         357 :   PetscCall(VecRestoreArray(y,&py));
      51         357 :   PetscFunctionReturn(PETSC_SUCCESS);
      52             : }
      53             : 
      54          46 : static PetscErrorCode BVMultInPlace_Svec(BV V,Mat Q,PetscInt s,PetscInt e)
      55             : {
      56          46 :   BV_SVEC           *ctx = (BV_SVEC*)V->data;
      57          46 :   PetscScalar       *pv;
      58          46 :   const PetscScalar *q;
      59          46 :   PetscInt          ldq;
      60             : 
      61          46 :   PetscFunctionBegin;
      62          46 :   if (s>=e || !V->n) PetscFunctionReturn(PETSC_SUCCESS);
      63          46 :   PetscCall(MatDenseGetLDA(Q,&ldq));
      64          46 :   PetscCall(VecGetArray(ctx->v,&pv));
      65          46 :   PetscCall(MatDenseGetArrayRead(Q,&q));
      66          46 :   PetscCall(BVMultInPlace_BLAS_Private(V,V->n,V->k-V->l,s-V->l,e-V->l,pv+(V->nc+V->l)*V->ld,V->ld,q+V->l*ldq+V->l,ldq,PETSC_FALSE));
      67          46 :   PetscCall(MatDenseRestoreArrayRead(Q,&q));
      68          46 :   PetscCall(VecRestoreArray(ctx->v,&pv));
      69          46 :   PetscFunctionReturn(PETSC_SUCCESS);
      70             : }
      71             : 
      72           1 : static PetscErrorCode BVMultInPlaceHermitianTranspose_Svec(BV V,Mat Q,PetscInt s,PetscInt e)
      73             : {
      74           1 :   BV_SVEC           *ctx = (BV_SVEC*)V->data;
      75           1 :   PetscScalar       *pv;
      76           1 :   const PetscScalar *q;
      77           1 :   PetscInt          ldq;
      78             : 
      79           1 :   PetscFunctionBegin;
      80           1 :   if (s>=e || !V->n) PetscFunctionReturn(PETSC_SUCCESS);
      81           1 :   PetscCall(MatDenseGetLDA(Q,&ldq));
      82           1 :   PetscCall(VecGetArray(ctx->v,&pv));
      83           1 :   PetscCall(MatDenseGetArrayRead(Q,&q));
      84           1 :   PetscCall(BVMultInPlace_BLAS_Private(V,V->n,V->k-V->l,s-V->l,e-V->l,pv+(V->nc+V->l)*V->ld,V->ld,q+V->l*ldq+V->l,ldq,PETSC_TRUE));
      85           1 :   PetscCall(MatDenseRestoreArrayRead(Q,&q));
      86           1 :   PetscCall(VecRestoreArray(ctx->v,&pv));
      87           1 :   PetscFunctionReturn(PETSC_SUCCESS);
      88             : }
      89             : 
      90         241 : static PetscErrorCode BVDot_Svec(BV X,BV Y,Mat M)
      91             : {
      92         241 :   BV_SVEC           *x = (BV_SVEC*)X->data,*y = (BV_SVEC*)Y->data;
      93         241 :   const PetscScalar *px,*py;
      94         241 :   PetscScalar       *m;
      95         241 :   PetscInt          ldm;
      96             : 
      97         241 :   PetscFunctionBegin;
      98         241 :   PetscCall(MatDenseGetLDA(M,&ldm));
      99         241 :   PetscCall(VecGetArrayRead(x->v,&px));
     100         241 :   PetscCall(VecGetArrayRead(y->v,&py));
     101         241 :   PetscCall(MatDenseGetArray(M,&m));
     102         241 :   PetscCall(BVDot_BLAS_Private(X,Y->k-Y->l,X->k-X->l,X->n,py+(Y->nc+Y->l)*Y->ld,Y->ld,px+(X->nc+X->l)*X->ld,X->ld,m+X->l*ldm+Y->l,ldm,x->mpi));
     103         241 :   PetscCall(MatDenseRestoreArray(M,&m));
     104         241 :   PetscCall(VecRestoreArrayRead(x->v,&px));
     105         241 :   PetscCall(VecRestoreArrayRead(y->v,&py));
     106         241 :   PetscFunctionReturn(PETSC_SUCCESS);
     107             : }
     108             : 
     109         415 : static PetscErrorCode BVDotVec_Svec(BV X,Vec y,PetscScalar *q)
     110             : {
     111         415 :   BV_SVEC           *x = (BV_SVEC*)X->data;
     112         415 :   const PetscScalar *px,*py;
     113         415 :   PetscScalar       *qq=q;
     114         415 :   Vec               z = y;
     115             : 
     116         415 :   PetscFunctionBegin;
     117         415 :   if (PetscUnlikely(X->matrix)) {
     118          62 :     PetscCall(BV_IPMatMult(X,y));
     119          62 :     z = X->Bx;
     120             :   }
     121         415 :   PetscCall(VecGetArrayRead(x->v,&px));
     122         415 :   PetscCall(VecGetArrayRead(z,&py));
     123         415 :   if (!q) PetscCall(VecGetArray(X->buffer,&qq));
     124         415 :   PetscCall(BVDotVec_BLAS_Private(X,X->n,X->k-X->l,px+(X->nc+X->l)*X->ld,X->ld,py,qq,x->mpi));
     125         415 :   if (!q) PetscCall(VecRestoreArray(X->buffer,&qq));
     126         415 :   PetscCall(VecRestoreArrayRead(z,&py));
     127         415 :   PetscCall(VecRestoreArrayRead(x->v,&px));
     128         415 :   PetscFunctionReturn(PETSC_SUCCESS);
     129             : }
     130             : 
     131           4 : static PetscErrorCode BVDotVec_Local_Svec(BV X,Vec y,PetscScalar *m)
     132             : {
     133           4 :   BV_SVEC        *x = (BV_SVEC*)X->data;
     134           4 :   PetscScalar    *px,*py;
     135           4 :   Vec            z = y;
     136             : 
     137           4 :   PetscFunctionBegin;
     138           4 :   if (PetscUnlikely(X->matrix)) {
     139           0 :     PetscCall(BV_IPMatMult(X,y));
     140           0 :     z = X->Bx;
     141             :   }
     142           4 :   PetscCall(VecGetArray(x->v,&px));
     143           4 :   PetscCall(VecGetArray(z,&py));
     144           4 :   PetscCall(BVDotVec_BLAS_Private(X,X->n,X->k-X->l,px+(X->nc+X->l)*X->ld,X->ld,py,m,PETSC_FALSE));
     145           4 :   PetscCall(VecRestoreArray(z,&py));
     146           4 :   PetscCall(VecRestoreArray(x->v,&px));
     147           4 :   PetscFunctionReturn(PETSC_SUCCESS);
     148             : }
     149             : 
     150         331 : static PetscErrorCode BVScale_Svec(BV bv,PetscInt j,PetscScalar alpha)
     151             : {
     152         331 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     153         331 :   PetscScalar    *array;
     154             : 
     155         331 :   PetscFunctionBegin;
     156         331 :   if (!bv->n) PetscFunctionReturn(PETSC_SUCCESS);
     157         331 :   PetscCall(VecGetArray(ctx->v,&array));
     158         331 :   if (PetscUnlikely(j<0)) PetscCall(BVScale_BLAS_Private(bv,(bv->k-bv->l)*bv->ld,array+(bv->nc+bv->l)*bv->ld,alpha));
     159         327 :   else PetscCall(BVScale_BLAS_Private(bv,bv->n,array+(bv->nc+j)*bv->ld,alpha));
     160         331 :   PetscCall(VecRestoreArray(ctx->v,&array));
     161         331 :   PetscFunctionReturn(PETSC_SUCCESS);
     162             : }
     163             : 
     164         109 : static PetscErrorCode BVNorm_Svec(BV bv,PetscInt j,NormType type,PetscReal *val)
     165             : {
     166         109 :   BV_SVEC           *ctx = (BV_SVEC*)bv->data;
     167         109 :   const PetscScalar *array;
     168             : 
     169         109 :   PetscFunctionBegin;
     170         109 :   PetscCall(VecGetArrayRead(ctx->v,&array));
     171         109 :   if (PetscUnlikely(j<0)) PetscCall(BVNorm_LAPACK_Private(bv,bv->n,bv->k-bv->l,array+(bv->nc+bv->l)*bv->ld,bv->ld,type,val,ctx->mpi));
     172          41 :   else PetscCall(BVNorm_LAPACK_Private(bv,bv->n,1,array+(bv->nc+j)*bv->ld,bv->ld,type,val,ctx->mpi));
     173         109 :   PetscCall(VecRestoreArrayRead(ctx->v,&array));
     174         109 :   PetscFunctionReturn(PETSC_SUCCESS);
     175             : }
     176             : 
     177           2 : static PetscErrorCode BVNorm_Local_Svec(BV bv,PetscInt j,NormType type,PetscReal *val)
     178             : {
     179           2 :   BV_SVEC           *ctx = (BV_SVEC*)bv->data;
     180           2 :   const PetscScalar *array;
     181             : 
     182           2 :   PetscFunctionBegin;
     183           2 :   PetscCall(VecGetArrayRead(ctx->v,&array));
     184           2 :   if (PetscUnlikely(j<0)) PetscCall(BVNorm_LAPACK_Private(bv,bv->n,bv->k-bv->l,array+(bv->nc+bv->l)*bv->ld,bv->ld,type,val,PETSC_FALSE));
     185           2 :   else PetscCall(BVNorm_LAPACK_Private(bv,bv->n,1,array+(bv->nc+j)*bv->ld,bv->ld,type,val,PETSC_FALSE));
     186           2 :   PetscCall(VecRestoreArrayRead(ctx->v,&array));
     187           2 :   PetscFunctionReturn(PETSC_SUCCESS);
     188             : }
     189             : 
     190           3 : static PetscErrorCode BVNormalize_Svec(BV bv,PetscScalar *eigi)
     191             : {
     192           3 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     193           3 :   PetscScalar    *array,*wi=NULL;
     194             : 
     195           3 :   PetscFunctionBegin;
     196           3 :   PetscCall(VecGetArray(ctx->v,&array));
     197           3 :   if (eigi) wi = eigi+bv->l;
     198           3 :   PetscCall(BVNormalize_LAPACK_Private(bv,bv->n,bv->k-bv->l,array+(bv->nc+bv->l)*bv->ld,bv->ld,wi,ctx->mpi));
     199           3 :   PetscCall(VecRestoreArray(ctx->v,&array));
     200           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     201             : }
     202             : 
     203         103 : static PetscErrorCode BVMatMult_Svec(BV V,Mat A,BV W)
     204             : {
     205         103 :   PetscInt       j;
     206         103 :   Mat            Vmat,Wmat;
     207         103 :   Vec            vv,ww;
     208             : 
     209         103 :   PetscFunctionBegin;
     210         103 :   if (V->vmm) {
     211          96 :     PetscCall(BVGetMat(V,&Vmat));
     212          96 :     PetscCall(BVGetMat(W,&Wmat));
     213          96 :     PetscCall(MatProductCreateWithMat(A,Vmat,NULL,Wmat));
     214          96 :     PetscCall(MatProductSetType(Wmat,MATPRODUCT_AB));
     215          96 :     PetscCall(MatProductSetFromOptions(Wmat));
     216          96 :     PetscCall(MatProductSymbolic(Wmat));
     217          96 :     PetscCall(MatProductNumeric(Wmat));
     218          96 :     PetscCall(MatProductClear(Wmat));
     219          96 :     PetscCall(BVRestoreMat(V,&Vmat));
     220          96 :     PetscCall(BVRestoreMat(W,&Wmat));
     221             :   } else {
     222          53 :     for (j=0;j<V->k-V->l;j++) {
     223          46 :       PetscCall(BVGetColumn(V,V->l+j,&vv));
     224          46 :       PetscCall(BVGetColumn(W,W->l+j,&ww));
     225          46 :       PetscCall(MatMult(A,vv,ww));
     226          46 :       PetscCall(BVRestoreColumn(V,V->l+j,&vv));
     227          46 :       PetscCall(BVRestoreColumn(W,W->l+j,&ww));
     228             :     }
     229             :   }
     230         103 :   PetscFunctionReturn(PETSC_SUCCESS);
     231             : }
     232             : 
     233          97 : static PetscErrorCode BVCopy_Svec(BV V,BV W)
     234             : {
     235          97 :   BV_SVEC           *v = (BV_SVEC*)V->data,*w = (BV_SVEC*)W->data;
     236          97 :   const PetscScalar *pv;
     237          97 :   PetscScalar       *pw;
     238          97 :   PetscInt          j;
     239             : 
     240          97 :   PetscFunctionBegin;
     241          97 :   PetscCall(VecGetArrayRead(v->v,&pv));
     242          97 :   PetscCall(VecGetArray(w->v,&pw));
     243         726 :   for (j=0;j<V->k-V->l;j++) PetscCall(PetscArraycpy(pw+(W->nc+W->l+j)*W->ld,pv+(V->nc+V->l+j)*V->ld,V->n));
     244          97 :   PetscCall(VecRestoreArrayRead(v->v,&pv));
     245          97 :   PetscCall(VecRestoreArray(w->v,&pw));
     246          97 :   PetscFunctionReturn(PETSC_SUCCESS);
     247             : }
     248             : 
     249           2 : static PetscErrorCode BVCopyColumn_Svec(BV V,PetscInt j,PetscInt i)
     250             : {
     251           2 :   BV_SVEC        *v = (BV_SVEC*)V->data;
     252           2 :   PetscScalar    *pv;
     253             : 
     254           2 :   PetscFunctionBegin;
     255           2 :   PetscCall(VecGetArray(v->v,&pv));
     256           2 :   PetscCall(PetscArraycpy(pv+(V->nc+i)*V->ld,pv+(V->nc+j)*V->ld,V->n));
     257           2 :   PetscCall(VecRestoreArray(v->v,&pv));
     258           2 :   PetscFunctionReturn(PETSC_SUCCESS);
     259             : }
     260             : 
     261          11 : static PetscErrorCode BVResize_Svec(BV bv,PetscInt m,PetscBool copy)
     262             : {
     263          11 :   BV_SVEC           *ctx = (BV_SVEC*)bv->data;
     264          11 :   PetscScalar       *pnew;
     265          11 :   const PetscScalar *pv;
     266          11 :   PetscInt          bs;
     267          11 :   Vec               vnew;
     268          11 :   char              str[50];
     269             : 
     270          11 :   PetscFunctionBegin;
     271          11 :   PetscCall(PetscLayoutGetBlockSize(bv->map,&bs));
     272          11 :   PetscCall(VecCreate(PetscObjectComm((PetscObject)bv),&vnew));
     273          11 :   PetscCall(VecSetType(vnew,bv->vtype));
     274          11 :   PetscCall(VecSetSizes(vnew,m*bv->ld,PETSC_DECIDE));
     275          11 :   PetscCall(VecSetBlockSize(vnew,bs));
     276          11 :   if (((PetscObject)bv)->name) {
     277          11 :     PetscCall(PetscSNPrintf(str,sizeof(str),"%s_0",((PetscObject)bv)->name));
     278          11 :     PetscCall(PetscObjectSetName((PetscObject)vnew,str));
     279             :   }
     280          11 :   if (copy) {
     281           2 :     PetscCall(VecGetArrayRead(ctx->v,&pv));
     282           2 :     PetscCall(VecGetArray(vnew,&pnew));
     283           2 :     PetscCall(PetscArraycpy(pnew,pv,PetscMin(m,bv->m)*bv->ld));
     284           2 :     PetscCall(VecRestoreArrayRead(ctx->v,&pv));
     285           2 :     PetscCall(VecRestoreArray(vnew,&pnew));
     286             :   }
     287          11 :   PetscCall(VecDestroy(&ctx->v));
     288          11 :   ctx->v = vnew;
     289          11 :   PetscFunctionReturn(PETSC_SUCCESS);
     290             : }
     291             : 
     292        2698 : static PetscErrorCode BVGetColumn_Svec(BV bv,PetscInt j,Vec *v)
     293             : {
     294        2698 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     295        2698 :   PetscScalar    *pv;
     296        2698 :   PetscInt       l;
     297             : 
     298        2698 :   PetscFunctionBegin;
     299        2698 :   l = BVAvailableVec;
     300        2698 :   PetscCall(VecGetArray(ctx->v,&pv));
     301        2698 :   PetscCall(VecPlaceArray(bv->cv[l],pv+(bv->nc+j)*bv->ld));
     302        2698 :   PetscFunctionReturn(PETSC_SUCCESS);
     303             : }
     304             : 
     305        2698 : static PetscErrorCode BVRestoreColumn_Svec(BV bv,PetscInt j,Vec *v)
     306             : {
     307        2698 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     308        2698 :   PetscInt       l;
     309             : 
     310        2698 :   PetscFunctionBegin;
     311        2698 :   l = (j==bv->ci[0])? 0: 1;
     312        2698 :   PetscCall(VecResetArray(bv->cv[l]));
     313        2698 :   PetscCall(VecRestoreArray(ctx->v,NULL));
     314        2698 :   PetscFunctionReturn(PETSC_SUCCESS);
     315             : }
     316             : 
     317         239 : static PetscErrorCode BVGetArray_Svec(BV bv,PetscScalar **a)
     318             : {
     319         239 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     320             : 
     321         239 :   PetscFunctionBegin;
     322         239 :   PetscCall(VecGetArray(ctx->v,a));
     323         239 :   PetscFunctionReturn(PETSC_SUCCESS);
     324             : }
     325             : 
     326         239 : static PetscErrorCode BVRestoreArray_Svec(BV bv,PetscScalar **a)
     327             : {
     328         239 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     329             : 
     330         239 :   PetscFunctionBegin;
     331         239 :   PetscCall(VecRestoreArray(ctx->v,a));
     332         239 :   PetscFunctionReturn(PETSC_SUCCESS);
     333             : }
     334             : 
     335           8 : static PetscErrorCode BVGetArrayRead_Svec(BV bv,const PetscScalar **a)
     336             : {
     337           8 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     338             : 
     339           8 :   PetscFunctionBegin;
     340           8 :   PetscCall(VecGetArrayRead(ctx->v,a));
     341           8 :   PetscFunctionReturn(PETSC_SUCCESS);
     342             : }
     343             : 
     344           8 : static PetscErrorCode BVRestoreArrayRead_Svec(BV bv,const PetscScalar **a)
     345             : {
     346           8 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     347             : 
     348           8 :   PetscFunctionBegin;
     349           8 :   PetscCall(VecRestoreArrayRead(ctx->v,a));
     350           8 :   PetscFunctionReturn(PETSC_SUCCESS);
     351             : }
     352             : 
     353          12 : static PetscErrorCode BVView_Svec(BV bv,PetscViewer viewer)
     354             : {
     355          12 :   PetscInt          j;
     356          12 :   Vec               v;
     357          12 :   PetscViewerFormat format;
     358          12 :   PetscBool         isascii,ismatlab=PETSC_FALSE;
     359          12 :   const char        *bvname,*name;
     360             : 
     361          12 :   PetscFunctionBegin;
     362          12 :   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
     363          12 :   if (isascii) {
     364          12 :     PetscCall(PetscViewerGetFormat(viewer,&format));
     365          12 :     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(PETSC_SUCCESS);
     366          10 :     if (format == PETSC_VIEWER_ASCII_MATLAB) ismatlab = PETSC_TRUE;
     367             :   }
     368           0 :   if (ismatlab) {
     369           0 :     PetscCall(PetscObjectGetName((PetscObject)bv,&bvname));
     370           0 :     PetscCall(PetscViewerASCIIPrintf(viewer,"%s=[];\n",bvname));
     371             :   }
     372          48 :   for (j=0;j<bv->m;j++) {
     373          38 :     PetscCall(BVGetColumn(bv,j,&v));
     374          38 :     PetscCall(VecView(v,viewer));
     375          38 :     if (ismatlab) {
     376           0 :       PetscCall(PetscObjectGetName((PetscObject)v,&name));
     377           0 :       PetscCall(PetscViewerASCIIPrintf(viewer,"%s=[%s,%s];clear %s\n",bvname,bvname,name,name));
     378             :     }
     379          38 :     PetscCall(BVRestoreColumn(bv,j,&v));
     380             :   }
     381          10 :   PetscFunctionReturn(PETSC_SUCCESS);
     382             : }
     383             : 
     384         350 : static PetscErrorCode BVDestroy_Svec(BV bv)
     385             : {
     386         350 :   BV_SVEC        *ctx = (BV_SVEC*)bv->data;
     387             : 
     388         350 :   PetscFunctionBegin;
     389         350 :   PetscCall(VecDestroy(&ctx->v));
     390         350 :   PetscCall(VecDestroy(&bv->cv[0]));
     391         350 :   PetscCall(VecDestroy(&bv->cv[1]));
     392         350 :   PetscCall(PetscFree(bv->data));
     393         350 :   bv->cuda = PETSC_FALSE;
     394         350 :   PetscFunctionReturn(PETSC_SUCCESS);
     395             : }
     396             : 
     397         350 : SLEPC_EXTERN PetscErrorCode BVCreate_Svec(BV bv)
     398             : {
     399         350 :   BV_SVEC           *ctx;
     400         350 :   PetscInt          nloc,N,bs,tglobal=0,tlocal,lsplit,j,lda;
     401         350 :   PetscBool         seq,isdense;
     402         350 :   PetscScalar       *vv;
     403         350 :   const PetscScalar *aa,*array,*ptr;
     404         350 :   char              str[50];
     405         350 :   BV                parent;
     406         350 :   Vec               vpar;
     407         350 :   MatType           mtype;
     408             : 
     409         350 :   PetscFunctionBegin;
     410         350 :   PetscCall(PetscNew(&ctx));
     411         350 :   bv->data = (void*)ctx;
     412             : 
     413         350 :   PetscCall(PetscStrcmpAny(bv->vtype,&bv->cuda,VECSEQCUDA,VECMPICUDA,""));
     414         350 :   PetscCall(PetscStrcmpAny(bv->vtype,&bv->hip,VECSEQHIP,VECMPIHIP,""));
     415         350 :   PetscCall(PetscStrcmpAny(bv->vtype,&ctx->mpi,VECMPI,VECMPICUDA,VECMPIHIP,""));
     416             : 
     417         350 :   PetscCall(PetscStrcmp(bv->vtype,VECSEQ,&seq));
     418         350 :   PetscCheck(seq || ctx->mpi || bv->cuda || bv->hip,PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"BVSVEC does not support the requested vector type: %s",bv->vtype);
     419             : 
     420         350 :   PetscCall(PetscLayoutGetLocalSize(bv->map,&nloc));
     421         350 :   PetscCall(PetscLayoutGetSize(bv->map,&N));
     422         350 :   PetscCall(PetscLayoutGetBlockSize(bv->map,&bs));
     423         350 :   PetscCall(BV_SetDefaultLD(bv,nloc));
     424         350 :   tlocal = bv->m*bv->ld;
     425         350 :   PetscCall(PetscIntMultError(bv->m,N,&tglobal));  /* just to check integer overflow */
     426             : 
     427         350 :   if (PetscUnlikely(bv->issplit)) {
     428             :     /* split BV: create Vec sharing the memory of the parent BV */
     429          92 :     parent = bv->splitparent;
     430          92 :     lsplit = parent->lsplit;
     431          92 :     vpar = ((BV_SVEC*)parent->data)->v;
     432          92 :     if (bv->cuda) {
     433             : #if defined(PETSC_HAVE_CUDA)
     434             :       PetscCall(VecCUDAGetArrayRead(vpar,&array));
     435             :       if (bv->issplit>0) ptr = (bv->issplit==1)? array: array+lsplit*bv->ld;
     436             :       else ptr = (bv->issplit==1)? array: array-lsplit;
     437             :       PetscCall(VecCUDARestoreArrayRead(vpar,&array));
     438             :       if (ctx->mpi) PetscCall(VecCreateMPICUDAWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,PETSC_DECIDE,NULL,&ctx->v));
     439             :       else PetscCall(VecCreateSeqCUDAWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,NULL,&ctx->v));
     440             :       PetscCall(VecCUDAPlaceArray(ctx->v,ptr));
     441             : #endif
     442          92 :     } else if (bv->hip) {
     443             : #if defined(PETSC_HAVE_HIP)
     444             :       PetscCall(VecHIPGetArrayRead(vpar,&array));
     445             :       if (bv->issplit>0) ptr = (bv->issplit==1)? array: array+lsplit*bv->ld;
     446             :       else ptr = (bv->issplit==1)? array: array-lsplit;
     447             :       PetscCall(VecHIPRestoreArrayRead(vpar,&array));
     448             :       if (ctx->mpi) PetscCall(VecCreateMPIHIPWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,PETSC_DECIDE,NULL,&ctx->v));
     449             :       else PetscCall(VecCreateSeqHIPWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,NULL,&ctx->v));
     450             :       PetscCall(VecHIPPlaceArray(ctx->v,ptr));
     451             : #endif
     452             :     } else {
     453          92 :       PetscCall(VecGetArrayRead(vpar,&array));
     454          92 :       if (bv->issplit>0) ptr = (bv->issplit==1)? array: array+lsplit*bv->ld;
     455          12 :       else ptr = (bv->issplit==1)? array: array-lsplit;
     456          92 :       PetscCall(VecRestoreArrayRead(vpar,&array));
     457          92 :       if (ctx->mpi) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,PETSC_DECIDE,NULL,&ctx->v));
     458           4 :       else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,NULL,&ctx->v));
     459          92 :       PetscCall(VecPlaceArray(ctx->v,ptr));
     460             :     }
     461             :   } else {
     462             :     /* regular BV: create Vec to store the BV entries */
     463         258 :     PetscCall(VecCreate(PetscObjectComm((PetscObject)bv),&ctx->v));
     464         258 :     PetscCall(VecSetType(ctx->v,bv->vtype));
     465         258 :     PetscCall(VecSetSizes(ctx->v,tlocal,PETSC_DECIDE));
     466         258 :     PetscCall(VecSetBlockSize(ctx->v,bs));
     467             :   }
     468         350 :   if (((PetscObject)bv)->name) {
     469         118 :     PetscCall(PetscSNPrintf(str,sizeof(str),"%s_0",((PetscObject)bv)->name));
     470         118 :     PetscCall(PetscObjectSetName((PetscObject)ctx->v,str));
     471             :   }
     472             : 
     473         350 :   if (PetscUnlikely(bv->Acreate)) {
     474           2 :     PetscCall(MatGetType(bv->Acreate,&mtype));
     475           2 :     PetscCall(PetscStrcmpAny(mtype,&isdense,MATSEQDENSE,MATMPIDENSE,""));
     476           2 :     PetscCheck(isdense,PetscObjectComm((PetscObject)bv->Acreate),PETSC_ERR_SUP,"BVSVEC requires a dense matrix in BVCreateFromMat()");
     477           2 :     PetscCall(MatDenseGetArrayRead(bv->Acreate,&aa));
     478           2 :     PetscCall(MatDenseGetLDA(bv->Acreate,&lda));
     479           2 :     PetscCall(VecGetArray(ctx->v,&vv));
     480          18 :     for (j=0;j<bv->m;j++) PetscCall(PetscArraycpy(vv+j*bv->ld,aa+j*lda,bv->n));
     481           2 :     PetscCall(VecRestoreArray(ctx->v,&vv));
     482           2 :     PetscCall(MatDenseRestoreArrayRead(bv->Acreate,&aa));
     483           2 :     PetscCall(MatDestroy(&bv->Acreate));
     484             :   }
     485             : 
     486         350 :   PetscCall(BVCreateVecEmpty(bv,&bv->cv[0]));
     487         350 :   PetscCall(BVCreateVecEmpty(bv,&bv->cv[1]));
     488             : 
     489         350 :   if (bv->cuda) {
     490             : #if defined(PETSC_HAVE_CUDA)
     491             :     bv->ops->mult             = BVMult_Svec_CUDA;
     492             :     bv->ops->multvec          = BVMultVec_Svec_CUDA;
     493             :     bv->ops->multinplace      = BVMultInPlace_Svec_CUDA;
     494             :     bv->ops->multinplacetrans = BVMultInPlaceHermitianTranspose_Svec_CUDA;
     495             :     bv->ops->dot              = BVDot_Svec_CUDA;
     496             :     bv->ops->dotvec           = BVDotVec_Svec_CUDA;
     497             :     bv->ops->dotvec_local     = BVDotVec_Local_Svec_CUDA;
     498             :     bv->ops->scale            = BVScale_Svec_CUDA;
     499             :     bv->ops->norm             = BVNorm_Svec_CUDA;
     500             :     bv->ops->norm_local       = BVNorm_Local_Svec_CUDA;
     501             :     bv->ops->normalize        = BVNormalize_Svec_CUDA;
     502             :     bv->ops->matmult          = BVMatMult_Svec_CUDA;
     503             :     bv->ops->copy             = BVCopy_Svec_CUDA;
     504             :     bv->ops->copycolumn       = BVCopyColumn_Svec_CUDA;
     505             :     bv->ops->resize           = BVResize_Svec_CUDA;
     506             :     bv->ops->getcolumn        = BVGetColumn_Svec_CUDA;
     507             :     bv->ops->restorecolumn    = BVRestoreColumn_Svec_CUDA;
     508             :     bv->ops->restoresplit     = BVRestoreSplit_Svec_CUDA;
     509             :     bv->ops->restoresplitrows = BVRestoreSplitRows_Svec_CUDA;
     510             :     bv->ops->getmat           = BVGetMat_Svec_CUDA;
     511             :     bv->ops->restoremat       = BVRestoreMat_Svec_CUDA;
     512             : #endif
     513         350 :   } else if (bv->hip) {
     514             : #if defined(PETSC_HAVE_HIP)
     515             :     bv->ops->mult             = BVMult_Svec_HIP;
     516             :     bv->ops->multvec          = BVMultVec_Svec_HIP;
     517             :     bv->ops->multinplace      = BVMultInPlace_Svec_HIP;
     518             :     bv->ops->multinplacetrans = BVMultInPlaceHermitianTranspose_Svec_HIP;
     519             :     bv->ops->dot              = BVDot_Svec_HIP;
     520             :     bv->ops->dotvec           = BVDotVec_Svec_HIP;
     521             :     bv->ops->dotvec_local     = BVDotVec_Local_Svec_HIP;
     522             :     bv->ops->scale            = BVScale_Svec_HIP;
     523             :     bv->ops->norm             = BVNorm_Svec_HIP;
     524             :     bv->ops->norm_local       = BVNorm_Local_Svec_HIP;
     525             :     bv->ops->normalize        = BVNormalize_Svec_HIP;
     526             :     bv->ops->matmult          = BVMatMult_Svec_HIP;
     527             :     bv->ops->copy             = BVCopy_Svec_HIP;
     528             :     bv->ops->copycolumn       = BVCopyColumn_Svec_HIP;
     529             :     bv->ops->resize           = BVResize_Svec_HIP;
     530             :     bv->ops->getcolumn        = BVGetColumn_Svec_HIP;
     531             :     bv->ops->restorecolumn    = BVRestoreColumn_Svec_HIP;
     532             :     bv->ops->restoresplit     = BVRestoreSplit_Svec_HIP;
     533             :     bv->ops->restoresplitrows = BVRestoreSplitRows_Svec_HIP;
     534             :     bv->ops->getmat           = BVGetMat_Svec_HIP;
     535             :     bv->ops->restoremat       = BVRestoreMat_Svec_HIP;
     536             : #endif
     537             :   } else {
     538         350 :     bv->ops->mult             = BVMult_Svec;
     539         350 :     bv->ops->multvec          = BVMultVec_Svec;
     540         350 :     bv->ops->multinplace      = BVMultInPlace_Svec;
     541         350 :     bv->ops->multinplacetrans = BVMultInPlaceHermitianTranspose_Svec;
     542         350 :     bv->ops->dot              = BVDot_Svec;
     543         350 :     bv->ops->dotvec           = BVDotVec_Svec;
     544         350 :     bv->ops->dotvec_local     = BVDotVec_Local_Svec;
     545         350 :     bv->ops->scale            = BVScale_Svec;
     546         350 :     bv->ops->norm             = BVNorm_Svec;
     547         350 :     bv->ops->norm_local       = BVNorm_Local_Svec;
     548         350 :     bv->ops->normalize        = BVNormalize_Svec;
     549         350 :     bv->ops->matmult          = BVMatMult_Svec;
     550         350 :     bv->ops->copy             = BVCopy_Svec;
     551         350 :     bv->ops->copycolumn       = BVCopyColumn_Svec;
     552         350 :     bv->ops->resize           = BVResize_Svec;
     553         350 :     bv->ops->getcolumn        = BVGetColumn_Svec;
     554         350 :     bv->ops->restorecolumn    = BVRestoreColumn_Svec;
     555         350 :     bv->ops->getmat           = BVGetMat_Default;
     556         350 :     bv->ops->restoremat       = BVRestoreMat_Default;
     557             :   }
     558         350 :   bv->ops->getarray         = BVGetArray_Svec;
     559         350 :   bv->ops->restorearray     = BVRestoreArray_Svec;
     560         350 :   bv->ops->getarrayread     = BVGetArrayRead_Svec;
     561         350 :   bv->ops->restorearrayread = BVRestoreArrayRead_Svec;
     562         350 :   bv->ops->destroy          = BVDestroy_Svec;
     563         350 :   if (!ctx->mpi) bv->ops->view = BVView_Svec;
     564         350 :   PetscFunctionReturn(PETSC_SUCCESS);
     565             : }

Generated by: LCOV version 1.14