LCOV - code coverage report
Current view: top level - sys/classes/bv/tests - test11.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 130 140 92.9 %
Date: 2024-11-21 00:40:22 Functions: 2 2 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             : static char help[] = "Test BV block orthogonalization.\n\n";
      12             : 
      13             : #include <slepcbv.h>
      14             : 
      15             : /*
      16             :    Compute the Frobenius norm ||A(l:k,l:k)-diag||_F
      17             :  */
      18         496 : PetscErrorCode MyMatNorm(Mat A,PetscInt lda,PetscInt l,PetscInt k,PetscScalar diag,PetscReal *norm)
      19             : {
      20         496 :   PetscInt          i,j;
      21         496 :   const PetscScalar *pA;
      22         496 :   PetscReal         s,val;
      23             : 
      24         496 :   PetscFunctionBeginUser;
      25         496 :   PetscCall(MatDenseGetArrayRead(A,&pA));
      26             :   s = 0.0;
      27        3188 :   for (i=l;i<k;i++) {
      28       20288 :     for (j=l;j<k;j++) {
      29       17596 :       val = (i==j)? PetscAbsScalar(pA[i+j*lda]-diag): PetscAbsScalar(pA[i+j*lda]);
      30       17596 :       s += val*val;
      31             :     }
      32             :   }
      33         496 :   *norm = PetscSqrtReal(s);
      34         496 :   PetscCall(MatDenseRestoreArrayRead(A,&pA));
      35         496 :   PetscFunctionReturn(PETSC_SUCCESS);
      36             : }
      37             : 
      38         184 : int main(int argc,char **argv)
      39             : {
      40         184 :   BV             X,Y,Z,cached;
      41         184 :   Mat            B=NULL,M,R=NULL;
      42         184 :   Vec            v,t;
      43         184 :   PetscInt       i,j,n=20,l=2,k=8,Istart,Iend;
      44         184 :   PetscViewer    view;
      45         184 :   PetscBool      withb,resid,rand,verbose;
      46         184 :   PetscReal      norm;
      47         184 :   PetscScalar    alpha;
      48             : 
      49         184 :   PetscFunctionBeginUser;
      50         184 :   PetscCall(SlepcInitialize(&argc,&argv,NULL,help));
      51         184 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
      52         184 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-l",&l,NULL));
      53         184 :   PetscCall(PetscOptionsGetInt(NULL,NULL,"-k",&k,NULL));
      54         184 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-withb",&withb));
      55         184 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-resid",&resid));
      56         184 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-rand",&rand));
      57         184 :   PetscCall(PetscOptionsHasName(NULL,NULL,"-verbose",&verbose));
      58         320 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Test BV block orthogonalization (length %" PetscInt_FMT ", l=%" PetscInt_FMT ", k=%" PetscInt_FMT ")%s.\n",n,l,k,withb?" with non-standard inner product":""));
      59             : 
      60             :   /* Create template vector */
      61         184 :   PetscCall(VecCreate(PETSC_COMM_WORLD,&t));
      62         184 :   PetscCall(VecSetSizes(t,PETSC_DECIDE,n));
      63         184 :   PetscCall(VecSetFromOptions(t));
      64             : 
      65             :   /* Create BV object X */
      66         184 :   PetscCall(BVCreate(PETSC_COMM_WORLD,&X));
      67         184 :   PetscCall(PetscObjectSetName((PetscObject)X,"X"));
      68         184 :   PetscCall(BVSetSizesFromVec(X,t,k));
      69         184 :   PetscCall(BVSetFromOptions(X));
      70             : 
      71             :   /* Set up viewer */
      72         184 :   PetscCall(PetscViewerASCIIGetStdout(PETSC_COMM_WORLD,&view));
      73         184 :   if (verbose) PetscCall(PetscViewerPushFormat(view,PETSC_VIEWER_ASCII_MATLAB));
      74             : 
      75             :   /* Fill X entries */
      76         184 :   if (rand) PetscCall(BVSetRandom(X));
      77             :   else {
      78        1628 :     for (j=0;j<k;j++) {
      79        1444 :       PetscCall(BVGetColumn(X,j,&v));
      80        1444 :       PetscCall(VecSet(v,0.0));
      81       33008 :       for (i=0;i<=n/2;i++) {
      82       31564 :         if (i+j<n) {
      83       31564 :           alpha = (3.0*i+j-2)/(2*(i+j+1));
      84       31564 :           PetscCall(VecSetValue(v,i+j,alpha,INSERT_VALUES));
      85             :         }
      86             :       }
      87        1444 :       PetscCall(VecAssemblyBegin(v));
      88        1444 :       PetscCall(VecAssemblyEnd(v));
      89        1444 :       PetscCall(BVRestoreColumn(X,j,&v));
      90             :     }
      91             :   }
      92         184 :   if (verbose) PetscCall(BVView(X,view));
      93             : 
      94         184 :   if (withb) {
      95             :     /* Create inner product matrix */
      96          48 :     PetscCall(MatCreate(PETSC_COMM_WORLD,&B));
      97          48 :     PetscCall(MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,n,n));
      98          48 :     PetscCall(MatSetFromOptions(B));
      99          48 :     PetscCall(PetscObjectSetName((PetscObject)B,"B"));
     100             : 
     101          48 :     PetscCall(MatGetOwnershipRange(B,&Istart,&Iend));
     102         528 :     for (i=Istart;i<Iend;i++) {
     103         480 :       if (i>0) PetscCall(MatSetValue(B,i,i-1,-1.0,INSERT_VALUES));
     104         480 :       if (i<n-1) PetscCall(MatSetValue(B,i,i+1,-1.0,INSERT_VALUES));
     105         480 :       PetscCall(MatSetValue(B,i,i,2.0,INSERT_VALUES));
     106             :     }
     107          48 :     PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
     108          48 :     PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
     109          48 :     if (verbose) PetscCall(MatView(B,view));
     110          48 :     PetscCall(BVSetMatrix(X,B,PETSC_FALSE));
     111             :   }
     112             : 
     113             :   /* Create copy on Y */
     114         184 :   PetscCall(BVDuplicate(X,&Y));
     115         184 :   PetscCall(PetscObjectSetName((PetscObject)Y,"Y"));
     116         184 :   PetscCall(BVCopy(X,Y));
     117         184 :   PetscCall(MatCreateSeqDense(PETSC_COMM_SELF,k,k,NULL,&M));
     118             : 
     119         184 :   if (resid) {
     120             :     /* Create matrix R to store triangular factor */
     121          92 :     PetscCall(MatCreateSeqDense(PETSC_COMM_SELF,k,k,NULL,&R));
     122          92 :     PetscCall(PetscObjectSetName((PetscObject)R,"R"));
     123             :   }
     124             : 
     125         184 :   if (l>0) {
     126             :     /* First orthogonalize leading columns */
     127         156 :     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Orthogonalizing leading columns\n"));
     128         156 :     PetscCall(BVSetActiveColumns(Y,0,l));
     129         156 :     PetscCall(BVSetActiveColumns(X,0,l));
     130         156 :     PetscCall(BVOrthogonalize(Y,R));
     131         156 :     if (verbose) {
     132           0 :       PetscCall(BVView(Y,view));
     133           0 :       if (resid) PetscCall(MatView(R,view));
     134             :     }
     135             : 
     136         156 :     if (withb) {
     137             :       /* Extract cached BV and check it is equal to B*X */
     138          48 :       PetscCall(BVGetCachedBV(Y,&cached));
     139          48 :       PetscCall(BVDuplicate(X,&Z));
     140          48 :       PetscCall(BVSetMatrix(Z,NULL,PETSC_FALSE));
     141          48 :       PetscCall(BVSetActiveColumns(Z,0,l));
     142          48 :       PetscCall(BVCopy(X,Z));
     143          48 :       PetscCall(BVMatMult(X,B,Z));
     144          48 :       PetscCall(BVMult(Z,-1.0,1.0,cached,NULL));
     145          48 :       PetscCall(BVNorm(Z,NORM_FROBENIUS,&norm));
     146          48 :       if (norm<100*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Difference ||cached-BX|| < 100*eps\n"));
     147           0 :       else PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Difference ||cached-BX||: %g\n",(double)norm));
     148          48 :       PetscCall(BVDestroy(&Z));
     149             :     }
     150             : 
     151             :     /* Check orthogonality */
     152         156 :     PetscCall(BVDot(Y,Y,M));
     153         156 :     PetscCall(MyMatNorm(M,k,0,l,1.0,&norm));
     154         156 :     if (norm<100*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Level of orthogonality of Q1 < 100*eps\n"));
     155           0 :     else PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Level of orthogonality of Q1: %g\n",(double)norm));
     156             : 
     157         156 :     if (resid) {
     158             :       /* Check residual */
     159          64 :       PetscCall(BVDuplicate(X,&Z));
     160          64 :       PetscCall(BVSetMatrix(Z,NULL,PETSC_FALSE));
     161          64 :       PetscCall(BVSetActiveColumns(Z,0,l));
     162          64 :       PetscCall(BVCopy(X,Z));
     163          64 :       PetscCall(BVMult(Z,-1.0,1.0,Y,R));
     164          64 :       PetscCall(BVNorm(Z,NORM_FROBENIUS,&norm));
     165          64 :       if (norm<100*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Residual ||X1-Q1*R11|| < 100*eps\n"));
     166           0 :       else PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Residual ||X1-Q1*R11||: %g\n",(double)norm));
     167          64 :       PetscCall(BVDestroy(&Z));
     168             :     }
     169             : 
     170             :   }
     171             : 
     172             :   /* Now orthogonalize the rest of columns */
     173         184 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Orthogonalizing active columns\n"));
     174         184 :   PetscCall(BVSetActiveColumns(Y,l,k));
     175         184 :   PetscCall(BVSetActiveColumns(X,l,k));
     176         184 :   PetscCall(BVOrthogonalize(Y,R));
     177         184 :   if (verbose) {
     178           0 :     PetscCall(BVView(Y,view));
     179           0 :     if (resid) PetscCall(MatView(R,view));
     180             :   }
     181             : 
     182         184 :   if (l>0) {
     183             :     /* Check orthogonality */
     184         156 :     PetscCall(BVDot(Y,Y,M));
     185         156 :     PetscCall(MyMatNorm(M,k,l,k,1.0,&norm));
     186         156 :     if (norm<100*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Level of orthogonality of Q2 < 100*eps\n"));
     187           0 :     else PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Level of orthogonality of Q2: %g\n",(double)norm));
     188             :   }
     189             : 
     190             :   /* Check the complete decomposition */
     191         184 :   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Overall decomposition\n"));
     192         184 :   PetscCall(BVSetActiveColumns(Y,0,k));
     193         184 :   PetscCall(BVSetActiveColumns(X,0,k));
     194             : 
     195             :   /* Check orthogonality */
     196         184 :   PetscCall(BVDot(Y,Y,M));
     197         184 :   PetscCall(MyMatNorm(M,k,0,k,1.0,&norm));
     198         184 :   if (norm<100*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Level of orthogonality of Q < 100*eps\n"));
     199           0 :   else PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Level of orthogonality of Q: %g\n",(double)norm));
     200             : 
     201         184 :   if (resid) {
     202             :     /* Check residual */
     203          92 :     PetscCall(BVMult(X,-1.0,1.0,Y,R));
     204          92 :     PetscCall(BVSetMatrix(X,NULL,PETSC_FALSE));
     205          92 :     PetscCall(BVNorm(X,NORM_FROBENIUS,&norm));
     206          92 :     if (norm<100*PETSC_MACHINE_EPSILON) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Residual ||X-Q*R|| < 100*eps\n"));
     207           0 :     else PetscCall(PetscPrintf(PETSC_COMM_WORLD,"  Residual ||X-Q*R||: %g\n",(double)norm));
     208          92 :     PetscCall(MatDestroy(&R));
     209             :   }
     210             : 
     211         184 :   if (B) PetscCall(MatDestroy(&B));
     212         184 :   PetscCall(MatDestroy(&M));
     213         184 :   PetscCall(BVDestroy(&X));
     214         184 :   PetscCall(BVDestroy(&Y));
     215         184 :   PetscCall(VecDestroy(&t));
     216         184 :   PetscCall(SlepcFinalize());
     217             :   return 0;
     218             : }
     219             : 
     220             : /*TEST
     221             : 
     222             :    testset:
     223             :       args: -bv_orthog_block {{gs chol tsqr tsqrchol svqb}}
     224             :       nsize: 2
     225             :       output_file: output/test11_1.out
     226             :       test:
     227             :          suffix: 1
     228             :          args: -bv_type {{vecs contiguous svec mat}shared output}
     229             :       test:
     230             :          suffix: 1_cuda
     231             :          args: -bv_type {{svec mat}} -vec_type cuda
     232             :          requires: cuda
     233             :       test:
     234             :          suffix: 1_hip
     235             :          args: -bv_type {{svec mat}} -vec_type hip
     236             :          requires: hip
     237             : 
     238             :    testset:
     239             :       args: -withb -bv_orthog_block {{gs chol svqb}}
     240             :       nsize: 2
     241             :       output_file: output/test11_4.out
     242             :       test:
     243             :          suffix: 4
     244             :          args: -bv_type {{vecs contiguous svec mat}shared output}
     245             :       test:
     246             :          suffix: 4_cuda
     247             :          args: -bv_type {{svec mat}} -vec_type cuda -mat_type aijcusparse
     248             :          requires: cuda
     249             :       test:
     250             :          suffix: 4_hip
     251             :          args: -bv_type {{svec mat}} -vec_type hip -mat_type aijhipsparse
     252             :          requires: hip
     253             : 
     254             :    testset:
     255             :       args: -resid -bv_orthog_block {{gs chol tsqr tsqrchol svqb}}
     256             :       nsize: 2
     257             :       output_file: output/test11_6.out
     258             :       test:
     259             :          suffix: 6
     260             :          args: -bv_type {{vecs contiguous svec mat}shared output}
     261             :       test:
     262             :          suffix: 6_cuda
     263             :          args: -bv_type {{svec mat}} -vec_type cuda
     264             :          requires: cuda
     265             :       test:
     266             :          suffix: 6_hip
     267             :          args: -bv_type {{svec mat}} -vec_type hip
     268             :          requires: hip
     269             : 
     270             :    testset:
     271             :       args: -resid -withb -bv_orthog_block {{gs chol svqb}}
     272             :       nsize: 2
     273             :       output_file: output/test11_9.out
     274             :       test:
     275             :          suffix: 9
     276             :          args: -bv_type {{vecs contiguous svec mat}shared output}
     277             :       test:
     278             :          suffix: 9_cuda
     279             :          args: -bv_type {{svec mat}} -vec_type cuda -mat_type aijcusparse
     280             :          requires: cuda
     281             :       test:
     282             :          suffix: 9_hip
     283             :          args: -bv_type {{svec mat}} -vec_type hip -mat_type aijhipsparse
     284             :          requires: hip
     285             : 
     286             :    testset:
     287             :       args: -bv_orthog_block tsqr
     288             :       nsize: 7
     289             :       output_file: output/test11_1.out
     290             :       test:
     291             :          suffix: 11
     292             :          args: -bv_type {{vecs contiguous svec mat}shared output}
     293             :          requires: !defined(PETSCTEST_VALGRIND)
     294             :       test:
     295             :          suffix: 11_cuda
     296             :          TODO: too many processes accessing the GPU
     297             :          args: -bv_type {{svec mat}} -vec_type cuda
     298             :          requires: cuda !defined(PETSCTEST_VALGRIND)
     299             :       test:
     300             :          suffix: 11_hip
     301             :          TODO: too many processes accessing the GPU
     302             :          args: -bv_type {{svec mat}} -vec_type hip
     303             :          requires: hip !defined(PETSCTEST_VALGRIND)
     304             : 
     305             :    testset:
     306             :       args: -resid -n 180 -l 0 -k 7 -bv_orthog_block tsqr
     307             :       nsize: 7
     308             :       output_file: output/test11_12.out
     309             :       test:
     310             :          suffix: 12
     311             :          args: -bv_type {{vecs contiguous svec mat}shared output}
     312             :          requires: double !defined(PETSCTEST_VALGRIND)
     313             :       test:
     314             :          suffix: 12_cuda
     315             :          TODO: too many processes accessing the GPU
     316             :          args: -bv_type {{svec mat}} -vec_type cuda
     317             :          requires: cuda !single !defined(PETSCTEST_VALGRIND)
     318             :       test:
     319             :          suffix: 12_hip
     320             :          TODO: too many processes accessing the GPU
     321             :          args: -bv_type {{svec mat}} -vec_type hip
     322             :          requires: hip !single !defined(PETSCTEST_VALGRIND)
     323             : 
     324             : TEST*/

Generated by: LCOV version 1.14