// Copyright (c) 2023, ARM Limited. // // 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 "generate.h" #include "generate_utils.h" #include #include #include #include #include #include #include #include namespace { // Random generator template class PseudoRandomGeneratorFloat { public: PseudoRandomGeneratorFloat(uint64_t seed) : _gen(seed) { // Uniform real distribution generates real values in the range [a, b] // and requires that b - a <= std::numeric_limits::max() so here // we choose some arbitrary values that satisfy that condition. 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()); } FP getRandomUniformFloat() { return _unidis(_gen); } FP getRandomPWCFloat() { return _pwcdis(_gen); } private: std::mt19937 _gen; std::uniform_real_distribution _unidis; std::piecewise_constant_distribution _pwcdis; }; bool generateFP32(const TosaReference::GenerateConfig& cfg, void* data, size_t size) { const TosaReference::PseudoRandomInfo& prinfo = cfg.pseudoRandomInfo; PseudoRandomGeneratorFloat generator(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(); } return true; } } // namespace namespace TosaReference { bool generatePseudoRandom(const GenerateConfig& cfg, void* data, size_t size) { // Check we support the operator if (cfg.opType == Op::Op_UNKNOWN) { WARNING("[Generator][PR] Unknown operator."); return false; } switch (cfg.dataType) { case DType::DType_FP32: return generateFP32(cfg, data, size); default: WARNING("[Generator][PR] Unsupported type."); return false; } } } // namespace TosaReference