// SPDX-License-Identifier: MIT // Copyright (c) 2018-2024, Advanced Micro Devices, Inc. All rights reserved. #pragma once #include #include #include #include #include #include #include "ck/utility/data_type.hpp" namespace ck { namespace utils { template struct FillUniformDistribution { float a_{-5.f}; float b_{5.f}; template void operator()(ForwardIter first, ForwardIter last) const { std::mt19937 gen(11939); std::uniform_real_distribution dis(a_, b_); std::generate(first, last, [&dis, &gen]() { return ck::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::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}; template void operator()(ForwardIter first, ForwardIter last) const { std::mt19937 gen(11939); std::uniform_real_distribution dis(a_, b_); std::generate( first, last, [&dis, &gen]() { return ck::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 TransformIntoStructuralSparsity { // clang-format off static constexpr T valid_sequences[] = { 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, }; // clang-format on template void operator()(ForwardIter first, ForwardIter last) const { std::for_each(first, last, [=, idx = 0](T& elem) mutable { auto tmp_idx = idx; idx += 1; return elem *= valid_sequences[tmp_idx % (sizeof(valid_sequences) / sizeof(T))]; }); } 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))); } }; } // namespace utils } // namespace ck