/common/CUDAMCMLrng.cu

https://bitbucket.org/ezeferrero/qew · Cuda · 97 lines · 54 code · 16 blank · 27 comment · 9 complexity · 713c0588b07e7bd9921f55f596e77469 MD5 · raw file

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