xref: /petsc/src/sys/classes/random/interface/randreg.c (revision 2fe279fdf3e687a416e4eadb7d3c7a82d60442c6)
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 
22*2fe279fdSBarry Smith   Note:
23*2fe279fdSBarry Smith   See `PetscRandomType` for available random types (for instance, `PETSCRAND48`, `PETSCRAND`).
24*2fe279fdSBarry Smith 
25*2fe279fdSBarry Smith .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomGetType()`, `PetscRandomCreate()`
265c6c1daeSBarry Smith @*/
275c6c1daeSBarry Smith 
28d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type)
29d71ae5a4SJacob Faibussowitsch {
305c6c1daeSBarry Smith   PetscErrorCode (*r)(PetscRandom);
315c6c1daeSBarry Smith   PetscBool match;
325c6c1daeSBarry Smith 
335c6c1daeSBarry Smith   PetscFunctionBegin;
345c6c1daeSBarry Smith   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match));
363ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
375c6c1daeSBarry Smith 
389566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscRandomList, type, &r));
3928b400f6SJacob Faibussowitsch   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type);
405c6c1daeSBarry Smith 
41dbbe0bcdSBarry Smith   PetscTryTypeMethod(rnd, destroy);
420298fd71SBarry Smith   rnd->ops->destroy = NULL;
43dbbe0bcdSBarry Smith 
449566063dSJacob Faibussowitsch   PetscCall((*r)(rnd));
459566063dSJacob Faibussowitsch   PetscCall(PetscRandomSeed(rnd));
465c6c1daeSBarry Smith 
479566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type));
483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
495c6c1daeSBarry Smith }
505c6c1daeSBarry Smith 
515c6c1daeSBarry Smith /*@C
52811af0c4SBarry Smith   PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`.
535c6c1daeSBarry Smith 
545c6c1daeSBarry Smith   Not Collective
555c6c1daeSBarry Smith 
565c6c1daeSBarry Smith   Input Parameter:
575c6c1daeSBarry Smith . rnd  - The random number generator context
585c6c1daeSBarry Smith 
595c6c1daeSBarry Smith   Output Parameter:
605c6c1daeSBarry Smith . type - The type name
615c6c1daeSBarry Smith 
625c6c1daeSBarry Smith   Level: intermediate
635c6c1daeSBarry Smith 
64*2fe279fdSBarry Smith .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()`
655c6c1daeSBarry Smith @*/
66d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type)
67d71ae5a4SJacob Faibussowitsch {
685c6c1daeSBarry Smith   PetscFunctionBegin;
695c6c1daeSBarry Smith   PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1);
705c6c1daeSBarry Smith   PetscValidPointer(type, 2);
715c6c1daeSBarry Smith   *type = ((PetscObject)rnd)->type_name;
723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
735c6c1daeSBarry Smith }
745c6c1daeSBarry Smith 
755c6c1daeSBarry Smith /*@C
76811af0c4SBarry Smith   PetscRandomRegister -  Adds a new `PetscRandom` implementation
771c84c290SBarry Smith 
781c84c290SBarry Smith   Not Collective
791c84c290SBarry Smith 
801c84c290SBarry Smith   Input Parameters:
81*2fe279fdSBarry Smith + sname    - The name of a new user-defined creation routine
82*2fe279fdSBarry Smith - function - The creation routine
83*2fe279fdSBarry Smith 
84*2fe279fdSBarry Smith   Level: advanced
851c84c290SBarry Smith 
861c84c290SBarry Smith   Notes:
87811af0c4SBarry Smith   `PetscRandomRegister()` may be called multiple times to add several user-defined randome number generators
88811af0c4SBarry Smith 
89811af0c4SBarry Smith   For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c
901c84c290SBarry Smith 
911c84c290SBarry Smith   Sample usage:
921c84c290SBarry Smith .vb
93bdf89e91SBarry Smith     PetscRandomRegister("my_rand",  MyPetscRandomtorCreate);
941c84c290SBarry Smith .ve
951c84c290SBarry Smith 
961c84c290SBarry Smith   Then, your random type can be chosen with the procedural interface via
971c84c290SBarry Smith .vb
981c84c290SBarry Smith     PetscRandomCreate(MPI_Comm, PetscRandom *);
991c84c290SBarry Smith     PetscRandomSetType(PetscRandom,"my_random_name");
1001c84c290SBarry Smith .ve
1011c84c290SBarry Smith    or at runtime via the option
1021c84c290SBarry Smith .vb
1031c84c290SBarry Smith     -random_type my_random_name
1041c84c290SBarry Smith .ve
1051c84c290SBarry Smith 
106811af0c4SBarry Smith .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`, `PetscRandomRegister()`
1075c6c1daeSBarry Smith @*/
108d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom))
109d71ae5a4SJacob Faibussowitsch {
1105c6c1daeSBarry Smith   PetscFunctionBegin;
1119566063dSJacob Faibussowitsch   PetscCall(PetscRandomInitializePackage());
1129566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function));
1133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1145c6c1daeSBarry Smith }
1155c6c1daeSBarry Smith 
1165c6c1daeSBarry Smith #if defined(PETSC_HAVE_RAND)
1178cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom);
1185c6c1daeSBarry Smith #endif
1195c6c1daeSBarry Smith #if defined(PETSC_HAVE_DRAND48)
1208cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom);
1215c6c1daeSBarry Smith #endif
1225c6c1daeSBarry Smith #if defined(PETSC_HAVE_SPRNG)
1238cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom);
1245c6c1daeSBarry Smith #endif
125003ee160SMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom);
12625ccb61fSToby Isaac #if defined(PETSC_HAVE_RANDOM123)
12725ccb61fSToby Isaac PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom);
12825ccb61fSToby Isaac #endif
129808ba619SStefano Zampini #if defined(PETSC_HAVE_CUDA)
130808ba619SStefano Zampini PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom);
131808ba619SStefano Zampini #endif
1325c6c1daeSBarry Smith 
1335c6c1daeSBarry Smith /*@C
134*2fe279fdSBarry Smith   PetscRandomRegisterAll - Registers all of the implementations in the `PetscRandom` package.
1355c6c1daeSBarry Smith 
1365c6c1daeSBarry Smith    Not Collective
1375c6c1daeSBarry Smith 
1385c6c1daeSBarry Smith   Level: advanced
1395c6c1daeSBarry Smith 
140*2fe279fdSBarry Smith .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()`
1415c6c1daeSBarry Smith @*/
142d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscRandomRegisterAll(void)
143d71ae5a4SJacob Faibussowitsch {
1445c6c1daeSBarry Smith   PetscFunctionBegin;
1453ba16761SJacob Faibussowitsch   if (PetscRandomRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
1465c6c1daeSBarry Smith   PetscRandomRegisterAllCalled = PETSC_TRUE;
1475c6c1daeSBarry Smith #if defined(PETSC_HAVE_RAND)
1489566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRAND, PetscRandomCreate_Rand));
1495c6c1daeSBarry Smith #endif
1505c6c1daeSBarry Smith #if defined(PETSC_HAVE_DRAND48)
1519566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRAND48, PetscRandomCreate_Rand48));
1525c6c1daeSBarry Smith #endif
1535c6c1daeSBarry Smith #if defined(PETSC_HAVE_SPRNG)
1549566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCSPRNG, PetscRandomCreate_Sprng));
1555c6c1daeSBarry Smith #endif
1569566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRANDER48, PetscRandomCreate_Rander48));
15725ccb61fSToby Isaac #if defined(PETSC_HAVE_RANDOM123)
1589566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCRANDOM123, PetscRandomCreate_Random123));
15925ccb61fSToby Isaac #endif
160808ba619SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1619566063dSJacob Faibussowitsch   PetscCall(PetscRandomRegister(PETSCCURAND, PetscRandomCreate_CURAND));
162808ba619SStefano Zampini #endif
1633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1645c6c1daeSBarry Smith }
165