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