rustfft/fft_helper.rs
1use crate::{
2 array_utils,
3 common::{fft_error_immut, fft_error_inplace, fft_error_outofplace},
4};
5
6// A utility that validates the provided FFT parameters, executes the FFT if validation succeeds, or panics with a hopefully helpful error message if validation fails
7// Since this implementation is basically always the same across all algorithms, this helper keeps us from having to duplicate it
8#[inline(always)]
9pub fn fft_helper_inplace<T>(
10 buffer: &mut [T],
11 scratch: &mut [T],
12 chunk_size: usize,
13 required_scratch: usize,
14 chunk_fn: impl FnMut(&mut [T], &mut [T]),
15) {
16 if chunk_size == 0 {
17 return;
18 }
19
20 let result =
21 array_utils::validate_and_iter(buffer, scratch, chunk_size, required_scratch, chunk_fn);
22
23 if result.is_err() {
24 // We want to trigger a panic, because the passed parameters failed validation in some way.
25 // But we want to avoid doing it in this function to reduce code size, so call a function marked cold and inline(never) that will do it for us
26 fft_error_inplace(chunk_size, buffer.len(), required_scratch, scratch.len());
27 }
28}
29
30// A utility that validates the provided FFT parameters, executes the FFT if validation succeeds, or panics with a hopefully helpful error message if validation fails
31// Since this implementation is basically always the same across all algorithms, this helper keeps us from having to duplicate it
32#[allow(dead_code)]
33#[inline(always)]
34pub fn fft_helper_inplace_unroll2x<T>(
35 buffer: &mut [T],
36 chunk_size: usize,
37 chunk2x_fn: impl FnMut(&mut [T]),
38 chunk_fn: impl FnMut(&mut [T]),
39) {
40 if chunk_size == 0 {
41 return;
42 }
43
44 let result = array_utils::validate_and_iter_unroll2x(buffer, chunk_size, chunk2x_fn, chunk_fn);
45
46 if result.is_err() {
47 // We want to trigger a panic, because the passed parameters failed validation in some way.
48 // But we want to avoid doing it in this function to reduce code size, so call a function marked cold and inline(never) that will do it for us
49 fft_error_inplace(chunk_size, buffer.len(), 0, 0);
50 }
51}
52
53// A utility that validates the provided FFT parameters, executes the FFT if validation succeeds, or panics with a hopefully helpful error message if validation fails
54// Since this implementation is basically always the same across all algorithms, this helper keeps us from having to duplicate it
55#[inline(always)]
56pub fn fft_helper_immut<T>(
57 input: &[T],
58 output: &mut [T],
59 scratch: &mut [T],
60 chunk_size: usize,
61 required_scratch: usize,
62 chunk_fn: impl FnMut(&[T], &mut [T], &mut [T]),
63) {
64 if chunk_size == 0 {
65 return;
66 }
67
68 let result = array_utils::validate_and_zip(
69 input,
70 output,
71 scratch,
72 chunk_size,
73 required_scratch,
74 chunk_fn,
75 );
76
77 if result.is_err() {
78 // We want to trigger a panic, because the passed parameters failed validation in some way.
79 // But we want to avoid doing it in this function to reduce code size, so call a function marked cold and inline(never) that will do it for us
80 fft_error_immut(
81 chunk_size,
82 input.len(),
83 output.len(),
84 required_scratch,
85 scratch.len(),
86 );
87 }
88}
89
90// A utility that validates the provided FFT parameters, executes the FFT if validation succeeds, or panics with a hopefully helpful error message if validation fails
91// Since this implementation is basically always the same across all algorithms, this helper keeps us from having to duplicate it
92#[allow(dead_code)]
93#[inline(always)]
94pub fn fft_helper_immut_unroll2x<T>(
95 input: &[T],
96 output: &mut [T],
97 chunk_size: usize,
98 chunk2x_fn: impl FnMut(&[T], &mut [T]),
99 chunk_fn: impl FnMut(&[T], &mut [T]),
100) {
101 if chunk_size == 0 {
102 return;
103 }
104
105 let result =
106 array_utils::validate_and_zip_unroll2x(input, output, chunk_size, chunk2x_fn, chunk_fn);
107
108 if result.is_err() {
109 // We want to trigger a panic, because the passed parameters failed validation in some way.
110 // But we want to avoid doing it in this function to reduce code size, so call a function marked cold and inline(never) that will do it for us
111 fft_error_immut(chunk_size, input.len(), output.len(), 0, 0);
112 }
113}
114
115// A utility that validates the provided FFT parameters, executes the FFT if validation succeeds, or panics with a hopefully helpful error message if validation fails
116// Since this implementation is basically always the same across all algorithms, this helper keeps us from having to duplicate it
117#[inline(always)]
118pub fn fft_helper_outofplace<T>(
119 input: &mut [T],
120 output: &mut [T],
121 scratch: &mut [T],
122 chunk_size: usize,
123 required_scratch: usize,
124 chunk_fn: impl FnMut(&mut [T], &mut [T], &mut [T]),
125) {
126 if chunk_size == 0 {
127 return;
128 }
129
130 let result = array_utils::validate_and_zip_mut(
131 input,
132 output,
133 scratch,
134 chunk_size,
135 required_scratch,
136 chunk_fn,
137 );
138
139 if result.is_err() {
140 // We want to trigger a panic, because the passed parameters failed validation in some way.
141 // But we want to avoid doing it in this function to reduce code size, so call a function marked cold and inline(never) that will do it for us
142 fft_error_outofplace(
143 chunk_size,
144 input.len(),
145 output.len(),
146 required_scratch,
147 scratch.len(),
148 );
149 }
150}
151
152// A utility that validates the provided FFT parameters, executes the FFT if validation succeeds, or panics with a hopefully helpful error message if validation fails
153// Since this implementation is basically always the same across all algorithms, this helper keeps us from having to duplicate it
154#[allow(dead_code)]
155#[inline(always)]
156pub fn fft_helper_outofplace_unroll2x<T>(
157 input: &mut [T],
158 output: &mut [T],
159 chunk_size: usize,
160 chunk2x_fn: impl FnMut(&mut [T], &mut [T]),
161 chunk_fn: impl FnMut(&mut [T], &mut [T]),
162) {
163 if chunk_size == 0 {
164 return;
165 }
166
167 let result =
168 array_utils::validate_and_zip_mut_unroll2x(input, output, chunk_size, chunk2x_fn, chunk_fn);
169
170 if result.is_err() {
171 // We want to trigger a panic, because the passed parameters failed validation in some way.
172 // But we want to avoid doing it in this function to reduce code size, so call a function marked cold and inline(never) that will do it for us
173 fft_error_outofplace(chunk_size, input.len(), output.len(), 0, 0);
174 }
175}