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
15using namespace Fortran::runtime;
16
17TEST(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, format: "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(x: sumsq / n)};
39 std::fprintf(stderr, format: "stddev of %d random numbers: %g\n", n, sdev);
40 double expect{1.0 / std::sqrt(x: 12.0)}; // stddev of uniform dist [0..1]
41 EXPECT_GE(sdev, 0.95 * expect);
42 EXPECT_LT(sdev, 1.05 * expect);
43}
44
45TEST(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

source code of flang/unittests/Runtime/Random.cpp