Actual source code: svec.c
slepc-3.22.2 2024-12-02
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 as a single Vec
12: */
14: #include <slepc/private/bvimpl.h>
15: #include "svec.h"
17: static PetscErrorCode BVMult_Svec(BV Y,PetscScalar alpha,PetscScalar beta,BV X,Mat Q)
18: {
19: BV_SVEC *y = (BV_SVEC*)Y->data,*x = (BV_SVEC*)X->data;
20: const PetscScalar *px,*q;
21: PetscScalar *py;
22: PetscInt ldq;
24: PetscFunctionBegin;
25: PetscCall(VecGetArrayRead(x->v,&px));
26: PetscCall(VecGetArray(y->v,&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(VecRestoreArrayRead(x->v,&px));
34: PetscCall(VecRestoreArray(y->v,&py));
35: PetscFunctionReturn(PETSC_SUCCESS);
36: }
38: static PetscErrorCode BVMultVec_Svec(BV X,PetscScalar alpha,PetscScalar beta,Vec y,PetscScalar *q)
39: {
40: BV_SVEC *x = (BV_SVEC*)X->data;
41: PetscScalar *px,*py,*qq=q;
43: PetscFunctionBegin;
44: PetscCall(VecGetArray(x->v,&px));
45: PetscCall(VecGetArray(y,&py));
46: if (!q) PetscCall(VecGetArray(X->buffer,&qq));
47: 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: if (!q) PetscCall(VecRestoreArray(X->buffer,&qq));
49: PetscCall(VecRestoreArray(x->v,&px));
50: PetscCall(VecRestoreArray(y,&py));
51: PetscFunctionReturn(PETSC_SUCCESS);
52: }
54: static PetscErrorCode BVMultInPlace_Svec(BV V,Mat Q,PetscInt s,PetscInt e)
55: {
56: BV_SVEC *ctx = (BV_SVEC*)V->data;
57: PetscScalar *pv;
58: const PetscScalar *q;
59: PetscInt ldq;
61: PetscFunctionBegin;
62: if (s>=e || !V->n) PetscFunctionReturn(PETSC_SUCCESS);
63: PetscCall(MatDenseGetLDA(Q,&ldq));
64: PetscCall(VecGetArray(ctx->v,&pv));
65: PetscCall(MatDenseGetArrayRead(Q,&q));
66: 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: PetscCall(MatDenseRestoreArrayRead(Q,&q));
68: PetscCall(VecRestoreArray(ctx->v,&pv));
69: PetscFunctionReturn(PETSC_SUCCESS);
70: }
72: static PetscErrorCode BVMultInPlaceHermitianTranspose_Svec(BV V,Mat Q,PetscInt s,PetscInt e)
73: {
74: BV_SVEC *ctx = (BV_SVEC*)V->data;
75: PetscScalar *pv;
76: const PetscScalar *q;
77: PetscInt ldq;
79: PetscFunctionBegin;
80: if (s>=e || !V->n) PetscFunctionReturn(PETSC_SUCCESS);
81: PetscCall(MatDenseGetLDA(Q,&ldq));
82: PetscCall(VecGetArray(ctx->v,&pv));
83: PetscCall(MatDenseGetArrayRead(Q,&q));
84: 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: PetscCall(MatDenseRestoreArrayRead(Q,&q));
86: PetscCall(VecRestoreArray(ctx->v,&pv));
87: PetscFunctionReturn(PETSC_SUCCESS);
88: }
90: static PetscErrorCode BVDot_Svec(BV X,BV Y,Mat M)
91: {
92: BV_SVEC *x = (BV_SVEC*)X->data,*y = (BV_SVEC*)Y->data;
93: const PetscScalar *px,*py;
94: PetscScalar *m;
95: PetscInt ldm;
97: PetscFunctionBegin;
98: PetscCall(MatDenseGetLDA(M,&ldm));
99: PetscCall(VecGetArrayRead(x->v,&px));
100: PetscCall(VecGetArrayRead(y->v,&py));
101: PetscCall(MatDenseGetArray(M,&m));
102: 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: PetscCall(MatDenseRestoreArray(M,&m));
104: PetscCall(VecRestoreArrayRead(x->v,&px));
105: PetscCall(VecRestoreArrayRead(y->v,&py));
106: PetscFunctionReturn(PETSC_SUCCESS);
107: }
109: static PetscErrorCode BVDotVec_Svec(BV X,Vec y,PetscScalar *q)
110: {
111: BV_SVEC *x = (BV_SVEC*)X->data;
112: const PetscScalar *px,*py;
113: PetscScalar *qq=q;
114: Vec z = y;
116: PetscFunctionBegin;
117: if (PetscUnlikely(X->matrix)) {
118: PetscCall(BV_IPMatMult(X,y));
119: z = X->Bx;
120: }
121: PetscCall(VecGetArrayRead(x->v,&px));
122: PetscCall(VecGetArrayRead(z,&py));
123: if (!q) PetscCall(VecGetArray(X->buffer,&qq));
124: 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: if (!q) PetscCall(VecRestoreArray(X->buffer,&qq));
126: PetscCall(VecRestoreArrayRead(z,&py));
127: PetscCall(VecRestoreArrayRead(x->v,&px));
128: PetscFunctionReturn(PETSC_SUCCESS);
129: }
131: static PetscErrorCode BVDotVec_Local_Svec(BV X,Vec y,PetscScalar *m)
132: {
133: BV_SVEC *x = (BV_SVEC*)X->data;
134: PetscScalar *px,*py;
135: Vec z = y;
137: PetscFunctionBegin;
138: if (PetscUnlikely(X->matrix)) {
139: PetscCall(BV_IPMatMult(X,y));
140: z = X->Bx;
141: }
142: PetscCall(VecGetArray(x->v,&px));
143: PetscCall(VecGetArray(z,&py));
144: 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: PetscCall(VecRestoreArray(z,&py));
146: PetscCall(VecRestoreArray(x->v,&px));
147: PetscFunctionReturn(PETSC_SUCCESS);
148: }
150: static PetscErrorCode BVScale_Svec(BV bv,PetscInt j,PetscScalar alpha)
151: {
152: BV_SVEC *ctx = (BV_SVEC*)bv->data;
153: PetscScalar *array;
155: PetscFunctionBegin;
156: if (!bv->n) PetscFunctionReturn(PETSC_SUCCESS);
157: PetscCall(VecGetArray(ctx->v,&array));
158: if (PetscUnlikely(j<0)) PetscCall(BVScale_BLAS_Private(bv,(bv->k-bv->l)*bv->ld,array+(bv->nc+bv->l)*bv->ld,alpha));
159: else PetscCall(BVScale_BLAS_Private(bv,bv->n,array+(bv->nc+j)*bv->ld,alpha));
160: PetscCall(VecRestoreArray(ctx->v,&array));
161: PetscFunctionReturn(PETSC_SUCCESS);
162: }
164: static PetscErrorCode BVNorm_Svec(BV bv,PetscInt j,NormType type,PetscReal *val)
165: {
166: BV_SVEC *ctx = (BV_SVEC*)bv->data;
167: const PetscScalar *array;
169: PetscFunctionBegin;
170: PetscCall(VecGetArrayRead(ctx->v,&array));
171: 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: else PetscCall(BVNorm_LAPACK_Private(bv,bv->n,1,array+(bv->nc+j)*bv->ld,bv->ld,type,val,ctx->mpi));
173: PetscCall(VecRestoreArrayRead(ctx->v,&array));
174: PetscFunctionReturn(PETSC_SUCCESS);
175: }
177: static PetscErrorCode BVNorm_Local_Svec(BV bv,PetscInt j,NormType type,PetscReal *val)
178: {
179: BV_SVEC *ctx = (BV_SVEC*)bv->data;
180: const PetscScalar *array;
182: PetscFunctionBegin;
183: PetscCall(VecGetArrayRead(ctx->v,&array));
184: 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: else PetscCall(BVNorm_LAPACK_Private(bv,bv->n,1,array+(bv->nc+j)*bv->ld,bv->ld,type,val,PETSC_FALSE));
186: PetscCall(VecRestoreArrayRead(ctx->v,&array));
187: PetscFunctionReturn(PETSC_SUCCESS);
188: }
190: static PetscErrorCode BVNormalize_Svec(BV bv,PetscScalar *eigi)
191: {
192: BV_SVEC *ctx = (BV_SVEC*)bv->data;
193: PetscScalar *array,*wi=NULL;
195: PetscFunctionBegin;
196: PetscCall(VecGetArray(ctx->v,&array));
197: if (eigi) wi = eigi+bv->l;
198: PetscCall(BVNormalize_LAPACK_Private(bv,bv->n,bv->k-bv->l,array+(bv->nc+bv->l)*bv->ld,bv->ld,wi,ctx->mpi));
199: PetscCall(VecRestoreArray(ctx->v,&array));
200: PetscFunctionReturn(PETSC_SUCCESS);
201: }
203: static PetscErrorCode BVMatMult_Svec(BV V,Mat A,BV W)
204: {
205: PetscInt j;
206: Mat Vmat,Wmat;
207: Vec vv,ww;
209: PetscFunctionBegin;
210: if (V->vmm) {
211: PetscCall(BVGetMat(V,&Vmat));
212: PetscCall(BVGetMat(W,&Wmat));
213: PetscCall(MatProductCreateWithMat(A,Vmat,NULL,Wmat));
214: PetscCall(MatProductSetType(Wmat,MATPRODUCT_AB));
215: PetscCall(MatProductSetFromOptions(Wmat));
216: PetscCall(MatProductSymbolic(Wmat));
217: PetscCall(MatProductNumeric(Wmat));
218: PetscCall(MatProductClear(Wmat));
219: PetscCall(BVRestoreMat(V,&Vmat));
220: PetscCall(BVRestoreMat(W,&Wmat));
221: } else {
222: for (j=0;j<V->k-V->l;j++) {
223: PetscCall(BVGetColumn(V,V->l+j,&vv));
224: PetscCall(BVGetColumn(W,W->l+j,&ww));
225: PetscCall(MatMult(A,vv,ww));
226: PetscCall(BVRestoreColumn(V,V->l+j,&vv));
227: PetscCall(BVRestoreColumn(W,W->l+j,&ww));
228: }
229: }
230: PetscFunctionReturn(PETSC_SUCCESS);
231: }
233: static PetscErrorCode BVCopy_Svec(BV V,BV W)
234: {
235: BV_SVEC *v = (BV_SVEC*)V->data,*w = (BV_SVEC*)W->data;
236: const PetscScalar *pv;
237: PetscScalar *pw;
238: PetscInt j;
240: PetscFunctionBegin;
241: PetscCall(VecGetArrayRead(v->v,&pv));
242: PetscCall(VecGetArray(w->v,&pw));
243: 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: PetscCall(VecRestoreArrayRead(v->v,&pv));
245: PetscCall(VecRestoreArray(w->v,&pw));
246: PetscFunctionReturn(PETSC_SUCCESS);
247: }
249: static PetscErrorCode BVCopyColumn_Svec(BV V,PetscInt j,PetscInt i)
250: {
251: BV_SVEC *v = (BV_SVEC*)V->data;
252: PetscScalar *pv;
254: PetscFunctionBegin;
255: PetscCall(VecGetArray(v->v,&pv));
256: PetscCall(PetscArraycpy(pv+(V->nc+i)*V->ld,pv+(V->nc+j)*V->ld,V->n));
257: PetscCall(VecRestoreArray(v->v,&pv));
258: PetscFunctionReturn(PETSC_SUCCESS);
259: }
261: static PetscErrorCode BVResize_Svec(BV bv,PetscInt m,PetscBool copy)
262: {
263: BV_SVEC *ctx = (BV_SVEC*)bv->data;
264: PetscScalar *pnew;
265: const PetscScalar *pv;
266: PetscInt bs;
267: Vec vnew;
268: char str[50];
270: PetscFunctionBegin;
271: PetscCall(PetscLayoutGetBlockSize(bv->map,&bs));
272: PetscCall(VecCreate(PetscObjectComm((PetscObject)bv),&vnew));
273: PetscCall(VecSetType(vnew,bv->vtype));
274: PetscCall(VecSetSizes(vnew,m*bv->ld,PETSC_DECIDE));
275: PetscCall(VecSetBlockSize(vnew,bs));
276: if (((PetscObject)bv)->name) {
277: PetscCall(PetscSNPrintf(str,sizeof(str),"%s_0",((PetscObject)bv)->name));
278: PetscCall(PetscObjectSetName((PetscObject)vnew,str));
279: }
280: if (copy) {
281: PetscCall(VecGetArrayRead(ctx->v,&pv));
282: PetscCall(VecGetArray(vnew,&pnew));
283: PetscCall(PetscArraycpy(pnew,pv,PetscMin(m,bv->m)*bv->ld));
284: PetscCall(VecRestoreArrayRead(ctx->v,&pv));
285: PetscCall(VecRestoreArray(vnew,&pnew));
286: }
287: PetscCall(VecDestroy(&ctx->v));
288: ctx->v = vnew;
289: PetscFunctionReturn(PETSC_SUCCESS);
290: }
292: static PetscErrorCode BVGetColumn_Svec(BV bv,PetscInt j,Vec *v)
293: {
294: BV_SVEC *ctx = (BV_SVEC*)bv->data;
295: PetscScalar *pv;
296: PetscInt l;
298: PetscFunctionBegin;
299: l = BVAvailableVec;
300: PetscCall(VecGetArray(ctx->v,&pv));
301: PetscCall(VecPlaceArray(bv->cv[l],pv+(bv->nc+j)*bv->ld));
302: PetscFunctionReturn(PETSC_SUCCESS);
303: }
305: static PetscErrorCode BVRestoreColumn_Svec(BV bv,PetscInt j,Vec *v)
306: {
307: BV_SVEC *ctx = (BV_SVEC*)bv->data;
308: PetscInt l;
310: PetscFunctionBegin;
311: l = (j==bv->ci[0])? 0: 1;
312: PetscCall(VecResetArray(bv->cv[l]));
313: PetscCall(VecRestoreArray(ctx->v,NULL));
314: PetscFunctionReturn(PETSC_SUCCESS);
315: }
317: static PetscErrorCode BVGetArray_Svec(BV bv,PetscScalar **a)
318: {
319: BV_SVEC *ctx = (BV_SVEC*)bv->data;
321: PetscFunctionBegin;
322: PetscCall(VecGetArray(ctx->v,a));
323: PetscFunctionReturn(PETSC_SUCCESS);
324: }
326: static PetscErrorCode BVRestoreArray_Svec(BV bv,PetscScalar **a)
327: {
328: BV_SVEC *ctx = (BV_SVEC*)bv->data;
330: PetscFunctionBegin;
331: PetscCall(VecRestoreArray(ctx->v,a));
332: PetscFunctionReturn(PETSC_SUCCESS);
333: }
335: static PetscErrorCode BVGetArrayRead_Svec(BV bv,const PetscScalar **a)
336: {
337: BV_SVEC *ctx = (BV_SVEC*)bv->data;
339: PetscFunctionBegin;
340: PetscCall(VecGetArrayRead(ctx->v,a));
341: PetscFunctionReturn(PETSC_SUCCESS);
342: }
344: static PetscErrorCode BVRestoreArrayRead_Svec(BV bv,const PetscScalar **a)
345: {
346: BV_SVEC *ctx = (BV_SVEC*)bv->data;
348: PetscFunctionBegin;
349: PetscCall(VecRestoreArrayRead(ctx->v,a));
350: PetscFunctionReturn(PETSC_SUCCESS);
351: }
353: static PetscErrorCode BVView_Svec(BV bv,PetscViewer viewer)
354: {
355: PetscInt j;
356: Vec v;
357: PetscViewerFormat format;
358: PetscBool isascii,ismatlab=PETSC_FALSE;
359: const char *bvname,*name;
361: PetscFunctionBegin;
362: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
363: if (isascii) {
364: PetscCall(PetscViewerGetFormat(viewer,&format));
365: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(PETSC_SUCCESS);
366: if (format == PETSC_VIEWER_ASCII_MATLAB) ismatlab = PETSC_TRUE;
367: }
368: if (ismatlab) {
369: PetscCall(PetscObjectGetName((PetscObject)bv,&bvname));
370: PetscCall(PetscViewerASCIIPrintf(viewer,"%s=[];\n",bvname));
371: }
372: for (j=0;j<bv->m;j++) {
373: PetscCall(BVGetColumn(bv,j,&v));
374: PetscCall(VecView(v,viewer));
375: if (ismatlab) {
376: PetscCall(PetscObjectGetName((PetscObject)v,&name));
377: PetscCall(PetscViewerASCIIPrintf(viewer,"%s=[%s,%s];clear %s\n",bvname,bvname,name,name));
378: }
379: PetscCall(BVRestoreColumn(bv,j,&v));
380: }
381: PetscFunctionReturn(PETSC_SUCCESS);
382: }
384: static PetscErrorCode BVDestroy_Svec(BV bv)
385: {
386: BV_SVEC *ctx = (BV_SVEC*)bv->data;
388: PetscFunctionBegin;
389: PetscCall(VecDestroy(&ctx->v));
390: PetscCall(VecDestroy(&bv->cv[0]));
391: PetscCall(VecDestroy(&bv->cv[1]));
392: PetscCall(PetscFree(bv->data));
393: bv->cuda = PETSC_FALSE;
394: PetscFunctionReturn(PETSC_SUCCESS);
395: }
397: SLEPC_EXTERN PetscErrorCode BVCreate_Svec(BV bv)
398: {
399: BV_SVEC *ctx;
400: PetscInt nloc,N,bs,tglobal=0,tlocal,lsplit,j,lda;
401: PetscBool seq,isdense;
402: PetscScalar *vv;
403: const PetscScalar *aa,*array,*ptr;
404: char str[50];
405: BV parent;
406: Vec vpar;
407: MatType mtype;
409: PetscFunctionBegin;
410: PetscCall(PetscNew(&ctx));
411: bv->data = (void*)ctx;
413: PetscCall(PetscStrcmpAny(bv->vtype,&bv->cuda,VECSEQCUDA,VECMPICUDA,""));
414: PetscCall(PetscStrcmpAny(bv->vtype,&bv->hip,VECSEQHIP,VECMPIHIP,""));
415: PetscCall(PetscStrcmpAny(bv->vtype,&ctx->mpi,VECMPI,VECMPICUDA,VECMPIHIP,""));
417: PetscCall(PetscStrcmp(bv->vtype,VECSEQ,&seq));
418: 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);
420: PetscCall(PetscLayoutGetLocalSize(bv->map,&nloc));
421: PetscCall(PetscLayoutGetSize(bv->map,&N));
422: PetscCall(PetscLayoutGetBlockSize(bv->map,&bs));
423: PetscCall(BV_SetDefaultLD(bv,nloc));
424: tlocal = bv->m*bv->ld;
425: PetscCall(PetscIntMultError(bv->m,N,&tglobal)); /* just to check integer overflow */
427: if (PetscUnlikely(bv->issplit)) {
428: /* split BV: create Vec sharing the memory of the parent BV */
429: parent = bv->splitparent;
430: lsplit = parent->lsplit;
431: vpar = ((BV_SVEC*)parent->data)->v;
432: 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: } 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: PetscCall(VecGetArrayRead(vpar,&array));
454: if (bv->issplit>0) ptr = (bv->issplit==1)? array: array+lsplit*bv->ld;
455: else ptr = (bv->issplit==1)? array: array-lsplit;
456: PetscCall(VecRestoreArrayRead(vpar,&array));
457: if (ctx->mpi) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,PETSC_DECIDE,NULL,&ctx->v));
458: else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)bv),bs,tlocal,NULL,&ctx->v));
459: PetscCall(VecPlaceArray(ctx->v,ptr));
460: }
461: } else {
462: /* regular BV: create Vec to store the BV entries */
463: PetscCall(VecCreate(PetscObjectComm((PetscObject)bv),&ctx->v));
464: PetscCall(VecSetType(ctx->v,bv->vtype));
465: PetscCall(VecSetSizes(ctx->v,tlocal,PETSC_DECIDE));
466: PetscCall(VecSetBlockSize(ctx->v,bs));
467: }
468: if (((PetscObject)bv)->name) {
469: PetscCall(PetscSNPrintf(str,sizeof(str),"%s_0",((PetscObject)bv)->name));
470: PetscCall(PetscObjectSetName((PetscObject)ctx->v,str));
471: }
473: if (PetscUnlikely(bv->Acreate)) {
474: PetscCall(MatGetType(bv->Acreate,&mtype));
475: PetscCall(PetscStrcmpAny(mtype,&isdense,MATSEQDENSE,MATMPIDENSE,""));
476: PetscCheck(isdense,PetscObjectComm((PetscObject)bv->Acreate),PETSC_ERR_SUP,"BVSVEC requires a dense matrix in BVCreateFromMat()");
477: PetscCall(MatDenseGetArrayRead(bv->Acreate,&aa));
478: PetscCall(MatDenseGetLDA(bv->Acreate,&lda));
479: PetscCall(VecGetArray(ctx->v,&vv));
480: for (j=0;j<bv->m;j++) PetscCall(PetscArraycpy(vv+j*bv->ld,aa+j*lda,bv->n));
481: PetscCall(VecRestoreArray(ctx->v,&vv));
482: PetscCall(MatDenseRestoreArrayRead(bv->Acreate,&aa));
483: PetscCall(MatDestroy(&bv->Acreate));
484: }
486: PetscCall(BVCreateVecEmpty(bv,&bv->cv[0]));
487: PetscCall(BVCreateVecEmpty(bv,&bv->cv[1]));
489: 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: } 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: bv->ops->mult = BVMult_Svec;
539: bv->ops->multvec = BVMultVec_Svec;
540: bv->ops->multinplace = BVMultInPlace_Svec;
541: bv->ops->multinplacetrans = BVMultInPlaceHermitianTranspose_Svec;
542: bv->ops->dot = BVDot_Svec;
543: bv->ops->dotvec = BVDotVec_Svec;
544: bv->ops->dotvec_local = BVDotVec_Local_Svec;
545: bv->ops->scale = BVScale_Svec;
546: bv->ops->norm = BVNorm_Svec;
547: bv->ops->norm_local = BVNorm_Local_Svec;
548: bv->ops->normalize = BVNormalize_Svec;
549: bv->ops->matmult = BVMatMult_Svec;
550: bv->ops->copy = BVCopy_Svec;
551: bv->ops->copycolumn = BVCopyColumn_Svec;
552: bv->ops->resize = BVResize_Svec;
553: bv->ops->getcolumn = BVGetColumn_Svec;
554: bv->ops->restorecolumn = BVRestoreColumn_Svec;
555: bv->ops->getmat = BVGetMat_Default;
556: bv->ops->restoremat = BVRestoreMat_Default;
557: }
558: bv->ops->getarray = BVGetArray_Svec;
559: bv->ops->restorearray = BVRestoreArray_Svec;
560: bv->ops->getarrayread = BVGetArrayRead_Svec;
561: bv->ops->restorearrayread = BVRestoreArrayRead_Svec;
562: bv->ops->destroy = BVDestroy_Svec;
563: if (!ctx->mpi) bv->ops->view = BVView_Svec;
564: PetscFunctionReturn(PETSC_SUCCESS);
565: }