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:   Note:
    163:   This function never needs to be called by PETSc users.

    165: .seealso: `PetscInitialize()`
    166: @*/
    167: PetscErrorCode VecInitializePackage(void)
    168: {
    169:   char      logList[256];
    170:   PetscBool opt, pkg;
    171:   PetscInt  i;

    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

    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];

    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:   }

    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));

    269:   /* Register the different norm types for cached norms */
    270:   for (i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataRegister(NormIds + i));

    272:   /* Register package finalizer */
    273:   PetscCall(PetscRegisterFinalize(VecFinalizePackage));
    274:   PetscFunctionReturn(PETSC_SUCCESS);
    275: }

    277: /*@C
    278:   VecFinalizePackage - This function finalizes everything in the Vec package. It is called
    279:   from PetscFinalize().

    281:   Level: developer

    283: .seealso: `PetscInitialize()`
    284: @*/
    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: }

    298: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
    299: /*
    300:   PetscDLLibraryRegister - This function is called when the dynamic library it is in is opened.

    302:   This one registers all the methods that are in the PETSc `Vec` library.

    304:  */
    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: }

    316: #endif /* PETSC_HAVE_DYNAMIC_LIBRARIES */