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