GCC Code Coverage Report


Directory: ./
File: include/slepc/private/slepcimpl.h
Date: 2026-01-12 03:57:26
Exec Total Coverage
Lines: 72 84 85.7%
Functions: 5 5 100.0%
Branches: 111 220 50.5%

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 #pragma once
12
13 #include <slepcsys.h>
14 #include <petsc/private/petscimpl.h>
15
16 /* SUBMANSEC = Sys */
17
18 SLEPC_INTERN PetscBool SlepcBeganPetsc;
19
20 /* SlepcSwap - swap two variables a,b of the same type using a temporary variable t */
21 #define SlepcSwap(a,b,t) do {t=a;a=b;b=t;} while (0)
22
23 /*MC
24 SlepcHeaderCreate - Creates a SLEPc object
25
26 Input Parameters:
27 + classid - the classid associated with this object
28 . class_name - string name of class; should be static
29 . descr - string containing short description; should be static
30 . mansec - string indicating section in manual pages; should be static
31 . comm - the MPI Communicator
32 . destroy - the destroy routine for this object
33 - view - the view routine for this object
34
35 Output Parameter:
36 . h - the newly created object
37
38 Note:
39 This is equivalent to `PetscHeaderCreate()` but makes sure that `SlepcInitialize()`
40 has been called.
41
42 Level: developer
43 M*/
44 #define SlepcHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
45 ((PetscErrorCode)((!SlepcInitializeCalled && \
46 PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,PETSC_ERR_ORDER,PETSC_ERROR_INITIAL, \
47 "Must call SlepcInitialize instead of PetscInitialize to use SLEPc classes")) || \
48 PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view)))
49
50 /* context for structured eigenproblem matrices created via MatCreateXXX */
51 struct _n_SlepcMatStruct {
52 PetscInt cookie; /* identify which structured matrix */
53 PetscScalar s; /* in BSE sign of the bottom part of the vector */
54 };
55 typedef struct _n_SlepcMatStruct* SlepcMatStruct;
56
57 #define SLEPC_MAT_STRUCT_BSE 88101
58 #define SLEPC_MAT_STRUCT_HAMILT 88102
59
60 /*
61 SlepcCheckMatStruct - Check that a given Mat is a structured matrix of the wanted type.
62
63 Returns true/false in flg if it is given, otherwise yields an error if the check fails.
64 If cookie==0 it will check for any type.
65 */
66 448 static inline PetscErrorCode SlepcCheckMatStruct(Mat A,PetscInt cookie,PetscBool *flg)
67 {
68 448 PetscContainer container;
69 448 SlepcMatStruct mctx;
70
71
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
448 PetscFunctionBegin;
72
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
448 if (flg) *flg = PETSC_FALSE;
73
4/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
448 PetscCall(PetscObjectQuery((PetscObject)A,"SlepcMatStruct",(PetscObject*)&container));
74
10/16
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
448 if (flg && !container) PetscFunctionReturn(PETSC_SUCCESS);
75
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
369 PetscCheck(container,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"The Mat is not a structured matrix");
76
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
369 if (cookie) {
77
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
369 PetscCall(PetscContainerGetPointer(container,(void**)&mctx));
78
1/18
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
369 if (flg && (!mctx || mctx->cookie!=cookie)) PetscFunctionReturn(PETSC_SUCCESS);
79
2/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
369 PetscCheck(mctx && mctx->cookie==cookie,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"The type of structured matrix is different from the expected one");
80 }
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
369 if (flg) *flg = PETSC_TRUE;
82
6/12
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
57 PetscFunctionReturn(PETSC_SUCCESS);
83 }
84
85 /*
86 SlepcPrintEigenvalueASCII - Print an eigenvalue on an ASCII viewer.
87 */
88 53804 static inline PetscErrorCode SlepcPrintEigenvalueASCII(PetscViewer viewer,PetscScalar eigr,PetscScalar eigi)
89 {
90 53804 PetscReal re,im;
91
92
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
53804 PetscFunctionBegin;
93 #if defined(PETSC_USE_COMPLEX)
94 27181 re = PetscRealPart(eigr);
95 27181 im = PetscImaginaryPart(eigr);
96 27181 (void)eigi;
97 #else
98 26623 re = eigr;
99 26623 im = eigi;
100 #endif
101 /* print zero instead of tiny value */
102
8/8
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 25 times.
✓ Branch 5 taken 25 times.
✓ Branch 6 taken 23 times.
✓ Branch 7 taken 22 times.
53804 if (PetscAbs(im) && PetscAbs(re)/PetscAbs(im)<PETSC_SMALL) re = 0.0;
103
8/8
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 29 times.
53418 if (PetscAbs(re) && PetscAbs(im)/PetscAbs(re)<PETSC_SMALL) im = 0.0;
104 /* print as real if imaginary part is zero */
105
6/8
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
19284 if (im!=(PetscReal)0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%.5f%+.5fi",(double)re,(double)im));
106
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
49328 else PetscCall(PetscViewerASCIIPrintf(viewer,"%.5f",(double)re));
107
6/12
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
10639 PetscFunctionReturn(PETSC_SUCCESS);
108 }
109
110 /*
111 SlepcViewEigenvector - Outputs an eigenvector xr,xi to a viewer.
112 In complex scalars only xr is written.
113 The name of xr,xi is set before writing, based on the label, the index, and the name of obj.
114 */
115 135 static inline PetscErrorCode SlepcViewEigenvector(PetscViewer viewer,Vec xr,Vec xi,const char *label,PetscInt index,PetscObject obj)
116 {
117 135 size_t count;
118 135 char vname[30];
119 135 const char *pname;
120
121
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
135 PetscFunctionBegin;
122
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
135 PetscCall(PetscObjectGetName(obj,&pname));
123
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
135 PetscCall(PetscSNPrintfCount(vname,sizeof(vname),"%s%s",&count,label,PetscDefined(USE_COMPLEX)?"":"r"));
124 135 count--;
125
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
135 PetscCall(PetscSNPrintf(vname+count,sizeof(vname)-count,"%" PetscInt_FMT "_%s",index,pname));
126
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
135 PetscCall(PetscObjectSetName((PetscObject)xr,vname));
127
4/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
135 PetscCall(VecView(xr,viewer));
128 #if !defined(PETSC_USE_COMPLEX)
129 70 vname[count-1] = 'i';
130
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
70 PetscCall(PetscObjectSetName((PetscObject)xi,vname));
131
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
70 PetscCall(VecView(xi,viewer));
132 #else
133 13 (void)xi;
134 #endif
135
6/12
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
27 PetscFunctionReturn(PETSC_SUCCESS);
136 }
137
138 /* Macros for strings with different value in real and complex */
139 #if defined(PETSC_USE_COMPLEX)
140 #define SLEPC_STRING_HERMITIAN "hermitian"
141 #else
142 #define SLEPC_STRING_HERMITIAN "symmetric"
143 #endif
144
145 /* Private functions that are shared by several classes */
146 SLEPC_SINGLE_LIBRARY_INTERN PetscErrorCode SlepcBasisReference_Private(PetscInt,Vec*,PetscInt*,Vec**);
147 SLEPC_SINGLE_LIBRARY_INTERN PetscErrorCode SlepcBasisDestroy_Private(PetscInt*,Vec**);
148 SLEPC_SINGLE_LIBRARY_INTERN PetscErrorCode SlepcMonitorMakeKey_Internal(const char[],PetscViewerType,PetscViewerFormat,char[]);
149 SLEPC_SINGLE_LIBRARY_INTERN PetscErrorCode PetscViewerAndFormatCreate_Internal(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);
150
151 SLEPC_INTERN PetscErrorCode SlepcCitationsInitialize(void);
152 SLEPC_INTERN PetscErrorCode SlepcInitialize_DynamicLibraries(void);
153 SLEPC_INTERN PetscErrorCode SlepcInitialize_Packages(void);
154
155 /* Macro to check a sequential Mat (including GPU) */
156 #if !defined(PETSC_USE_DEBUG)
157 #define SlepcMatCheckSeq(h) do {(void)(h);} while (0)
158 #else
159 #if defined(PETSC_HAVE_CUDA)
160 #define SlepcMatCheckSeq(h) do { PetscCheckTypeNames((h),MATSEQDENSE,MATSEQDENSECUDA); } while (0)
161 #elif defined(PETSC_HAVE_HIP)
162 #define SlepcMatCheckSeq(h) do { PetscCheckTypeNames((h),MATSEQDENSE,MATSEQDENSEHIP); } while (0)
163 #else
164 #define SlepcMatCheckSeq(h) do { PetscCheckTypeName((h),MATSEQDENSE); } while (0)
165 #endif
166 #endif
167
168 /* Definitions needed to work with GPU kernels */
169 #if defined(PETSC_HAVE_CUPM)
170 #include <petscdevice_cupm.h>
171
172 #define X_AXIS 0
173 #define Y_AXIS 1
174
175 #define SLEPC_TILE_SIZE_X 32
176 #define SLEPC_BLOCK_SIZE_X 128
177 #define SLEPC_TILE_SIZE_Y 32
178 #define SLEPC_BLOCK_SIZE_Y 128
179
180 3392 static inline PetscErrorCode SlepcKernelSetGrid1D(PetscInt rows,dim3 *dimGrid,dim3 *dimBlock,PetscInt *dimGrid_xcount)
181 {
182 3392 int card;
183 #if defined(PETSC_HAVE_CUDA)
184 3392 struct cudaDeviceProp devprop;
185 #elif defined(PETSC_HAVE_HIP)
186 hipDeviceProp_t devprop;
187 #endif
188
189 3392 PetscFunctionBegin;
190 #if defined(PETSC_HAVE_CUDA)
191
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3392 PetscCallCUDA(cudaGetDevice(&card));
192
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3392 PetscCallCUDA(cudaGetDeviceProperties(&devprop,card));
193 #elif defined(PETSC_HAVE_HIP)
194 PetscCallHIP(hipGetDevice(&card));
195 PetscCallHIP(hipGetDeviceProperties(&devprop,card));
196 #endif
197 3392 *dimGrid_xcount = 1;
198
199 /* X axis */
200 3392 dimGrid->x = 1;
201 3392 dimBlock->x = SLEPC_BLOCK_SIZE_X;
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
3392 if (rows>SLEPC_BLOCK_SIZE_X) dimGrid->x = (rows+SLEPC_BLOCK_SIZE_X-1)/SLEPC_BLOCK_SIZE_X;
203 3392 else dimBlock->x = rows;
204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
3392 if (dimGrid->x>(unsigned)devprop.maxGridSize[X_AXIS]) {
205 *dimGrid_xcount = (dimGrid->x+(devprop.maxGridSize[X_AXIS]-1))/devprop.maxGridSize[X_AXIS];
206 dimGrid->x = devprop.maxGridSize[X_AXIS];
207 }
208 PetscFunctionReturn(PETSC_SUCCESS);
209 }
210
211 72 static inline PetscErrorCode SlepcKernelSetGrid2DTiles(PetscInt rows,PetscInt cols,dim3 *dimGrid,dim3 *dimBlock,PetscInt *dimGrid_xcount,PetscInt *dimGrid_ycount)
212 {
213 72 int card;
214 #if defined(PETSC_HAVE_CUDA)
215 72 struct cudaDeviceProp devprop;
216 #elif defined(PETSC_HAVE_HIP)
217 hipDeviceProp_t devprop;
218 #endif
219
220 72 PetscFunctionBegin;
221 #if defined(PETSC_HAVE_CUDA)
222
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
72 PetscCallCUDA(cudaGetDevice(&card));
223
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
72 PetscCallCUDA(cudaGetDeviceProperties(&devprop,card));
224 #elif defined(PETSC_HAVE_HIP)
225 PetscCallHIP(hipGetDevice(&card));
226 PetscCallHIP(hipGetDeviceProperties(&devprop,card));
227 #endif
228 72 *dimGrid_xcount = *dimGrid_ycount = 1;
229
230 /* X axis */
231 72 dimGrid->x = 1;
232 72 dimBlock->x = SLEPC_BLOCK_SIZE_X;
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
72 if (rows>SLEPC_BLOCK_SIZE_X*SLEPC_TILE_SIZE_X) dimGrid->x = (rows+SLEPC_BLOCK_SIZE_X*SLEPC_TILE_SIZE_X-1)/(SLEPC_BLOCK_SIZE_X*SLEPC_TILE_SIZE_X);
234 72 else dimBlock->x = (rows+SLEPC_TILE_SIZE_X-1)/SLEPC_TILE_SIZE_X;
235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
72 if (dimGrid->x>(unsigned)devprop.maxGridSize[X_AXIS]) {
236 *dimGrid_xcount = (dimGrid->x+(devprop.maxGridSize[X_AXIS]-1))/devprop.maxGridSize[X_AXIS];
237 dimGrid->x = devprop.maxGridSize[X_AXIS];
238 }
239
240 /* Y axis */
241 72 dimGrid->y = 1;
242 72 dimBlock->y = SLEPC_BLOCK_SIZE_Y;
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
72 if (cols>SLEPC_BLOCK_SIZE_Y*SLEPC_TILE_SIZE_Y) dimGrid->y = (cols+SLEPC_BLOCK_SIZE_Y*SLEPC_TILE_SIZE_Y-1)/(SLEPC_BLOCK_SIZE_Y*SLEPC_TILE_SIZE_Y);
244 72 else dimBlock->y = (cols+SLEPC_TILE_SIZE_Y-1)/SLEPC_TILE_SIZE_Y;
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
72 if (dimGrid->y>(unsigned)devprop.maxGridSize[Y_AXIS]) {
246 *dimGrid_ycount = (dimGrid->y+(devprop.maxGridSize[Y_AXIS]-1))/devprop.maxGridSize[Y_AXIS];
247 dimGrid->y = devprop.maxGridSize[Y_AXIS];
248 }
249 PetscFunctionReturn(PETSC_SUCCESS);
250 }
251 #undef X_AXIS
252 #undef Y_AXIS
253 #endif
254