xref: /petsc/src/sys/classes/random/interface/randreg.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
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   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: `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 component 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   Sample usage:
86 .vb
87     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
88 .ve
89 
90   Then, your random type can be chosen with the procedural interface via
91 .vb
92     PetscRandomCreate(MPI_Comm, PetscRandom *);
93     PetscRandomSetType(PetscRandom,"my_random_name");
94 .ve
95    or at runtime via the option
96 .vb
97     -random_type my_random_name
98 .ve
99 
100   Notes:
101     For an example of the code needed to interface your own random number generator see
102          src/sys/random/impls/rand/rand.c
103 
104   Level: advanced
105 
106 .seealso: `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`, `PetscRandomRegister()`
107 @*/
108 PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom)) {
109   PetscFunctionBegin;
110   PetscCall(PetscRandomInitializePackage());
111   PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function));
112   PetscFunctionReturn(0);
113 }
114 
115 #if defined(PETSC_HAVE_RAND)
116 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
117 #endif
118 #if defined(PETSC_HAVE_DRAND48)
119 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
120 #endif
121 #if defined(PETSC_HAVE_SPRNG)
122 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
123 #endif
124 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom);
125 #if defined(PETSC_HAVE_RANDOM123)
126 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom);
127 #endif
128 #if defined(PETSC_HAVE_CUDA)
129 PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom);
130 #endif
131 
132 /*@C
133   PetscRandomRegisterAll - Registers all of the components in the PetscRandom package.
134 
135   Not Collective
136 
137   Level: advanced
138 
139 .seealso: `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
140 @*/
141 PetscErrorCode PetscRandomRegisterAll(void) {
142   PetscFunctionBegin;
143   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(0);
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(0);
162 }
163