Date: 2025-03-28T21:11:10+00:00

Actual source code: randreg.c

      1: #include <petsc/private/randomimpl.h>

      3: PetscFunctionList PetscRandomList              = NULL;
      4: PetscBool         PetscRandomRegisterAllCalled = PETSC_FALSE;

      6: /*@
      7:   PetscRandomSetType - Builds a context for generating a particular type of random numbers.

      9:   Collective

     11:   Input Parameters:
     12: + rnd  - The random number generator context
     13: - type - The name of the random type

     15:   Options Database Key:
     16: . -random_type <type> - Sets the random type; use -help for a list
     17:                      of available types

     19:   Level: intermediate

     21:   Note:
     22:   See `PetscRandomType` for available random types (for instance, `PETSCRAND48`, `PETSCRAND`).

     24: .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomGetType()`, `PetscRandomCreate()`
     25: @*/
     26: PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
     27: {
     28:   PetscErrorCode (*r)(PetscRandom);
     29:   PetscBool match;

     31:   PetscFunctionBegin;
     33:   PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match));
     34:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

     36:   PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
     37:   PetscCheck(r, PetscObjectComm((PetscObject)rnd), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);

     39:   PetscTryTypeMethod(rnd, destroy);
     40:   rnd->ops->destroy = NULL;

     42:   PetscCall((*r)(rnd));
     43:   PetscCall(PetscRandomSeed(rnd));

     45:   PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
     46:   PetscFunctionReturn(PETSC_SUCCESS);
     47: }

     49: /*@
     50:   PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`.

     52:   Not Collective

     54:   Input Parameter:
     55: . rnd - The random number generator context

     57:   Output Parameter:
     58: . type - The type name

     60:   Level: intermediate

     62: .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()`
     63: @*/
     64: PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
     65: {
     66:   PetscFunctionBegin;
     68:   PetscAssertPointer(type, 2);
     69:   *type = ((PetscObject)rnd)->type_name;
     70:   PetscFunctionReturn(PETSC_SUCCESS);
     71: }

     73: /*@C
     74:   PetscRandomRegister -  Adds a new `PetscRandom` implementation

     76:   Not Collective, No Fortran Support

     78:   Input Parameters:
     79: + sname    - The name of a new user-defined creation routine
     80: - function - The creation routine

     82:   Level: advanced

     84:   Notes:
     85:   `PetscRandomRegister()` may be called multiple times to add several user-defined random number generators

     87:   For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c

     89:   Example Usage:
     90: .vb
     91:     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
     92: .ve

     94:   Then, your random type can be chosen with the procedural interface via
     95: .vb
     96:     PetscRandomCreate(MPI_Comm, PetscRandom *);
     97:     PetscRandomSetType(PetscRandom,"my_random_name");
     98: .ve
     99:   or at runtime via the option
    100: .vb
    101:     -random_type my_random_name
    102: .ve

    104: .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`
    105: @*/
    106: PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom))
    107: {
    108:   PetscFunctionBegin;
    109:   PetscCall(PetscRandomInitializePackage());
    110:   PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function));
    111:   PetscFunctionReturn(PETSC_SUCCESS);
    112: }

    114: #if defined(PETSC_HAVE_RAND)
    115: PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
    116: #endif
    117: #if defined(PETSC_HAVE_DRAND48)
    118: PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
    119: #endif
    120: #if defined(PETSC_HAVE_SPRNG)
    121: PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
    122: #endif
    123: PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom);
    124: #if defined(PETSC_HAVE_RANDOM123)
    125: PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom);
    126: #endif
    127: #if defined(PETSC_HAVE_CUDA)
    128: PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom);
    129: #endif

    131: /*@C
    132:   PetscRandomRegisterAll - Registers all of the implementations in the `PetscRandom` package.

    134:   Not Collective

    136:   Level: advanced

    138: .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
    139: @*/
    140: PetscErrorCode PetscRandomRegisterAll(void)
    141: {
    142:   PetscFunctionBegin;
    143:   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
    144:   PetscRandomRegisterAllCalled = PETSC_TRUE;
    145: #if defined(PETSC_HAVE_RAND)
    146:   PetscCall(PetscRandomRegister(PETSCRAND, PetscRandomCreate_Rand));
    147: #endif
    148: #if defined(PETSC_HAVE_DRAND48)
    149:   PetscCall(PetscRandomRegister(PETSCRAND48, PetscRandomCreate_Rand48));
    150: #endif
    151: #if defined(PETSC_HAVE_SPRNG)
    152:   PetscCall(PetscRandomRegister(PETSCSPRNG, PetscRandomCreate_Sprng));
    153: #endif
    154:   PetscCall(PetscRandomRegister(PETSCRANDER48, PetscRandomCreate_Rander48));
    155: #if defined(PETSC_HAVE_RANDOM123)
    156:   PetscCall(PetscRandomRegister(PETSCRANDOM123, PetscRandomCreate_Random123));
    157: #endif
    158: #if defined(PETSC_HAVE_CUDA)
    159:   PetscCall(PetscRandomRegister(PETSCCURAND, PetscRandomCreate_CURAND));
    160: #endif
    161:   PetscFunctionReturn(PETSC_SUCCESS);
    162: }