Leandro Lacerda 8d7b50e572
[Offload][Conformance] Add RandomGenerator for large input spaces (#154252)
This patch implements the `RandomGenerator`, a new input generator that
enables conformance testing for functions with large input spaces (e.g.,
double-precision math functions).

**Architectural Refactoring**

To support different generation strategies in a clean and extensible
way, the existing `ExhaustiveGenerator` was refactored into a new class
hierarchy:
* A new abstract base class, `RangeBasedGenerator`, was introduced using
the Curiously Recurring Template Pattern (CRTP). It contains the common
logic for generators that operate on a sequence of ranges.
* `ExhaustiveGenerator` now inherits from this base class, simplifying
its implementation.

**New Components**
* The new `RandomGenerator` class also inherits from
`RangeBasedGenerator`. It implements a strategy that randomly samples a
specified number of points from the total input space.
* Random number generation is handled by a new, self-contained
`RandomState` class (a `xorshift64*` PRNG seeded with `splitmix64`) to
ensure deterministic and reproducible random streams for testing.

**Example Usage**

As a first use case and demonstration of this new capability, this patch
also adds the first double-precision conformance test for the `log`
function. This test uses the new `RandomGenerator` to validate the
implementations from the `llvm-libm`, `cuda-math`, and `hip-math`
providers.
2025-08-20 13:37:01 -05:00

54 lines
1.5 KiB
C++

//===----------------------------------------------------------------------===//
//
// 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 RandomState class, a fast and
/// lightweight pseudo-random number generator.
///
/// The implementation is based on the xorshift* generator, seeded using the
/// SplitMix64 generator for robust initialization. For more details on the
/// algorithm, see: https://en.wikipedia.org/wiki/Xorshift
///
//===----------------------------------------------------------------------===//
#ifndef MATHTEST_RANDOMSTATE_HPP
#define MATHTEST_RANDOMSTATE_HPP
#include <cstdint>
struct SeedTy {
uint64_t Value;
};
class [[nodiscard]] RandomState {
uint64_t State;
[[nodiscard]] static constexpr uint64_t splitMix64(uint64_t X) noexcept {
X += 0x9E3779B97F4A7C15ULL;
X = (X ^ (X >> 30)) * 0xBF58476D1CE4E5B9ULL;
X = (X ^ (X >> 27)) * 0x94D049BB133111EBULL;
X = (X ^ (X >> 31));
return X ? X : 0x9E3779B97F4A7C15ULL;
}
public:
explicit constexpr RandomState(SeedTy Seed) noexcept
: State(splitMix64(Seed.Value)) {}
inline uint64_t next() noexcept {
uint64_t X = State;
X ^= X >> 12;
X ^= X << 25;
X ^= X >> 27;
State = X;
return X * 0x2545F4914F6CDD1DULL;
}
};
#endif // MATHTEST_RANDOMSTATE_HPP