xref: /petsc/src/sys/classes/random/interface/randreg.c (revision 29912973eddc2d63379123316d6141c93d64bbc2)
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
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   Level: intermediate
21 
22   Note:
23   See `PetscRandomType` for available random types (for instance, `PETSCRAND48`, `PETSCRAND`).
24 
25 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomGetType()`, `PetscRandomCreate()`
26 @*/
27 
28 PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
29 {
30   PetscErrorCode (*r)(PetscRandom);
31   PetscBool match;
32 
33   PetscFunctionBegin;
34   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
35   PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match));
36   if (match) PetscFunctionReturn(PETSC_SUCCESS);
37 
38   PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
39   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);
40 
41   PetscTryTypeMethod(rnd, destroy);
42   rnd->ops->destroy = NULL;
43 
44   PetscCall((*r)(rnd));
45   PetscCall(PetscRandomSeed(rnd));
46 
47   PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
48   PetscFunctionReturn(PETSC_SUCCESS);
49 }
50 
51 /*@C
52   PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`.
53 
54   Not Collective
55 
56   Input Parameter:
57 . rnd  - The random number generator context
58 
59   Output Parameter:
60 . type - The type name
61 
62   Level: intermediate
63 
64 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()`
65 @*/
66 PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
67 {
68   PetscFunctionBegin;
69   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
70   PetscValidPointer(type, 2);
71   *type = ((PetscObject)rnd)->type_name;
72   PetscFunctionReturn(PETSC_SUCCESS);
73 }
74 
75 /*@C
76   PetscRandomRegister -  Adds a new `PetscRandom` implementation
77 
78   Not Collective
79 
80   Input Parameters:
81 + sname    - The name of a new user-defined creation routine
82 - function - The creation routine
83 
84   Level: advanced
85 
86   Notes:
87   `PetscRandomRegister()` may be called multiple times to add several user-defined randome number generators
88 
89   For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c
90 
91   Sample usage:
92 .vb
93     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
94 .ve
95 
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
105 
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 }
115 
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
132 
133 /*@C
134   PetscRandomRegisterAll - Registers all of the implementations in the `PetscRandom` package.
135 
136    Not Collective
137 
138   Level: advanced
139 
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 }
165