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