dft-fft.hpp (4483B)
1 /** @addtogroup dft 2 * @{ 3 */ 4 /* 5 Copyright (C) 2016-2023 Dan Cazarin (https://www.kfrlib.com) 6 This file is part of KFR 7 8 KFR is free software: you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation, either version 2 of the License, or 11 (at your option) any later version. 12 13 KFR is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with KFR. 20 21 If GPL is not suitable for your project, you must purchase a commercial license to use KFR. 22 Buying a commercial license is mandatory as soon as you develop commercial activities without 23 disclosing the source code of your own applications. 24 See https://www.kfrlib.com for details. 25 */ 26 #pragma once 27 28 #include <kfr/base/basic_expressions.hpp> 29 #include <kfr/math/complex_math.hpp> 30 #include <kfr/testo/assert.hpp> 31 #include <kfr/dft/cache.hpp> 32 #include <kfr/dft/fft.hpp> 33 #include "bitrev.hpp" 34 #include "ft.hpp" 35 36 namespace kfr 37 { 38 39 inline namespace CMT_ARCH_NAME 40 { 41 namespace intrinsics 42 { 43 struct name_test_impl 44 { 45 }; 46 } // namespace intrinsics 47 } // namespace CMT_ARCH_NAME 48 49 template <typename T, cpu_t cpu> 50 struct dft_name_impl 51 { 52 }; 53 54 template <typename Class> 55 inline const char* dft_name(Class*) 56 { 57 constexpr static size_t prefix_len = ctype_name<intrinsics::name_test_impl>().length() - 14; 58 static constexpr cstring full_name = ctype_name<std::decay_t<Class>>(); 59 static constexpr cstring name_arch = 60 concat_cstring(full_name.slice(csize<prefix_len>), make_cstring("("), 61 make_cstring(CMT_STRINGIFY(CMT_ARCH_NAME)), make_cstring(")")); 62 return name_arch.c_str(); 63 } 64 65 #define DFT_STAGE_FN \ 66 KFR_MEM_INTRINSIC void do_execute(cdirect_t, complex<T>* out, const complex<T>* in, u8* temp) final \ 67 { \ 68 return do_execute<false>(out, in, temp); \ 69 } \ 70 KFR_MEM_INTRINSIC void do_execute(cinvert_t, complex<T>* out, const complex<T>* in, u8* temp) final \ 71 { \ 72 return do_execute<true>(out, in, temp); \ 73 } 74 #define DFT_STAGE_FN_NONFINAL \ 75 void do_execute(cdirect_t, complex<T>* out, const complex<T>* in, u8* temp) override \ 76 { \ 77 return do_execute<false>(out, in, temp); \ 78 } \ 79 void do_execute(cinvert_t, complex<T>* out, const complex<T>* in, u8* temp) override \ 80 { \ 81 return do_execute<true>(out, in, temp); \ 82 } 83 84 inline namespace CMT_ARCH_NAME 85 { 86 87 #define DFT_ASSERT TESTO_ASSERT_INACTIVE 88 89 template <typename T> 90 constexpr size_t fft_vector_width = vector_width<T>; 91 92 CMT_PRAGMA_GNU(GCC diagnostic push) 93 #if CMT_HAS_WARNING("-Wassume") 94 CMT_PRAGMA_GNU(GCC diagnostic ignored "-Wassume") 95 #endif 96 97 template <typename Stage, bool add_stages = true, typename T, typename... Args> 98 void add_stage(dft_plan<T>* plan, Args... args) 99 { 100 dft_stage<T>* stage = new Stage(args...); 101 stage->need_reorder = true; 102 plan->data_size += stage->data_size; 103 plan->temp_size += stage->temp_size; 104 plan->all_stages.push_back(dft_stage_ptr<T>(stage)); 105 if constexpr (add_stages) 106 { 107 plan->stages[0].push_back(stage); 108 plan->stages[1].push_back(stage); 109 } 110 } 111 112 } // namespace CMT_ARCH_NAME 113 114 } // namespace kfr