0
# Events and Process Ranges
1
2
Mark specific points in execution with instantaneous events and create cross-process or cross-thread ranges that can span multiple function calls. These capabilities provide fine-grained profiling control for complex applications.
3
4
## Capabilities
5
6
### Instantaneous Events
7
8
Use `nvtx.mark` to create point-in-time events that appear as vertical markers in NVIDIA Nsight Systems timeline visualization.
9
10
```python { .api }
11
def mark(message: str = None, color: Union[str, int] = "blue",
12
domain: str = None, category: Union[str, int] = None,
13
payload: Union[int, float] = None):
14
"""
15
Mark an instantaneous event.
16
17
Parameters:
18
- message: Description of the event
19
- color: Color for visualization (default "blue")
20
- domain: Domain name (default "NVTX")
21
- category: Category name or ID for grouping
22
- payload: Numeric value associated with event
23
"""
24
```
25
26
**Usage Example:**
27
28
```python
29
import nvtx
30
import time
31
32
def training_loop():
33
for epoch in range(100):
34
nvtx.mark("epoch_start", color="green", payload=epoch)
35
36
for batch in batches:
37
train_batch(batch)
38
39
# Mark significant events
40
nvtx.mark("validation_checkpoint", color="yellow", payload=epoch)
41
validate_model()
42
43
if epoch % 10 == 0:
44
nvtx.mark("model_save", color="purple", payload=epoch)
45
save_model()
46
47
nvtx.mark("epoch_end", color="red", payload=epoch)
48
```
49
50
### Process Ranges
51
52
Use `start_range` and `end_range` to create ranges that can span across function calls, threads, or even processes. These provide more flexibility than push/pop ranges.
53
54
```python { .api }
55
def start_range(message: str = None, color: Union[str, int] = None,
56
domain: str = None, category: Union[str, int] = None,
57
payload: Union[int, float] = None) -> Optional[Tuple[int, int]]:
58
"""
59
Mark the beginning of a process range.
60
61
Parameters:
62
- message: Description of the range
63
- color: Color for visualization
64
- domain: Domain name (default "NVTX")
65
- category: Category name or ID for grouping
66
- payload: Numeric value associated with range
67
68
Returns:
69
- Tuple of (range_id, domain_handle) for use with end_range
70
"""
71
72
def end_range(range_id: Optional[Tuple[int, int]]):
73
"""
74
Mark the end of a process range started with start_range.
75
76
Parameters:
77
- range_id: Tuple returned by start_range call
78
"""
79
```
80
81
**Usage Example:**
82
83
```python
84
import nvtx
85
import time
86
import threading
87
88
# Cross-function ranges
89
def complex_pipeline():
90
# Start range that spans multiple functions
91
pipeline_range = nvtx.start_range("data_pipeline", color="blue")
92
93
data = load_data()
94
processed = process_data(data)
95
results = analyze_data(processed)
96
97
# End range after all processing
98
nvtx.end_range(pipeline_range)
99
return results
100
101
# Cross-thread ranges
102
class BackgroundProcessor:
103
def __init__(self):
104
self.active_ranges = {}
105
106
def start_background_task(self, task_id):
107
range_id = nvtx.start_range(f"background_task_{task_id}",
108
color="orange", payload=task_id)
109
self.active_ranges[task_id] = range_id
110
111
# Start background thread
112
thread = threading.Thread(target=self._process_task, args=(task_id,))
113
thread.start()
114
115
def _process_task(self, task_id):
116
# Long-running background work
117
time.sleep(5)
118
119
# End the range from background thread
120
if task_id in self.active_ranges:
121
nvtx.end_range(self.active_ranges[task_id])
122
del self.active_ranges[task_id]
123
```
124
125
### Overlapping and Nested Ranges
126
127
Process ranges support complex overlapping and nesting patterns that push/pop ranges cannot handle.
128
129
**Usage Example:**
130
131
```python
132
import nvtx
133
import asyncio
134
135
async def concurrent_processing():
136
# Start multiple overlapping ranges
137
range1 = nvtx.start_range("async_task_1", color="blue")
138
range2 = nvtx.start_range("async_task_2", color="green")
139
range3 = nvtx.start_range("async_task_3", color="red")
140
141
# Tasks can complete in any order
142
await asyncio.gather(
143
process_async_task_1(),
144
process_async_task_2(),
145
process_async_task_3()
146
)
147
148
# End ranges as tasks complete (order may vary)
149
nvtx.end_range(range2) # Task 2 finished first
150
nvtx.end_range(range1) # Task 1 finished second
151
nvtx.end_range(range3) # Task 3 finished last
152
```
153
154
## Parameter Details
155
156
### Message Parameter
157
158
- **Type**: `Optional[str]`
159
- **Events**: Describes the specific event or milestone
160
- **Ranges**: Describes the operation or phase
161
- **Caching**: Messages are cached as Registered Strings for performance
162
- **Naming**: Use consistent naming patterns for better visualization
163
164
### Color Parameter
165
166
- **Type**: `Optional[Union[str, int]]`
167
- **Events**: Default "blue" if not specified
168
- **Ranges**: No default, uses domain default
169
- **Visualization**: Choose colors that create clear visual separation in timeline
170
- **Consistency**: Use consistent colors for similar event types
171
172
### Domain Parameter
173
174
- **Type**: `Optional[str]`
175
- **Default**: "NVTX"
176
- **Cross-Process**: Same domain name enables correlation across processes
177
- **Organization**: Group related events and ranges
178
179
### Category Parameter
180
181
- **Type**: `Optional[Union[str, int]]`
182
- **Grouping**: Categories appear as separate tracks in profiler
183
- **Events**: Useful for grouping similar event types
184
- **Ranges**: Useful for distinguishing different types of operations
185
186
### Payload Parameter
187
188
- **Type**: `Optional[Union[int, float]]`
189
- **Events**: Event-specific data (iteration number, size, count)
190
- **Ranges**: Range-specific metrics (expected duration, priority, size)
191
- **Analysis**: Enables data-driven performance analysis
192
193
## Return Values
194
195
### start_range Return Value
196
197
- **Type**: `Optional[Tuple[int, int]]`
198
- **Contents**: `(range_id, domain_handle)` when NVTX is enabled, `None` when disabled
199
- **Usage**: Must be passed exactly to corresponding `end_range` call
200
- **Storage**: Can be stored in variables, data structures, or passed between functions/threads
201
- **Lifetime**: Valid until `end_range` is called
202
203
## Error Handling
204
205
- **Invalid Range ID**: `end_range` with invalid or already-ended range ID is safely ignored
206
- **Missing end_range**: Unclosed ranges may appear as ongoing in profiler visualization
207
- **Thread Safety**: Range IDs can be safely passed between threads
208
- **Exception Safety**: Range IDs remain valid even if exceptions occur
209
210
## Performance Considerations
211
212
- **Domain API**: Use `Domain.start_range` and `Domain.end_range` for better performance
213
- **Range Tracking**: Store range IDs efficiently for high-frequency operations
214
- **Cleanup**: Always call `end_range` to avoid memory leaks in profiler
215
- **Overhead**: Process ranges have slightly more overhead than push/pop ranges
216
217
## Use Cases
218
219
### Event Marking
220
221
- **Checkpoints**: Save points, validation milestones
222
- **State Changes**: Mode switches, phase transitions
223
- **External Events**: Network requests, file I/O completion
224
- **Debug Points**: Variable state inspection points
225
226
### Process Ranges
227
228
- **Async Operations**: Operations spanning multiple async calls
229
- **Cross-Thread Work**: Work distributed across thread pools
230
- **Pipeline Stages**: Multi-stage processing pipelines
231
- **Resource Lifetimes**: Database connections, file handles