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 on rnd 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 Note: 21 See "petsc/include/petscsys.h" for available random types (for instance, `PETSCRAND48`, `PETSCRAND`). 22 23 Level: intermediate 24 25 .seealso: `PetscRandom`, `PetscRandomGetType()`, `PetscRandomCreate()` 26 @*/ 27 28 PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type) 29 { 30 PetscErrorCode (*r)(PetscRandom); 31 PetscBool match; 32 33 PetscFunctionBegin; 34 PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1); 35 PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match)); 36 if (match) PetscFunctionReturn(0); 37 38 PetscCall(PetscFunctionListFind(PetscRandomList, type, &r)); 39 PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type); 40 41 PetscTryTypeMethod(rnd, destroy); 42 rnd->ops->destroy = NULL; 43 44 PetscCall((*r)(rnd)); 45 PetscCall(PetscRandomSeed(rnd)); 46 47 PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type)); 48 PetscFunctionReturn(0); 49 } 50 51 /*@C 52 PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`. 53 54 Not Collective 55 56 Input Parameter: 57 . rnd - The random number generator context 58 59 Output Parameter: 60 . type - The type name 61 62 Level: intermediate 63 64 .seealso: `PetscRandom`, `PetscRandomSetType()`, `PetscRandomCreate()` 65 @*/ 66 PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type) 67 { 68 PetscFunctionBegin; 69 PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1); 70 PetscValidPointer(type, 2); 71 *type = ((PetscObject)rnd)->type_name; 72 PetscFunctionReturn(0); 73 } 74 75 /*@C 76 PetscRandomRegister - Adds a new `PetscRandom` implementation 77 78 Not Collective 79 80 Input Parameters: 81 + name - The name of a new user-defined creation routine 82 - create_func - The creation routine itself 83 84 Notes: 85 `PetscRandomRegister()` may be called multiple times to add several user-defined randome 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 Sample 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 Level: advanced 105 106 .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()`, `PetscRandomRegister()` 107 @*/ 108 PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom)) 109 { 110 PetscFunctionBegin; 111 PetscCall(PetscRandomInitializePackage()); 112 PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function)); 113 PetscFunctionReturn(0); 114 } 115 116 #if defined(PETSC_HAVE_RAND) 117 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom); 118 #endif 119 #if defined(PETSC_HAVE_DRAND48) 120 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom); 121 #endif 122 #if defined(PETSC_HAVE_SPRNG) 123 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom); 124 #endif 125 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom); 126 #if defined(PETSC_HAVE_RANDOM123) 127 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom); 128 #endif 129 #if defined(PETSC_HAVE_CUDA) 130 PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom); 131 #endif 132 133 /*@C 134 PetscRandomRegisterAll - Registers all of the components in the `PetscRandom` package. 135 136 Not Collective 137 138 Level: advanced 139 140 .seealso: `PetscRandom`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()` 141 @*/ 142 PetscErrorCode PetscRandomRegisterAll(void) 143 { 144 PetscFunctionBegin; 145 if (PetscRandomRegisterAllCalled) PetscFunctionReturn(0); 146 PetscRandomRegisterAllCalled = PETSC_TRUE; 147 #if defined(PETSC_HAVE_RAND) 148 PetscCall(PetscRandomRegister(PETSCRAND, PetscRandomCreate_Rand)); 149 #endif 150 #if defined(PETSC_HAVE_DRAND48) 151 PetscCall(PetscRandomRegister(PETSCRAND48, PetscRandomCreate_Rand48)); 152 #endif 153 #if defined(PETSC_HAVE_SPRNG) 154 PetscCall(PetscRandomRegister(PETSCSPRNG, PetscRandomCreate_Sprng)); 155 #endif 156 PetscCall(PetscRandomRegister(PETSCRANDER48, PetscRandomCreate_Rander48)); 157 #if defined(PETSC_HAVE_RANDOM123) 158 PetscCall(PetscRandomRegister(PETSCRANDOM123, PetscRandomCreate_Random123)); 159 #endif 160 #if defined(PETSC_HAVE_CUDA) 161 PetscCall(PetscRandomRegister(PETSCCURAND, PetscRandomCreate_CURAND)); 162 #endif 163 PetscFunctionReturn(0); 164 } 165