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 */