xref: /petsc/src/vec/vec/interface/dlregisvec.c (revision 58bddbc0aeb8e2276be3739270a4176cb222ba3a)
1 #include <petsc/private/vecimpl.h> /*I "petscvec.h" */
2 #include <petsc/private/isimpl.h>
3 #include <petscpf.h>
4 #include <petscsf.h>
5 #include <petscsection.h>
6 #include <petscao.h>
7 
8 static PetscBool         ISPackageInitialized = PETSC_FALSE;
9 extern PetscFunctionList ISLocalToGlobalMappingList;
10 const char              *ISInfos[] = {"SORTED", "UNIQUE", "PERMUTATION", "INTERVAL", "IDENTITY", "ISInfo", "IS_", NULL};
11 
12 /*@C
13   ISFinalizePackage - This function destroys everything in the `IS` package. It is
14   called from `PetscFinalize()`.
15 
16   Level: developer
17 
18 .seealso: `PetscFinalize()`
19 @*/
ISFinalizePackage(void)20 PetscErrorCode ISFinalizePackage(void)
21 {
22   PetscFunctionBegin;
23   PetscCall(PetscFunctionListDestroy(&ISList));
24   PetscCall(PetscFunctionListDestroy(&ISLocalToGlobalMappingList));
25   PetscCall(PetscFunctionListDestroy(&PetscSectionSymList));
26   ISPackageInitialized                    = PETSC_FALSE;
27   ISRegisterAllCalled                     = PETSC_FALSE;
28   ISLocalToGlobalMappingRegisterAllCalled = PETSC_FALSE;
29   PetscFunctionReturn(PETSC_SUCCESS);
30 }
31 
32 /*@C
33   ISInitializePackage - This function initializes everything in the `IS` package. It is called
34   from PetscDLLibraryRegister_petscvec() when using dynamic libraries, and on the first call to ISCreateXXXX()
35   when using shared or static libraries.
36 
37   Level: developer
38 
39 .seealso: `PetscInitialize()`
40 @*/
ISInitializePackage(void)41 PetscErrorCode ISInitializePackage(void)
42 {
43   char      logList[256];
44   PetscBool opt, pkg;
45 
46   PetscFunctionBegin;
47   if (ISPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
48   ISPackageInitialized = PETSC_TRUE;
49   /* Register Classes */
50   PetscCall(PetscClassIdRegister("Index Set", &IS_CLASSID));
51   PetscCall(PetscClassIdRegister("IS L to G Mapping", &IS_LTOGM_CLASSID));
52   PetscCall(PetscClassIdRegister("Section", &PETSC_SECTION_CLASSID));
53   PetscCall(PetscClassIdRegister("Section Symmetry", &PETSC_SECTION_SYM_CLASSID));
54   /* Register Constructors */
55   PetscCall(ISRegisterAll());
56   PetscCall(ISLocalToGlobalMappingRegisterAll());
57   /* Register Events */
58   PetscCall(PetscLogEventRegister("ISView", IS_CLASSID, &IS_View));
59   PetscCall(PetscLogEventRegister("ISLoad", IS_CLASSID, &IS_Load));
60   /* Process Info */
61   {
62     PetscClassId classids[4];
63 
64     classids[0] = IS_CLASSID;
65     classids[1] = IS_LTOGM_CLASSID;
66     classids[2] = PETSC_SECTION_CLASSID;
67     classids[3] = PETSC_SECTION_SYM_CLASSID;
68     PetscCall(PetscInfoProcessClass("is", 2, classids));
69     PetscCall(PetscInfoProcessClass("section", 2, &classids[2]));
70   }
71   /* Process summary exclusions */
72   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
73   if (opt) {
74     PetscCall(PetscStrInList("is", logList, ',', &pkg));
75     if (pkg) PetscCall(PetscLogEventExcludeClass(IS_CLASSID));
76     if (pkg) PetscCall(PetscLogEventExcludeClass(IS_LTOGM_CLASSID));
77     PetscCall(PetscStrInList("section", logList, ',', &pkg));
78     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSC_SECTION_CLASSID));
79     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSC_SECTION_SYM_CLASSID));
80   }
81   /* Register package finalizer */
82   PetscCall(PetscRegisterFinalize(ISFinalizePackage));
83   PetscFunctionReturn(PETSC_SUCCESS);
84 }
85 
86 extern MPI_Op PetscSplitReduction_Op;
87 
88 /*
89        These two functions are the MPI reduction operation used for max and min with index
90    A call to MPI_Op_create() converts the function Vec[Max,Min]_Local() to the MPI operator Vec[Max,Min]_Local_Op.
91 
92 */
93 MPI_Op MPIU_MAXLOC = 0;
94 MPI_Op MPIU_MINLOC = 0;
95 
MPIU_MaxIndex_Local(void * in,void * out,PetscMPIInt * cnt,MPI_Datatype * datatype)96 static void MPIAPI MPIU_MaxIndex_Local(void *in, void *out, PetscMPIInt *cnt, MPI_Datatype *datatype)
97 {
98   struct PetscRealInt {
99     PetscReal v;
100     PetscInt  i;
101   };
102   struct PetscRealInt *xin  = (struct PetscRealInt *)in;
103   struct PetscRealInt *xout = (struct PetscRealInt *)out;
104   int                  c;
105 
106   PetscFunctionBegin;
107   if (*datatype != MPIU_REAL_INT) {
108     PetscCallAbort(MPI_COMM_SELF, (*PetscErrorPrintf)("Can only handle MPIU_REAL_INT data types"));
109     PETSCABORT(MPI_COMM_SELF, PETSC_ERR_ARG_WRONG);
110   }
111   for (c = 0; c < *cnt; c++) {
112     if (xin[c].v > xout[c].v) {
113       xout[c].v = xin[c].v;
114       xout[c].i = xin[c].i;
115     } else if (xin[c].v == xout[c].v) {
116       xout[c].i = PetscMin(xin[c].i, xout[c].i);
117     }
118   }
119   PetscFunctionReturnVoid(); /* cannot return a value */
120 }
121 
MPIU_MinIndex_Local(void * in,void * out,PetscMPIInt * cnt,MPI_Datatype * datatype)122 static void MPIAPI MPIU_MinIndex_Local(void *in, void *out, PetscMPIInt *cnt, MPI_Datatype *datatype)
123 {
124   struct PetscRealInt {
125     PetscReal v;
126     PetscInt  i;
127   };
128   struct PetscRealInt *xin  = (struct PetscRealInt *)in;
129   struct PetscRealInt *xout = (struct PetscRealInt *)out;
130   int                  c;
131 
132   PetscFunctionBegin;
133   if (*datatype != MPIU_REAL_INT) {
134     PetscCallAbort(MPI_COMM_SELF, (*PetscErrorPrintf)("Can only handle MPIU_REAL_INT data types"));
135     PETSCABORT(MPI_COMM_SELF, PETSC_ERR_ARG_WRONG);
136   }
137   for (c = 0; c < *cnt; c++) {
138     if (xin[c].v < xout[c].v) {
139       xout[c].v = xin[c].v;
140       xout[c].i = xin[c].i;
141     } else if (xin[c].v == xout[c].v) {
142       xout[c].i = PetscMin(xin[c].i, xout[c].i);
143     }
144   }
145   PetscFunctionReturnVoid(); /* cannot return a value */
146 }
147 
148 PETSC_EXTERN void MPIAPI PetscSplitReduction_Local(void *, void *, PetscMPIInt *, MPI_Datatype *);
149 
150 const char *const NormTypes[] = {"1", "2", "FROBENIUS", "INFINITY", "1_AND_2", "NormType", "NORM_", NULL};
151 PetscInt          NormIds[4]; /* map from NormType to IDs used to cache norm values, 1_AND_2 is excluded */
152 
153 static PetscBool VecPackageInitialized = PETSC_FALSE;
154 
155 /*@C
156   VecInitializePackage - This function initializes everything in the `Vec` package. It is called
157   from PetscDLLibraryRegister_petscvec() when using dynamic libraries, and on the first call to `VecCreate()`
158   when using shared or static libraries.
159 
160   Level: developer
161 
162   Note:
163   This function never needs to be called by PETSc users.
164 
165 .seealso: `PetscInitialize()`
166 @*/
VecInitializePackage(void)167 PetscErrorCode VecInitializePackage(void)
168 {
169   char      logList[256];
170   PetscBool opt, pkg;
171   PetscInt  i;
172 
173   PetscFunctionBegin;
174   if (VecPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
175   VecPackageInitialized = PETSC_TRUE;
176   /* Register Classes */
177   PetscCall(PetscClassIdRegister("Vector", &VEC_CLASSID));
178   /* Register Constructors */
179   PetscCall(VecRegisterAll());
180   /* Register Events */
181   PetscCall(PetscLogEventRegister("VecView", VEC_CLASSID, &VEC_View));
182   PetscCall(PetscLogEventRegister("VecMax", VEC_CLASSID, &VEC_Max));
183   PetscCall(PetscLogEventRegister("VecMin", VEC_CLASSID, &VEC_Min));
184   PetscCall(PetscLogEventRegister("VecDot", VEC_CLASSID, &VEC_Dot));
185   PetscCall(PetscLogEventRegister("VecDotNorm2", VEC_CLASSID, &VEC_DotNorm2));
186   PetscCall(PetscLogEventRegister("VecMDot", VEC_CLASSID, &VEC_MDot));
187   PetscCall(PetscLogEventRegister("VecTDot", VEC_CLASSID, &VEC_TDot));
188   PetscCall(PetscLogEventRegister("VecMTDot", VEC_CLASSID, &VEC_MTDot));
189   PetscCall(PetscLogEventRegister("VecNorm", VEC_CLASSID, &VEC_Norm));
190   PetscCall(PetscLogEventRegister("VecScale", VEC_CLASSID, &VEC_Scale));
191   PetscCall(PetscLogEventRegister("VecShift", VEC_CLASSID, &VEC_Shift));
192   PetscCall(PetscLogEventRegister("VecCopy", VEC_CLASSID, &VEC_Copy));
193   PetscCall(PetscLogEventRegister("VecSet", VEC_CLASSID, &VEC_Set));
194   PetscCall(PetscLogEventRegister("VecAXPY", VEC_CLASSID, &VEC_AXPY));
195   PetscCall(PetscLogEventRegister("VecAYPX", VEC_CLASSID, &VEC_AYPX));
196   PetscCall(PetscLogEventRegister("VecAXPBYCZ", VEC_CLASSID, &VEC_AXPBYPCZ));
197   PetscCall(PetscLogEventRegister("VecWAXPY", VEC_CLASSID, &VEC_WAXPY));
198   PetscCall(PetscLogEventRegister("VecMAXPY", VEC_CLASSID, &VEC_MAXPY));
199   PetscCall(PetscLogEventRegister("VecSwap", VEC_CLASSID, &VEC_Swap));
200   PetscCall(PetscLogEventRegister("VecOps", VEC_CLASSID, &VEC_Ops));
201   PetscCall(PetscLogEventRegister("VecAssemblyBegin", VEC_CLASSID, &VEC_AssemblyBegin));
202   PetscCall(PetscLogEventRegister("VecAssemblyEnd", VEC_CLASSID, &VEC_AssemblyEnd));
203   PetscCall(PetscLogEventRegister("VecPointwiseMult", VEC_CLASSID, &VEC_PointwiseMult));
204   PetscCall(PetscLogEventRegister("VecPointwiseDiv", VEC_CLASSID, &VEC_PointwiseDivide));
205   PetscCall(PetscLogEventRegister("VecReciprocal", VEC_CLASSID, &VEC_Reciprocal));
206   PetscCall(PetscLogEventRegister("VecSetValues", VEC_CLASSID, &VEC_SetValues));
207   PetscCall(PetscLogEventRegister("VecSetPreallCOO", VEC_CLASSID, &VEC_SetPreallocateCOO));
208   PetscCall(PetscLogEventRegister("VecSetValuesCOO", VEC_CLASSID, &VEC_SetValuesCOO));
209   PetscCall(PetscLogEventRegister("VecLoad", VEC_CLASSID, &VEC_Load));
210   PetscCall(PetscLogEventRegister("VecScatterBegin", VEC_CLASSID, &VEC_ScatterBegin));
211   PetscCall(PetscLogEventRegister("VecScatterEnd", VEC_CLASSID, &VEC_ScatterEnd));
212   PetscCall(PetscLogEventRegister("VecSetRandom", VEC_CLASSID, &VEC_SetRandom));
213   PetscCall(PetscLogEventRegister("VecReduceArith", VEC_CLASSID, &VEC_ReduceArithmetic));
214   PetscCall(PetscLogEventRegister("VecReduceComm", VEC_CLASSID, &VEC_ReduceCommunication));
215   PetscCall(PetscLogEventRegister("VecReduceBegin", VEC_CLASSID, &VEC_ReduceBegin));
216   PetscCall(PetscLogEventRegister("VecReduceEnd", VEC_CLASSID, &VEC_ReduceEnd));
217   PetscCall(PetscLogEventRegister("VecNormalize", VEC_CLASSID, &VEC_Normalize));
218 #if defined(PETSC_HAVE_VIENNACL)
219   PetscCall(PetscLogEventRegister("VecVCLCopyTo", VEC_CLASSID, &VEC_ViennaCLCopyToGPU));
220   PetscCall(PetscLogEventRegister("VecVCLCopyFrom", VEC_CLASSID, &VEC_ViennaCLCopyFromGPU));
221 #endif
222 #if defined(PETSC_HAVE_CUDA)
223   PetscCall(PetscLogEventRegister("VecCUDACopyTo", VEC_CLASSID, &VEC_CUDACopyToGPU));
224   PetscCall(PetscLogEventRegister("VecCUDACopyFrom", VEC_CLASSID, &VEC_CUDACopyFromGPU));
225 #endif
226 #if defined(PETSC_HAVE_HIP)
227   PetscCall(PetscLogEventRegister("VecHIPCopyTo", VEC_CLASSID, &VEC_HIPCopyToGPU));
228   PetscCall(PetscLogEventRegister("VecHIPCopyFrom", VEC_CLASSID, &VEC_HIPCopyFromGPU));
229 #endif
230 
231   /* Mark non-collective events */
232   PetscCall(PetscLogEventSetCollective(VEC_SetValues, PETSC_FALSE));
233 #if defined(PETSC_HAVE_VIENNACL)
234   PetscCall(PetscLogEventSetCollective(VEC_ViennaCLCopyToGPU, PETSC_FALSE));
235   PetscCall(PetscLogEventSetCollective(VEC_ViennaCLCopyFromGPU, PETSC_FALSE));
236 #endif
237 #if defined(PETSC_HAVE_CUDA)
238   PetscCall(PetscLogEventSetCollective(VEC_CUDACopyToGPU, PETSC_FALSE));
239   PetscCall(PetscLogEventSetCollective(VEC_CUDACopyFromGPU, PETSC_FALSE));
240 #endif
241 #if defined(PETSC_HAVE_HIP)
242   PetscCall(PetscLogEventSetCollective(VEC_HIPCopyToGPU, PETSC_FALSE));
243   PetscCall(PetscLogEventSetCollective(VEC_HIPCopyFromGPU, PETSC_FALSE));
244 #endif
245   /* Turn off high traffic events by default */
246   PetscCall(PetscLogEventSetActiveAll(VEC_SetValues, PETSC_FALSE));
247   /* Process Info */
248   {
249     PetscClassId classids[1];
250 
251     classids[0] = VEC_CLASSID;
252     PetscCall(PetscInfoProcessClass("vec", 1, classids));
253   }
254   /* Process summary exclusions */
255   PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
256   if (opt) {
257     PetscCall(PetscStrInList("vec", logList, ',', &pkg));
258     if (pkg) PetscCall(PetscLogEventExcludeClass(VEC_CLASSID));
259     if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCSF_CLASSID));
260   }
261 
262   /*
263     Create the special MPI reduction operation that may be used by VecNorm/DotBegin()
264   */
265   PetscCallMPI(MPI_Op_create(PetscSplitReduction_Local, 1, &PetscSplitReduction_Op));
266   PetscCallMPI(MPI_Op_create(MPIU_MaxIndex_Local, 1, &MPIU_MAXLOC));
267   PetscCallMPI(MPI_Op_create(MPIU_MinIndex_Local, 1, &MPIU_MINLOC));
268 
269   /* Register the different norm types for cached norms */
270   for (i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataRegister(NormIds + i));
271 
272   /* Register package finalizer */
273   PetscCall(PetscRegisterFinalize(VecFinalizePackage));
274   PetscFunctionReturn(PETSC_SUCCESS);
275 }
276 
277 /*@C
278   VecFinalizePackage - This function finalizes everything in the Vec package. It is called
279   from PetscFinalize().
280 
281   Level: developer
282 
283 .seealso: `PetscInitialize()`
284 @*/
VecFinalizePackage(void)285 PetscErrorCode VecFinalizePackage(void)
286 {
287   PetscFunctionBegin;
288   PetscCall(PetscFunctionListDestroy(&VecList));
289   PetscCallMPI(MPI_Op_free(&PetscSplitReduction_Op));
290   PetscCallMPI(MPI_Op_free(&MPIU_MAXLOC));
291   PetscCallMPI(MPI_Op_free(&MPIU_MINLOC));
292   if (Petsc_Reduction_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Reduction_keyval));
293   VecPackageInitialized = PETSC_FALSE;
294   VecRegisterAllCalled  = PETSC_FALSE;
295   PetscFunctionReturn(PETSC_SUCCESS);
296 }
297 
298 #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
299 /*
300   PetscDLLibraryRegister - This function is called when the dynamic library it is in is opened.
301 
302   This one registers all the methods that are in the PETSc `Vec` library.
303 
304  */
PetscDLLibraryRegister_petscvec(void)305 PETSC_EXTERN PetscErrorCode PetscDLLibraryRegister_petscvec(void)
306 {
307   PetscFunctionBegin;
308   PetscCall(PetscSFInitializePackage());
309   PetscCall(ISInitializePackage());
310   PetscCall(AOInitializePackage());
311   PetscCall(VecInitializePackage());
312   PetscCall(PFInitializePackage());
313   PetscFunctionReturn(PETSC_SUCCESS);
314 }
315 
316 #endif /* PETSC_HAVE_DYNAMIC_LIBRARIES */
317