/common/CUDAMCMLrng.cu
CUDA | 97 lines | 78 code | 19 blank | 0 comment | 0 complexity | 713c0588b07e7bd9921f55f596e77469 MD5 | raw file
1/* This file is part of CUDAMCML.
2
3 CUDAMCML is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 CUDAMCML is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with CUDAMCML. If not, see <http://www.gnu.org/licenses/>.*/
15
16//#define PI 3.141592653589793238462643383279502884197169399375105820
17
18__device__ __inline__ float rand_MWC_co(unsigned long long* x, const unsigned int* a)
19{
20 //Generate a random number [0,1)
21 *x=(*x&0xffffffffull)*(*a)+(*x>>32);
22 return __fdividef(__uint2float_rz((unsigned int)(*x)),(float)0x100000000);// The typecast will truncate the x so that it is 0<=x<(2^32-1),__uint2float_rz ensures a round towards zero since 32-bit floating point cannot represent all integers that large. Dividing by 2^32 will hence yield [0,1)
23
24}//end __device__ rand_MWC_co
25
26__device__ __inline__ float rand_MWC_oc(unsigned long long* x,unsigned int* a)
27{
28 //Generate a random number (0,1]
29 return 1.0f-rand_MWC_co(x,a);
30}//end __device__ rand_MWC_oc
31
32
33int init_RNG(unsigned long long *x, unsigned int *a,
34 const unsigned int n_rng, const char *safeprimes_file, unsigned long long xinit)
35{
36 FILE *fp = NULL;
37 int fscanf_result = 0;
38 unsigned int begin = 0u;
39 unsigned int fora,tmp1,tmp2;
40
41 assert(x!=NULL && a!=NULL);
42 assert(safeprimes_file!=NULL);
43
44 if (strlen(safeprimes_file)==0) {
45 // Try to find it in the local directory
46 safeprimes_file = "safeprimes_base32.txt";
47 }
48
49 fp = fopen(safeprimes_file, "r");
50 if (fp==NULL) {
51 printf("Could not find the file of safeprimes (%s)! Terminating!\n", safeprimes_file);
52 return 1;
53 }
54
55 fscanf_result = fscanf(fp,"%u %u %u", &begin, &tmp1, &tmp2);
56 if (fscanf_result<3) {
57 printf("Problem reading first safeprime from file %s\n", safeprimes_file);
58 exit(1);
59 }
60
61 // Here we set up a loop, using the first multiplier in the file to generate x's and c's
62 // There are some restictions to these two numbers:
63 // 0<=c<a and 0<=x<b, where a is the multiplier and b is the base (2^32)
64 // also [x,c]=[0,0] and [b-1,a-1] are not allowed.
65
66 //Make sure xinit is a valid seed (using the above mentioned restrictions)
67 if ((xinit == 0ull) | (((unsigned int)(xinit>>32))>=(begin-1)) | (((unsigned int)xinit)>=0xfffffffful)) {
68 //xinit (probably) not a valid seed! (we have excluded a few unlikely exceptions)
69 printf("%llu not a valid seed! Terminating!\n", xinit);
70 return 1;
71 }
72
73 for (unsigned int i=0; i<n_rng; i++) {
74 fscanf_result = fscanf(fp,"%u %u %u", &fora, &tmp1, &tmp2);
75 if (fscanf_result<3) {
76 printf("Problem reading safeprime %d out of %d from file %s\n", i+2, n_rng+1, safeprimes_file);
77 exit(1);
78 }
79 a[i] = fora;
80 x[i] = 0;
81 while ((x[i]==0) | (((unsigned int)(x[i]>>32))>=(fora-1)) | (((unsigned int)x[i])>=0xfffffffful)) {
82 //generate a random number
83 xinit = (xinit&0xffffffffull)*(begin)+(xinit>>32);
84
85 //calculate c and store in the upper 32 bits of x[i]
86 x[i] = (unsigned int) floor((((double)((unsigned int)xinit))/(double)0x100000000)*fora);//Make sure 0<=c<a
87 x[i] = x[i]<<32;
88
89 //generate a random number and store in the lower 32 bits of x[i] (as the initial x of the generator)
90 xinit = (xinit&0xffffffffull)*(begin)+(xinit>>32);//x will be 0<=x<b, where b is the base 2^32
91 x[i] += (unsigned int) xinit;
92 }
93 }
94 fclose(fp);
95
96 return 0;
97}