xref: /petsc/src/sys/classes/random/interface/randreg.c (revision 83c9f7f220f3448cfcd2a76a64462ac242b37309)
1 
2 #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/
3 
4 PetscFunctionList PetscRandomList              = NULL;
5 PetscBool         PetscRandomRegisterAllCalled = PETSC_FALSE;
6 
7 /*@C
8   PetscRandomSetType - Builds a context for generating a particular type of random numbers.
9 
10   Collective on rnd
11 
12   Input Parameters:
13 + rnd   - The random number generator context
14 - type - The name of the random type
15 
16   Options Database Key:
17 . -random_type <type> - Sets the random type; use -help for a list
18                      of available types
19 
20   Note:
21   See "petsc/include/petscsys.h" for available random types (for instance, `PETSCRAND48`, `PETSCRAND`).
22 
23   Level: intermediate
24 
25 .seealso: `PetscRandom`, `PetscRandomGetType()`, `PetscRandomCreate()`
26 @*/
27 
28 PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type) {
29   PetscErrorCode (*r)(PetscRandom);
30   PetscBool match;
31 
32   PetscFunctionBegin;
33   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
34   PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match));
35   if (match) PetscFunctionReturn(0);
36 
37   PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
38   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);
39 
40   PetscTryTypeMethod(rnd, destroy);
41   rnd->ops->destroy = NULL;
42 
43   PetscCall((*r)(rnd));
44   PetscCall(PetscRandomSeed(rnd));
45 
46   PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
47   PetscFunctionReturn(0);
48 }
49 
50 /*@C
51   PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`.
52 
53   Not Collective
54 
55   Input Parameter:
56 . rnd  - The random number generator context
57 
58   Output Parameter:
59 . type - The type name
60 
61   Level: intermediate
62 
63 .seealso: `PetscRandom`, `PetscRandomSetType()`, `PetscRandomCreate()`
64 @*/
65 PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type) {
66   PetscFunctionBegin;
67   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
68   PetscValidPointer(type, 2);
69   *type = ((PetscObject)rnd)->type_name;
70   PetscFunctionReturn(0);
71 }
72 
73 /*@C
74   PetscRandomRegister -  Adds a new `PetscRandom` implementation
75 
76   Not Collective
77 
78   Input Parameters:
79 + name        - The name of a new user-defined creation routine
80 - create_func - The creation routine itself
81 
82   Notes:
83   `PetscRandomRegister()` may be called multiple times to add several user-defined randome number generators
84 
85   For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c
86 
87   Sample usage:
88 .vb
89     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
90 .ve
91 
92   Then, your random type can be chosen with the procedural interface via
93 .vb
94     PetscRandomCreate(MPI_Comm, PetscRandom *);
95     PetscRandomSetType(PetscRandom,"my_random_name");
96 .ve
97    or at runtime via the option
98 .vb
99     -random_type my_random_name
100 .ve
101 
102   Level: advanced
103 
104 .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`, `PetscRandomRegister()`
105 @*/
106 PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom)) {
107   PetscFunctionBegin;
108   PetscCall(PetscRandomInitializePackage());
109   PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function));
110   PetscFunctionReturn(0);
111 }
112 
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
129 
130 /*@C
131   PetscRandomRegisterAll - Registers all of the components in the `PetscRandom` package.
132 
133   Not Collective
134 
135   Level: advanced
136 
137 .seealso: `PetscRandom`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
138 @*/
139 PetscErrorCode PetscRandomRegisterAll(void) {
140   PetscFunctionBegin;
141   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(0);
142   PetscRandomRegisterAllCalled = PETSC_TRUE;
143 #if defined(PETSC_HAVE_RAND)
144   PetscCall(PetscRandomRegister(PETSCRAND, PetscRandomCreate_Rand));
145 #endif
146 #if defined(PETSC_HAVE_DRAND48)
147   PetscCall(PetscRandomRegister(PETSCRAND48, PetscRandomCreate_Rand48));
148 #endif
149 #if defined(PETSC_HAVE_SPRNG)
150   PetscCall(PetscRandomRegister(PETSCSPRNG, PetscRandomCreate_Sprng));
151 #endif
152   PetscCall(PetscRandomRegister(PETSCRANDER48, PetscRandomCreate_Rander48));
153 #if defined(PETSC_HAVE_RANDOM123)
154   PetscCall(PetscRandomRegister(PETSCRANDOM123, PetscRandomCreate_Random123));
155 #endif
156 #if defined(PETSC_HAVE_CUDA)
157   PetscCall(PetscRandomRegister(PETSCCURAND, PetscRandomCreate_CURAND));
158 #endif
159   PetscFunctionReturn(0);
160 }
161