PageRenderTime 24ms CodeModel.GetById 16ms app.highlight 6ms RepoModel.GetById 0ms app.codeStats 0ms

/common/CUDAMCMLrng.cu

https://bitbucket.org/ezeferrero/qew
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}