Actual source code: randreg.c
1: #include <petsc/private/randomimpl.h>
3: PetscFunctionList PetscRandomList = NULL;
4: PetscBool PetscRandomRegisterAllCalled = PETSC_FALSE;
6: /*@C
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: /*@C
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
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: }