xref: /petsc/src/sys/classes/random/interface/randreg.c (revision 0619917b5a674bb687c64e7daba2ab22be99af31)
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 PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
28 {
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(PETSC_SUCCESS);
36 
37   PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
38   PetscCheck(r, PetscObjectComm((PetscObject)rnd), 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(PETSC_SUCCESS);
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`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()`
64 @*/
65 PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
66 {
67   PetscFunctionBegin;
68   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
69   PetscAssertPointer(type, 2);
70   *type = ((PetscObject)rnd)->type_name;
71   PetscFunctionReturn(PETSC_SUCCESS);
72 }
73 
74 /*@C
75   PetscRandomRegister -  Adds a new `PetscRandom` implementation
76 
77   Not Collective
78 
79   Input Parameters:
80 + sname    - The name of a new user-defined creation routine
81 - function - The creation routine
82 
83   Level: advanced
84 
85   Notes:
86   `PetscRandomRegister()` may be called multiple times to add several user-defined randome number generators
87 
88   For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c
89 
90   Example Usage:
91 .vb
92     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
93 .ve
94 
95   Then, your random type can be chosen with the procedural interface via
96 .vb
97     PetscRandomCreate(MPI_Comm, PetscRandom *);
98     PetscRandomSetType(PetscRandom,"my_random_name");
99 .ve
100   or at runtime via the option
101 .vb
102     -random_type my_random_name
103 .ve
104 
105 .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`
106 @*/
107 PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom))
108 {
109   PetscFunctionBegin;
110   PetscCall(PetscRandomInitializePackage());
111   PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function));
112   PetscFunctionReturn(PETSC_SUCCESS);
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 implementations in the `PetscRandom` package.
134 
135   Not Collective
136 
137   Level: advanced
138 
139 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
140 @*/
141 PetscErrorCode PetscRandomRegisterAll(void)
142 {
143   PetscFunctionBegin;
144   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
145   PetscRandomRegisterAllCalled = PETSC_TRUE;
146 #if defined(PETSC_HAVE_RAND)
147   PetscCall(PetscRandomRegister(PETSCRAND, PetscRandomCreate_Rand));
148 #endif
149 #if defined(PETSC_HAVE_DRAND48)
150   PetscCall(PetscRandomRegister(PETSCRAND48, PetscRandomCreate_Rand48));
151 #endif
152 #if defined(PETSC_HAVE_SPRNG)
153   PetscCall(PetscRandomRegister(PETSCSPRNG, PetscRandomCreate_Sprng));
154 #endif
155   PetscCall(PetscRandomRegister(PETSCRANDER48, PetscRandomCreate_Rander48));
156 #if defined(PETSC_HAVE_RANDOM123)
157   PetscCall(PetscRandomRegister(PETSCRANDOM123, PetscRandomCreate_Random123));
158 #endif
159 #if defined(PETSC_HAVE_CUDA)
160   PetscCall(PetscRandomRegister(PETSCCURAND, PetscRandomCreate_CURAND));
161 #endif
162   PetscFunctionReturn(PETSC_SUCCESS);
163 }
164