0
# Configuration and Utilities
1
2
Global configuration settings, utility functions for finding optimal transform sizes, and system information access. These utilities help optimize performance and provide information about the pyFFTW installation.
3
4
## Capabilities
5
6
### Optimization Utilities
7
8
Functions to find optimal sizes and parameters for FFT operations.
9
10
```python { .api }
11
def next_fast_len(target):
12
"""
13
Find the next efficient length for FFT transforms.
14
15
FFTW is most efficient for sizes that have small prime factors.
16
This function finds the smallest length >= target that gives
17
good performance.
18
19
Parameters:
20
- target: int - Target transform length
21
22
Returns:
23
- int: Optimal length >= target for efficient transforms
24
"""
25
```
26
27
### Configuration Constants
28
29
Global configuration values that affect pyFFTW behavior.
30
31
```python { .api }
32
# Optimal SIMD alignment for the current CPU (in bytes)
33
simd_alignment: int
34
35
# Default number of threads for multi-threaded operations
36
NUM_THREADS: int
37
38
# Default planner effort level
39
PLANNER_EFFORT: str # Usually 'FFTW_ESTIMATE'
40
```
41
42
### Type and Version Information
43
44
Constants providing information about supported types and FFTW version.
45
46
```python { .api }
47
# PyFFTW package version string (e.g., '0.15.0')
48
__version__: str
49
50
# FFTW library version string (e.g., '3.3.10')
51
fftw_version: str
52
53
# FFTW version as tuple (e.g., (3, 3, 10))
54
fftw_version_tuple: tuple
55
56
# Compiler flags used to build FFTW
57
fftw_cc: str
58
59
# Threading type ('OMP', 'pthreads', or None)
60
_threading_type: str
61
62
# Supported precision types
63
_supported_types: list # ['32', '64', 'ld']
64
65
# Supported numpy complex types
66
_supported_nptypes_complex: list
67
68
# Supported numpy real types
69
_supported_nptypes_real: list
70
71
# Human-readable type names
72
_all_types_human_readable: list
73
74
# Numpy type mappings
75
_all_types_np: list
76
77
# FFTW version information dictionary
78
_fftw_version_dict: dict
79
80
# FFTW compiler information dictionary
81
_fftw_cc_dict: dict
82
```
83
84
### Configuration Module
85
86
The `pyfftw.config` module provides runtime configuration management.
87
88
```python { .api }
89
# Configuration variables (from pyfftw.config)
90
NUM_THREADS: int # Number of threads (from env PYFFTW_NUM_THREADS or OMP_NUM_THREADS)
91
PLANNER_EFFORT: str # Planner effort (from env PYFFTW_PLANNER_EFFORT)
92
```
93
94
## Usage Examples
95
96
### Finding Optimal Transform Sizes
97
98
```python
99
import pyfftw
100
import numpy as np
101
102
# Find optimal sizes for various targets
103
targets = [100, 500, 1000, 1500, 2000]
104
105
print("Target -> Optimal (overhead)")
106
for target in targets:
107
optimal = pyfftw.next_fast_len(target)
108
overhead = (optimal - target) / target * 100
109
print(f"{target:4d} -> {optimal:4d} ({overhead:5.1f}%)")
110
111
# Use optimal size for better performance
112
target_size = 1000
113
optimal_size = pyfftw.next_fast_len(target_size)
114
115
# Create data with optimal size
116
data = np.random.randn(optimal_size) + 1j * np.random.randn(optimal_size)
117
result = pyfftw.empty_aligned(optimal_size, dtype='complex128')
118
119
# This will be more efficient than using target_size directly
120
fft_obj = pyfftw.FFTW(data, result)
121
```
122
123
### System Information
124
125
```python
126
import pyfftw
127
128
# Display system and version information
129
print("=== pyFFTW System Information ===")
130
print(f"FFTW Version: {pyfftw.fftw_version}")
131
print(f"FFTW Version Tuple: {pyfftw.fftw_version_tuple}")
132
print(f"FFTW Compiler: {pyfftw.fftw_cc}")
133
print(f"Threading Type: {pyfftw._threading_type}")
134
print(f"SIMD Alignment: {pyfftw.simd_alignment} bytes")
135
136
print(f"\nSupported Types: {pyfftw._supported_types}")
137
print(f"Complex Types: {pyfftw._supported_nptypes_complex}")
138
print(f"Real Types: {pyfftw._supported_nptypes_real}")
139
140
# Check configuration
141
import pyfftw.config
142
print(f"\n=== Configuration ===")
143
print(f"Default Threads: {pyfftw.config.NUM_THREADS}")
144
print(f"Default Planner Effort: {pyfftw.config.PLANNER_EFFORT}")
145
```
146
147
### Environment Configuration
148
149
```python
150
import os
151
import pyfftw.config
152
153
# Configuration can be controlled via environment variables
154
print("Current configuration:")
155
print(f"NUM_THREADS: {pyfftw.config.NUM_THREADS}")
156
print(f"PLANNER_EFFORT: {pyfftw.config.PLANNER_EFFORT}")
157
158
# Example of setting environment variables
159
# (these would typically be set before importing pyfftw)
160
os.environ['PYFFTW_NUM_THREADS'] = '8'
161
os.environ['PYFFTW_PLANNER_EFFORT'] = 'FFTW_PATIENT'
162
163
# Reload configuration (normally not needed in real applications)
164
pyfftw.config._reload_config()
165
166
print("\nAfter setting environment variables:")
167
print(f"NUM_THREADS: {pyfftw.config.NUM_THREADS}")
168
print(f"PLANNER_EFFORT: {pyfftw.config.PLANNER_EFFORT}")
169
```
170
171
### Performance Optimization Utilities
172
173
```python
174
import pyfftw
175
import numpy as np
176
import time
177
178
def benchmark_sizes(base_size, num_variations=10):
179
"""Benchmark different sizes around a base size."""
180
181
# Test the base size and optimal size
182
optimal_size = pyfftw.next_fast_len(base_size)
183
184
sizes_to_test = [base_size, optimal_size]
185
186
# Add some variations
187
for i in range(1, num_variations):
188
test_size = base_size + i * 10
189
sizes_to_test.append(test_size)
190
sizes_to_test.append(pyfftw.next_fast_len(test_size))
191
192
# Remove duplicates and sort
193
sizes_to_test = sorted(list(set(sizes_to_test)))
194
195
results = {}
196
197
for size in sizes_to_test:
198
# Create aligned arrays
199
data = pyfftw.empty_aligned(size, dtype='complex128')
200
result = pyfftw.empty_aligned(size, dtype='complex128')
201
202
# Fill with random data
203
data[:] = np.random.randn(size) + 1j * np.random.randn(size)
204
205
# Create FFTW object
206
fft_obj = pyfftw.FFTW(data, result, flags=('FFTW_MEASURE',))
207
208
# Benchmark execution time
209
num_runs = max(10, 1000000 // size) # Adjust runs based on size
210
211
start = time.time()
212
for _ in range(num_runs):
213
fft_obj()
214
elapsed = time.time() - start
215
216
avg_time = elapsed / num_runs * 1e6 # microseconds
217
results[size] = avg_time
218
219
# Display results
220
print(f"Size benchmarks (base size: {base_size}, optimal: {optimal_size})")
221
print("Size Time (μs) Relative")
222
print("-" * 30)
223
224
base_time = results[base_size]
225
for size in sorted(results.keys()):
226
time_us = results[size]
227
relative = time_us / base_time
228
marker = " (optimal)" if size == optimal_size else ""
229
print(f"{size:5d} {time_us:8.2f} {relative:6.2f}{marker}")
230
231
# Run benchmark
232
benchmark_sizes(1000)
233
```
234
235
### Type Support Detection
236
237
```python
238
import pyfftw
239
import numpy as np
240
241
def check_type_support():
242
"""Check which data types are supported."""
243
244
test_size = 64
245
246
# Test different data types
247
types_to_test = [
248
('float32', np.float32),
249
('float64', np.float64),
250
('longdouble', np.longdouble),
251
('complex64', np.complex64),
252
('complex128', np.complex128),
253
('clongdouble', np.clongdouble if hasattr(np, 'clongdouble') else None)
254
]
255
256
print("Data Type Support:")
257
print("Type Supported Size (bytes)")
258
print("-" * 40)
259
260
for type_name, numpy_type in types_to_test:
261
if numpy_type is None:
262
print(f"{type_name:12s} No -")
263
continue
264
265
try:
266
# Try to create arrays and FFTW object
267
if 'complex' in type_name:
268
input_array = pyfftw.empty_aligned(test_size, dtype=numpy_type)
269
output_array = pyfftw.empty_aligned(test_size, dtype=numpy_type)
270
else:
271
# For real types, output is complex
272
input_array = pyfftw.empty_aligned(test_size, dtype=numpy_type)
273
if numpy_type == np.float32:
274
output_dtype = np.complex64
275
elif numpy_type == np.longdouble:
276
output_dtype = np.clongdouble if hasattr(np, 'clongdouble') else np.complex128
277
else:
278
output_dtype = np.complex128
279
output_array = pyfftw.empty_aligned(test_size//2 + 1, dtype=output_dtype)
280
281
# Try to create FFTW object
282
fft_obj = pyfftw.FFTW(input_array, output_array)
283
284
supported = "Yes"
285
type_size = numpy_type().itemsize
286
287
except Exception as e:
288
supported = "No"
289
type_size = numpy_type().itemsize if hasattr(numpy_type(), 'itemsize') else 0
290
291
print(f"{type_name:12s} {supported:3s} {type_size}")
292
293
check_type_support()
294
```
295
296
### Custom Configuration Class
297
298
```python
299
import pyfftw
300
import pyfftw.config
301
import threading
302
303
class PyFFTWConfig:
304
"""Custom configuration manager for pyFFTW applications."""
305
306
def __init__(self):
307
self._lock = threading.Lock()
308
self.load_defaults()
309
310
def load_defaults(self):
311
"""Load default configuration values."""
312
self.num_threads = pyfftw.config.NUM_THREADS
313
self.planner_effort = pyfftw.config.PLANNER_EFFORT
314
self.simd_alignment = pyfftw.simd_alignment
315
self.auto_align = True
316
self.auto_contiguous = True
317
318
def get_fft_kwargs(self):
319
"""Get standard kwargs for FFTW functions."""
320
with self._lock:
321
return {
322
'threads': self.num_threads,
323
'planner_effort': self.planner_effort,
324
'auto_align_input': self.auto_align,
325
'auto_contiguous': self.auto_contiguous
326
}
327
328
def set_performance_mode(self, mode='balanced'):
329
"""Set predefined performance modes."""
330
with self._lock:
331
if mode == 'speed':
332
self.planner_effort = 'FFTW_ESTIMATE'
333
self.num_threads = pyfftw.config.NUM_THREADS
334
elif mode == 'balanced':
335
self.planner_effort = 'FFTW_MEASURE'
336
self.num_threads = min(4, pyfftw.config.NUM_THREADS)
337
elif mode == 'quality':
338
self.planner_effort = 'FFTW_PATIENT'
339
self.num_threads = 1 # Single thread for reproducibility
340
else:
341
raise ValueError(f"Unknown mode: {mode}")
342
343
def create_fft_object(self, input_array, output_array, **kwargs):
344
"""Create FFTW object with current configuration."""
345
config_kwargs = self.get_fft_kwargs()
346
config_kwargs.update(kwargs) # Allow override
347
348
return pyfftw.FFTW(input_array, output_array, **config_kwargs)
349
350
# Usage example
351
config = PyFFTWConfig()
352
353
# Set different performance modes
354
config.set_performance_mode('quality')
355
356
# Create FFT object with configuration
357
data = pyfftw.empty_aligned(1024, dtype='complex128')
358
result = pyfftw.empty_aligned(1024, dtype='complex128')
359
360
fft_obj = config.create_fft_object(data, result)
361
```