0
# Decorators
1
2
Function decorators that provide fine-grained control over transpilation behavior, optimization hints, and code generation options for enhanced performance.
3
4
## Capabilities
5
6
### Performance Optimization Decorators
7
8
Decorators that influence code generation and optimization strategies for improved performance.
9
10
```python { .api }
11
from pyccel.decorators import pure, elemental, inline
12
13
def pure(f):
14
"""
15
Mark function as pure (no side effects).
16
17
Indicates that the function has no side effects and its output
18
depends only on its inputs. Enables aggressive optimizations.
19
20
Parameters:
21
- f: Function to mark as pure
22
23
Returns:
24
Original function (decorator is a compile-time hint)
25
"""
26
27
def elemental(f):
28
"""
29
Mark function as elemental for array operations.
30
31
Indicates that the function can be applied element-wise to arrays,
32
enabling vectorization and parallel execution optimizations.
33
34
Parameters:
35
- f: Function to mark as elemental
36
37
Returns:
38
Original function (decorator is a compile-time hint)
39
"""
40
41
def inline(f):
42
"""
43
Inline function calls for performance.
44
45
Indicates that function calls should print the function body
46
directly instead of generating a function call, reducing
47
call overhead for small functions.
48
49
Parameters:
50
- f: Function to inline
51
52
Returns:
53
Original function (decorator is a compile-time hint)
54
"""
55
```
56
57
Usage examples:
58
59
```python
60
from pyccel.decorators import pure, elemental, inline
61
62
@pure
63
def square(x):
64
"""Pure function - no side effects."""
65
return x * x
66
67
@elemental
68
def add_arrays(a, b):
69
"""Elemental function - operates element-wise."""
70
return a + b
71
72
@inline
73
def small_computation(x, y):
74
"""Small function to be inlined."""
75
return x * 2 + y * 3
76
```
77
78
### Memory Management Decorators
79
80
Decorators that control memory allocation and access patterns for arrays.
81
82
```python { .api }
83
from pyccel.decorators import stack_array, allow_negative_index
84
85
def stack_array(f, *args):
86
"""
87
Store specified arrays on the stack instead of heap.
88
89
Decorator indicates that arrays mentioned in args should be stored
90
on the stack for faster access, suitable for small, fixed-size arrays.
91
92
Parameters:
93
- f: Function to which decorator is applied
94
- args: list of str
95
Names of arrays to store on stack
96
97
Returns:
98
Decorator function that returns original function
99
"""
100
101
def allow_negative_index(f, *args):
102
"""
103
Enable negative indexing for specified arrays.
104
105
Decorator indicates that arrays mentioned in args can be accessed
106
with negative indexes. Uses modulo function for non-constant indexing,
107
which may impact performance.
108
109
Parameters:
110
- f: Function to which decorator is applied
111
- args: list of str
112
Names of arrays that support negative indexing
113
114
Returns:
115
Decorator function that returns original function
116
"""
117
```
118
119
Usage examples:
120
121
```python
122
from pyccel.decorators import stack_array, allow_negative_index
123
import numpy as np
124
125
@stack_array('temp_array', 'result')
126
def matrix_computation(input_data):
127
"""Function with stack-allocated temporary arrays."""
128
temp_array = np.zeros(10) # Allocated on stack
129
result = np.zeros(5) # Allocated on stack
130
# ... computation logic
131
return result
132
133
@allow_negative_index('data', 'indices')
134
def process_with_negative_indexing(data, indices):
135
"""Function that supports negative array indexing."""
136
# Can use data[-1], data[-2], etc.
137
return data[indices[-1]] + data[indices[-2]]
138
```
139
140
### Compilation Control Decorators
141
142
Decorators that control the transpilation process and code generation behavior.
143
144
```python { .api }
145
from pyccel.decorators import bypass, private, sympy
146
147
def bypass(f):
148
"""
149
Bypass Pyccel processing for the function.
150
151
Indicates that the function should not be transpiled by Pyccel
152
and should remain as native Python code.
153
154
Parameters:
155
- f: Function to bypass
156
157
Returns:
158
Original function unchanged
159
"""
160
161
def private(f):
162
"""
163
Mark function as private to the module.
164
165
Indicates that the function should not be exposed in the
166
public interface of the generated code.
167
168
Parameters:
169
- f: Function to mark as private
170
171
Returns:
172
Original function (decorator is a compile-time hint)
173
"""
174
175
def sympy(f):
176
"""
177
Enable SymPy integration for the function.
178
179
Indicates that the function may use SymPy expressions
180
and should be processed with SymPy support enabled.
181
182
Parameters:
183
- f: Function with SymPy integration
184
185
Returns:
186
Original function (decorator is a compile-time hint)
187
"""
188
```
189
190
Usage examples:
191
192
```python
193
from pyccel.decorators import bypass, private, sympy
194
import sympy as sp
195
196
@bypass
197
def debug_function(data):
198
"""This function remains in Python (not transpiled)."""
199
print(f"Debug: processing {len(data)} items")
200
return data
201
202
@private
203
def internal_helper(x, y):
204
"""Private function not exposed in public interface."""
205
return x * y + 1
206
207
@sympy
208
def symbolic_computation(expr, x_val):
209
"""Function that works with SymPy expressions."""
210
return expr.subs('x', x_val)
211
```
212
213
## Decorator Combinations
214
215
Multiple decorators can be combined for fine-grained control:
216
217
```python
218
from pyccel.decorators import pure, elemental, inline, stack_array
219
220
@pure
221
@elemental
222
@inline
223
@stack_array('temp')
224
def optimized_function(a, b):
225
"""Highly optimized function with multiple decorators."""
226
temp = a + b # Stack allocated
227
return temp * temp # Pure, elemental, inlined
228
```
229
230
## Important Notes
231
232
### Decorator Behavior
233
234
- All decorators return the original function unchanged at runtime
235
- Decorators provide compile-time hints to the Pyccel transpiler
236
- They have no effect when functions are run in pure Python mode
237
- Decorator effects only apply when code is transpiled via epyccel or command-line tools
238
239
### Performance Considerations
240
241
- `@pure` enables aggressive optimizations but requires no side effects
242
- `@elemental` enables vectorization but requires element-wise operations
243
- `@inline` reduces call overhead but may increase code size
244
- `@stack_array` improves access speed but limited by stack size
245
- `@allow_negative_index` adds modulo operations, potentially reducing performance
246
247
## Module Import
248
249
```python { .api }
250
from pyccel.decorators import (
251
allow_negative_index,
252
bypass,
253
elemental,
254
inline,
255
private,
256
pure,
257
stack_array,
258
sympy,
259
)
260
```