CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cython

Python compiler that transforms Python code into C/C++ extensions for high-performance computing.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

debugging-profiling.mddocs/

Debugging and Profiling

Cython provides comprehensive debugging and profiling capabilities for analyzing and optimizing Cython code. These tools enable source-level debugging, performance analysis, and identification of bottlenecks in compiled extensions.

Capabilities

Cython Debugger (cygdb)

GDB-based debugger that enables source-level debugging of both Python and Cython code.

cygdb [options] [path-to-project-directory] [gdb-args...]

Options:
  --gdb-executable GDB         GDB executable to use (default: gdb)
  --verbose                    Verbose output
  -h, --help                   Show help

Requirements:
  - cython_debug/ directory with debug information
  - Python executable compiled with debug symbols
  - GDB with Python support

Debug Build Configuration

Compiler directives and build options for debugging support.

# Compilation options for debugging
compiler_directives = {
    'linetrace': True,           # Enable line tracing
    'binding': True,             # Enable function binding
    'profile': True,             # Enable profiling hooks
    'emit_code_comments': True,  # Add code comments in C output
}

# Build with debugging information
cythonize("module.pyx", gdb_debug=True, **compiler_directives)

Profiling Integration

Integration with Python profiling tools and performance analysis.

@cython.profile(True)
def profiled_function():
    """Function with profiling enabled."""
    pass

@cython.linetrace(True)
@cython.binding(True)
def traced_function():
    """Function with line tracing for detailed profiling."""
    pass

Annotation and Performance Analysis

HTML annotation generation for performance analysis and optimization.

# Generate annotated HTML output
cython -a source.pyx                    # Basic annotation
cython -a --annotate-coverage coverage.xml source.pyx  # With coverage data

# Via cythonize
cythonize --annotate source.pyx

Usage Examples

Setting Up Debug Environment

# setup.py for debug builds
from setuptools import setup
from Cython.Build import cythonize

debug_args = {
    'gdb_debug': True,
    'compiler_directives': {
        'linetrace': True,
        'binding': True,
        'profile': True,
        'emit_code_comments': True,
        'language_level': 3,
    }
}

setup(
    ext_modules=cythonize("src/*.pyx", **debug_args),
    zip_safe=False,
)

Basic Debugging Session

# 1. Build with debug information
python setup.py build_ext --inplace --debug

# 2. Start debugging session
cygdb

# 3. In GDB, set breakpoints and run
(gdb) cy break module.pyx:42
(gdb) cy run
(gdb) cy step
(gdb) cy print variable_name
(gdb) cy list

Advanced Debugging Commands

# Cython-specific GDB commands
(gdb) cy break my_module.fast_function  # Break at Cython function
(gdb) cy step                           # Step through Cython code
(gdb) cy next                           # Next line in Cython code
(gdb) cy print cython_var               # Print Cython variable
(gdb) cy print local_vars               # Print all local variables
(gdb) cy list                           # List current Cython source
(gdb) cy bt                             # Cython backtrace
(gdb) cy up                             # Move up Cython call stack
(gdb) cy down                           # Move down Cython call stack

Debugging with IPython

%load_ext cython

%%cython --gdb
def debug_function(int n):
    cdef int i, total = 0
    
    for i in range(n):
        total += i * i  # Breakpoint can be set here
    
    return total

# Function is compiled with debug information
result = debug_function(100)

Profiling with cProfile

import cProfile
import pstats

# Enable profiling in Cython
%%cython -X profile=True -X linetrace=True -X binding=True
def slow_function(int n):
    cdef int i, result = 0
    for i in range(n):
        result += expensive_operation(i)
    return result

def expensive_operation(int x):
    return x * x * x

# Profile the function
cProfile.run('slow_function(10000)', 'profile_stats')

# Analyze results
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative')
stats.print_stats()

Line-by-Line Profiling with line_profiler

# Install: pip install line_profiler

%load_ext line_profiler

%%cython -X linetrace=True -X binding=True
@profile
def line_profiled_function(double[:] arr):
    cdef int i
    cdef double total = 0.0
    cdef int n = arr.shape[0]
    
    for i in range(n):           # This line will be profiled
        total += arr[i] * 2.0    # This line will be profiled
    
    return total

# Run with line profiler
%lprun -f line_profiled_function line_profiled_function(data)

Memory Profiling

# Install: pip install memory_profiler

%load_ext memory_profiler

%%cython -X profile=True
@profile
def memory_intensive_function(int n):
    cdef list data = []
    cdef int i
    
    for i in range(n):
        data.append(i * i)  # Memory allocation tracked
    
    return sum(data)

# Profile memory usage
%mprun -f memory_intensive_function memory_intensive_function(100000)

Annotation Analysis

# After running: cython -a my_module.pyx
# Open my_module.html in browser

%%cython -a
import numpy as np
cimport numpy as cnp

def analyze_performance(cnp.double_t[:] data):
    """Function to analyze with annotations."""
    cdef int i
    cdef double total = 0.0
    cdef int n = data.shape[0]
    
    # Yellow lines indicate Python interaction overhead
    # White lines indicate pure C code
    for i in range(n):
        total += data[i]  # Should be white (fast)
    
    return total  # May be yellow (Python object creation)

Coverage-Based Annotation

# 1. Run tests with coverage
python -m pytest --cov=my_module --cov-report=xml

# 2. Generate annotated output with coverage data
cython -a --annotate-coverage coverage.xml my_module.pyx

# 3. View coverage-annotated HTML
# Green highlighting shows well-tested code
# Red highlighting shows untested code paths

Debugging C Extensions

# For debugging at the C level
%%cython --gdb -X emit_code_comments=True
def c_level_debug(int x):
    cdef int* ptr = <int*>malloc(sizeof(int) * 10)
    
    if ptr == NULL:
        raise MemoryError("Failed to allocate memory")
    
    ptr[0] = x  # Can inspect C-level memory in GDB
    
    cdef int result = ptr[0] * 2
    free(ptr)
    
    return result

Performance Benchmarking

import timeit

%%cython -X boundscheck=False -X wraparound=False -X cdivision=True
def optimized_function(double[:] data):
    cdef int i
    cdef double total = 0.0
    cdef int n = data.shape[0]
    
    for i in range(n):
        total += data[i]
    
    return total

# Benchmark against Python version
import numpy as np
data = np.random.random(1000000)

cython_time = timeit.timeit(
    lambda: optimized_function(data),
    number=100
)

python_time = timeit.timeit(
    lambda: sum(data),
    number=100
)

print(f"Cython: {cython_time:.4f}s")
print(f"Python: {python_time:.4f}s")
print(f"Speedup: {python_time/cython_time:.2f}x")

Debugging Build Issues

# Verbose compilation for debugging build problems
cython --verbose my_module.pyx

# Generate intermediate C code for inspection
cython --output-file my_module.c my_module.pyx

# Check generated C code
less my_module.c

# Debug compilation errors
cython -Werror my_module.pyx  # Treat warnings as errors

Custom GDB Configuration

# Create .cygdbinit file for custom GDB commands
echo "set print pretty on" > .cygdbinit
echo "set pagination off" >> .cygdbinit
echo "define cy-locals" >> .cygdbinit
echo "  cy print local_vars" >> .cygdbinit
echo "end" >> .cygdbinit

# Use custom configuration
cygdb --gdb-executable gdb-multiarch

Integration with IDEs

# VS Code configuration for Cython debugging
# In .vscode/launch.json:
{
    "name": "Python: Cython Debug",
    "type": "python",
    "request": "launch",
    "program": "${workspaceFolder}/test_script.py",
    "console": "integratedTerminal",
    "justMyCode": false,
    "env": {
        "CYTHON_DEBUG": "1"
    }
}

The debugging and profiling capabilities in Cython provide comprehensive tools for analyzing performance bottlenecks, identifying optimization opportunities, and debugging both Python and C-level code in compiled extensions.

Install with Tessl CLI

npx tessl i tessl/pypi-cython

docs

build-system.md

c-cpp-interoperability.md

command-line-tools.md

core-language.md

debugging-profiling.md

import-system.md

index.md

ipython-integration.md

tile.json