Line | Branch | Exec | Source |
---|---|---|---|
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 | This file implements a wrapper to the Elemental SVD solver | ||
12 | */ | ||
13 | |||
14 | #include <slepc/private/svdimpl.h> /*I "slepcsvd.h" I*/ | ||
15 | #include <petsc/private/petscelemental.h> | ||
16 | |||
17 | typedef struct { | ||
18 | Mat Ae; /* converted matrix */ | ||
19 | } SVD_Elemental; | ||
20 | |||
21 | 12 | static PetscErrorCode SVDSetUp_Elemental(SVD svd) | |
22 | { | ||
23 | 12 | SVD_Elemental *ctx = (SVD_Elemental*)svd->data; | |
24 | 12 | PetscInt M,N; | |
25 | |||
26 | 12 | PetscFunctionBegin; | |
27 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
12 | SVDCheckStandard(svd); |
28 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
12 | SVDCheckDefinite(svd); |
29 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | if (svd->nsv==0) svd->nsv = 1; |
30 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(MatGetSize(svd->A,&M,&N)); |
31 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
12 | PetscCheck(M==N,PetscObjectComm((PetscObject)svd),PETSC_ERR_SUP,"Not implemented for rectangular matrices"); |
32 | 12 | svd->ncv = N; | |
33 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
12 | if (svd->mpd!=PETSC_DETERMINE) PetscCall(PetscInfo(svd,"Warning: parameter mpd ignored\n")); |
34 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
12 | if (svd->max_it==PETSC_DETERMINE) svd->max_it = 1; |
35 | 12 | svd->leftbasis = PETSC_TRUE; | |
36 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
12 | SVDCheckIgnored(svd,SVD_FEATURE_STOPPING); |
37 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(SVDAllocateSolution(svd,0)); |
38 | |||
39 | /* convert matrix */ | ||
40 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(MatDestroy(&ctx->Ae)); |
41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(MatConvert(svd->OP,MATELEMENTAL,MAT_INITIAL_MATRIX,&ctx->Ae)); |
42 | PetscFunctionReturn(PETSC_SUCCESS); | ||
43 | } | ||
44 | |||
45 | 12 | static PetscErrorCode SVDSolve_Elemental(SVD svd) | |
46 | { | ||
47 | 12 | SVD_Elemental *ctx = (SVD_Elemental*)svd->data; | |
48 | 12 | Mat A = ctx->Ae,Z,Q,U,V; | |
49 | 12 | Mat_Elemental *a = (Mat_Elemental*)A->data,*q,*z; | |
50 | 12 | PetscInt i,rrank,ridx,erow; | |
51 | |||
52 | 12 | PetscFunctionBegin; | |
53 | 12 | El::DistMatrix<PetscReal,El::STAR,El::VC> sigma(*a->grid); | |
54 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&Z)); |
55 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&Q)); |
56 | 12 | z = (Mat_Elemental*)Z->data; | |
57 | 12 | q = (Mat_Elemental*)Q->data; | |
58 | |||
59 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
12 | El::SVD(*a->emat,*z->emat,sigma,*q->emat); |
60 | |||
61 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
3156 | for (i=0;i<svd->ncv;i++) { |
62 | 3144 | P2RO(A,1,i,&rrank,&ridx); | |
63 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
3144 | RO2E(A,1,rrank,ridx,&erow); |
64 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
3144 | svd->sigma[i] = sigma.Get(erow,0); |
65 | } | ||
66 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(BVGetMat(svd->U,&U)); |
67 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(MatConvert(Z,MATDENSE,MAT_REUSE_MATRIX,&U)); |
68 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(BVRestoreMat(svd->U,&U)); |
69 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(MatDestroy(&Z)); |
70 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(BVGetMat(svd->V,&V)); |
71 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(MatConvert(Q,MATDENSE,MAT_REUSE_MATRIX,&V)); |
72 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(BVRestoreMat(svd->V,&V)); |
73 |
2/6✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
12 | PetscCall(MatDestroy(&Q)); |
74 | |||
75 | 12 | svd->nconv = svd->ncv; | |
76 | 12 | svd->its = 1; | |
77 | 12 | svd->reason = SVD_CONVERGED_TOL; | |
78 | 12 | PetscFunctionReturn(PETSC_SUCCESS); | |
79 | 12 | } | |
80 | |||
81 | 12 | static PetscErrorCode SVDDestroy_Elemental(SVD svd) | |
82 | { | ||
83 | 12 | PetscFunctionBegin; | |
84 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(PetscFree(svd->data)); |
85 | PetscFunctionReturn(PETSC_SUCCESS); | ||
86 | } | ||
87 | |||
88 | 12 | static PetscErrorCode SVDReset_Elemental(SVD svd) | |
89 | { | ||
90 | 12 | SVD_Elemental *ctx = (SVD_Elemental*)svd->data; | |
91 | |||
92 | 12 | PetscFunctionBegin; | |
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(MatDestroy(&ctx->Ae)); |
94 | PetscFunctionReturn(PETSC_SUCCESS); | ||
95 | } | ||
96 | |||
97 | 12 | SLEPC_EXTERN PetscErrorCode SVDCreate_Elemental(SVD svd) | |
98 | { | ||
99 | 12 | SVD_Elemental *ctx; | |
100 | |||
101 | 12 | PetscFunctionBegin; | |
102 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(PetscNew(&ctx)); |
103 | 12 | svd->data = (void*)ctx; | |
104 | |||
105 | 12 | svd->ops->solve = SVDSolve_Elemental; | |
106 | 12 | svd->ops->setup = SVDSetUp_Elemental; | |
107 | 12 | svd->ops->destroy = SVDDestroy_Elemental; | |
108 | 12 | svd->ops->reset = SVDReset_Elemental; | |
109 | 12 | PetscFunctionReturn(PETSC_SUCCESS); | |
110 | } | ||
111 |