or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation.mddomains.mdevents-ranges.mdindex.mdprofiling.md

profiling.mddocs/

0

# Automatic Profiling

1

2

Automatically annotate all function calls in your program with configurable detail levels, including line numbers and C function support. The Profile class provides comprehensive automatic annotation without manual code modification.

3

4

## Capabilities

5

6

### Profile Class

7

8

The `Profile` class enables automatic annotation of all function calls using Python's profiling hooks with configurable detail levels and C function support.

9

10

```python { .api }

11

class Profile:

12

def __init__(self, linenos: bool = True, annotate_cfuncs: bool = True):

13

"""

14

Create a Profile object for automatic function call annotation.

15

16

Parameters:

17

- linenos: Include file and line number information in annotations

18

- annotate_cfuncs: Also annotate C-extension and builtin functions

19

"""

20

21

def enable(self):

22

"""

23

Start annotating function calls automatically.

24

Sets up profiling hooks for current thread and all new threads.

25

"""

26

27

def disable(self):

28

"""

29

Stop annotating function calls automatically.

30

Removes profiling hooks from current thread and new threads.

31

"""

32

```

33

34

**Basic Usage Example:**

35

36

```python

37

import nvtx

38

import time

39

40

# Create profiler with default settings

41

profiler = nvtx.Profile()

42

43

# Enable automatic annotation

44

profiler.enable()

45

46

# All function calls are now automatically annotated

47

def process_data():

48

time.sleep(0.1) # This will be annotated

49

compute_results()

50

51

def compute_results():

52

time.sleep(0.2) # This will also be annotated

53

54

process_data()

55

56

# Stop automatic annotation

57

profiler.disable()

58

59

# Function calls after disable() are not annotated

60

process_data() # Not annotated

61

```

62

63

### Configuration Options

64

65

#### Line Number Information

66

67

Control whether file names and line numbers are included in annotation messages:

68

69

```python

70

import nvtx

71

72

# Include line numbers (default)

73

profiler_with_lines = nvtx.Profile(linenos=True)

74

75

# Example annotation message: "main.py:42(process_data)"

76

77

# Exclude line numbers for cleaner display

78

profiler_clean = nvtx.Profile(linenos=False)

79

80

# Example annotation message: "process_data"

81

```

82

83

**Usage Example:**

84

85

```python

86

import nvtx

87

import time

88

89

def detailed_profiling():

90

# Detailed profiling with file and line info

91

profiler = nvtx.Profile(linenos=True)

92

profiler.enable()

93

94

def func_a():

95

time.sleep(0.1)

96

func_b()

97

98

def func_b():

99

time.sleep(0.1)

100

101

func_a() # Annotations show: "example.py:123(func_a)", "example.py:126(func_b)"

102

profiler.disable()

103

104

def clean_profiling():

105

# Clean profiling with function names only

106

profiler = nvtx.Profile(linenos=False)

107

profiler.enable()

108

109

def func_a():

110

time.sleep(0.1)

111

func_b()

112

113

def func_b():

114

time.sleep(0.1)

115

116

func_a() # Annotations show: "func_a", "func_b"

117

profiler.disable()

118

```

119

120

#### C Function Annotation

121

122

Control whether C extensions and builtin functions are annotated:

123

124

```python

125

import nvtx

126

127

# Annotate C functions (default)

128

profiler_full = nvtx.Profile(annotate_cfuncs=True)

129

130

# Skip C functions for focus on Python code

131

profiler_python_only = nvtx.Profile(annotate_cfuncs=False)

132

```

133

134

**Usage Example:**

135

136

```python

137

import nvtx

138

import time

139

import json

140

141

def c_function_profiling():

142

# Profile including C functions

143

profiler = nvtx.Profile(annotate_cfuncs=True)

144

profiler.enable()

145

146

data = {"key": "value"}

147

json_str = json.dumps(data) # json.dumps is C function - will be annotated

148

time.sleep(0.1) # time.sleep is C function - will be annotated

149

150

profiler.disable()

151

152

def python_only_profiling():

153

# Profile Python functions only

154

profiler = nvtx.Profile(annotate_cfuncs=False)

155

profiler.enable()

156

157

data = {"key": "value"}

158

json_str = json.dumps(data) # json.dumps is C function - NOT annotated

159

time.sleep(0.1) # time.sleep is C function - NOT annotated

160

161

def python_func():

162

return "python"

163

164

result = python_func() # Python function - will be annotated

165

166

profiler.disable()

167

```

168

169

### Thread Handling

170

171

The Profile class automatically handles both current thread and new thread annotation:

172

173

```python

174

import nvtx

175

import threading

176

import time

177

178

def automatic_thread_profiling():

179

# Create and enable profiler

180

profiler = nvtx.Profile()

181

profiler.enable()

182

183

def worker_function(worker_id):

184

time.sleep(0.1)

185

print(f"Worker {worker_id} completed")

186

187

# Main thread function calls are annotated

188

main_work()

189

190

# New threads are also automatically profiled

191

threads = []

192

for i in range(3):

193

thread = threading.Thread(target=worker_function, args=(i,))

194

threads.append(thread)

195

thread.start()

196

197

# Wait for all threads

198

for thread in threads:

199

thread.join()

200

201

profiler.disable()

202

```

203

204

## Command-Line Interface

205

206

NVTX provides a command-line interface for automatic profiling of entire Python programs:

207

208

```bash

209

python -m nvtx [options] scriptfile [args] ...

210

```

211

212

### Command-Line Options

213

214

```bash

215

--linenos # Include file and line number information (default)

216

--no-linenos # Do not include file and line number information

217

--annotate-cfuncs # Also annotate C-extension and builtin functions

218

```

219

220

**Usage Examples:**

221

222

```bash

223

# Profile with default settings (line numbers, no C functions)

224

python -m nvtx my_script.py

225

226

# Profile with line numbers and C functions

227

python -m nvtx --annotate-cfuncs my_script.py

228

229

# Profile with clean function names only

230

python -m nvtx --no-linenos my_script.py arg1 arg2

231

232

# Full profiling with all options

233

python -m nvtx --linenos --annotate-cfuncs my_script.py --input data.txt

234

```

235

236

## Integration Patterns

237

238

### Context-Managed Profiling

239

240

Use profiling for specific code sections:

241

242

```python

243

import nvtx

244

245

class ProfiledSection:

246

def __init__(self, **profile_kwargs):

247

self.profiler = nvtx.Profile(**profile_kwargs)

248

249

def __enter__(self):

250

self.profiler.enable()

251

return self.profiler

252

253

def __exit__(self, exc_type, exc_val, exc_tb):

254

self.profiler.disable()

255

256

# Usage

257

with ProfiledSection(linenos=True, annotate_cfuncs=False) as profiler:

258

# All function calls in this block are automatically annotated

259

complex_algorithm()

260

data_processing()

261

```

262

263

### Conditional Profiling

264

265

Enable profiling based on environment or configuration:

266

267

```python

268

import nvtx

269

import os

270

271

class ConditionalProfiler:

272

def __init__(self):

273

self.profiler = None

274

self.enabled = os.getenv('ENABLE_NVTX_PROFILING', 'false').lower() == 'true'

275

276

if self.enabled:

277

self.profiler = nvtx.Profile(

278

linenos=os.getenv('NVTX_LINENOS', 'true').lower() == 'true',

279

annotate_cfuncs=os.getenv('NVTX_C_FUNCS', 'false').lower() == 'true'

280

)

281

282

def enable(self):

283

if self.profiler:

284

self.profiler.enable()

285

286

def disable(self):

287

if self.profiler:

288

self.profiler.disable()

289

290

# Global profiler instance

291

profiler = ConditionalProfiler()

292

293

def main():

294

profiler.enable()

295

try:

296

run_application()

297

finally:

298

profiler.disable()

299

```

300

301

### Decorator-Based Profiling

302

303

Create decorators for automatic profiling of specific functions:

304

305

```python

306

import nvtx

307

from functools import wraps

308

309

def auto_profile(linenos=True, annotate_cfuncs=False):

310

def decorator(func):

311

@wraps(func)

312

def wrapper(*args, **kwargs):

313

profiler = nvtx.Profile(linenos=linenos, annotate_cfuncs=annotate_cfuncs)

314

profiler.enable()

315

try:

316

return func(*args, **kwargs)

317

finally:

318

profiler.disable()

319

return wrapper

320

return decorator

321

322

# Usage

323

@auto_profile(linenos=True, annotate_cfuncs=True)

324

def critical_function():

325

# All nested function calls will be automatically annotated

326

helper_function_1()

327

helper_function_2()

328

return results

329

```

330

331

## Performance Considerations

332

333

### Overhead

334

335

- **Python Functions**: Minimal overhead for Python function annotation

336

- **C Functions**: Higher overhead when `annotate_cfuncs=True` due to additional hook processing

337

- **Line Numbers**: Slight additional overhead when `linenos=True` for file path resolution

338

- **Frequency**: Very high-frequency function calls may benefit from selective profiling

339

340

### Optimization Strategies

341

342

```python

343

import nvtx

344

345

# Strategy 1: Profile specific modules only

346

def selective_profiling():

347

profiler = nvtx.Profile(annotate_cfuncs=False) # Skip C functions

348

profiler.enable()

349

350

# Only profile specific parts of application

351

critical_business_logic()

352

353

profiler.disable()

354

355

# Strategy 2: Use sampling for long-running applications

356

import time

357

358

def sampled_profiling():

359

profiler = nvtx.Profile()

360

361

for iteration in range(1000):

362

if iteration % 100 == 0: # Profile every 100th iteration

363

profiler.enable()

364

process_iteration(iteration)

365

profiler.disable()

366

else:

367

process_iteration(iteration)

368

```

369

370

### Memory Usage

371

372

- **String Registration**: Function names are registered as NVTX strings for efficiency

373

- **Thread Locals**: Each thread maintains separate profiling state

374

- **Cleanup**: Profiler automatically cleans up when disabled

375

376

## Error Handling

377

378

- **Exception Safety**: Profiling continues even when annotated functions raise exceptions

379

- **Thread Safety**: Multiple threads can use profiling simultaneously

380

- **Nested Enable/Disable**: Multiple enable() calls are safe; last disable() stops profiling

381

- **NVTX Disabled**: All profiling becomes no-op when NVTX_DISABLE environment variable is set

382

383

## Limitations

384

385

- **Recursive Functions**: Deep recursion may create very nested annotation hierarchies

386

- **Generator Functions**: Generator yields/resumes create separate annotation ranges

387

- **Async Functions**: Each await point creates separate ranges for async function calls

388

- **Import Time**: Functions called during module import are profiled if profiler is already enabled