// SPDX-License-Identifier: MIT // Copyright (c) 2018-2023, Advanced Micro Devices, Inc. All rights reserved. #pragma once #include #include #include #include #include #include #include #include "ck_tile/core.hpp" namespace ck_tile { template struct FillUniformDistribution { float a_{-5.f}; float b_{5.f}; std::optional seed_{11939}; template void operator()(ForwardIter first, ForwardIter last) const { std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}()); std::uniform_real_distribution dis(a_, b_); std::generate(first, last, [&dis, &gen]() { return ck_tile::type_convert(dis(gen)); }); } template auto operator()(ForwardRange&& range) const -> std::void_t()( std::begin(std::forward(range)), std::end(std::forward(range))))> { (*this)(std::begin(std::forward(range)), std::end(std::forward(range))); } }; template struct FillNormalDistribution { float mean_{0.f}; float variance_{1.f}; std::optional seed_{11939}; template void operator()(ForwardIter first, ForwardIter last) const { std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}()); std::normal_distribution dis(mean_, std::sqrt(variance_)); std::generate(first, last, [&dis, &gen]() { return ck_tile::type_convert(dis(gen)); }); } template auto operator()(ForwardRange&& range) const -> std::void_t()( std::begin(std::forward(range)), std::end(std::forward(range))))> { (*this)(std::begin(std::forward(range)), std::end(std::forward(range))); } }; // Normally FillUniformDistributionIntegerValue should use std::uniform_int_distribution as below. // However this produces segfaults in std::mt19937 which look like inifite loop. // template // struct FillUniformDistributionIntegerValue // { // int a_{-5}; // int b_{5}; // // template // void operator()(ForwardIter first, ForwardIter last) const // { // std::mt19937 gen(11939); // std::uniform_int_distribution dis(a_, b_); // std::generate( // first, last, [&dis, &gen]() { return ck_tile::type_convert(dis(gen)); }); // } // }; // Workaround for uniform_int_distribution not working as expected. See note above.< template struct FillUniformDistributionIntegerValue { float a_{-5.f}; float b_{5.f}; std::optional seed_{11939}; template void operator()(ForwardIter first, ForwardIter last) const { std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}()); std::uniform_real_distribution dis(a_, b_); std::generate( first, last, [&dis, &gen]() { return ck_tile::type_convert(std::round(dis(gen))); }); } template auto operator()(ForwardRange&& range) const -> std::void_t()( std::begin(std::forward(range)), std::end(std::forward(range))))> { (*this)(std::begin(std::forward(range)), std::end(std::forward(range))); } }; template struct FillNormalDistributionIntegerValue { float mean_{0.f}; float variance_{1.f}; std::optional seed_{11939}; template void operator()(ForwardIter first, ForwardIter last) const { std::mt19937 gen(seed_.has_value() ? *seed_ : std::random_device{}()); std::normal_distribution dis(mean_, std::sqrt(variance_)); std::generate( first, last, [&dis, &gen]() { return ck_tile::type_convert(std::round(dis(gen))); }); } template auto operator()(ForwardRange&& range) const -> std::void_t()( std::begin(std::forward(range)), std::end(std::forward(range))))> { (*this)(std::begin(std::forward(range)), std::end(std::forward(range))); } }; template struct FillMonotonicSeq { T init_value_{0}; T step_{1}; template void operator()(ForwardIter first, ForwardIter last) const { std::generate(first, last, [=, n = init_value_]() mutable { auto tmp = n; n += step_; return tmp; }); } template auto operator()(ForwardRange&& range) const -> std::void_t()( std::begin(std::forward(range)), std::end(std::forward(range))))> { (*this)(std::begin(std::forward(range)), std::end(std::forward(range))); } }; template struct FillConstant { T value_{0}; template void operator()(ForwardIter first, ForwardIter last) const { std::fill(first, last, value_); } template auto operator()(ForwardRange&& range) const -> std::void_t< decltype(std::declval()(std::begin(std::forward(range)), std::end(std::forward(range))))> { (*this)(std::begin(std::forward(range)), std::end(std::forward(range))); } }; template struct FillTrigValue { template struct LinearTrigGen { int i{0}; auto operator()() { float v = 0; if constexpr(UseCos_) { v = cos(i); } else { v = sin(i); } if constexpr(UseAbs_) v = abs(v); i++; return ck_tile::type_convert(v); } }; template void operator()(ForwardIter first, ForwardIter last) const { LinearTrigGen gen; std::generate(first, last, gen); } template auto operator()(ForwardRange&& range) const -> std::void_t< decltype(std::declval()(std::begin(std::forward(range)), std::end(std::forward(range))))> { (*this)(std::begin(std::forward(range)), std::end(std::forward(range))); } }; } // namespace ck_tile