[llvm] [Offload][Conformance] Add `RandomGenerator` for large input spaces (PR #154252)

Leandro Lacerda via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 19 05:34:37 PDT 2025


================
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the definition of the RandomGenerator class, a concrete
+/// range-based generator that randomly creates inputs from a given sequence of
+/// ranges.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef MATHTEST_RANDOMGENERATOR_HPP
+#define MATHTEST_RANDOMGENERATOR_HPP
+
+#include "mathtest/IndexedRange.hpp"
+#include "mathtest/RandomState.hpp"
+#include "mathtest/RangeBasedGenerator.hpp"
+
+#include <cstddef>
+#include <cstdint>
+#include <tuple>
+
+namespace mathtest {
+
+template <typename... InTypes>
+class [[nodiscard]] RandomGenerator final
+    : public RangeBasedGenerator<RandomGenerator<InTypes...>, InTypes...> {
+
+  friend class RangeBasedGenerator<RandomGenerator<InTypes...>, InTypes...>;
+
+  using Base = RangeBasedGenerator<RandomGenerator<InTypes...>, InTypes...>;
+
+  using Base::RangesTuple;
+  using Base::SizeToGenerate;
+
+public:
+  explicit constexpr RandomGenerator(
+      SeedTy BaseSeed, uint64_t Size,
+      const IndexedRange<InTypes> &...Ranges) noexcept
+      : Base(Ranges...), BaseSeed(BaseSeed) {
+    SizeToGenerate = Size;
+  }
+
+private:
+  [[nodiscard]] static uint64_t getRandomIndex(RandomState &RNG,
+                                               uint64_t RangeSize) noexcept {
+    if (RangeSize == 0)
+      return 0;
+
+    const uint64_t Threshold = (-RangeSize) % RangeSize;
----------------
leandrolcampos wrote:

That's a great question, For unsigned types like `uint64_t`, the negation `-RangeSize` is defined by two's complement and is equivalent to `(2^64 - RangeSize)`. The modulo of this value correctly gives us the number of values to discard from the beginning of the random sequence to avoid modulo bias.

It's a standard technique for debiasing the modulo operator. This article by Daniel Lemire explains it well: https://lemire.me/blog/2016/06/30/fast-random-shuffling/


https://github.com/llvm/llvm-project/pull/154252


More information about the llvm-commits mailing list