Unify fuzzer random number generation into a single class
BUG=tint:1098
Change-Id: I84931804515487d931bbbb5f0d5239d03ca76dfc
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/63300
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Alastair Donaldson <afdx@google.com>
diff --git a/fuzzers/BUILD.gn b/fuzzers/BUILD.gn
index 89857d0..9295aef 100644
--- a/fuzzers/BUILD.gn
+++ b/fuzzers/BUILD.gn
@@ -66,6 +66,8 @@
]
sources = [
+ "random_generator.cc",
+ "random_generator.h",
"tint_common_fuzzer.cc",
"tint_common_fuzzer.h",
]
diff --git a/fuzzers/CMakeLists.txt b/fuzzers/CMakeLists.txt
index b24229f..6b962d7 100644
--- a/fuzzers/CMakeLists.txt
+++ b/fuzzers/CMakeLists.txt
@@ -17,6 +17,8 @@
${NAME}.cc
cli.cc
cli.h
+ random_generator.cc
+ random_generator.h
tint_common_fuzzer.cc
tint_common_fuzzer.h
tint_init_fuzzer.cc
diff --git a/fuzzers/random_generator.cc b/fuzzers/random_generator.cc
new file mode 100644
index 0000000..18b88fe
--- /dev/null
+++ b/fuzzers/random_generator.cc
@@ -0,0 +1,89 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "fuzzers/random_generator.h"
+
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+namespace tint {
+namespace fuzzers {
+
+namespace {
+
+/// Generate integer from uniform distribution
+/// @tparam I - integer type
+/// @param engine - random number engine to use
+/// @param lower - Lower bound of integer generated
+/// @param upper - Upper bound of integer generated
+/// @returns i, where lower <= i < upper
+template <typename I>
+I RandomUInt(std::mt19937* engine, I lower, I upper) {
+ assert(lower < upper && "|lower| must be stictly less than |upper|");
+
+ return std::uniform_int_distribution<I>(lower, upper - 1)(*engine);
+}
+
+} // namespace
+
+RandomGenerator::RandomGenerator(uint32_t seed) : engine_(seed) {}
+
+uint32_t RandomGenerator::GetUInt32(uint32_t lower, uint32_t upper) {
+ return RandomUInt(&engine_, lower, upper);
+}
+
+uint32_t RandomGenerator::GetUInt32(uint32_t bound) {
+ assert(bound > 0 && "|bound| must be greater than 0");
+ return RandomUInt(&engine_, 0u, bound);
+}
+
+uint64_t RandomGenerator::GetUInt64(uint64_t lower, uint64_t upper) {
+ return RandomUInt(&engine_, lower, upper);
+}
+
+uint64_t RandomGenerator::GetUInt64(uint64_t bound) {
+ assert(bound > 0 && "|bound| must be greater than 0");
+ return RandomUInt(&engine_, static_cast<uint64_t>(0), bound);
+}
+
+uint8_t RandomGenerator::GetByte() {
+ return std::independent_bits_engine<std::mt19937, 8, uint8_t>(engine_)();
+}
+
+uint32_t RandomGenerator::Get4Bytes() {
+ return std::independent_bits_engine<std::mt19937, 32, uint32_t>(engine_)();
+}
+
+std::vector<uint8_t> RandomGenerator::GetNBytes(size_t n) {
+ std::vector<uint8_t> result(n);
+ std::generate(
+ std::begin(result), std::end(result),
+ std::independent_bits_engine<std::mt19937, 8, uint8_t>(engine_));
+ return result;
+}
+
+bool RandomGenerator::GetBool() {
+ return RandomUInt(&engine_, 0u, 2u);
+}
+
+bool RandomGenerator::GetWeightedBool(uint32_t percentage) {
+ static const uint32_t kMaxPercentage = 100;
+ assert(percentage <= kMaxPercentage &&
+ "|percentage| needs to be within [0, 100]");
+ return RandomUInt(&engine_, 0u, kMaxPercentage) < percentage;
+}
+
+} // namespace fuzzers
+} // namespace tint
diff --git a/fuzzers/random_generator.h b/fuzzers/random_generator.h
new file mode 100644
index 0000000..c90a3e7
--- /dev/null
+++ b/fuzzers/random_generator.h
@@ -0,0 +1,87 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef FUZZERS_RANDOM_GENERATOR_H_
+#define FUZZERS_RANDOM_GENERATOR_H_
+
+#include <random>
+#include <vector>
+
+namespace tint {
+namespace fuzzers {
+
+/// Pseudo random generator utility class for fuzzing
+class RandomGenerator {
+ public:
+ /// @brief Initializes the internal engine
+ /// @param seed - seed value passed to engine
+ explicit RandomGenerator(uint32_t seed);
+ ~RandomGenerator() {}
+
+ /// Get uint32_t value from uniform distribution.
+ /// @param lower - lower bound of integer generated
+ /// @param upper - upper bound of integer generated
+ /// @returns i, where lower <= i < upper
+ uint32_t GetUInt32(uint32_t lower, uint32_t upper);
+
+ /// Get uint32_t value from uniform distribution.
+ /// @param bound - Upper bound of integer generated
+ /// @returns i, where 0 <= i < bound
+ uint32_t GetUInt32(uint32_t bound);
+
+ /// Get uint32_t value from uniform distribution.
+ /// @param lower - lower bound of integer generated
+ /// @param upper - upper bound of integer generated
+ /// @returns i, where lower <= i < upper
+ uint64_t GetUInt64(uint64_t lower, uint64_t upper);
+
+ /// Get uint64_t value from uniform distribution.
+ /// @param bound - Upper bound of integer generated
+ /// @returns i, where 0 <= i < bound
+ uint64_t GetUInt64(uint64_t bound);
+
+ /// Get 1 byte of pseudo-random data
+ /// Should be more efficient then calling GetNBytes(1);
+ /// @returns 1-byte of random data
+ uint8_t GetByte();
+
+ /// Get 4 bytes of pseudo-random data
+ /// Should be more efficient then calling GetNBytes(4);
+ /// @returns 4-bytes of random data
+ uint32_t Get4Bytes();
+
+ /// Get N bytes of pseudo-random data
+ /// @param n - number of bytes of data to generate
+ /// @returns |N|-bytes of random data as vector
+ std::vector<uint8_t> GetNBytes(size_t n);
+
+ /// Get random bool with even odds
+ /// @returns true 50% of the time and false %50 of time.
+ bool GetBool();
+
+ /// Get random bool with weighted odds
+ /// @param percentage - likelihood of true being returned
+ /// @returns true |percentage|% of the time, and false (100 - |percentage|)%
+ /// of the time.
+ bool GetWeightedBool(uint32_t percentage);
+
+ private:
+ std::mt19937 engine_;
+
+}; // class RandomGenerator
+
+} // namespace fuzzers
+} // namespace tint
+
+#endif // FUZZERS_RANDOM_GENERATOR_H_
diff --git a/fuzzers/tint_ast_fuzzer/BUILD.gn b/fuzzers/tint_ast_fuzzer/BUILD.gn
index 888aca5..1b8a1f5 100644
--- a/fuzzers/tint_ast_fuzzer/BUILD.gn
+++ b/fuzzers/tint_ast_fuzzer/BUILD.gn
@@ -42,8 +42,6 @@
"cli.cc",
"cli.h",
"fuzzer.cc",
- "mt_rng.cc",
- "mt_rng.h",
"mutation.cc",
"mutation.h",
"mutation_finder.cc",
@@ -60,8 +58,6 @@
"probability_context.cc",
"probability_context.h",
"protobufs/tint_ast_fuzzer.h",
- "random_number_generator.cc",
- "random_number_generator.h",
"util.h",
]
}
diff --git a/fuzzers/tint_ast_fuzzer/CMakeLists.txt b/fuzzers/tint_ast_fuzzer/CMakeLists.txt
index 854b08d..1dcb668 100644
--- a/fuzzers/tint_ast_fuzzer/CMakeLists.txt
+++ b/fuzzers/tint_ast_fuzzer/CMakeLists.txt
@@ -35,7 +35,7 @@
COMMENT "Generate protobuf sources from proto definition file.")
set(LIBTINT_AST_FUZZER_SOURCES
- mt_rng.h
+ ../random_generator.h
mutation.h
mutation_finder.h
mutation_finders/replace_identifiers.h
@@ -44,12 +44,11 @@
node_id_map.h
probability_context.h
protobufs/tint_ast_fuzzer.h
- random_number_generator.h
util.h
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.h)
set(LIBTINT_AST_FUZZER_SOURCES ${LIBTINT_AST_FUZZER_SOURCES}
- mt_rng.cc
+ ../random_generator.cc
mutation.cc
mutation_finder.cc
mutation_finders/replace_identifiers.cc
@@ -57,7 +56,6 @@
mutator.cc
node_id_map.cc
probability_context.cc
- random_number_generator.cc
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc PROPERTIES COMPILE_FLAGS -w)
diff --git a/fuzzers/tint_ast_fuzzer/fuzzer.cc b/fuzzers/tint_ast_fuzzer/fuzzer.cc
index dcee8dd..cdb1693 100644
--- a/fuzzers/tint_ast_fuzzer/fuzzer.cc
+++ b/fuzzers/tint_ast_fuzzer/fuzzer.cc
@@ -15,8 +15,8 @@
#include <cstddef>
#include <cstdint>
+#include "fuzzers/random_generator.h"
#include "fuzzers/tint_ast_fuzzer/cli.h"
-#include "fuzzers/tint_ast_fuzzer/mt_rng.h"
#include "fuzzers/tint_ast_fuzzer/mutator.h"
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
#include "fuzzers/tint_common_fuzzer.h"
@@ -54,8 +54,8 @@
}
// Run the mutator.
- MtRng mt_rng(seed);
- ProbabilityContext probability_context(&mt_rng);
+ RandomGenerator generator(seed);
+ ProbabilityContext probability_context(&generator);
program = Mutate(std::move(program), &probability_context,
cli_params.enable_all_mutations,
cli_params.mutation_batch_size, nullptr);
diff --git a/fuzzers/tint_ast_fuzzer/mt_rng.cc b/fuzzers/tint_ast_fuzzer/mt_rng.cc
deleted file mode 100644
index 586b2d9..0000000
--- a/fuzzers/tint_ast_fuzzer/mt_rng.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2021 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "fuzzers/tint_ast_fuzzer/mt_rng.h"
-
-#include <cassert>
-
-namespace tint {
-namespace fuzzers {
-namespace ast_fuzzer {
-namespace {
-
-template <typename T>
-T RandomUInt(std::mt19937* rng, T bound) {
- assert(bound > 0 && "`bound` must be positive");
- return std::uniform_int_distribution<T>(0, bound - 1)(*rng);
-}
-
-} // namespace
-
-MtRng::MtRng(uint32_t seed) : rng_(seed) {}
-
-uint32_t MtRng::RandomUint32(uint32_t bound) {
- return RandomUInt(&rng_, bound);
-}
-
-uint64_t MtRng::RandomUint64(uint64_t bound) {
- return RandomUInt(&rng_, bound);
-}
-
-} // namespace ast_fuzzer
-} // namespace fuzzers
-} // namespace tint
diff --git a/fuzzers/tint_ast_fuzzer/mt_rng.h b/fuzzers/tint_ast_fuzzer/mt_rng.h
deleted file mode 100644
index ebbddc4..0000000
--- a/fuzzers/tint_ast_fuzzer/mt_rng.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2021 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef FUZZERS_TINT_AST_FUZZER_MT_RNG_H_
-#define FUZZERS_TINT_AST_FUZZER_MT_RNG_H_
-
-#include <random>
-
-#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
-
-namespace tint {
-namespace fuzzers {
-namespace ast_fuzzer {
-
-/// The random number generator that uses STL's Mersenne Twister (std::mt19937)
-/// under the hood.
-class MtRng : public RandomNumberGenerator {
- public:
- /// @brief Initializes this RNG with some `seed`.
- /// @param seed - passed down to the `std::mt19937`.
- explicit MtRng(uint32_t seed);
-
- uint32_t RandomUint32(uint32_t bound) override;
- uint64_t RandomUint64(uint64_t bound) override;
-
- private:
- std::mt19937 rng_;
-};
-
-} // namespace ast_fuzzer
-} // namespace fuzzers
-} // namespace tint
-
-#endif // FUZZERS_TINT_AST_FUZZER_MT_RNG_H_
diff --git a/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc b/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
index 3af0059..bf12407 100644
--- a/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
+++ b/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
@@ -16,7 +16,6 @@
#include "gtest/gtest.h"
-#include "fuzzers/tint_ast_fuzzer/mt_rng.h"
#include "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
#include "fuzzers/tint_ast_fuzzer/mutator.h"
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
diff --git a/fuzzers/tint_ast_fuzzer/mutator.h b/fuzzers/tint_ast_fuzzer/mutator.h
index 7746e6a..59aa5b7 100644
--- a/fuzzers/tint_ast_fuzzer/mutator.h
+++ b/fuzzers/tint_ast_fuzzer/mutator.h
@@ -20,7 +20,6 @@
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
#include "fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.h"
-#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
#include "src/program.h"
diff --git a/fuzzers/tint_ast_fuzzer/probability_context.cc b/fuzzers/tint_ast_fuzzer/probability_context.cc
index 1b38a10..8db9557 100644
--- a/fuzzers/tint_ast_fuzzer/probability_context.cc
+++ b/fuzzers/tint_ast_fuzzer/probability_context.cc
@@ -14,6 +14,8 @@
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
+#include <cassert>
+
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
@@ -23,15 +25,18 @@
} // namespace
-ProbabilityContext::ProbabilityContext(RandomNumberGenerator* rng)
- : rng_(rng),
+ProbabilityContext::ProbabilityContext(RandomGenerator* generator)
+ : generator_(generator),
chance_of_replacing_identifiers_(
- RandomFromRange(kChanceOfReplacingIdentifiers)) {}
+ RandomFromRange(kChanceOfReplacingIdentifiers)) {
+ assert(generator != nullptr && "generator must not be nullptr");
+}
uint32_t ProbabilityContext::RandomFromRange(
std::pair<uint32_t, uint32_t> range) {
assert(range.first <= range.second && "Range must be non-decreasing");
- return range.first + rng_->RandomUint32(range.second - range.first + 1);
+ return generator_->GetUInt32(
+ range.first, range.second + 1); // + 1 need since range is inclusive.
}
} // namespace ast_fuzzer
diff --git a/fuzzers/tint_ast_fuzzer/probability_context.h b/fuzzers/tint_ast_fuzzer/probability_context.h
index 572f125..c96b7ba 100644
--- a/fuzzers/tint_ast_fuzzer/probability_context.h
+++ b/fuzzers/tint_ast_fuzzer/probability_context.h
@@ -18,7 +18,7 @@
#include <utility>
#include <vector>
-#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
+#include "fuzzers/random_generator.h"
namespace tint {
namespace fuzzers {
@@ -29,16 +29,21 @@
class ProbabilityContext {
public:
/// Initializes this instance with a random number generator.
- /// @param rng - may not be a `nullptr`. Must remain in scope as long as this
+ /// @param generator - must not be a `nullptr`. Must remain in scope as long
+ /// as this
/// instance exists.
- explicit ProbabilityContext(RandomNumberGenerator* rng);
+ explicit ProbabilityContext(RandomGenerator* generator);
- /// @copydoc RandomNumberGenerator::RandomBool
- bool RandomBool() { return rng_->RandomBool(); }
+ /// Get random bool with even odds
+ /// @returns true 50% of the time and false %50 of time.
+ bool RandomBool() { return generator_->GetBool(); }
- /// @copydoc RandomNumberGenerator::ChoosePercentage
+ /// Get random bool with weighted odds
+ /// @param percentage - likelihood of true being returned
+ /// @returns true |percentage|% of the time, and false (100 - |percentage|)%
+ /// of the time.
bool ChoosePercentage(uint32_t percentage) {
- return rng_->ChoosePercentage(percentage);
+ return generator_->GetWeightedBool(percentage);
}
/// Returns a random value in the range `[0; arr.size())`.
@@ -47,7 +52,7 @@
/// @return the random index in the `arr`.
template <typename T>
size_t GetRandomIndex(const std::vector<T>& arr) {
- return static_cast<size_t>(rng_->RandomUint64(arr.size()));
+ return static_cast<size_t>(generator_->GetUInt64(arr.size()));
}
/// @return the probability of replacing some identifier with some other one.
@@ -60,7 +65,7 @@
/// @return an random number in the range `[a; b]`.
uint32_t RandomFromRange(std::pair<uint32_t, uint32_t> range);
- RandomNumberGenerator* rng_;
+ RandomGenerator* generator_;
uint32_t chance_of_replacing_identifiers_;
};
diff --git a/fuzzers/tint_ast_fuzzer/random_number_generator.cc b/fuzzers/tint_ast_fuzzer/random_number_generator.cc
deleted file mode 100644
index 6d32e38..0000000
--- a/fuzzers/tint_ast_fuzzer/random_number_generator.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2021 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
-
-namespace tint {
-namespace fuzzers {
-namespace ast_fuzzer {
-
-RandomNumberGenerator::~RandomNumberGenerator() = default;
-
-bool RandomNumberGenerator::RandomBool() {
- return RandomUint32(2);
-}
-
-bool RandomNumberGenerator::ChoosePercentage(uint32_t percentage) {
- assert(percentage <= 100 && "|percentage| is invalid");
- // 100 is used as a bound instead of 101 because otherwise it would be
- // possible to return `false` when `percentage == 100` holds. This would
- // happen when the result of `RandomUint32` is 100 as well.
- return RandomUint32(100) < percentage;
-}
-
-} // namespace ast_fuzzer
-} // namespace fuzzers
-} // namespace tint
diff --git a/fuzzers/tint_ast_fuzzer/random_number_generator.h b/fuzzers/tint_ast_fuzzer/random_number_generator.h
deleted file mode 100644
index 27b1b54..0000000
--- a/fuzzers/tint_ast_fuzzer/random_number_generator.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2021 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef FUZZERS_TINT_AST_FUZZER_RANDOM_NUMBER_GENERATOR_H_
-#define FUZZERS_TINT_AST_FUZZER_RANDOM_NUMBER_GENERATOR_H_
-
-#include <cassert>
-#include <cstdint>
-#include <vector>
-
-namespace tint {
-namespace fuzzers {
-namespace ast_fuzzer {
-
-/// Abstracts away the underlying algorithm that is used to generate random
-/// numbers.
-class RandomNumberGenerator {
- public:
- /// Virtual destructor.
- virtual ~RandomNumberGenerator();
-
- /// @brief Compute a random `uint32_t` value in the range `[0; bound)`.
- /// @param bound - the upper exclusive bound for the computed integer
- /// (must be positive).
- /// @return the random number.
- virtual uint32_t RandomUint32(uint32_t bound) = 0;
-
- /// @brief Compute a random `uint64_t` value in the range `[0; bound)`.
- /// @param bound - the upper exclusive bound for the computed integer
- /// (must be positive).
- /// @return the random number.
- virtual uint64_t RandomUint64(uint64_t bound) = 0;
-
- /// @return a randomly generated boolean value.
- bool RandomBool();
-
- /// @param percentage - must be in the range `[0; 100]`.
- /// @return `true` with `percentage` probability.
- bool ChoosePercentage(uint32_t percentage);
-};
-
-} // namespace ast_fuzzer
-} // namespace fuzzers
-} // namespace tint
-
-#endif // FUZZERS_TINT_AST_FUZZER_RANDOM_NUMBER_GENERATOR_H_
diff --git a/fuzzers/tint_regex_fuzzer/CMakeLists.txt b/fuzzers/tint_regex_fuzzer/CMakeLists.txt
index d4ae7c1..bd3fd8c 100644
--- a/fuzzers/tint_regex_fuzzer/CMakeLists.txt
+++ b/fuzzers/tint_regex_fuzzer/CMakeLists.txt
@@ -21,7 +21,8 @@
endfunction()
set(LIBTINT_REGEX_FUZZER_SOURCES
- util.h
+ ../random_generator.cc
+ ../random_generator.h
wgsl_mutator.cc
wgsl_mutator.h)
diff --git a/fuzzers/tint_regex_fuzzer/fuzzer.cc b/fuzzers/tint_regex_fuzzer/fuzzer.cc
index 5c527c3..06f73dd 100644
--- a/fuzzers/tint_regex_fuzzer/fuzzer.cc
+++ b/fuzzers/tint_regex_fuzzer/fuzzer.cc
@@ -16,12 +16,11 @@
#include <cstddef>
#include <cstdint>
+#include "fuzzers/random_generator.h"
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_regex_fuzzer/cli.h"
#include "fuzzers/tint_regex_fuzzer/override_cli_params.h"
-#include "fuzzers/tint_regex_fuzzer/util.h"
#include "fuzzers/tint_regex_fuzzer/wgsl_mutator.h"
-
#include "src/reader/wgsl/parser.h"
#include "src/writer/wgsl/generator.h"
@@ -57,13 +56,13 @@
unsigned seed) {
std::string wgsl_code(data, data + size);
const std::vector<std::string> delimiters{";"};
- std::mt19937 generator(seed);
+ RandomGenerator generator(seed);
std::string delimiter =
- delimiters[GetRandomIntFromRange(0, delimiters.size() - 1, generator)];
+ delimiters[generator.GetUInt64(delimiters.size() - 1u)];
- MutationKind mutation_kind = static_cast<MutationKind>(GetRandomIntFromRange(
- 0, static_cast<size_t>(MutationKind::kNumMutationKinds) - 1, generator));
+ MutationKind mutation_kind = static_cast<MutationKind>(generator.GetUInt64(
+ static_cast<size_t>(MutationKind::kNumMutationKinds) - 1u));
switch (mutation_kind) {
case MutationKind::kSwapIntervals:
diff --git a/fuzzers/tint_regex_fuzzer/util.h b/fuzzers/tint_regex_fuzzer/util.h
deleted file mode 100644
index dfdc052..0000000
--- a/fuzzers/tint_regex_fuzzer/util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2021 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef FUZZERS_TINT_REGEX_FUZZER_UTIL_H_
-#define FUZZERS_TINT_REGEX_FUZZER_UTIL_H_
-
-#include <random>
-
-namespace tint {
-namespace fuzzers {
-namespace regex_fuzzer {
-
-inline size_t GetRandomIntFromRange(size_t lower_bound,
- size_t upper_bound,
- std::mt19937& generator) {
- std::uniform_int_distribution<size_t> dist(lower_bound, upper_bound);
- return dist(generator);
-}
-} // namespace regex_fuzzer
-} // namespace fuzzers
-} // namespace tint
-#endif // FUZZERS_TINT_REGEX_FUZZER_UTIL_H_
diff --git a/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc b/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc
index 2745001..164f0e4 100644
--- a/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc
+++ b/fuzzers/tint_regex_fuzzer/wgsl_mutator.cc
@@ -17,13 +17,12 @@
#include <cassert>
#include <cstring>
#include <map>
-#include <random>
#include <regex>
#include <string>
#include <utility>
#include <vector>
-#include "fuzzers/tint_regex_fuzzer/util.h"
+#include "fuzzers/random_generator.h"
namespace tint {
namespace fuzzers {
@@ -137,7 +136,7 @@
bool SwapRandomIntervals(const std::string& delimiter,
std::string& wgsl_code,
- std::mt19937& generator) {
+ RandomGenerator& generator) {
std::vector<size_t> delimiter_positions =
FindDelimiterIndices(delimiter, wgsl_code);
@@ -148,14 +147,10 @@
// When generating the i-th random number, we should make sure that there are
// at least (3-i) numbers greater than this number.
- size_t ind1 =
- GetRandomIntFromRange(0, delimiter_positions.size() - 3U, generator);
- size_t ind2 = GetRandomIntFromRange(
- ind1 + 1U, delimiter_positions.size() - 2U, generator);
- size_t ind3 =
- GetRandomIntFromRange(ind2, delimiter_positions.size() - 2U, generator);
- size_t ind4 = GetRandomIntFromRange(
- ind3 + 1U, delimiter_positions.size() - 1U, generator);
+ size_t ind1 = generator.GetUInt64(delimiter_positions.size() - 3u);
+ size_t ind2 = generator.GetUInt64(ind1 + 1u, delimiter_positions.size() - 2u);
+ size_t ind3 = generator.GetUInt64(ind2, delimiter_positions.size() - 2u);
+ size_t ind4 = generator.GetUInt64(ind3 + 1u, delimiter_positions.size() - 1u);
SwapIntervals(delimiter_positions[ind1],
delimiter_positions[ind2] - delimiter_positions[ind1],
@@ -168,7 +163,7 @@
bool DeleteRandomInterval(const std::string& delimiter,
std::string& wgsl_code,
- std::mt19937& generator) {
+ RandomGenerator& generator) {
std::vector<size_t> delimiter_positions =
FindDelimiterIndices(delimiter, wgsl_code);
@@ -177,10 +172,8 @@
return false;
}
- size_t ind1 =
- GetRandomIntFromRange(0, delimiter_positions.size() - 2U, generator);
- size_t ind2 = GetRandomIntFromRange(
- ind1 + 1U, delimiter_positions.size() - 1U, generator);
+ size_t ind1 = generator.GetUInt64(delimiter_positions.size() - 2u);
+ size_t ind2 = generator.GetUInt64(ind1 + 1u, delimiter_positions.size() - 1u);
DeleteInterval(delimiter_positions[ind1],
delimiter_positions[ind2] - delimiter_positions[ind1],
@@ -191,7 +184,7 @@
bool DuplicateRandomInterval(const std::string& delimiter,
std::string& wgsl_code,
- std::mt19937& generator) {
+ RandomGenerator& generator) {
std::vector<size_t> delimiter_positions =
FindDelimiterIndices(delimiter, wgsl_code);
@@ -200,13 +193,9 @@
return false;
}
- size_t ind1 =
- GetRandomIntFromRange(0, delimiter_positions.size() - 2U, generator);
- size_t ind2 = GetRandomIntFromRange(
- ind1 + 1U, delimiter_positions.size() - 1U, generator);
-
- size_t ind3 =
- GetRandomIntFromRange(0, delimiter_positions.size() - 1U, generator);
+ size_t ind1 = generator.GetUInt64(delimiter_positions.size() - 2u);
+ size_t ind2 = generator.GetUInt64(ind1 + 1u, delimiter_positions.size() - 1u);
+ size_t ind3 = generator.GetUInt64(delimiter_positions.size() - 1u);
DuplicateInterval(delimiter_positions[ind1],
delimiter_positions[ind2] - delimiter_positions[ind1],
@@ -215,7 +204,8 @@
return true;
}
-bool ReplaceRandomIdentifier(std::string& wgsl_code, std::mt19937& generator) {
+bool ReplaceRandomIdentifier(std::string& wgsl_code,
+ RandomGenerator& generator) {
std::vector<std::pair<size_t, size_t>> identifiers =
GetIdentifiers(wgsl_code);
@@ -224,15 +214,12 @@
return false;
}
- size_t id1_index =
- GetRandomIntFromRange(0, identifiers.size() - 1U, generator);
-
- size_t id2_index =
- GetRandomIntFromRange(0, identifiers.size() - 1U, generator);
+ size_t id1_index = generator.GetUInt64(identifiers.size() - 1u);
+ size_t id2_index = generator.GetUInt64(identifiers.size() - 1u);
// The two identifiers must be different
while (id1_index == id2_index) {
- id2_index = GetRandomIntFromRange(0, identifiers.size() - 1U, generator);
+ id2_index = generator.GetUInt64(identifiers.size() - 1u);
}
ReplaceRegion(identifiers[id1_index].first, identifiers[id1_index].second,
@@ -242,7 +229,8 @@
return true;
}
-bool ReplaceRandomIntLiteral(std::string& wgsl_code, std::mt19937& generator) {
+bool ReplaceRandomIntLiteral(std::string& wgsl_code,
+ RandomGenerator& generator) {
std::vector<std::pair<size_t, size_t>> literals = GetIntLiterals(wgsl_code);
// Need at least one integer literal
@@ -250,14 +238,13 @@
return false;
}
- size_t id1_index = GetRandomIntFromRange(0, literals.size() - 1U, generator);
+ size_t id1_index = generator.GetUInt64(literals.size() - 1u);
// INT_MAX = 2147483647, INT_MIN = -2147483648
std::vector<std::string> boundary_values = {
"2147483647", "-2147483648", "1", "-1", "0", "4294967295"};
- size_t boundary_index =
- GetRandomIntFromRange(0, boundary_values.size() - 1U, generator);
+ size_t boundary_index = generator.GetUInt64(boundary_values.size() - 1u);
ReplaceInterval(literals[id1_index].first, literals[id1_index].second,
boundary_values[boundary_index], wgsl_code);
diff --git a/fuzzers/tint_regex_fuzzer/wgsl_mutator.h b/fuzzers/tint_regex_fuzzer/wgsl_mutator.h
index ba8d9d5..37ce688 100644
--- a/fuzzers/tint_regex_fuzzer/wgsl_mutator.h
+++ b/fuzzers/tint_regex_fuzzer/wgsl_mutator.h
@@ -15,11 +15,12 @@
#ifndef FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_
#define FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_
-#include <random>
#include <string>
#include <utility>
#include <vector>
+#include "fuzzers/random_generator.h"
+
namespace tint {
namespace fuzzers {
namespace regex_fuzzer {
@@ -114,7 +115,7 @@
/// @return true if a swap happened or false otherwise.
bool SwapRandomIntervals(const std::string& delimiter,
std::string& wgsl_code,
- std::mt19937& generator);
+ RandomGenerator& generator);
/// A function that, given a WGSL-like string and a delimiter,
/// generates another WGSL-like string by deleting a random
@@ -125,7 +126,7 @@
/// @return true if a deletion happened or false otherwise.
bool DeleteRandomInterval(const std::string& delimiter,
std::string& wgsl_code,
- std::mt19937& generator);
+ RandomGenerator& generator);
/// A function that, given a WGSL-like string and a delimiter,
/// generates another WGSL-like string by duplicating a random
@@ -136,20 +137,22 @@
/// @return true if a duplication happened or false otherwise.
bool DuplicateRandomInterval(const std::string& delimiter,
std::string& wgsl_code,
- std::mt19937& generator);
+ RandomGenerator& generator);
/// Replaces a randomly-chosen identifier in wgsl_code.
/// @param wgsl_code - WGSL-like string where the replacement will occur.
/// @param generator - the random number generator.
/// @return true if a replacement happened or false otherwise.
-bool ReplaceRandomIdentifier(std::string& wgsl_code, std::mt19937& generator);
+bool ReplaceRandomIdentifier(std::string& wgsl_code,
+ RandomGenerator& generator);
/// Replaces the value of a randomly-chosen integer with one of
/// the values in the set {INT_MAX, INT_MIN, 0, -1}.
/// @param wgsl_code - WGSL-like string where the replacement will occur.
/// @param generator - the random number generator.
/// @return true if a replacement happened or false otherwise.
-bool ReplaceRandomIntLiteral(std::string& wgsl_code, std::mt19937& generator);
+bool ReplaceRandomIntLiteral(std::string& wgsl_code,
+ RandomGenerator& generator);
} // namespace regex_fuzzer
} // namespace fuzzers
diff --git a/fuzzers/tint_spirv_tools_fuzzer/CMakeLists.txt b/fuzzers/tint_spirv_tools_fuzzer/CMakeLists.txt
index 92790c1..6bb2097 100644
--- a/fuzzers/tint_spirv_tools_fuzzer/CMakeLists.txt
+++ b/fuzzers/tint_spirv_tools_fuzzer/CMakeLists.txt
@@ -13,6 +13,7 @@
# limitations under the License.
set(FUZZER_SOURCES
+ ../random_generator.cc
cli.cc
fuzzer.cc
mutator.cc
@@ -23,6 +24,7 @@
util.cc)
set(FUZZER_SOURCES ${FUZZER_SOURCES}
+ ../random_generator.h
cli.h
mutator.h
mutator_cache.h
@@ -32,8 +34,8 @@
util.h)
set(FUZZER_SOURCES ${FUZZER_SOURCES}
- ../tint_common_fuzzer.h
- ../tint_common_fuzzer.cc)
+ ../tint_common_fuzzer.cc
+ ../tint_common_fuzzer.h)
function(configure_spirv_tools_fuzzer_target NAME SOURCES)
add_executable(${NAME} ${SOURCES})
@@ -61,6 +63,7 @@
target_link_libraries(tint_spirv_tools_fuzzer libtint-fuzz)
set(DEBUGGER_SOURCES
+ ../random_generator.cc
cli.cc
mutator.cc
mutator_debugger.cc
@@ -70,6 +73,7 @@
util.cc)
set(DEBUGGER_SOURCES ${DEBUGGER_SOURCES}
+ ../random_generator.h
cli.h
mutator.h
spirv_fuzz_mutator.h
diff --git a/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc b/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
index ce6fec5..0ffc9a2 100644
--- a/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
+++ b/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
@@ -14,10 +14,10 @@
#include <cassert>
#include <memory>
-#include <random>
#include <string>
#include <vector>
+#include "fuzzers/random_generator.h"
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_spirv_tools_fuzzer/cli.h"
#include "fuzzers/tint_spirv_tools_fuzzer/mutator_cache.h"
@@ -67,9 +67,8 @@
}
assert(!types.empty() && "At least one mutator type must be specified");
- std::mt19937 rng(seed);
- auto mutator_type =
- types[std::uniform_int_distribution<size_t>(0, types.size() - 1)(rng)];
+ RandomGenerator generator(seed);
+ auto mutator_type = types[generator.GetUInt64(types.size())];
const auto& mutator_params = context->params.mutator_params;
switch (mutator_type) {
diff --git a/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.cc b/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.cc
index 360f1d9..0b75ed3 100644
--- a/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.cc
+++ b/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.cc
@@ -66,7 +66,7 @@
optimized_binary_(),
validate_after_each_opt_(validate_after_each_opt),
opt_batch_size_(opt_batch_size),
- rng_(seed) {
+ generator_(seed) {
assert(spvtools::SpirvTools(target_env).Validate(original_binary_) &&
"Initial binary is invalid");
assert(!opt_passes_.empty() && "Must be at least one pass");
@@ -105,8 +105,7 @@
std::vector<std::string> passes;
while (passes.size() < num_of_passes) {
- auto idx = std::uniform_int_distribution<size_t>(
- 0, opt_passes_.size() - 1)(rng_);
+ auto idx = generator_.GetUInt64(opt_passes_.size());
passes.push_back(opt_passes_[idx]);
}
diff --git a/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.h b/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.h
index 6d055e4..51514fa 100644
--- a/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.h
+++ b/fuzzers/tint_spirv_tools_fuzzer/spirv_opt_mutator.h
@@ -15,11 +15,11 @@
#ifndef FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_OPT_MUTATOR_H_
#define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_OPT_MUTATOR_H_
-#include <random>
#include <sstream>
#include <string>
#include <vector>
+#include "fuzzers/random_generator.h"
#include "fuzzers/tint_spirv_tools_fuzzer/mutator.h"
#include "spirv-tools/libspirv.h"
@@ -86,7 +86,7 @@
std::stringstream errors_;
// The random number generator initialized with `seed_`.
- std::mt19937 rng_;
+ RandomGenerator generator_;
};
} // namespace spvtools_fuzzer
diff --git a/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.cc b/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.cc
index dccbfe3..e95a8de 100644
--- a/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.cc
+++ b/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.cc
@@ -44,7 +44,7 @@
bool validate_after_each_reduction)
: ir_context_(nullptr),
finders_(),
- rng_(seed),
+ generator_(seed),
errors_(),
is_valid_(true),
reductions_batch_size_(reductions_batch_size),
diff --git a/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.h b/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.h
index 4d656d8..2f25146 100644
--- a/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.h
+++ b/fuzzers/tint_spirv_tools_fuzzer/spirv_reduce_mutator.h
@@ -16,12 +16,12 @@
#define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_REDUCE_MUTATOR_H_
#include <memory>
-#include <random>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
+#include "fuzzers/random_generator.h"
#include "fuzzers/tint_spirv_tools_fuzzer/mutator.h"
#include "source/reduce/reduction_opportunity_finder.h"
@@ -65,7 +65,7 @@
private:
template <typename T, typename... Args>
void MaybeAddFinder(Args&&... args) {
- if (enable_all_reductions_ || std::uniform_int_distribution<>(0, 1)(rng_)) {
+ if (enable_all_reductions_ || generator_.GetBool()) {
finders_.push_back(std::make_unique<T>(std::forward<Args>(args)...));
}
}
@@ -73,16 +73,14 @@
template <typename T>
T* GetRandomElement(std::vector<T>* arr) {
assert(!arr->empty() && "Can't get random element from an empty vector");
- auto index =
- std::uniform_int_distribution<size_t>(0, arr->size() - 1)(rng_);
+ auto index = generator_.GetUInt64(arr->size());
return &(*arr)[index];
}
template <typename T>
T* GetRandomElement(std::vector<std::unique_ptr<T>>* arr) {
assert(!arr->empty() && "Can't get random element from an empty vector");
- auto index =
- std::uniform_int_distribution<size_t>(0, arr->size() - 1)(rng_);
+ auto index = generator_.GetUInt64(arr->size());
return (*arr)[index].get();
}
@@ -97,7 +95,7 @@
finders_;
// Random number generator initialized with `seed_`.
- std::mt19937 rng_;
+ RandomGenerator generator_;
// All the errors produced by the reducer.
std::stringstream errors_;