xref: /petsc/src/sys/classes/random/interface/randreg.c (revision 8fd105b637c659b5723a6c3ba83a32bc84aa12fb)
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 particular type of random numbers.
9 
10   Collective on PetscRandom
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   Notes:
21   See "petsc/include/petscsys.h" for available random types (for instance, PETSCRAND48, PETSCRAND).
22 
23   Level: intermediate
24 
25 .seealso: `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(0);
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(0);
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: `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(0);
73 }
74 
75 /*@C
76   PetscRandomRegister -  Adds a new PetscRandom component implementation
77 
78   Not Collective
79 
80   Input Parameters:
81 + name        - The name of a new user-defined creation routine
82 - create_func - The creation routine itself
83 
84   Notes:
85   PetscRandomRegister() may be called multiple times to add several user-defined randome number generators
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   Notes:
103     For an example of the code needed to interface your own random number generator see
104          src/sys/random/impls/rand/rand.c
105 
106   Level: advanced
107 
108 .seealso: `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`, `PetscRandomRegister()`
109 @*/
110 PetscErrorCode  PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom))
111 {
112   PetscFunctionBegin;
113   PetscCall(PetscRandomInitializePackage());
114   PetscCall(PetscFunctionListAdd(&PetscRandomList,sname,function));
115   PetscFunctionReturn(0);
116 }
117 
118 #if defined(PETSC_HAVE_RAND)
119 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
120 #endif
121 #if defined(PETSC_HAVE_DRAND48)
122 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
123 #endif
124 #if defined(PETSC_HAVE_SPRNG)
125 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
126 #endif
127 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom);
128 #if defined(PETSC_HAVE_RANDOM123)
129 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom);
130 #endif
131 #if defined(PETSC_HAVE_CUDA)
132 PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom);
133 #endif
134 
135 /*@C
136   PetscRandomRegisterAll - Registers all of the components in the PetscRandom package.
137 
138   Not Collective
139 
140   Level: advanced
141 
142 .seealso: `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
143 @*/
144 PetscErrorCode  PetscRandomRegisterAll(void)
145 {
146   PetscFunctionBegin;
147   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(0);
148   PetscRandomRegisterAllCalled = PETSC_TRUE;
149 #if defined(PETSC_HAVE_RAND)
150   PetscCall(PetscRandomRegister(PETSCRAND,PetscRandomCreate_Rand));
151 #endif
152 #if defined(PETSC_HAVE_DRAND48)
153   PetscCall(PetscRandomRegister(PETSCRAND48,PetscRandomCreate_Rand48));
154 #endif
155 #if defined(PETSC_HAVE_SPRNG)
156   PetscCall(PetscRandomRegister(PETSCSPRNG,PetscRandomCreate_Sprng));
157 #endif
158   PetscCall(PetscRandomRegister(PETSCRANDER48,PetscRandomCreate_Rander48));
159 #if defined(PETSC_HAVE_RANDOM123)
160   PetscCall(PetscRandomRegister(PETSCRANDOM123,PetscRandomCreate_Random123));
161 #endif
162 #if defined(PETSC_HAVE_CUDA)
163   PetscCall(PetscRandomRegister(PETSCCURAND,PetscRandomCreate_CURAND));
164 #endif
165   PetscFunctionReturn(0);
166 }
167