xref: /petsc/src/sys/classes/random/interface/randreg.c (revision aec76313382a76d73a95f2051cbe4b1eab55c1c7)
15c6c1daeSBarry Smith 
2d6cc7855SJacob Faibussowitsch #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/
35c6c1daeSBarry Smith 
40298fd71SBarry Smith PetscFunctionList PetscRandomList              = NULL;
55c6c1daeSBarry Smith PetscBool         PetscRandomRegisterAllCalled = PETSC_FALSE;
65c6c1daeSBarry Smith 
75c6c1daeSBarry Smith /*@C
8811af0c4SBarry Smith   PetscRandomSetType - Builds a context for generating a particular type of random numbers.
95c6c1daeSBarry Smith 
10c3339decSBarry Smith   Collective
115c6c1daeSBarry Smith 
125c6c1daeSBarry Smith   Input Parameters:
135c6c1daeSBarry Smith + rnd  - The random number generator context
145c6c1daeSBarry Smith - type - The name of the random type
155c6c1daeSBarry Smith 
165c6c1daeSBarry Smith   Options Database Key:
175c6c1daeSBarry Smith . -random_type <type> - Sets the random type; use -help for a list
185c6c1daeSBarry Smith                      of available types
195c6c1daeSBarry Smith 
205c6c1daeSBarry Smith   Level: intermediate
215c6c1daeSBarry Smith 
222fe279fdSBarry Smith   Note:
232fe279fdSBarry Smith   See `PetscRandomType` for available random types (for instance, `PETSCRAND48`, `PETSCRAND`).
242fe279fdSBarry Smith 
252fe279fdSBarry Smith .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomGetType()`, `PetscRandomCreate()`
265c6c1daeSBarry Smith @*/
27d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
28d71ae5a4SJacob Faibussowitsch {
295c6c1daeSBarry Smith   PetscErrorCode (*r)(PetscRandom);
305c6c1daeSBarry Smith   PetscBool match;
315c6c1daeSBarry Smith 
325c6c1daeSBarry Smith   PetscFunctionBegin;
335c6c1daeSBarry Smith   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
349566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match));
353ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
365c6c1daeSBarry Smith 
379566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
386adde796SStefano Zampini   PetscCheck(r, PetscObjectComm((PetscObject)rnd), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);
395c6c1daeSBarry Smith 
40dbbe0bcdSBarry Smith   PetscTryTypeMethod(rnd, destroy);
410298fd71SBarry Smith   rnd->ops->destroy = NULL;
42dbbe0bcdSBarry Smith 
439566063dSJacob Faibussowitsch   PetscCall((*r)(rnd));
449566063dSJacob Faibussowitsch   PetscCall(PetscRandomSeed(rnd));
455c6c1daeSBarry Smith 
469566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
485c6c1daeSBarry Smith }
495c6c1daeSBarry Smith 
505c6c1daeSBarry Smith /*@C
51811af0c4SBarry Smith   PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`.
525c6c1daeSBarry Smith 
535c6c1daeSBarry Smith   Not Collective
545c6c1daeSBarry Smith 
555c6c1daeSBarry Smith   Input Parameter:
565c6c1daeSBarry Smith . rnd - The random number generator context
575c6c1daeSBarry Smith 
585c6c1daeSBarry Smith   Output Parameter:
595c6c1daeSBarry Smith . type - The type name
605c6c1daeSBarry Smith 
615c6c1daeSBarry Smith   Level: intermediate
625c6c1daeSBarry Smith 
632fe279fdSBarry Smith .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()`
645c6c1daeSBarry Smith @*/
65d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
66d71ae5a4SJacob Faibussowitsch {
675c6c1daeSBarry Smith   PetscFunctionBegin;
685c6c1daeSBarry Smith   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
695c6c1daeSBarry Smith   PetscValidPointer(type, 2);
705c6c1daeSBarry Smith   *type = ((PetscObject)rnd)->type_name;
713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
725c6c1daeSBarry Smith }
735c6c1daeSBarry Smith 
745c6c1daeSBarry Smith /*@C
75811af0c4SBarry Smith   PetscRandomRegister -  Adds a new `PetscRandom` implementation
761c84c290SBarry Smith 
771c84c290SBarry Smith   Not Collective
781c84c290SBarry Smith 
791c84c290SBarry Smith   Input Parameters:
802fe279fdSBarry Smith + sname    - The name of a new user-defined creation routine
812fe279fdSBarry Smith - function - The creation routine
822fe279fdSBarry Smith 
832fe279fdSBarry Smith   Level: advanced
841c84c290SBarry Smith 
851c84c290SBarry Smith   Notes:
86811af0c4SBarry Smith   `PetscRandomRegister()` may be called multiple times to add several user-defined randome number generators
87811af0c4SBarry Smith 
88811af0c4SBarry Smith   For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c
891c84c290SBarry Smith 
90*aec76313SJacob Faibussowitsch   Example Usage:
911c84c290SBarry Smith .vb
92bdf89e91SBarry Smith     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
931c84c290SBarry Smith .ve
941c84c290SBarry Smith 
951c84c290SBarry Smith   Then, your random type can be chosen with the procedural interface via
961c84c290SBarry Smith .vb
971c84c290SBarry Smith     PetscRandomCreate(MPI_Comm, PetscRandom *);
981c84c290SBarry Smith     PetscRandomSetType(PetscRandom,"my_random_name");
991c84c290SBarry Smith .ve
1001c84c290SBarry Smith   or at runtime via the option
1011c84c290SBarry Smith .vb
1021c84c290SBarry Smith     -random_type my_random_name
1031c84c290SBarry Smith .ve
1041c84c290SBarry Smith 
105811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`, `PetscRandomRegister()`
1065c6c1daeSBarry Smith @*/
107d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom))
108d71ae5a4SJacob Faibussowitsch {
1095c6c1daeSBarry Smith   PetscFunctionBegin;
1109566063dSJacob Faibussowitsch   PetscCall(PetscRandomInitializePackage());
1119566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function));
1123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1135c6c1daeSBarry Smith }
1145c6c1daeSBarry Smith 
1155c6c1daeSBarry Smith #if defined(PETSC_HAVE_RAND)
1168cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
1175c6c1daeSBarry Smith #endif
1185c6c1daeSBarry Smith #if defined(PETSC_HAVE_DRAND48)
1198cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
1205c6c1daeSBarry Smith #endif
1215c6c1daeSBarry Smith #if defined(PETSC_HAVE_SPRNG)
1228cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
1235c6c1daeSBarry Smith #endif
124003ee160SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom);
12525ccb61fSToby Isaac #if defined(PETSC_HAVE_RANDOM123)
12625ccb61fSToby Isaac PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom);
12725ccb61fSToby Isaac #endif
128808ba619SStefano Zampini #if defined(PETSC_HAVE_CUDA)
129808ba619SStefano Zampini PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom);
130808ba619SStefano Zampini #endif
1315c6c1daeSBarry Smith 
1325c6c1daeSBarry Smith /*@C
1332fe279fdSBarry Smith   PetscRandomRegisterAll - Registers all of the implementations in the `PetscRandom` package.
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith   Not Collective
1365c6c1daeSBarry Smith 
1375c6c1daeSBarry Smith   Level: advanced
1385c6c1daeSBarry Smith 
1392fe279fdSBarry Smith .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
1405c6c1daeSBarry Smith @*/
141d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomRegisterAll(void)
142d71ae5a4SJacob Faibussowitsch {
1435c6c1daeSBarry Smith   PetscFunctionBegin;
1443ba16761SJacob Faibussowitsch   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
1455c6c1daeSBarry Smith   PetscRandomRegisterAllCalled = PETSC_TRUE;
1465c6c1daeSBarry Smith #if defined(PETSC_HAVE_RAND)
1479566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRAND, PetscRandomCreate_Rand));
1485c6c1daeSBarry Smith #endif
1495c6c1daeSBarry Smith #if defined(PETSC_HAVE_DRAND48)
1509566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRAND48, PetscRandomCreate_Rand48));
1515c6c1daeSBarry Smith #endif
1525c6c1daeSBarry Smith #if defined(PETSC_HAVE_SPRNG)
1539566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCSPRNG, PetscRandomCreate_Sprng));
1545c6c1daeSBarry Smith #endif
1559566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRANDER48, PetscRandomCreate_Rander48));
15625ccb61fSToby Isaac #if defined(PETSC_HAVE_RANDOM123)
1579566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRANDOM123, PetscRandomCreate_Random123));
15825ccb61fSToby Isaac #endif
159808ba619SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1609566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCCURAND, PetscRandomCreate_CURAND));
161808ba619SStefano Zampini #endif
1623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1635c6c1daeSBarry Smith }
164