1 //===-- flang/unittests/Runtime/Random.cpp ----------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "flang/Runtime/random.h" 10 #include "gtest/gtest.h" 11 #include "flang/Runtime/descriptor.h" 12 #include "flang/Runtime/type-code.h" 13 #include <cmath> 14 15 using namespace Fortran::runtime; 16 17 TEST(RandomNumber, Real4) { 18 StaticDescriptor<1> statDesc; 19 Descriptor &harvest{statDesc.descriptor()}; 20 static constexpr int n{10000}; 21 float xs[n]{}; 22 SubscriptValue extent[1]{n}; 23 harvest.Establish(TypeCategory::Real, 4, xs, 1, extent); 24 RTNAME(RandomNumber)(harvest, __FILE__, __LINE__); 25 double sum{0}; 26 for (int j{0}; j < n; ++j) { 27 sum += xs[j]; 28 } 29 double mean{sum / n}; 30 std::fprintf(stderr, "mean of %d random numbers: %g\n", n, mean); 31 EXPECT_GE(mean, 0.95 * 0.5); // mean of uniform dist [0..1] is of course 0.5 32 EXPECT_LE(mean, 1.05 * 0.5); 33 double sumsq{0}; 34 for (int j{0}; j < n; ++j) { 35 double diff{xs[j] - mean}; 36 sumsq += diff * diff; 37 } 38 double sdev{std::sqrt(sumsq / n)}; 39 std::fprintf(stderr, "stddev of %d random numbers: %g\n", n, sdev); 40 double expect{1.0 / std::sqrt(12.0)}; // stddev of uniform dist [0..1] 41 EXPECT_GE(sdev, 0.95 * expect); 42 EXPECT_LT(sdev, 1.05 * expect); 43 } 44 45 TEST(RandomNumber, RandomSeed) { 46 StaticDescriptor<1> statDesc[2]; 47 Descriptor &desc{statDesc[0].descriptor()}; 48 std::int32_t n; 49 desc.Establish(TypeCategory::Integer, 4, &n, 0, nullptr); 50 RTNAME(RandomSeedSize)(desc, __FILE__, __LINE__); 51 EXPECT_EQ(n, 1); 52 SubscriptValue extent[1]{1}; 53 desc.Establish(TypeCategory::Integer, 4, &n, 1, extent); 54 RTNAME(RandomSeedGet)(desc, __FILE__, __LINE__); 55 Descriptor &harvest{statDesc[1].descriptor()}; 56 float x; 57 harvest.Establish(TypeCategory::Real, 4, &x, 1, extent); 58 RTNAME(RandomNumber)(harvest, __FILE__, __LINE__); 59 float got{x}; 60 RTNAME(RandomSeedPut)(desc, __FILE__, __LINE__); // n from RandomSeedGet() 61 RTNAME(RandomNumber)(harvest, __FILE__, __LINE__); 62 EXPECT_EQ(x, got); 63 } 64