Actual source code: bvmat.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: */
 10: /*
 11:    BV implemented with a dense Mat
 12: */

 14: #include <slepc/private/bvimpl.h>
 15: #include "bvmat.h"

 17: static PetscErrorCode BVMult_Mat(BV Y,PetscScalar alpha,PetscScalar beta,BV X,Mat Q)
 18: {
 19:   BV_MAT            *y = (BV_MAT*)Y->data,*x = (BV_MAT*)X->data;
 20:   PetscScalar       *py;
 21:   const PetscScalar *px,*q;
 22:   PetscInt          ldq;

 24:   PetscFunctionBegin;
 25:   PetscCall(MatDenseGetArrayRead(x->A,&px));
 26:   PetscCall(MatDenseGetArray(y->A,&py));
 27:   if (Q) {
 28:     PetscCall(MatDenseGetLDA(Q,&ldq));
 29:     PetscCall(MatDenseGetArrayRead(Q,&q));
 30:     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:     PetscCall(MatDenseRestoreArrayRead(Q,&q));
 32:   } 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:   PetscCall(MatDenseRestoreArrayRead(x->A,&px));
 34:   PetscCall(MatDenseRestoreArray(y->A,&py));
 35:   PetscFunctionReturn(PETSC_SUCCESS);
 36: }

 38: static PetscErrorCode BVMultVec_Mat(BV X,PetscScalar alpha,PetscScalar beta,Vec y,PetscScalar *q)
 39: {
 40:   BV_MAT            *x = (BV_MAT*)X->data;
 41:   PetscScalar       *py,*qq=q;
 42:   const PetscScalar *px;

 44:   PetscFunctionBegin;
 45:   PetscCall(MatDenseGetArrayRead(x->A,&px));
 46:   PetscCall(VecGetArray(y,&py));
 47:   if (!q) PetscCall(VecGetArray(X->buffer,&qq));
 48:   PetscCall(BVMultVec_BLAS_Private(X,X->n,X->k-X->l,alpha,px+(X->nc+X->l)*X->ld,X->ld,qq,beta,py));
 49:   if (!q) PetscCall(VecRestoreArray(X->buffer,&qq));
 50:   PetscCall(MatDenseRestoreArrayRead(x->A,&px));
 51:   PetscCall(VecRestoreArray(y,&py));
 52:   PetscFunctionReturn(PETSC_SUCCESS);
 53: }

 55: static PetscErrorCode BVMultInPlace_Mat(BV V,Mat Q,PetscInt s,PetscInt e)
 56: {
 57:   BV_MAT            *ctx = (BV_MAT*)V->data;
 58:   PetscScalar       *pv;
 59:   const PetscScalar *q;
 60:   PetscInt          ldq;

 62:   PetscFunctionBegin;
 63:   if (s>=e || !V->n) PetscFunctionReturn(PETSC_SUCCESS);
 64:   PetscCall(MatDenseGetLDA(Q,&ldq));
 65:   PetscCall(MatDenseGetArray(ctx->A,&pv));
 66:   PetscCall(MatDenseGetArrayRead(Q,&q));
 67:   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));
 68:   PetscCall(MatDenseRestoreArrayRead(Q,&q));
 69:   PetscCall(MatDenseRestoreArray(ctx->A,&pv));
 70:   PetscFunctionReturn(PETSC_SUCCESS);
 71: }

 73: static PetscErrorCode BVMultInPlaceHermitianTranspose_Mat(BV V,Mat Q,PetscInt s,PetscInt e)
 74: {
 75:   BV_MAT            *ctx = (BV_MAT*)V->data;
 76:   PetscScalar       *pv;
 77:   const PetscScalar *q;
 78:   PetscInt          ldq;

 80:   PetscFunctionBegin;
 81:   if (s>=e || !V->n) PetscFunctionReturn(PETSC_SUCCESS);
 82:   PetscCall(MatDenseGetLDA(Q,&ldq));
 83:   PetscCall(MatDenseGetArray(ctx->A,&pv));
 84:   PetscCall(MatDenseGetArrayRead(Q,&q));
 85:   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));
 86:   PetscCall(MatDenseRestoreArrayRead(Q,&q));
 87:   PetscCall(MatDenseRestoreArray(ctx->A,&pv));
 88:   PetscFunctionReturn(PETSC_SUCCESS);
 89: }

 91: static PetscErrorCode BVDot_Mat(BV X,BV Y,Mat M)
 92: {
 93:   BV_MAT            *x = (BV_MAT*)X->data,*y = (BV_MAT*)Y->data;
 94:   PetscScalar       *m;
 95:   const PetscScalar *px,*py;
 96:   PetscInt          ldm;

 98:   PetscFunctionBegin;
 99:   PetscCall(MatDenseGetLDA(M,&ldm));
100:   PetscCall(MatDenseGetArrayRead(x->A,&px));
101:   PetscCall(MatDenseGetArrayRead(y->A,&py));
102:   PetscCall(MatDenseGetArray(M,&m));
103:   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));
104:   PetscCall(MatDenseRestoreArray(M,&m));
105:   PetscCall(MatDenseRestoreArrayRead(x->A,&px));
106:   PetscCall(MatDenseRestoreArrayRead(y->A,&py));
107:   PetscFunctionReturn(PETSC_SUCCESS);
108: }

110: static PetscErrorCode BVDotVec_Mat(BV X,Vec y,PetscScalar *q)
111: {
112:   BV_MAT            *x = (BV_MAT*)X->data;
113:   PetscScalar       *qq=q;
114:   const PetscScalar *px,*py;
115:   Vec               z = y;

117:   PetscFunctionBegin;
118:   if (PetscUnlikely(X->matrix)) {
119:     PetscCall(BV_IPMatMult(X,y));
120:     z = X->Bx;
121:   }
122:   PetscCall(MatDenseGetArrayRead(x->A,&px));
123:   PetscCall(VecGetArrayRead(z,&py));
124:   if (!q) PetscCall(VecGetArray(X->buffer,&qq));
125:   PetscCall(BVDotVec_BLAS_Private(X,X->n,X->k-X->l,px+(X->nc+X->l)*X->ld,X->ld,py,qq,x->mpi));
126:   if (!q) PetscCall(VecRestoreArray(X->buffer,&qq));
127:   PetscCall(VecRestoreArrayRead(z,&py));
128:   PetscCall(MatDenseRestoreArrayRead(x->A,&px));
129:   PetscFunctionReturn(PETSC_SUCCESS);
130: }

132: static PetscErrorCode BVDotVec_Local_Mat(BV X,Vec y,PetscScalar *m)
133: {
134:   BV_MAT            *x = (BV_MAT*)X->data;
135:   const PetscScalar *px,*py;
136:   Vec               z = y;

138:   PetscFunctionBegin;
139:   if (PetscUnlikely(X->matrix)) {
140:     PetscCall(BV_IPMatMult(X,y));
141:     z = X->Bx;
142:   }
143:   PetscCall(MatDenseGetArrayRead(x->A,&px));
144:   PetscCall(VecGetArrayRead(z,&py));
145:   PetscCall(BVDotVec_BLAS_Private(X,X->n,X->k-X->l,px+(X->nc+X->l)*X->ld,X->ld,py,m,PETSC_FALSE));
146:   PetscCall(VecRestoreArrayRead(z,&py));
147:   PetscCall(MatDenseRestoreArrayRead(x->A,&px));
148:   PetscFunctionReturn(PETSC_SUCCESS);
149: }

151: static PetscErrorCode BVScale_Mat(BV bv,PetscInt j,PetscScalar alpha)
152: {
153:   BV_MAT         *ctx = (BV_MAT*)bv->data;
154:   PetscScalar    *array;

156:   PetscFunctionBegin;
157:   if (!bv->n) PetscFunctionReturn(PETSC_SUCCESS);
158:   PetscCall(MatDenseGetArray(ctx->A,&array));
159:   if (PetscUnlikely(j<0)) PetscCall(BVScale_BLAS_Private(bv,(bv->k-bv->l)*bv->ld,array+(bv->nc+bv->l)*bv->ld,alpha));
160:   else PetscCall(BVScale_BLAS_Private(bv,bv->n,array+(bv->nc+j)*bv->ld,alpha));
161:   PetscCall(MatDenseRestoreArray(ctx->A,&array));
162:   PetscFunctionReturn(PETSC_SUCCESS);
163: }

165: static PetscErrorCode BVNorm_Mat(BV bv,PetscInt j,NormType type,PetscReal *val)
166: {
167:   BV_MAT            *ctx = (BV_MAT*)bv->data;
168:   const PetscScalar *array;

170:   PetscFunctionBegin;
171:   PetscCall(MatDenseGetArrayRead(ctx->A,&array));
172:   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));
173:   else PetscCall(BVNorm_LAPACK_Private(bv,bv->n,1,array+(bv->nc+j)*bv->ld,bv->ld,type,val,ctx->mpi));
174:   PetscCall(MatDenseRestoreArrayRead(ctx->A,&array));
175:   PetscFunctionReturn(PETSC_SUCCESS);
176: }

178: static PetscErrorCode BVNorm_Local_Mat(BV bv,PetscInt j,NormType type,PetscReal *val)
179: {
180:   BV_MAT            *ctx = (BV_MAT*)bv->data;
181:   const PetscScalar *array;

183:   PetscFunctionBegin;
184:   PetscCall(MatDenseGetArrayRead(ctx->A,&array));
185:   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));
186:   else PetscCall(BVNorm_LAPACK_Private(bv,bv->n,1,array+(bv->nc+j)*bv->ld,bv->ld,type,val,PETSC_FALSE));
187:   PetscCall(MatDenseRestoreArrayRead(ctx->A,&array));
188:   PetscFunctionReturn(PETSC_SUCCESS);
189: }

191: static PetscErrorCode BVNormalize_Mat(BV bv,PetscScalar *eigi)
192: {
193:   BV_MAT         *ctx = (BV_MAT*)bv->data;
194:   PetscScalar    *array,*wi=NULL;

196:   PetscFunctionBegin;
197:   PetscCall(MatDenseGetArray(ctx->A,&array));
198:   if (eigi) wi = eigi+bv->l;
199:   PetscCall(BVNormalize_LAPACK_Private(bv,bv->n,bv->k-bv->l,array+(bv->nc+bv->l)*bv->ld,bv->ld,wi,ctx->mpi));
200:   PetscCall(MatDenseRestoreArray(ctx->A,&array));
201:   PetscFunctionReturn(PETSC_SUCCESS);
202: }

204: static PetscErrorCode BVMatMult_Mat(BV V,Mat A,BV W)
205: {
206:   PetscInt       j;
207:   Mat            Vmat,Wmat;
208:   Vec            vv,ww;

210:   PetscFunctionBegin;
211:   if (V->vmm) {
212:     PetscCall(BVGetMat(V,&Vmat));
213:     PetscCall(BVGetMat(W,&Wmat));
214:     PetscCall(MatProductCreateWithMat(A,Vmat,NULL,Wmat));
215:     PetscCall(MatProductSetType(Wmat,MATPRODUCT_AB));
216:     PetscCall(MatProductSetFromOptions(Wmat));
217:     PetscCall(MatProductSymbolic(Wmat));
218:     PetscCall(MatProductNumeric(Wmat));
219:     PetscCall(MatProductClear(Wmat));
220:     PetscCall(BVRestoreMat(V,&Vmat));
221:     PetscCall(BVRestoreMat(W,&Wmat));
222:   } else {
223:     for (j=0;j<V->k-V->l;j++) {
224:       PetscCall(BVGetColumn(V,V->l+j,&vv));
225:       PetscCall(BVGetColumn(W,W->l+j,&ww));
226:       PetscCall(MatMult(A,vv,ww));
227:       PetscCall(BVRestoreColumn(V,V->l+j,&vv));
228:       PetscCall(BVRestoreColumn(W,W->l+j,&ww));
229:     }
230:   }
231:   PetscFunctionReturn(PETSC_SUCCESS);
232: }

234: static PetscErrorCode BVCopy_Mat(BV V,BV W)
235: {
236:   BV_MAT            *v = (BV_MAT*)V->data,*w = (BV_MAT*)W->data;
237:   const PetscScalar *pv;
238:   PetscScalar       *pw;
239:   PetscInt          j;

241:   PetscFunctionBegin;
242:   PetscCall(MatDenseGetArrayRead(v->A,&pv));
243:   PetscCall(MatDenseGetArray(w->A,&pw));
244:   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));
245:   PetscCall(MatDenseRestoreArrayRead(v->A,&pv));
246:   PetscCall(MatDenseRestoreArray(w->A,&pw));
247:   PetscFunctionReturn(PETSC_SUCCESS);
248: }

250: static PetscErrorCode BVCopyColumn_Mat(BV V,PetscInt j,PetscInt i)
251: {
252:   BV_MAT         *v = (BV_MAT*)V->data;
253:   PetscScalar    *pv;

255:   PetscFunctionBegin;
256:   PetscCall(MatDenseGetArray(v->A,&pv));
257:   PetscCall(PetscArraycpy(pv+(V->nc+i)*V->ld,pv+(V->nc+j)*V->ld,V->n));
258:   PetscCall(MatDenseRestoreArray(v->A,&pv));
259:   PetscFunctionReturn(PETSC_SUCCESS);
260: }

262: static PetscErrorCode BVResize_Mat(BV bv,PetscInt m,PetscBool copy)
263: {
264:   BV_MAT            *ctx = (BV_MAT*)bv->data;
265:   Mat               A,Msrc,Mdst;
266:   char              str[50];

268:   PetscFunctionBegin;
269:   PetscCall(MatCreateDenseFromVecType(PetscObjectComm((PetscObject)bv),bv->vtype,bv->n,PETSC_DECIDE,bv->N,m,bv->ld,NULL,&A));
270:   if (((PetscObject)bv)->name) {
271:     PetscCall(PetscSNPrintf(str,sizeof(str),"%s_0",((PetscObject)bv)->name));
272:     PetscCall(PetscObjectSetName((PetscObject)A,str));
273:   }
274:   if (copy) {
275:     PetscCall(MatDenseGetSubMatrix(ctx->A,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PetscMin(m,bv->m),&Msrc));
276:     PetscCall(MatDenseGetSubMatrix(A,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PetscMin(m,bv->m),&Mdst));
277:     PetscCall(MatCopy(Msrc,Mdst,SAME_NONZERO_PATTERN));
278:     PetscCall(MatDenseRestoreSubMatrix(ctx->A,&Msrc));
279:     PetscCall(MatDenseRestoreSubMatrix(A,&Mdst));
280:   }
281:   PetscCall(MatDestroy(&ctx->A));
282:   ctx->A = A;
283:   PetscFunctionReturn(PETSC_SUCCESS);
284: }

286: static PetscErrorCode BVGetColumn_Mat(BV bv,PetscInt j,Vec *v)
287: {
288:   BV_MAT         *ctx = (BV_MAT*)bv->data;
289:   PetscScalar    *pA;
290:   PetscInt       l;

292:   PetscFunctionBegin;
293:   l = BVAvailableVec;
294:   PetscCall(MatDenseGetArray(ctx->A,&pA));
295:   PetscCall(VecPlaceArray(bv->cv[l],pA+(bv->nc+j)*bv->ld));
296:   PetscFunctionReturn(PETSC_SUCCESS);
297: }

299: static PetscErrorCode BVRestoreColumn_Mat(BV bv,PetscInt j,Vec *v)
300: {
301:   BV_MAT         *ctx = (BV_MAT*)bv->data;
302:   PetscScalar    *pA;
303:   PetscInt       l;

305:   PetscFunctionBegin;
306:   l = (j==bv->ci[0])? 0: 1;
307:   PetscCall(VecResetArray(bv->cv[l]));
308:   PetscCall(MatDenseRestoreArray(ctx->A,&pA));
309:   PetscFunctionReturn(PETSC_SUCCESS);
310: }

312: static PetscErrorCode BVGetArray_Mat(BV bv,PetscScalar **a)
313: {
314:   BV_MAT         *ctx = (BV_MAT*)bv->data;

316:   PetscFunctionBegin;
317:   PetscCall(MatDenseGetArray(ctx->A,a));
318:   PetscFunctionReturn(PETSC_SUCCESS);
319: }

321: static PetscErrorCode BVRestoreArray_Mat(BV bv,PetscScalar **a)
322: {
323:   BV_MAT         *ctx = (BV_MAT*)bv->data;

325:   PetscFunctionBegin;
326:   if (a) PetscCall(MatDenseRestoreArray(ctx->A,a));
327:   PetscFunctionReturn(PETSC_SUCCESS);
328: }

330: static PetscErrorCode BVGetArrayRead_Mat(BV bv,const PetscScalar **a)
331: {
332:   BV_MAT         *ctx = (BV_MAT*)bv->data;

334:   PetscFunctionBegin;
335:   PetscCall(MatDenseGetArrayRead(ctx->A,a));
336:   PetscFunctionReturn(PETSC_SUCCESS);
337: }

339: static PetscErrorCode BVRestoreArrayRead_Mat(BV bv,const PetscScalar **a)
340: {
341:   BV_MAT         *ctx = (BV_MAT*)bv->data;

343:   PetscFunctionBegin;
344:   if (a) PetscCall(MatDenseRestoreArrayRead(ctx->A,a));
345:   PetscFunctionReturn(PETSC_SUCCESS);
346: }

348: static PetscErrorCode BVView_Mat(BV bv,PetscViewer viewer)
349: {
350:   Mat               A;
351:   PetscViewerFormat format;
352:   PetscBool         isascii;
353:   const char        *bvname,*name;

355:   PetscFunctionBegin;
356:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
357:   if (isascii) {
358:     PetscCall(PetscViewerGetFormat(viewer,&format));
359:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(PETSC_SUCCESS);
360:   }
361:   PetscCall(BVGetMat(bv,&A));
362:   PetscCall(MatView(A,viewer));
363:   if (format == PETSC_VIEWER_ASCII_MATLAB) {
364:     PetscCall(PetscObjectGetName((PetscObject)A,&name));
365:     PetscCall(PetscObjectGetName((PetscObject)bv,&bvname));
366:     PetscCall(PetscViewerASCIIPrintf(viewer,"%s=%s;clear %s\n",bvname,name,name));
367:     if (bv->nc) PetscCall(PetscViewerASCIIPrintf(viewer,"%s=%s(:,%" PetscInt_FMT ":end);\n",bvname,bvname,bv->nc+1));
368:   }
369:   PetscCall(BVRestoreMat(bv,&A));
370:   PetscFunctionReturn(PETSC_SUCCESS);
371: }

373: static PetscErrorCode BVDestroy_Mat(BV bv)
374: {
375:   BV_MAT         *ctx = (BV_MAT*)bv->data;

377:   PetscFunctionBegin;
378:   PetscCall(MatDestroy(&ctx->A));
379:   PetscCall(VecDestroy(&bv->cv[0]));
380:   PetscCall(VecDestroy(&bv->cv[1]));
381:   PetscCall(PetscFree(bv->data));
382:   PetscFunctionReturn(PETSC_SUCCESS);
383: }

385: /*MC
386:    BVMAT - BVMAT = "mat" - A basis vectors object represented by a dense `Mat`.

388:    Level: beginner

390: .seealso: [](sec:bv), `BV`, `BVType`, `BVSetType()`
391: M*/

393: SLEPC_EXTERN PetscErrorCode BVCreate_Mat(BV bv)
394: {
395:   BV_MAT         *ctx;
396:   PetscInt       nloc,lsplit;
397:   PetscBool      seq;
398:   char           str[50];
399:   PetscScalar    *array,*ptr=NULL;
400:   BV             parent;
401:   Mat            Apar;

403:   PetscFunctionBegin;
404:   PetscCall(PetscNew(&ctx));
405:   bv->data = (void*)ctx;

407:   PetscCall(PetscStrcmpAny(bv->vtype,&bv->cuda,VECSEQCUDA,VECMPICUDA,""));
408:   PetscCall(PetscStrcmpAny(bv->vtype,&bv->hip,VECSEQHIP,VECMPIHIP,""));
409:   PetscCall(PetscStrcmpAny(bv->vtype,&ctx->mpi,VECMPI,VECMPICUDA,VECMPIHIP,""));

411:   PetscCall(PetscStrcmp(bv->vtype,VECSEQ,&seq));
412:   PetscCheck(seq || ctx->mpi || bv->cuda || bv->hip,PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"BVMAT does not support the requested vector type: %s",bv->vtype);

414:   PetscCall(PetscLayoutGetLocalSize(bv->map,&nloc));
415:   PetscCall(BV_SetDefaultLD(bv,nloc));

417:   if (PetscUnlikely(bv->issplit)) {
418:     /* split BV: share the memory of the parent BV */
419:     parent = bv->splitparent;
420:     lsplit = parent->lsplit;
421:     Apar = ((BV_MAT*)parent->data)->A;
422:     if (bv->cuda) {
423: #if defined(PETSC_HAVE_CUDA)
424:       PetscCall(MatDenseCUDAGetArray(Apar,&array));
425:       if (bv->issplit>0) ptr = (bv->issplit==1)? array: array+lsplit*bv->ld;
426:       else ptr = (bv->issplit==1)? array: array-lsplit;
427:       PetscCall(MatDenseCUDARestoreArray(Apar,&array));
428: #endif
429:     } else if (bv->hip) {
430: #if defined(PETSC_HAVE_HIP)
431:       PetscCall(MatDenseHIPGetArray(Apar,&array));
432:       if (bv->issplit>0) ptr = (bv->issplit==1)? array: array+lsplit*bv->ld;
433:       else ptr = (bv->issplit==1)? array: array-lsplit;
434:       PetscCall(MatDenseHIPRestoreArray(Apar,&array));
435: #endif
436:     } else {
437:       PetscCall(MatDenseGetArray(Apar,&array));
438:       if (bv->issplit>0) ptr = (bv->issplit==1)? array: array+lsplit*bv->ld;
439:       else ptr = (bv->issplit==-1)? array: array-lsplit;
440:       PetscCall(MatDenseRestoreArray(Apar,&array));
441:     }
442:   }

444:   PetscCall(MatCreateDenseFromVecType(PetscObjectComm((PetscObject)bv),bv->vtype,nloc,PETSC_DECIDE,bv->N,bv->m,bv->ld,ptr,&ctx->A));
445:   if (((PetscObject)bv)->name) {
446:     PetscCall(PetscSNPrintf(str,sizeof(str),"%s_0",((PetscObject)bv)->name));
447:     PetscCall(PetscObjectSetName((PetscObject)ctx->A,str));
448:   }

450:   if (PetscUnlikely(bv->Acreate)) {
451:     PetscCall(MatConvert(bv->Acreate,bv->cuda?MATDENSECUDA:bv->hip?MATDENSEHIP:MATDENSE,MAT_REUSE_MATRIX,&ctx->A));
452:     PetscCall(MatDestroy(&bv->Acreate));
453:   }

455:   PetscCall(BVCreateVecEmpty(bv,&bv->cv[0]));
456:   PetscCall(BVCreateVecEmpty(bv,&bv->cv[1]));

458:   if (bv->cuda) {
459: #if defined(PETSC_HAVE_CUDA)
460:     bv->ops->mult             = BVMult_Mat_CUDA;
461:     bv->ops->multvec          = BVMultVec_Mat_CUDA;
462:     bv->ops->multinplace      = BVMultInPlace_Mat_CUDA;
463:     bv->ops->multinplacetrans = BVMultInPlaceHermitianTranspose_Mat_CUDA;
464:     bv->ops->dot              = BVDot_Mat_CUDA;
465:     bv->ops->dotvec           = BVDotVec_Mat_CUDA;
466:     bv->ops->dotvec_local     = BVDotVec_Local_Mat_CUDA;
467:     bv->ops->scale            = BVScale_Mat_CUDA;
468:     bv->ops->norm             = BVNorm_Mat_CUDA;
469:     bv->ops->norm_local       = BVNorm_Local_Mat_CUDA;
470:     bv->ops->normalize        = BVNormalize_Mat_CUDA;
471:     bv->ops->matmult          = BVMatMult_Mat_CUDA;
472:     bv->ops->copy             = BVCopy_Mat_CUDA;
473:     bv->ops->copycolumn       = BVCopyColumn_Mat_CUDA;
474:     bv->ops->getcolumn        = BVGetColumn_Mat_CUDA;
475:     bv->ops->restorecolumn    = BVRestoreColumn_Mat_CUDA;
476:     bv->ops->restoresplit     = BVRestoreSplit_Mat_CUDA;
477:     bv->ops->restoresplitrows = BVRestoreSplitRows_Mat_CUDA;
478:     bv->ops->getmat           = BVGetMat_Mat_CUDA;
479:     bv->ops->restoremat       = BVRestoreMat_Mat_CUDA;
480: #endif
481:   } else if (bv->hip) {
482: #if defined(PETSC_HAVE_HIP)
483:     bv->ops->mult             = BVMult_Mat_HIP;
484:     bv->ops->multvec          = BVMultVec_Mat_HIP;
485:     bv->ops->multinplace      = BVMultInPlace_Mat_HIP;
486:     bv->ops->multinplacetrans = BVMultInPlaceHermitianTranspose_Mat_HIP;
487:     bv->ops->dot              = BVDot_Mat_HIP;
488:     bv->ops->dotvec           = BVDotVec_Mat_HIP;
489:     bv->ops->dotvec_local     = BVDotVec_Local_Mat_HIP;
490:     bv->ops->scale            = BVScale_Mat_HIP;
491:     bv->ops->norm             = BVNorm_Mat_HIP;
492:     bv->ops->norm_local       = BVNorm_Local_Mat_HIP;
493:     bv->ops->normalize        = BVNormalize_Mat_HIP;
494:     bv->ops->matmult          = BVMatMult_Mat_HIP;
495:     bv->ops->copy             = BVCopy_Mat_HIP;
496:     bv->ops->copycolumn       = BVCopyColumn_Mat_HIP;
497:     bv->ops->getcolumn        = BVGetColumn_Mat_HIP;
498:     bv->ops->restorecolumn    = BVRestoreColumn_Mat_HIP;
499:     bv->ops->restoresplit     = BVRestoreSplit_Mat_HIP;
500:     bv->ops->restoresplitrows = BVRestoreSplitRows_Mat_HIP;
501:     bv->ops->getmat           = BVGetMat_Mat_HIP;
502:     bv->ops->restoremat       = BVRestoreMat_Mat_HIP;
503: #endif
504:   } else {
505:     bv->ops->mult             = BVMult_Mat;
506:     bv->ops->multvec          = BVMultVec_Mat;
507:     bv->ops->multinplace      = BVMultInPlace_Mat;
508:     bv->ops->multinplacetrans = BVMultInPlaceHermitianTranspose_Mat;
509:     bv->ops->dot              = BVDot_Mat;
510:     bv->ops->dotvec           = BVDotVec_Mat;
511:     bv->ops->dotvec_local     = BVDotVec_Local_Mat;
512:     bv->ops->scale            = BVScale_Mat;
513:     bv->ops->norm             = BVNorm_Mat;
514:     bv->ops->norm_local       = BVNorm_Local_Mat;
515:     bv->ops->normalize        = BVNormalize_Mat;
516:     bv->ops->matmult          = BVMatMult_Mat;
517:     bv->ops->copy             = BVCopy_Mat;
518:     bv->ops->copycolumn       = BVCopyColumn_Mat;
519:     bv->ops->getcolumn        = BVGetColumn_Mat;
520:     bv->ops->restorecolumn    = BVRestoreColumn_Mat;
521:     bv->ops->getmat           = BVGetMat_Default;
522:     bv->ops->restoremat       = BVRestoreMat_Default;
523:   }
524:   bv->ops->resize           = BVResize_Mat;
525:   bv->ops->getarray         = BVGetArray_Mat;
526:   bv->ops->restorearray     = BVRestoreArray_Mat;
527:   bv->ops->getarrayread     = BVGetArrayRead_Mat;
528:   bv->ops->restorearrayread = BVRestoreArrayRead_Mat;
529:   bv->ops->destroy          = BVDestroy_Mat;
530:   bv->ops->view             = BVView_Mat;
531:   PetscFunctionReturn(PETSC_SUCCESS);
532: }