blob: edc8d0eaccb82d678865703bb90f8c36518433ce [file] [log] [blame]
Georgios Pinitas0bc78492019-03-18 20:07:37 +00001/*
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +01002 * Copyright (c) 2019-2020 Arm Limited.
Georgios Pinitas0bc78492019-03-18 20:07:37 +00003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010024#include "src/core/utils/helpers/fft.h"
Georgios Pinitas0bc78492019-03-18 20:07:37 +000025
26#include <numeric>
27
28namespace arm_compute
29{
30namespace helpers
31{
32namespace fft
33{
34std::vector<unsigned int> decompose_stages(unsigned int N, const std::set<unsigned int> &supported_factors)
35{
36 std::vector<unsigned int> stages;
37 unsigned int res = N;
38
39 // Early exit if no supported factors are provided
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010040 if (supported_factors.empty())
Georgios Pinitas0bc78492019-03-18 20:07:37 +000041 {
42 return stages;
43 }
44
45 // Create reverse iterator (Start decomposing from the larger supported factors)
46 auto rfactor_it = supported_factors.rbegin();
47
48 // Decomposition step
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010049 while (res != 0)
Georgios Pinitas0bc78492019-03-18 20:07:37 +000050 {
51 const unsigned int factor = *rfactor_it;
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010052 if (0 == (res % factor) && res >= factor)
Georgios Pinitas0bc78492019-03-18 20:07:37 +000053 {
54 stages.push_back(factor);
55 res /= factor;
56 }
57 else
58 {
59 ++rfactor_it;
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010060 if (rfactor_it == supported_factors.rend())
Georgios Pinitas0bc78492019-03-18 20:07:37 +000061 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010062 if (res > 1)
Georgios Pinitas0bc78492019-03-18 20:07:37 +000063 {
64 // Couldn't decompose with given factors
65 stages.clear();
66 return stages;
67 }
68 else
69 {
70 res = 0;
71 }
72 }
73 }
74 }
75
76 return stages;
77}
78
79std::vector<unsigned int> digit_reverse_indices(unsigned int N, const std::vector<unsigned int> &fft_stages)
80{
81 std::vector<unsigned int> idx_digit_reverse;
82
83 // Early exit in case N and fft stages do not match
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010084 const float stages_prod =
85 std::accumulate(std::begin(fft_stages), std::end(fft_stages), 1, std::multiplies<unsigned int>());
86 if (stages_prod != N)
Georgios Pinitas0bc78492019-03-18 20:07:37 +000087 {
88 return idx_digit_reverse;
89 }
90
91 // Resize digit reverse vector
92 idx_digit_reverse.resize(N);
93
94 // Get number of radix stages
95 unsigned int n_stages = fft_stages.size();
96
97 // Scan elements
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010098 for (unsigned int n = 0; n < N; ++n)
Georgios Pinitas0bc78492019-03-18 20:07:37 +000099 {
100 unsigned int k = n;
101 unsigned int Nx = fft_stages[0];
102
103 // Scan stages
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100104 for (unsigned int s = 1; s < n_stages; ++s)
Georgios Pinitas0bc78492019-03-18 20:07:37 +0000105 {
106 // radix of stage i-th
107 unsigned int Ny = fft_stages[s];
108 unsigned int Ni = Ny * Nx;
109
110 // Update k index
111 k = (k * Ny) % Ni + (k / Nx) % Ny + Ni * (k / Ni);
112
113 // Update Nx
114 Nx *= Ny;
115 }
116
117 // K is the index of digit-reverse
118 idx_digit_reverse[n] = k;
119 }
120
121 return idx_digit_reverse;
122}
123} // namespace fft
124} // namespace helpers
125} // namespace arm_compute