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 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 Level: intermediate 21 22 Note: 23 See `PetscRandomType` for available random types (for instance, `PETSCRAND48`, `PETSCRAND`). 24 25 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomGetType()`, `PetscRandomCreate()` 26 @*/ 27 PetscErrorCode PetscRandomSetType(PetscRandom rnd, PetscRandomType type) 28 { 29 PetscErrorCode (*r)(PetscRandom); 30 PetscBool match; 31 32 PetscFunctionBegin; 33 PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1); 34 PetscCall(PetscObjectTypeCompare((PetscObject)rnd, type, &match)); 35 if (match) PetscFunctionReturn(PETSC_SUCCESS); 36 37 PetscCall(PetscFunctionListFind(PetscRandomList, type, &r)); 38 PetscCheck(r, PetscObjectComm((PetscObject)rnd), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown random type: %s", type); 39 40 PetscTryTypeMethod(rnd, destroy); 41 rnd->ops->destroy = NULL; 42 43 PetscCall((*r)(rnd)); 44 PetscCall(PetscRandomSeed(rnd)); 45 46 PetscCall(PetscObjectChangeTypeName((PetscObject)rnd, type)); 47 PetscFunctionReturn(PETSC_SUCCESS); 48 } 49 50 /*@C 51 PetscRandomGetType - Gets the type name (as a string) from the `PetscRandom`. 52 53 Not Collective 54 55 Input Parameter: 56 . rnd - The random number generator context 57 58 Output Parameter: 59 . type - The type name 60 61 Level: intermediate 62 63 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomSetType()`, `PetscRandomCreate()` 64 @*/ 65 PetscErrorCode PetscRandomGetType(PetscRandom rnd, PetscRandomType *type) 66 { 67 PetscFunctionBegin; 68 PetscValidHeaderSpecific(rnd, PETSC_RANDOM_CLASSID, 1); 69 PetscAssertPointer(type, 2); 70 *type = ((PetscObject)rnd)->type_name; 71 PetscFunctionReturn(PETSC_SUCCESS); 72 } 73 74 /*@C 75 PetscRandomRegister - Adds a new `PetscRandom` implementation 76 77 Not Collective 78 79 Input Parameters: 80 + sname - The name of a new user-defined creation routine 81 - function - The creation routine 82 83 Level: advanced 84 85 Notes: 86 `PetscRandomRegister()` may be called multiple times to add several user-defined randome number generators 87 88 For an example of the code needed to interface your own random number generator see src/sys/random/impls/rand/rand.c 89 90 Example Usage: 91 .vb 92 PetscRandomRegister("my_rand", MyPetscRandomtorCreate); 93 .ve 94 95 Then, your random type can be chosen with the procedural interface via 96 .vb 97 PetscRandomCreate(MPI_Comm, PetscRandom *); 98 PetscRandomSetType(PetscRandom,"my_random_name"); 99 .ve 100 or at runtime via the option 101 .vb 102 -random_type my_random_name 103 .ve 104 105 .seealso: `PetscRandom`, `PetscRandomRegisterAll()`, `PetscRandomRegisterDestroy()` 106 @*/ 107 PetscErrorCode PetscRandomRegister(const char sname[], PetscErrorCode (*function)(PetscRandom)) 108 { 109 PetscFunctionBegin; 110 PetscCall(PetscRandomInitializePackage()); 111 PetscCall(PetscFunctionListAdd(&PetscRandomList, sname, function)); 112 PetscFunctionReturn(PETSC_SUCCESS); 113 } 114 115 #if defined(PETSC_HAVE_RAND) 116 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand(PetscRandom); 117 #endif 118 #if defined(PETSC_HAVE_DRAND48) 119 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rand48(PetscRandom); 120 #endif 121 #if defined(PETSC_HAVE_SPRNG) 122 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Sprng(PetscRandom); 123 #endif 124 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Rander48(PetscRandom); 125 #if defined(PETSC_HAVE_RANDOM123) 126 PETSC_EXTERN PetscErrorCode PetscRandomCreate_Random123(PetscRandom); 127 #endif 128 #if defined(PETSC_HAVE_CUDA) 129 PETSC_EXTERN PetscErrorCode PetscRandomCreate_CURAND(PetscRandom); 130 #endif 131 132 /*@C 133 PetscRandomRegisterAll - Registers all of the implementations in the `PetscRandom` package. 134 135 Not Collective 136 137 Level: advanced 138 139 .seealso: `PetscRandom`, `PetscRandomType`, `PetscRandomRegister()`, `PetscRandomRegisterDestroy()` 140 @*/ 141 PetscErrorCode PetscRandomRegisterAll(void) 142 { 143 PetscFunctionBegin; 144 if (PetscRandomRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 145 PetscRandomRegisterAllCalled = PETSC_TRUE; 146 #if defined(PETSC_HAVE_RAND) 147 PetscCall(PetscRandomRegister(PETSCRAND, PetscRandomCreate_Rand)); 148 #endif 149 #if defined(PETSC_HAVE_DRAND48) 150 PetscCall(PetscRandomRegister(PETSCRAND48, PetscRandomCreate_Rand48)); 151 #endif 152 #if defined(PETSC_HAVE_SPRNG) 153 PetscCall(PetscRandomRegister(PETSCSPRNG, PetscRandomCreate_Sprng)); 154 #endif 155 PetscCall(PetscRandomRegister(PETSCRANDER48, PetscRandomCreate_Rander48)); 156 #if defined(PETSC_HAVE_RANDOM123) 157 PetscCall(PetscRandomRegister(PETSCRANDOM123, PetscRandomCreate_Random123)); 158 #endif 159 #if defined(PETSC_HAVE_CUDA) 160 PetscCall(PetscRandomRegister(PETSCCURAND, PetscRandomCreate_CURAND)); 161 #endif 162 PetscFunctionReturn(PETSC_SUCCESS); 163 } 164