From a4d907e8686791dd84ed987d0d79325c4d908b73 Mon Sep 17 00:00:00 2001 From: Jeremy Johnson Date: Thu, 26 Oct 2023 13:53:14 +0100 Subject: Main compliance testing support for MUL Update verify ULP mode to allow fractions (e.g. 0.5). Update pseudo generator to accept ranges. Fix up pseudo random distribution based on ranges. Change-Id: I9168c5f7d37722678c0f1f9e906953c8cec367b1 Signed-off-by: Jeremy Johnson --- .../src/generate/generate_pseudo_random.cc | 62 ++++++++++++++++++---- reference_model/src/generate/generate_utils.cc | 7 ++- reference_model/src/generate/generate_utils.h | 2 +- 3 files changed, 58 insertions(+), 13 deletions(-) (limited to 'reference_model/src/generate') diff --git a/reference_model/src/generate/generate_pseudo_random.cc b/reference_model/src/generate/generate_pseudo_random.cc index 858a4b2..f234796 100644 --- a/reference_model/src/generate/generate_pseudo_random.cc +++ b/reference_model/src/generate/generate_pseudo_random.cc @@ -40,40 +40,76 @@ public: constexpr auto min = std::numeric_limits::lowest() / 2; constexpr auto max = std::numeric_limits::max() / 2; static_assert(max <= std::numeric_limits::max() + min); - _unidis = std::uniform_real_distribution(min, max); - // Piecewise Constant distribution - const std::array intervals{ min, min + 1000, -1000.0, 0.0, 1000.0, max - 1000, max }; - const std::array weights{ 1.0, 0.1, 1.0, 2.0, 1.0, 0.1, 1.0 }; - _pwcdis = std::piecewise_constant_distribution(intervals.begin(), intervals.end(), weights.begin()); + setDistribution(min, max); } - FP getRandomUniformFloat() + PseudoRandomGeneratorFloat(uint64_t seed, FP min, FP max) + : _gen(seed) { - return _unidis(_gen); + setDistribution(min, max); } - FP getRandomPWCFloat() + FP getRandomFloat() { - return _pwcdis(_gen); + if (_useUniform) + return _unidis(_gen); + else + return _pwcdis(_gen); } private: + void setDistribution(FP min, FP max) + { + _unidis = std::uniform_real_distribution(min, max); + + // Piecewise Constant distribution for larger ranges + double range = std::abs(max - min); + double mid; + if (max == -min) + mid = 0.f; + else + mid = (range / 2) + min; + double segment = std::min(1000.0, range / 5); + + const std::array intervals{ + min, min + segment, mid - segment, mid, mid + segment, max - segment, max + }; + const std::array weights{ 1.0, 0.1, 1.0, 2.0, 1.0, 0.1, 1.0 }; + _pwcdis = std::piecewise_constant_distribution(intervals.begin(), intervals.end(), weights.begin()); + + // Uniform distribution works well on smaller ranges + _useUniform = (range < 2000.0); + } + std::mt19937 _gen; std::uniform_real_distribution _unidis; std::piecewise_constant_distribution _pwcdis; + bool _useUniform; }; bool generateFP32(const TosaReference::GenerateConfig& cfg, void* data, size_t size) { const TosaReference::PseudoRandomInfo& prinfo = cfg.pseudoRandomInfo; - PseudoRandomGeneratorFloat generator(prinfo.rngSeed); + + PseudoRandomGeneratorFloat* generator; + + if (prinfo.range.size() == 2) + { + const float min = std::stof(prinfo.range[0]); + const float max = std::stof(prinfo.range[1]); + generator = new PseudoRandomGeneratorFloat(prinfo.rngSeed, min, max); + } + else + { + generator = new PseudoRandomGeneratorFloat(prinfo.rngSeed); + } float* a = reinterpret_cast(data); const auto T = TosaReference::numElementsFromShape(cfg.shape); for (auto t = 0; t < T; ++t) { - a[t] = generator.getRandomPWCFloat(); + a[t] = generator->getRandomFloat(); } return true; } @@ -90,6 +126,10 @@ bool generatePseudoRandom(const GenerateConfig& cfg, void* data, size_t size) WARNING("[Generator][PR] Unknown operator."); return false; } + if (cfg.pseudoRandomInfo.range.size() != 0 || cfg.pseudoRandomInfo.range.size() != 2) + { + WARNING("[Generator][PR] Invalid range."); + } switch (cfg.dataType) { diff --git a/reference_model/src/generate/generate_utils.cc b/reference_model/src/generate/generate_utils.cc index d3bb076..ae6dfcb 100644 --- a/reference_model/src/generate/generate_utils.cc +++ b/reference_model/src/generate/generate_utils.cc @@ -38,10 +38,11 @@ NLOHMANN_JSON_SERIALIZE_ENUM(DType, NLOHMANN_JSON_SERIALIZE_ENUM(Op, { { Op::Op_UNKNOWN, "UNKNOWN" }, + { Op::Op_CONV2D, "CONV2D" }, { Op::Op_MATMUL, "MATMUL" }, { Op::Op_MAX_POOL2D, "MAX_POOL2D" }, + { Op::Op_MUL, "MUL" }, { Op::Op_PAD, "PAD" }, - { Op::Op_CONV2D, "CONV2D" }, }) } // namespace tosa @@ -84,6 +85,10 @@ void from_json(const nlohmann::json& j, DotProductInfo& dotProductInfo) void from_json(const nlohmann::json& j, PseudoRandomInfo& pseudoRandomInfo) { j.at("rng_seed").get_to(pseudoRandomInfo.rngSeed); + if (j.contains("range")) + { + j.at("range").get_to(pseudoRandomInfo.range); + } } void from_json(const nlohmann::json& j, GenerateConfig& cfg) diff --git a/reference_model/src/generate/generate_utils.h b/reference_model/src/generate/generate_utils.h index 7c55f1d..8d0f654 100644 --- a/reference_model/src/generate/generate_utils.h +++ b/reference_model/src/generate/generate_utils.h @@ -61,7 +61,7 @@ struct PseudoRandomInfo PseudoRandomInfo() = default; int64_t rngSeed; - // TODO: Add range support + std::vector range; }; /// \brief Generator configuration -- cgit v1.2.1