Actual source code: dlregisvec.c
1: #include <petsc/private/vecimpl.h>
2: #include <petsc/private/isimpl.h>
3: #include <petscpf.h>
4: #include <petscsf.h>
5: #include <petscsection.h>
6: #include <petscao.h>
8: static PetscBool ISPackageInitialized = PETSC_FALSE;
9: extern PetscFunctionList ISLocalToGlobalMappingList;
10: const char *ISInfos[] = {"SORTED", "UNIQUE", "PERMUTATION", "INTERVAL", "IDENTITY", "ISInfo", "IS_", NULL};
12: /*@C
13: ISFinalizePackage - This function destroys everything in the `IS` package. It is
14: called from `PetscFinalize()`.
16: Level: developer
18: .seealso: `PetscFinalize()`
19: @*/
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: }
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.
37: Level: developer
39: .seealso: `PetscInitialize()`
40: @*/
41: PetscErrorCode ISInitializePackage(void)
42: {
43: char logList[256];
44: PetscBool opt, pkg;
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];
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: }
86: extern MPI_Op PetscSplitReduction_Op;
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.
92: */
93: MPI_Op MPIU_MAXLOC = 0;
94: MPI_Op MPIU_MINLOC = 0;
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;
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: }
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;
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: }
148: PETSC_EXTERN void MPIAPI PetscSplitReduction_Local(void *, void *, PetscMPIInt *, MPI_Datatype *);
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 */
153: static PetscBool VecPackageInitialized = PETSC_FALSE;
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.
160: Level: developer
162: .seealso: `PetscInitialize()`
163: @*/
164: PetscErrorCode VecInitializePackage(void)
165: {
166: char logList[256];
167: PetscBool opt, pkg;
168: PetscInt i;
170: PetscFunctionBegin;
171: if (VecPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
172: VecPackageInitialized = PETSC_TRUE;
173: /* Register Classes */
174: PetscCall(PetscClassIdRegister("Vector", &VEC_CLASSID));
175: /* Register Constructors */
176: PetscCall(VecRegisterAll());
177: /* Register Events */
178: PetscCall(PetscLogEventRegister("VecView", VEC_CLASSID, &VEC_View));
179: PetscCall(PetscLogEventRegister("VecMax", VEC_CLASSID, &VEC_Max));
180: PetscCall(PetscLogEventRegister("VecMin", VEC_CLASSID, &VEC_Min));
181: PetscCall(PetscLogEventRegister("VecDot", VEC_CLASSID, &VEC_Dot));
182: PetscCall(PetscLogEventRegister("VecDotNorm2", VEC_CLASSID, &VEC_DotNorm2));
183: PetscCall(PetscLogEventRegister("VecMDot", VEC_CLASSID, &VEC_MDot));
184: PetscCall(PetscLogEventRegister("VecTDot", VEC_CLASSID, &VEC_TDot));
185: PetscCall(PetscLogEventRegister("VecMTDot", VEC_CLASSID, &VEC_MTDot));
186: PetscCall(PetscLogEventRegister("VecNorm", VEC_CLASSID, &VEC_Norm));
187: PetscCall(PetscLogEventRegister("VecScale", VEC_CLASSID, &VEC_Scale));
188: PetscCall(PetscLogEventRegister("VecShift", VEC_CLASSID, &VEC_Shift));
189: PetscCall(PetscLogEventRegister("VecCopy", VEC_CLASSID, &VEC_Copy));
190: PetscCall(PetscLogEventRegister("VecSet", VEC_CLASSID, &VEC_Set));
191: PetscCall(PetscLogEventRegister("VecAXPY", VEC_CLASSID, &VEC_AXPY));
192: PetscCall(PetscLogEventRegister("VecAYPX", VEC_CLASSID, &VEC_AYPX));
193: PetscCall(PetscLogEventRegister("VecAXPBYCZ", VEC_CLASSID, &VEC_AXPBYPCZ));
194: PetscCall(PetscLogEventRegister("VecWAXPY", VEC_CLASSID, &VEC_WAXPY));
195: PetscCall(PetscLogEventRegister("VecMAXPY", VEC_CLASSID, &VEC_MAXPY));
196: PetscCall(PetscLogEventRegister("VecSwap", VEC_CLASSID, &VEC_Swap));
197: PetscCall(PetscLogEventRegister("VecOps", VEC_CLASSID, &VEC_Ops));
198: PetscCall(PetscLogEventRegister("VecAssemblyBegin", VEC_CLASSID, &VEC_AssemblyBegin));
199: PetscCall(PetscLogEventRegister("VecAssemblyEnd", VEC_CLASSID, &VEC_AssemblyEnd));
200: PetscCall(PetscLogEventRegister("VecPointwiseMult", VEC_CLASSID, &VEC_PointwiseMult));
201: PetscCall(PetscLogEventRegister("VecSetValues", VEC_CLASSID, &VEC_SetValues));
202: PetscCall(PetscLogEventRegister("VecSetPreallCOO", VEC_CLASSID, &VEC_SetPreallocateCOO));
203: PetscCall(PetscLogEventRegister("VecSetValuesCOO", VEC_CLASSID, &VEC_SetValuesCOO));
204: PetscCall(PetscLogEventRegister("VecLoad", VEC_CLASSID, &VEC_Load));
205: PetscCall(PetscLogEventRegister("VecScatterBegin", VEC_CLASSID, &VEC_ScatterBegin));
206: PetscCall(PetscLogEventRegister("VecScatterEnd", VEC_CLASSID, &VEC_ScatterEnd));
207: PetscCall(PetscLogEventRegister("VecSetRandom", VEC_CLASSID, &VEC_SetRandom));
208: PetscCall(PetscLogEventRegister("VecReduceArith", VEC_CLASSID, &VEC_ReduceArithmetic));
209: PetscCall(PetscLogEventRegister("VecReduceComm", VEC_CLASSID, &VEC_ReduceCommunication));
210: PetscCall(PetscLogEventRegister("VecReduceBegin", VEC_CLASSID, &VEC_ReduceBegin));
211: PetscCall(PetscLogEventRegister("VecReduceEnd", VEC_CLASSID, &VEC_ReduceEnd));
212: PetscCall(PetscLogEventRegister("VecNormalize", VEC_CLASSID, &VEC_Normalize));
213: #if defined(PETSC_HAVE_VIENNACL)
214: PetscCall(PetscLogEventRegister("VecVCLCopyTo", VEC_CLASSID, &VEC_ViennaCLCopyToGPU));
215: PetscCall(PetscLogEventRegister("VecVCLCopyFrom", VEC_CLASSID, &VEC_ViennaCLCopyFromGPU));
216: #endif
217: #if defined(PETSC_HAVE_CUDA)
218: PetscCall(PetscLogEventRegister("VecCUDACopyTo", VEC_CLASSID, &VEC_CUDACopyToGPU));
219: PetscCall(PetscLogEventRegister("VecCUDACopyFrom", VEC_CLASSID, &VEC_CUDACopyFromGPU));
220: #endif
221: #if defined(PETSC_HAVE_HIP)
222: PetscCall(PetscLogEventRegister("VecHIPCopyTo", VEC_CLASSID, &VEC_HIPCopyToGPU));
223: PetscCall(PetscLogEventRegister("VecHIPCopyFrom", VEC_CLASSID, &VEC_HIPCopyFromGPU));
224: #endif
226: /* Mark non-collective events */
227: PetscCall(PetscLogEventSetCollective(VEC_SetValues, PETSC_FALSE));
228: #if defined(PETSC_HAVE_VIENNACL)
229: PetscCall(PetscLogEventSetCollective(VEC_ViennaCLCopyToGPU, PETSC_FALSE));
230: PetscCall(PetscLogEventSetCollective(VEC_ViennaCLCopyFromGPU, PETSC_FALSE));
231: #endif
232: #if defined(PETSC_HAVE_CUDA)
233: PetscCall(PetscLogEventSetCollective(VEC_CUDACopyToGPU, PETSC_FALSE));
234: PetscCall(PetscLogEventSetCollective(VEC_CUDACopyFromGPU, PETSC_FALSE));
235: #endif
236: #if defined(PETSC_HAVE_HIP)
237: PetscCall(PetscLogEventSetCollective(VEC_HIPCopyToGPU, PETSC_FALSE));
238: PetscCall(PetscLogEventSetCollective(VEC_HIPCopyFromGPU, PETSC_FALSE));
239: #endif
240: /* Turn off high traffic events by default */
241: PetscCall(PetscLogEventSetActiveAll(VEC_SetValues, PETSC_FALSE));
242: /* Process Info */
243: {
244: PetscClassId classids[1];
246: classids[0] = VEC_CLASSID;
247: PetscCall(PetscInfoProcessClass("vec", 1, classids));
248: }
249: /* Process summary exclusions */
250: PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
251: if (opt) {
252: PetscCall(PetscStrInList("vec", logList, ',', &pkg));
253: if (pkg) PetscCall(PetscLogEventExcludeClass(VEC_CLASSID));
254: if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCSF_CLASSID));
255: }
257: /*
258: Create the special MPI reduction operation that may be used by VecNorm/DotBegin()
259: */
260: PetscCallMPI(MPI_Op_create(PetscSplitReduction_Local, 1, &PetscSplitReduction_Op));
261: PetscCallMPI(MPI_Op_create(MPIU_MaxIndex_Local, 1, &MPIU_MAXLOC));
262: PetscCallMPI(MPI_Op_create(MPIU_MinIndex_Local, 1, &MPIU_MINLOC));
264: /* Register the different norm types for cached norms */
265: for (i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataRegister(NormIds + i));
267: /* Register package finalizer */
268: PetscCall(PetscRegisterFinalize(VecFinalizePackage));
269: PetscFunctionReturn(PETSC_SUCCESS);
270: }
272: /*@C
273: VecFinalizePackage - This function finalizes everything in the Vec package. It is called
274: from PetscFinalize().
276: Level: developer
278: .seealso: `PetscInitialize()`
279: @*/
280: PetscErrorCode VecFinalizePackage(void)
281: {
282: PetscFunctionBegin;
283: PetscCall(PetscFunctionListDestroy(&VecList));
284: PetscCallMPI(MPI_Op_free(&PetscSplitReduction_Op));
285: PetscCallMPI(MPI_Op_free(&MPIU_MAXLOC));
286: PetscCallMPI(MPI_Op_free(&MPIU_MINLOC));
287: if (Petsc_Reduction_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Reduction_keyval));
288: VecPackageInitialized = PETSC_FALSE;
289: VecRegisterAllCalled = PETSC_FALSE;
290: PetscFunctionReturn(PETSC_SUCCESS);
291: }
293: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
294: /*
295: PetscDLLibraryRegister - This function is called when the dynamic library it is in is opened.
297: This one registers all the methods that are in the PETSc `Vec` library.
299: */
300: PETSC_EXTERN PetscErrorCode PetscDLLibraryRegister_petscvec(void)
301: {
302: PetscFunctionBegin;
303: PetscCall(PetscSFInitializePackage());
304: PetscCall(ISInitializePackage());
305: PetscCall(AOInitializePackage());
306: PetscCall(VecInitializePackage());
307: PetscCall(PFInitializePackage());
308: PetscFunctionReturn(PETSC_SUCCESS);
309: }
311: #endif /* PETSC_HAVE_DYNAMIC_LIBRARIES */