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