1 #include <petsc/private/randomimpl.h> /*I "petscsys.h" I*/ 2 3 PetscFunctionList PetscRandomList = NULL; 4 PetscBool PetscRandomRegisterAllCalled = PETSC_FALSE; 5 6 /*@C 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 @*/ 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 /*@C 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 @*/ 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 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 @*/ 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 @*/ 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