[flang-commits] [flang] ea1a69d - [flang][runtime] Don't let random seed queries change the sequence

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Sat Jun 4 08:46:28 PDT 2022


Author: Peter Klausler
Date: 2022-06-04T08:01:46-07:00
New Revision: ea1a69d66dc7fd08b4b82492869ff3d6ae815991

URL: https://github.com/llvm/llvm-project/commit/ea1a69d66dc7fd08b4b82492869ff3d6ae815991
DIFF: https://github.com/llvm/llvm-project/commit/ea1a69d66dc7fd08b4b82492869ff3d6ae815991.diff

LOG: [flang][runtime] Don't let random seed queries change the sequence

When the current seed of the pseudo-random generator is queried
with CALL RANDOM_SEED(GET=n), that query should not change the
stream of pseudo-random numbers produced by CALL RANDOM_NUMBER().

Differential Revision: https://reviews.llvm.org/D127023

Added: 
    

Modified: 
    flang/runtime/random.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/random.cpp b/flang/runtime/random.cpp
index 93461e436c6ae..56138db7615d7 100644
--- a/flang/runtime/random.cpp
+++ b/flang/runtime/random.cpp
@@ -40,6 +40,19 @@ static constexpr int rangeBits{
 
 static Lock lock;
 static Generator generator;
+static std::optional<GeneratedWord> nextValue;
+
+// Call only with lock held
+static GeneratedWord GetNextValue() {
+  GeneratedWord result;
+  if (nextValue.has_value()) {
+    result = *nextValue;
+    nextValue.reset();
+  } else {
+    result = generator();
+  }
+  return result;
+}
 
 template <typename REAL, int PREC>
 inline void Generate(const Descriptor &harvest) {
@@ -55,12 +68,12 @@ inline void Generate(const Descriptor &harvest) {
     CriticalSection critical{lock};
     for (std::size_t j{0}; j < elements; ++j) {
       while (true) {
-        Int fraction{generator()};
+        Int fraction{GetNextValue()};
         if constexpr (words > 1) {
           for (std::size_t k{1}; k < words; ++k) {
             static constexpr auto rangeMask{
                 (GeneratedWord{1} << rangeBits) - 1};
-            GeneratedWord word{(generator() - generator.min()) & rangeMask};
+            GeneratedWord word{(GetNextValue() - generator.min()) & rangeMask};
             fraction = (fraction << rangeBits) | word;
           }
         }
@@ -161,6 +174,7 @@ void RTNAME(RandomSeedPut)(
   {
     CriticalSection critical{lock};
     generator.seed(seed);
+    nextValue = seed;
   }
 }
 
@@ -183,8 +197,8 @@ void RTNAME(RandomSeedGet)(
   GeneratedWord seed;
   {
     CriticalSection critical{lock};
-    seed = generator();
-    generator.seed(seed);
+    seed = GetNextValue();
+    nextValue = seed;
   }
   switch (kind) {
   case 4:


        


More information about the flang-commits mailing list