1 #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/
2
3 PetscFunctionList PetscRandomList = NULL;
4 PetscBool PetscRandomRegisterAllCalled = PETSC_FALSE;
5
6 /*@
7 PetscRandomSetType - Builds a context for generating a particular type of random numbers.
8
9 Collective
10
11 Input Parameters:
12 + rnd - The random number generator context
13 - type - The name of the random type
14
15 Options Database Key:
16 . -random_type <type> - Sets the random type; use -help for a list
17 of available types
18
19 Level: intermediate
20
21 Note:
22 See `PetscRandomType` for available random types (for instance, `PETSCRAND48`, `PETSCRAND`).
23
24 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomGetType()`, `PetscRandomCreate()`
25 @*/
PetscRandomSetType(PetscRandom rnd,PetscRandomType type)26 PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
27 {
28 PetscErrorCode (*r)(PetscRandom);
29 PetscBool match;
30
31 PetscFunctionBegin;
32 PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
33 PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match));
34 if (match) PetscFunctionReturn(PETSC_SUCCESS);
35
36 PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
37 PetscCheck(r, PetscObjectComm((PetscObject)rnd), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);
38
39 PetscTryTypeMethod(rnd, destroy);
40 rnd->ops->destroy = NULL;
41
42 PetscCall((*r)(rnd));
43 PetscCall(PetscRandomSeed(rnd));
44
45 PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
46 PetscFunctionReturn(PETSC_SUCCESS);
47 }
48
49 /*@
50 PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`.
51
52 Not Collective
53
54 Input Parameter:
55 . rnd - The random number generator context
56
57 Output Parameter:
58 . type - The type name
59
60 Level: intermediate
61
62 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()`
63 @*/
PetscRandomGetType(PetscRandom rnd,PetscRandomType * type)64 PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
65 {
66 PetscFunctionBegin;
67 PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
68 PetscAssertPointer(type, 2);
69 *type = ((PetscObject)rnd)->type_name;
70 PetscFunctionReturn(PETSC_SUCCESS);
71 }
72
73 /*@C
74 PetscRandomRegister - Adds a new `PetscRandom` implementation
75
76 Not Collective, No Fortran Support
77
78 Input Parameters:
79 + sname - The name of a new user-defined creation routine
80 - function - The creation routine
81
82 Level: advanced
83
84 Notes:
85 `PetscRandomRegister()` may be called multiple times to add several user-defined random number generators
86
87 For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c
88
89 Example 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 .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`
105 @*/
PetscRandomRegister(const char sname[],PetscErrorCode (* function)(PetscRandom))106 PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom))
107 {
108 PetscFunctionBegin;
109 PetscCall(PetscRandomInitializePackage());
110 PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function));
111 PetscFunctionReturn(PETSC_SUCCESS);
112 }
113
114 #if defined(PETSC_HAVE_RAND)
115 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
116 #endif
117 #if defined(PETSC_HAVE_DRAND48)
118 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
119 #endif
120 #if defined(PETSC_HAVE_SPRNG)
121 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
122 #endif
123 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom);
124 #if defined(PETSC_HAVE_RANDOM123)
125 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom);
126 #endif
127 #if defined(PETSC_HAVE_CUDA)
128 PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom);
129 #endif
130
131 /*@C
132 PetscRandomRegisterAll - Registers all of the implementations in the `PetscRandom` package.
133
134 Not Collective
135
136 Level: advanced
137
138 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
139 @*/
PetscRandomRegisterAll(void)140 PetscErrorCode PetscRandomRegisterAll(void)
141 {
142 PetscFunctionBegin;
143 if (PetscRandomRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
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(PETSC_SUCCESS);
162 }
163