/****************************************************************************** * Copyright (C) 2021 - 2026 Advanced Micro Devices, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. *******************************************************************************/ #pragma once #include #include #include #include // arithmetic helper functions static inline bool IsPo2(size_t u) { return (u != 0) && (0 == (u & (u - 1))); } // help function: Find the smallest power of 2 that is >= n; return its // power of 2 factor // e.g., CeilPo2 (7) returns 3 : (2^3 >= 7) static inline size_t CeilPo2(size_t n) { size_t v = 1, t = 0; while(v < n) { v <<= 1; t++; } return t; } static size_t max_prime_factor(size_t len) { if(len < 2) throw std::invalid_argument("No prime factor for lengths smaller than 2"); size_t ret = 1; while(len != 1) { ret++; if(ret * ret > len) ret = len; // len is actually prime while(len % ret == 0) len /= ret; } return ret; } template static inline T DivRoundingUp(T a, T b) { return (a + (b - 1)) / b; } template typename Titer::value_type product(Titer begin, Titer end) { return std::accumulate( begin, end, typename Titer::value_type(1), std::multiplies()); } template T product(const T* begin, const T* end) { return std::accumulate(begin, end, T(1), std::multiplies()); } template typename Titer::value_type sum(Titer begin, Titer end, typename Titer::value_type start_sum = 0) { return std::accumulate(begin, end, start_sum, std::plus()); } template typename Tcontainer::value_type sum(const Tcontainer& cont, typename Tcontainer::value_type start_sum = 0) { return sum(cont.cbegin(), cont.cend(), start_sum); } // count the number of total iterations for 1-, 2-, and 3-D dimensions template static inline size_t count_iters(const T1& i) { return i; } template static inline size_t count_iters(const std::tuple& i) { return std::get<0>(i) * std::get<1>(i); } template static inline size_t count_iters(const std::tuple& i) { return std::get<0>(i) * std::get<1>(i) * std::get<2>(i); }