LCOV - code coverage report
Current view: top level - sys/vec - veccomp0.h (source / functions) Hit Total Coverage
Test: SLEPc Lines: 143 163 87.7 %
Date: 2024-03-29 00:55:19 Functions: 7 12 58.3 %
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             : #include <petsc/private/vecimpl.h>
      12             : 
      13             : #if defined(__WITH_MPI__)
      14             : #define __SUF__(A) A##_MPI
      15             : #else
      16             : #define __SUF__(A) A##_Seq
      17             : #endif
      18             : #define __QUOTEME_(x) #x
      19             : #define __QUOTEME(x) __QUOTEME_(x)
      20             : #define __SUF_C__(A) __QUOTEME(__SUF__(A))
      21             : 
      22       21774 : static PetscErrorCode __SUF__(VecDot_Comp)(Vec a,Vec b,PetscScalar *z)
      23             : {
      24       21774 :   PetscScalar    sum = 0.0,work;
      25       21774 :   PetscInt       i;
      26       21774 :   Vec_Comp       *as = (Vec_Comp*)a->data,*bs = (Vec_Comp*)b->data;
      27             : 
      28       21774 :   PetscFunctionBegin;
      29       21774 :   SlepcValidVecComp(a,1);
      30       21774 :   SlepcValidVecComp(b,2);
      31       21774 :   if (as->x[0]->ops->dot_local) {
      32       43927 :     for (i=0,sum=0.0;i<as->n->n;i++) {
      33       22153 :       PetscUseTypeMethod(as->x[i],dot_local,bs->x[i],&work);
      34       22153 :       sum += work;
      35             :     }
      36             : #if defined(__WITH_MPI__)
      37       21774 :     work = sum;
      38       87096 :     PetscCall(MPIU_Allreduce(&work,&sum,1,MPIU_SCALAR,MPIU_SUM,PetscObjectComm((PetscObject)a)));
      39             : #endif
      40             :   } else {
      41           0 :     for (i=0,sum=0.0;i<as->n->n;i++) {
      42           0 :       PetscCall(VecDot(as->x[i],bs->x[i],&work));
      43           0 :       sum += work;
      44             :     }
      45             :   }
      46       21774 :   *z = sum;
      47       21774 :   PetscFunctionReturn(PETSC_SUCCESS);
      48             : }
      49             : 
      50       16701 : static PetscErrorCode __SUF__(VecMDot_Comp)(Vec a,PetscInt n,const Vec b[],PetscScalar *z)
      51             : {
      52       16701 :   PetscScalar    *work,*work0,*r;
      53       16701 :   Vec_Comp       *as = (Vec_Comp*)a->data;
      54       16701 :   Vec            *bx;
      55       16701 :   PetscInt       i,j;
      56             : 
      57       16701 :   PetscFunctionBegin;
      58       16701 :   SlepcValidVecComp(a,1);
      59       63442 :   for (i=0;i<n;i++) SlepcValidVecComp(b[i],3);
      60             : 
      61       16701 :   if (as->n->n == 0) {
      62           0 :     *z = 0;
      63           0 :     PetscFunctionReturn(PETSC_SUCCESS);
      64             :   }
      65             : 
      66       16701 :   PetscCall(PetscMalloc2(n,&work0,n,&bx));
      67             : 
      68             : #if defined(__WITH_MPI__)
      69       16701 :   if (as->x[0]->ops->mdot_local) {
      70       16701 :     r = work0; work = z;
      71             :   } else
      72             : #endif
      73             :   {
      74           0 :     r = z; work = work0;
      75             :   }
      76             : 
      77             :   /* z[i] <- a.x' * b[i].x */
      78       63442 :   for (i=0;i<n;i++) r[i] = 0.0;
      79       33660 :   for (j=0;j<as->n->n;j++) {
      80       64216 :     for (i=0;i<n;i++) bx[i] = ((Vec_Comp*)b[i]->data)->x[j];
      81       16959 :     if (as->x[0]->ops->mdot_local) PetscUseTypeMethod(as->x[j],mdot_local,n,bx,work);
      82           0 :     else PetscCall(VecMDot(as->x[j],n,bx,work));
      83       64216 :     for (i=0;i<n;i++) r[i] += work[i];
      84             :   }
      85             : 
      86             :   /* If def(__WITH_MPI__) and exists mdot_local */
      87             : #if defined(__WITH_MPI__)
      88       16701 :   if (as->x[0]->ops->mdot_local) {
      89             :     /* z[i] <- Allreduce(work[i]) */
      90       66804 :     PetscCall(MPIU_Allreduce(r,z,n,MPIU_SCALAR,MPIU_SUM,PetscObjectComm((PetscObject)a)));
      91             :   }
      92             : #endif
      93             : 
      94       16701 :   PetscCall(PetscFree2(work0,bx));
      95       16701 :   PetscFunctionReturn(PETSC_SUCCESS);
      96             : }
      97             : 
      98           3 : static PetscErrorCode __SUF__(VecTDot_Comp)(Vec a,Vec b,PetscScalar *z)
      99             : {
     100           3 :   PetscScalar    sum = 0.0,work;
     101           3 :   PetscInt       i;
     102           3 :   Vec_Comp       *as = (Vec_Comp*)a->data,*bs = (Vec_Comp*)b->data;
     103             : 
     104           3 :   PetscFunctionBegin;
     105           3 :   SlepcValidVecComp(a,1);
     106           3 :   SlepcValidVecComp(b,2);
     107           3 :   if (as->x[0]->ops->tdot_local) {
     108           9 :     for (i=0,sum=0.0;i<as->n->n;i++) {
     109           6 :       PetscUseTypeMethod(as->x[i],tdot_local,bs->x[i],&work);
     110           6 :       sum += work;
     111             :     }
     112             : #if defined(__WITH_MPI__)
     113           3 :     work = sum;
     114          12 :     PetscCall(MPIU_Allreduce(&work,&sum,1,MPIU_SCALAR,MPIU_SUM,PetscObjectComm((PetscObject)a)));
     115             : #endif
     116             :   } else {
     117           0 :     for (i=0,sum=0.0;i<as->n->n;i++) {
     118           0 :       PetscCall(VecTDot(as->x[i],bs->x[i],&work));
     119           0 :       sum += work;
     120             :     }
     121             :   }
     122           3 :   *z = sum;
     123           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     124             : }
     125             : 
     126           3 : static PetscErrorCode __SUF__(VecMTDot_Comp)(Vec a,PetscInt n,const Vec b[],PetscScalar *z)
     127             : {
     128           3 :   PetscScalar    *work,*work0,*r;
     129           3 :   Vec_Comp       *as = (Vec_Comp*)a->data;
     130           3 :   Vec            *bx;
     131           3 :   PetscInt       i,j;
     132             : 
     133           3 :   PetscFunctionBegin;
     134           3 :   SlepcValidVecComp(a,1);
     135           9 :   for (i=0;i<n;i++) SlepcValidVecComp(b[i],3);
     136             : 
     137           3 :   if (as->n->n == 0) {
     138           0 :     *z = 0;
     139           0 :     PetscFunctionReturn(PETSC_SUCCESS);
     140             :   }
     141             : 
     142           3 :   PetscCall(PetscMalloc2(n,&work0,n,&bx));
     143             : 
     144             : #if defined(__WITH_MPI__)
     145           3 :   if (as->x[0]->ops->mtdot_local) {
     146           3 :     r = work0; work = z;
     147             :   } else
     148             : #endif
     149             :   {
     150           0 :     r = z; work = work0;
     151             :   }
     152             : 
     153             :   /* z[i] <- a.x' * b[i].x */
     154           9 :   for (i=0;i<n;i++) r[i] = 0.0;
     155           9 :   for (j=0;j<as->n->n;j++) {
     156          18 :     for (i=0;i<n;i++) bx[i] = ((Vec_Comp*)b[i]->data)->x[j];
     157           6 :     if (as->x[0]->ops->mtdot_local) PetscUseTypeMethod(as->x[j],mtdot_local,n,bx,work);
     158           0 :     else PetscCall(VecMTDot(as->x[j],n,bx,work));
     159          18 :     for (i=0;i<n;i++) r[i] += work[i];
     160             :   }
     161             : 
     162             :   /* If def(__WITH_MPI__) and exists mtdot_local */
     163             : #if defined(__WITH_MPI__)
     164           3 :   if (as->x[0]->ops->mtdot_local) {
     165             :     /* z[i] <- Allreduce(work[i]) */
     166          12 :     PetscCall(MPIU_Allreduce(r,z,n,MPIU_SCALAR,MPIU_SUM,PetscObjectComm((PetscObject)a)));
     167             :   }
     168             : #endif
     169             : 
     170           3 :   PetscCall(PetscFree2(work0,bx));
     171           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     172             : }
     173             : 
     174       17878 : static PetscErrorCode __SUF__(VecNorm_Comp)(Vec a,NormType t,PetscReal *norm)
     175             : {
     176       17878 :   PetscReal      work[3],s=0.0;
     177       17878 :   Vec_Comp       *as = (Vec_Comp*)a->data;
     178       17878 :   PetscInt       i;
     179             : 
     180       17878 :   PetscFunctionBegin;
     181       17878 :   SlepcValidVecComp(a,1);
     182             :   /* Initialize norm */
     183       17878 :   switch (t) {
     184          12 :     case NORM_1: case NORM_INFINITY: *norm = 0.0; break;
     185       17863 :     case NORM_2: case NORM_FROBENIUS: *norm = 1.0; s = 0.0; break;
     186           3 :     case NORM_1_AND_2: norm[0] = 0.0; norm[1] = 1.0; s = 0.0; break;
     187             :   }
     188       36079 :   for (i=0;i<as->n->n;i++) {
     189       18201 :     if (as->x[0]->ops->norm_local) PetscUseTypeMethod(as->x[i],norm_local,t,work);
     190           0 :     else PetscCall(VecNorm(as->x[i],t,work));
     191             :     /* norm+= work */
     192       18201 :     switch (t) {
     193           6 :       case NORM_1: *norm+= *work; break;
     194       18171 :       case NORM_2: case NORM_FROBENIUS: AddNorm2(norm,&s,*work); break;
     195           6 :       case NORM_1_AND_2: norm[0]+= work[0]; AddNorm2(&norm[1],&s,work[1]); break;
     196          24 :       case NORM_INFINITY: *norm = PetscMax(*norm,*work); break;
     197             :     }
     198       18201 :   }
     199             : 
     200             :   /* If def(__WITH_MPI__) and exists norm_local */
     201             : #if defined(__WITH_MPI__)
     202       17878 :   if (as->x[0]->ops->norm_local) {
     203       17878 :     PetscReal work0[3];
     204             :     /* norm <- Allreduce(work) */
     205       17878 :     switch (t) {
     206           3 :     case NORM_1:
     207           3 :       work[0] = *norm;
     208          12 :       PetscCall(MPIU_Allreduce(work,norm,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)a)));
     209             :       break;
     210       17863 :     case NORM_2: case NORM_FROBENIUS:
     211       17863 :       work[0] = *norm; work[1] = s;
     212       71452 :       PetscCall(MPIU_Allreduce(work,work0,1,MPIU_NORM2,MPIU_NORM2_SUM,PetscObjectComm((PetscObject)a)));
     213       17863 :       *norm = GetNorm2(work0[0],work0[1]);
     214       17863 :       break;
     215           3 :     case NORM_1_AND_2:
     216           3 :       work[0] = norm[0]; work[1] = norm[1]; work[2] = s;
     217          12 :       PetscCall(MPIU_Allreduce(work,work0,1,MPIU_NORM1_AND_2,MPIU_NORM2_SUM,PetscObjectComm((PetscObject)a)));
     218           3 :       norm[0] = work0[0];
     219           3 :       norm[1] = GetNorm2(work0[1],work0[2]);
     220           3 :       break;
     221           9 :     case NORM_INFINITY:
     222           9 :       work[0] = *norm;
     223          36 :       PetscCall(MPIU_Allreduce(work,norm,1,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a)));
     224             :       break;
     225             :     }
     226       17878 :   }
     227             : #else
     228             :   /* Norm correction */
     229           0 :   switch (t) {
     230           0 :     case NORM_2: case NORM_FROBENIUS: *norm = GetNorm2(*norm,s); break;
     231           0 :     case NORM_1_AND_2: norm[1] = GetNorm2(norm[1],s); break;
     232           0 :     default: ;
     233             :   }
     234             : #endif
     235       17878 :   PetscFunctionReturn(PETSC_SUCCESS);
     236             : }
     237             : 
     238         193 : PetscErrorCode __SUF__(VecDotNorm2_Comp)(Vec v,Vec w,PetscScalar *dp,PetscScalar *nm)
     239             : {
     240         193 :   PetscScalar       dp0=0.0,nm0=0.0,dp1=0.0,nm1=0.0;
     241         193 :   const PetscScalar *vx,*wx;
     242         193 :   Vec_Comp          *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
     243         193 :   PetscInt          i,n;
     244         193 :   PetscBool         t0,t1;
     245             : #if defined(__WITH_MPI__)
     246          95 :   PetscScalar       work[4];
     247             : #endif
     248             : 
     249         193 :   PetscFunctionBegin;
     250             :   /* Compute recursively the local part */
     251         193 :   PetscCall(PetscObjectTypeCompare((PetscObject)v,VECCOMP,&t0));
     252         193 :   PetscCall(PetscObjectTypeCompare((PetscObject)w,VECCOMP,&t1));
     253         193 :   if (t0 && t1) {
     254          95 :     SlepcValidVecComp(v,1);
     255          95 :     SlepcValidVecComp(w,2);
     256         193 :     for (i=0;i<vs->n->n;i++) {
     257          98 :       PetscCall(VecDotNorm2_Comp_Seq(vs->x[i],ws->x[i],&dp1,&nm1));
     258          98 :       dp0 += dp1;
     259          98 :       nm0 += nm1;
     260             :     }
     261          98 :   } else if (!t0 && !t1) {
     262          98 :     PetscCall(VecGetLocalSize(v,&n));
     263          98 :     PetscCall(VecGetArrayRead(v,&vx));
     264          98 :     PetscCall(VecGetArrayRead(w,&wx));
     265       10234 :     for (i=0;i<n;i++) {
     266       10136 :       dp0 += vx[i]*PetscConj(wx[i]);
     267       10136 :       nm0 += wx[i]*PetscConj(wx[i]);
     268             :     }
     269          98 :     PetscCall(VecRestoreArrayRead(v,&vx));
     270          98 :     PetscCall(VecRestoreArrayRead(w,&wx));
     271           0 :   } else SETERRQ(PetscObjectComm((PetscObject)v),PETSC_ERR_ARG_INCOMP,"Incompatible vector types");
     272             : 
     273             : #if defined(__WITH_MPI__)
     274             :     /* [dp, nm] <- Allreduce([dp0, nm0]) */
     275          95 :     work[0] = dp0; work[1] = nm0;
     276         380 :     PetscCall(MPIU_Allreduce(work,&work[2],2,MPIU_SCALAR,MPIU_SUM,PetscObjectComm((PetscObject)v)));
     277          95 :     *dp = work[2]; *nm = work[3];
     278             : #else
     279          98 :     *dp = dp0; *nm = nm0;
     280             : #endif
     281         193 :   PetscFunctionReturn(PETSC_SUCCESS);
     282             : }
     283             : 
     284             : #undef __SUF__
     285             : #undef __QUOTEME
     286             : #undef __SUF_C__

Generated by: LCOV version 1.14