| 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 | /*MC | ||
| 98 | SVDELEMENTAL - SVDELEMENTAL = "elemental" - A wrapper to Elemental | ||
| 99 | singular value solvers {cite:p}`Pou13`. | ||
| 100 | |||
| 101 | Notes: | ||
| 102 | Only available for standard SVD problems. | ||
| 103 | |||
| 104 | Elemental has a direct singular value solver, that is, the full spectrum | ||
| 105 | is computed. Its storage format is similar to ScaLAPACK, but different, | ||
| 106 | and it may have better parallel performance in some cases. The | ||
| 107 | SLEPc solver is also in charge of the redistribution of matrices. | ||
| 108 | |||
| 109 | Level: beginner | ||
| 110 | |||
| 111 | .seealso: [](ch:svd), `SVD`, `SVDType`, `SVDSetType()` | ||
| 112 | M*/ | ||
| 113 | 12 | SLEPC_EXTERN PetscErrorCode SVDCreate_Elemental(SVD svd) | |
| 114 | { | ||
| 115 | 12 | SVD_Elemental *ctx; | |
| 116 | |||
| 117 | 12 | PetscFunctionBegin; | |
| 118 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
12 | PetscCall(PetscNew(&ctx)); |
| 119 | 12 | svd->data = (void*)ctx; | |
| 120 | |||
| 121 | 12 | svd->ops->solve = SVDSolve_Elemental; | |
| 122 | 12 | svd->ops->setup = SVDSetUp_Elemental; | |
| 123 | 12 | svd->ops->destroy = SVDDestroy_Elemental; | |
| 124 | 12 | svd->ops->reset = SVDReset_Elemental; | |
| 125 | 12 | PetscFunctionReturn(PETSC_SUCCESS); | |
| 126 | } | ||
| 127 |