Actual source code: randreg.c


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

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

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

 10:   Collective

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

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

 20:   Level: intermediate

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

 25: .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomGetType()`, `PetscRandomCreate()`
 26: @*/

 28: PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
 29: {
 30:   PetscErrorCode (*r)(PetscRandom);
 31:   PetscBool match;

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

 38:   PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
 39:   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);

 41:   PetscTryTypeMethod(rnd, destroy);
 42:   rnd->ops->destroy = NULL;

 44:   PetscCall((*r)(rnd));
 45:   PetscCall(PetscRandomSeed(rnd));

 47:   PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
 48:   PetscFunctionReturn(PETSC_SUCCESS);
 49: }

 51: /*@C
 52:   PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`.

 54:   Not Collective

 56:   Input Parameter:
 57: . rnd  - The random number generator context

 59:   Output Parameter:
 60: . type - The type name

 62:   Level: intermediate

 64: .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()`
 65: @*/
 66: PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
 67: {
 68:   PetscFunctionBegin;
 71:   *type = ((PetscObject)rnd)->type_name;
 72:   PetscFunctionReturn(PETSC_SUCCESS);
 73: }

 75: /*@C
 76:   PetscRandomRegister -  Adds a new `PetscRandom` implementation

 78:   Not Collective

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

 84:   Level: advanced

 86:   Notes:
 87:   `PetscRandomRegister()` may be called multiple times to add several user-defined randome number generators

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

 91:   Sample usage:
 92: .vb
 93:     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
 94: .ve

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

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

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

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

136:    Not Collective

138:   Level: advanced

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