xref: /petsc/src/sys/classes/random/interface/randreg.c (revision 8fb5bd83c3955fefcf33a54e3bb66920a9fa884b)
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   if (rnd->ops->destroy) {
42     PetscCall((*rnd->ops->destroy)(rnd));
43 
44     rnd->ops->destroy = NULL;
45   }
46   PetscCall((*r)(rnd));
47   PetscCall(PetscRandomSeed(rnd));
48 
49   PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
50   PetscFunctionReturn(0);
51 }
52 
53 /*@C
54   PetscRandomGetType - Gets the type name (as a string) from the PetscRandom.
55 
56   Not Collective
57 
58   Input Parameter:
59 . rnd  - The random number generator context
60 
61   Output Parameter:
62 . type - The type name
63 
64   Level: intermediate
65 
66 .seealso: `PetscRandomSetType()`, `PetscRandomCreate()`
67 @*/
68 PetscErrorCode  PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
69 {
70   PetscFunctionBegin;
71   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID,1);
72   PetscValidPointer(type,2);
73   *type = ((PetscObject)rnd)->type_name;
74   PetscFunctionReturn(0);
75 }
76 
77 /*@C
78   PetscRandomRegister -  Adds a new PetscRandom component implementation
79 
80   Not Collective
81 
82   Input Parameters:
83 + name        - The name of a new user-defined creation routine
84 - create_func - The creation routine itself
85 
86   Notes:
87   PetscRandomRegister() may be called multiple times to add several user-defined randome number generators
88 
89   Sample usage:
90 .vb
91     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
92 .ve
93 
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
103 
104   Notes:
105     For an example of the code needed to interface your own random number generator see
106          src/sys/random/impls/rand/rand.c
107 
108   Level: advanced
109 
110 .seealso: `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`, `PetscRandomRegister()`
111 @*/
112 PetscErrorCode  PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom))
113 {
114   PetscFunctionBegin;
115   PetscCall(PetscRandomInitializePackage());
116   PetscCall(PetscFunctionListAdd(&PetscRandomList,sname,function));
117   PetscFunctionReturn(0);
118 }
119 
120 #if defined(PETSC_HAVE_RAND)
121 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
122 #endif
123 #if defined(PETSC_HAVE_DRAND48)
124 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
125 #endif
126 #if defined(PETSC_HAVE_SPRNG)
127 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
128 #endif
129 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom);
130 #if defined(PETSC_HAVE_RANDOM123)
131 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom);
132 #endif
133 #if defined(PETSC_HAVE_CUDA)
134 PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom);
135 #endif
136 
137 /*@C
138   PetscRandomRegisterAll - Registers all of the components in the PetscRandom package.
139 
140   Not Collective
141 
142   Level: advanced
143 
144 .seealso: `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
145 @*/
146 PetscErrorCode  PetscRandomRegisterAll(void)
147 {
148   PetscFunctionBegin;
149   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(0);
150   PetscRandomRegisterAllCalled = PETSC_TRUE;
151 #if defined(PETSC_HAVE_RAND)
152   PetscCall(PetscRandomRegister(PETSCRAND,PetscRandomCreate_Rand));
153 #endif
154 #if defined(PETSC_HAVE_DRAND48)
155   PetscCall(PetscRandomRegister(PETSCRAND48,PetscRandomCreate_Rand48));
156 #endif
157 #if defined(PETSC_HAVE_SPRNG)
158   PetscCall(PetscRandomRegister(PETSCSPRNG,PetscRandomCreate_Sprng));
159 #endif
160   PetscCall(PetscRandomRegister(PETSCRANDER48,PetscRandomCreate_Rander48));
161 #if defined(PETSC_HAVE_RANDOM123)
162   PetscCall(PetscRandomRegister(PETSCRANDOM123,PetscRandomCreate_Random123));
163 #endif
164 #if defined(PETSC_HAVE_CUDA)
165   PetscCall(PetscRandomRegister(PETSCCURAND,PetscRandomCreate_CURAND));
166 #endif
167   PetscFunctionReturn(0);
168 }
169