homer512 icon

meshtool rand_generator fix

homer512 | PRO | 10/06/25 11:51:17 AM UTC (Edited) | 0 ⭐ | 16118 👁️ | Never ⏰ | []
Diff |

2.03 KB

|

Source Code

|

0 👍

/

0 👎

diff --git a/utils/rand_generator.h b/utils/rand_generator.h
index 45e09d0..eb7f41d 100644
--- a/utils/rand_generator.h
+++ b/utils/rand_generator.h
@@ -2,6 +2,7 @@
 #define _RAND_GENERATOR_H
 
 #include <stdlib.h>
+#include <random>
 #include <vector>
 
 #ifdef OPENMP
@@ -17,8 +18,23 @@ class rand_generator
   public:
   rand_generator(size_t rsize) : _rands(rsize), _ridx(0)
   {
+    /*
+     * We use a single seed value that is incremented per thread.
+     * See here for motivation:
+     * https://www.johndcook.com/blog/2016/01/29/random-number-generator-seed-mistakes/
+     */
+    static unsigned global_seed = std::random_device()();
+    unsigned thread_seed;
+#   pragma omp atomic relaxed capture
+    thread_seed = global_seed++;
+    /*
+     * Consider using a better random number generator. This one should resemble
+     * drand48(), which was used previously
+     */
+    std::minstd_rand rng(thread_seed);
+    std::uniform_real_distribution<float> distr;
     for(size_t i=0; i<_rands.size(); i++)
-      _rands[i] = drand48();
+      _rands[i] = distr(rng);
   }
 
   rand_generator() : rand_generator(4*1024*1024)
@@ -32,7 +48,11 @@ class rand_generator
 };
 
 class rand_generator_state {
-  mt_vector<rand_generator> global_rands;
+  /*
+   * use std::vector instead of mt_vector because we have to avoid calling
+   * new rand_generator[N] which would invoke the costly default constructor
+   */
+  std::vector<rand_generator> global_rands;
 
   public:
   rand_generator_state() {
@@ -41,8 +61,13 @@ class rand_generator_state {
     {
       int tid      = omp_get_thread_num();
       int nthreads = omp_get_num_threads();
-      if (tid == 0)
-        global_rands.resize(nthreads);
+      /*
+       * Create a vector of empty generators, then let each thread
+       * initialize its own
+       */
+#     pragma omp single
+      global_rands.resize(nthreads, rand_generator(0));
+      global_rands[tid] = rand_generator();
     }
 #else
     global_rands.resize(1);
 

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎