0
# Memory Management and Alignment
1
2
Utilities for creating and managing aligned arrays to maximize SIMD performance, plus functions for checking alignment and converting existing arrays. Proper alignment is crucial for optimal FFT performance as it enables efficient use of vector instructions.
3
4
## Capabilities
5
6
### Aligned Array Creation
7
8
Functions to create new arrays with optimal alignment for SIMD operations.
9
10
```python { .api }
11
def empty_aligned(shape, dtype='float64', order='C', n=None):
12
"""
13
Create an empty aligned array.
14
15
Parameters:
16
- shape: Shape of the array (int or tuple)
17
- dtype: Array data type (default: 'float64')
18
- order: Array order 'C' or 'F' (default: 'C')
19
- n: Byte alignment (default: optimal SIMD alignment)
20
21
Returns:
22
- Aligned numpy array
23
"""
24
25
def zeros_aligned(shape, dtype='float64', order='C', n=None):
26
"""
27
Create a zero-filled aligned array.
28
29
Parameters:
30
- shape: Shape of the array (int or tuple)
31
- dtype: Array data type (default: 'float64')
32
- order: Array order 'C' or 'F' (default: 'C')
33
- n: Byte alignment (default: optimal SIMD alignment)
34
35
Returns:
36
- Aligned numpy array filled with zeros
37
"""
38
39
def ones_aligned(shape, dtype='float64', order='C', n=None):
40
"""
41
Create a ones-filled aligned array.
42
43
Parameters:
44
- shape: Shape of the array (int or tuple)
45
- dtype: Array data type (default: 'float64')
46
- order: Array order 'C' or 'F' (default: 'C')
47
- n: Byte alignment (default: optimal SIMD alignment)
48
49
Returns:
50
- Aligned numpy array filled with ones
51
"""
52
53
def n_byte_align_empty(shape, n, dtype='float64', order='C'):
54
"""
55
Create an empty array aligned to n bytes.
56
57
Parameters:
58
- shape: Shape of the array (int or tuple)
59
- n: Desired byte alignment
60
- dtype: Array data type (default: 'float64')
61
- order: Array order 'C' or 'F' (default: 'C')
62
63
Returns:
64
- Aligned numpy array
65
"""
66
```
67
68
### Array Alignment Functions
69
70
Functions to align existing arrays and create aligned copies.
71
72
```python { .api }
73
def n_byte_align(array, n, dtype=None):
74
"""
75
Align an existing array to n bytes, creating a copy if necessary.
76
77
Parameters:
78
- array: Input array to align
79
- n: Desired byte alignment
80
- dtype: Target data type (default: preserve original)
81
82
Returns:
83
- Aligned array (may be a copy)
84
"""
85
86
def byte_align(array, n=None, dtype=None):
87
"""
88
Align an array to optimal byte boundary.
89
90
Parameters:
91
- array: Input array to align
92
- n: Byte alignment (default: optimal SIMD alignment)
93
- dtype: Target data type (default: preserve original)
94
95
Returns:
96
- Aligned array (may be a copy)
97
"""
98
```
99
100
### Alignment Checking
101
102
Functions to verify array alignment.
103
104
```python { .api }
105
def is_byte_aligned(array, n=None):
106
"""
107
Check if an array is byte aligned.
108
109
Parameters:
110
- array: Array to check
111
- n: Alignment to check (default: optimal SIMD alignment)
112
113
Returns:
114
- bool: True if aligned, False otherwise
115
"""
116
117
def is_n_byte_aligned(array, n):
118
"""
119
Check if an array is aligned to n bytes.
120
121
Parameters:
122
- array: Array to check
123
- n: Byte alignment to verify
124
125
Returns:
126
- bool: True if aligned to n bytes, False otherwise
127
"""
128
129
def n_byte_align_empty(shape, n, dtype='float64', order='C'):
130
"""
131
Create an n-byte aligned empty array with the given shape and data type.
132
133
Parameters:
134
- shape: array shape
135
- n: int, byte alignment boundary
136
- dtype: data type specifier (default: 'float64')
137
- order: array memory layout ('C' or 'F', default: 'C')
138
139
Returns:
140
- numpy.ndarray: n-byte aligned empty array
141
"""
142
```
143
144
### Alignment Constants
145
146
```python { .api }
147
# Optimal SIMD alignment for the current CPU
148
simd_alignment: int
149
```
150
151
## Usage Examples
152
153
### Creating Aligned Arrays
154
155
```python
156
import numpy as np
157
import pyfftw
158
159
# Create aligned arrays with default optimal alignment
160
a = pyfftw.empty_aligned((1024, 512), dtype='complex128')
161
b = pyfftw.zeros_aligned((1024, 512), dtype='complex128')
162
c = pyfftw.ones_aligned((1024, 512), dtype='float64')
163
164
# Create with specific alignment
165
d = pyfftw.n_byte_align_empty((1024,), 32, dtype='float64')
166
167
print(f"Optimal SIMD alignment: {pyfftw.simd_alignment} bytes")
168
print(f"Array a is aligned: {pyfftw.is_byte_aligned(a)}")
169
```
170
171
### Aligning Existing Arrays
172
173
```python
174
import numpy as np
175
import pyfftw
176
177
# Create unaligned array
178
original = np.random.randn(1024, 512)
179
print(f"Original aligned: {pyfftw.is_byte_aligned(original)}")
180
181
# Align the array
182
aligned = pyfftw.byte_align(original)
183
print(f"Aligned array: {pyfftw.is_byte_aligned(aligned)}")
184
185
# Check specific alignment
186
aligned_32 = pyfftw.n_byte_align(original, 32)
187
print(f"32-byte aligned: {pyfftw.is_n_byte_aligned(aligned_32, 32)}")
188
```
189
190
### Performance Comparison
191
192
```python
193
import numpy as np
194
import pyfftw
195
import time
196
197
# Create aligned and unaligned arrays
198
N = 1024 * 1024
199
aligned = pyfftw.empty_aligned(N, dtype='complex128')
200
unaligned = np.empty(N, dtype='complex128')
201
202
# Fill with data
203
aligned[:] = np.random.randn(N) + 1j * np.random.randn(N)
204
unaligned[:] = aligned.copy()
205
206
# Create FFTW objects
207
fft_aligned = pyfftw.FFTW(aligned, pyfftw.empty_aligned(N, dtype='complex128'))
208
fft_unaligned = pyfftw.FFTW(unaligned, np.empty(N, dtype='complex128'))
209
210
# Time the transforms
211
start = time.time()
212
for _ in range(100):
213
result_aligned = fft_aligned()
214
time_aligned = time.time() - start
215
216
start = time.time()
217
for _ in range(100):
218
result_unaligned = fft_unaligned()
219
time_unaligned = time.time() - start
220
221
print(f"Aligned: {time_aligned:.3f}s")
222
print(f"Unaligned: {time_unaligned:.3f}s")
223
print(f"Speedup: {time_unaligned/time_aligned:.2f}x")
224
```
225
226
### Working with Different Data Types
227
228
```python
229
import pyfftw
230
231
# Different precision levels
232
float32_array = pyfftw.empty_aligned((1024,), dtype='float32')
233
float64_array = pyfftw.empty_aligned((1024,), dtype='float64')
234
longdouble_array = pyfftw.empty_aligned((1024,), dtype='longdouble')
235
236
# Complex types
237
complex64_array = pyfftw.empty_aligned((1024,), dtype='complex64')
238
complex128_array = pyfftw.empty_aligned((1024,), dtype='complex128')
239
clongdouble_array = pyfftw.empty_aligned((1024,), dtype='clongdouble')
240
241
print("All arrays are aligned:")
242
for arr in [float32_array, float64_array, longdouble_array,
243
complex64_array, complex128_array, clongdouble_array]:
244
print(f"{arr.dtype}: {pyfftw.is_byte_aligned(arr)}")
245
```