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 (rander48|rand|rand48|sprng|random123|curand) - set the random number generator from the options database, see `PetscRandomType`.

     18:   Level: intermediate

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

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

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

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

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

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

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

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

     51:   Not Collective

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

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

     59:   Level: intermediate

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

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

     75:   Not Collective, No Fortran Support

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

     81:   Level: advanced

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

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

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

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

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

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

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

    133:   Not Collective

    135:   Level: advanced

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