CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-f90wrap

Fortran to Python interface generator with derived type support for automated wrapper generation

Pending
Overview
Eval results
Files

runtime.mddocs/

Runtime Support

Runtime classes and utilities that provide the foundation for generated wrapper code, handling derived type management, Fortran-Python interoperability, and memory management for f90wrap-generated Python extensions.

Capabilities

Fortran Type Base Classes

Core base classes that generated wrapper code inherits from to provide Fortran derived type functionality in Python.

class FortranDerivedType(object):
    """
    Base class for all Fortran derived types in Python.
    
    Provides memory management, copying, and handle-based access
    to Fortran derived type instances.
    """
    
    @classmethod
    def from_handle(cls, handle, alloc=False):
        """
        Create Python object from Fortran type handle.
        
        Parameters:
        - handle: int, opaque handle to Fortran type instance
        - alloc: bool, whether to allocate new memory
        
        Returns:
        New instance of the derived type class
        """
    
    def __copy__(self):
        """Create shallow copy of derived type instance."""
    
    def copy(self):
        """Create deep copy of derived type instance."""
class FortranDerivedTypeArray(object):
    """
    Array container for Fortran derived types.
    
    Provides Python sequence interface for arrays of Fortran derived types
    with proper memory management and element access.
    """
    
    def __init__(self, parent, getfunc, setfunc, lenfunc, doc, arraytype):
        """
        Initialize derived type array.
        
        Parameters:
        - parent: parent object containing the array
        - getfunc: function to get array element by index
        - setfunc: function to set array element by index  
        - lenfunc: function to get array length
        - doc: documentation string
        - arraytype: type of array elements
        """
    
    def iterindices(self):
        """Iterate over valid array indices."""
    
    def items(self):
        """Iterate over (index, value) pairs."""
    
    def __iter__(self):
        """Iterator protocol for array elements."""
    
    def __len__(self):
        """Get array length."""
    
    def __getitem__(self, i):
        """Get array element by index."""
    
    def __setitem__(self, i, value):
        """Set array element by index."""
    
    def __copy__(self):
        """Create shallow copy of array."""
    
    def copy(self):
        """Create deep copy of array."""
class FortranModule(object):
    """
    Base class for Fortran modules in Python.
    
    Provides namespace and organization for module-level procedures,
    types, and parameters.
    """

Type Registration and Lookup

System for registering and looking up Fortran type classes at runtime.

class register_class(object):
    """
    Decorator for registering Fortran type classes.
    
    Parameters:
    - cls_name: str, name of the class to register
    
    Returns:
    The registered class (for use as decorator)
    """
    
    def __init__(self, cls_name):
        """Initialize the decorator with class name."""
    
    def __call__(self, cls):
        """Register the class and return it."""

def lookup_class(cls_name):
    """
    Look up registered Fortran type class by name.
    
    Parameters:
    - cls_name: str, name of the class to look up
    
    Returns:
    The registered class
    
    Raises:
    KeyError if class name not found
    """

Memory Management Constants

Runtime constants for Fortran type handle management.

sizeof_fortran_t = ...  # Size in bytes of Fortran type handles
empty_handle = ...      # Empty/null type handle value  
empty_type = ...        # Empty type instance for initialization

Singleton Metaclass

Metaclass for implementing singleton pattern in Fortran module classes.

class Singleton(type):
    """Metaclass for creating singleton classes."""

Usage Examples

Using Generated Wrapper Classes

# Generated wrapper classes inherit from runtime base classes
from myfortrancode import MyType, MyModule

# Create instance using constructor
obj = MyType()

# Create from existing handle (advanced usage)
obj2 = MyType.from_handle(existing_handle)

# Copy instances
obj_copy = obj.copy()
obj_shallow = obj.__copy__()

# Access module-level functionality
result = MyModule.some_function(args)

Working with Derived Type Arrays

# Generated code creates arrays using FortranDerivedTypeArray
from myfortrancode import ContainerType

container = ContainerType()

# Access array elements (array property automatically created)
first_item = container.items[0] 
container.items[1] = new_item

# Iterate over array
for item in container.items:
    process(item)

# Get array length
count = len(container.items)

# Iterate with indices
for i, item in container.items.items():
    print(f"Item {i}: {item}")

Type Registration (Advanced)

from f90wrap.runtime import register_class, lookup_class

# Register custom type class
@register_class
class MyCustomType(FortranDerivedType):
    # Custom implementation
    pass

# Look up registered class
cls = lookup_class('MyCustomType')
if cls:
    instance = cls()

Custom Derived Type Implementation

from f90wrap.runtime import FortranDerivedType

class CustomFortranType(FortranDerivedType):
    def __init__(self, handle=None):
        if handle is None:
            # Call Fortran constructor
            self._handle = _mymodule.create_custom_type()
        else:
            self._handle = handle
    
    def __del__(self):
        # Ensure cleanup
        if hasattr(self, '_handle'):
            _mymodule.destroy_custom_type(self._handle)
    
    @property
    def value(self):
        """Access Fortran component through getter."""
        return _mymodule.get_custom_type_value(self._handle)
    
    @value.setter
    def value(self, val):
        """Set Fortran component through setter."""
        _mymodule.set_custom_type_value(self._handle, val)

Memory Management

Automatic Memory Management

The runtime classes provide automatic memory management for Fortran derived types:

  • Construction: Automatic allocation when Python objects are created
  • Destruction: Automatic cleanup when Python objects are garbage collected
  • Copying: Deep and shallow copy support with proper memory handling
  • Reference Counting: Integration with Python's reference counting system

Handle-Based Access

Fortran derived types are accessed through opaque handles:

  • Type Safety: Handles prevent direct memory access, ensuring type safety
  • Efficiency: Minimal overhead for Fortran-Python data transfer
  • Portability: Handle system works across different Fortran compilers
  • Debugging: Handle validation helps catch memory errors

Array Memory Management

Special handling for arrays of derived types:

  • Lazy Loading: Array elements loaded on demand to minimize memory usage
  • Copy Semantics: Proper deep/shallow copying for array elements
  • Index Validation: Bounds checking prevents buffer overflows
  • Memory Sharing: Efficient sharing of data between Python and Fortran

Error Handling

Exception Integration

Runtime classes integrate with Python's exception system:

try:
    obj = MyType()
    obj.risky_operation()
except RuntimeError as e:
    # Fortran runtime errors propagated as RuntimeError
    print(f"Fortran error: {e}")

Memory Error Detection

  • Handle Validation: Invalid handles detected and reported
  • Double-Free Protection: Prevention of multiple deallocations
  • Leak Detection: Warning for objects not properly cleaned up
  • Corruption Detection: Basic detection of memory corruption

Thread Safety

Thread-Safe Operations

The runtime system provides thread safety for:

  • Type Registration: Thread-safe class registration and lookup
  • Handle Management: Atomic handle operations where possible
  • Reference Counting: Thread-safe reference counting integration

Limitations

  • Fortran Thread Safety: Depends on underlying Fortran code thread safety
  • Global State: Some global state may require external synchronization
  • Compiler Specific: Thread safety varies by Fortran compiler

Performance Considerations

Optimization Features

  • Minimal Overhead: Thin wrapper layer with minimal Python overhead
  • Efficient Data Transfer: Direct memory access where possible
  • Lazy Evaluation: Deferred operations to minimize unnecessary computation
  • Memory Pooling: Reuse of frequently allocated objects

Performance Tips

  • Batch Operations: Group related operations to minimize call overhead
  • Memory Reuse: Reuse objects instead of frequent allocation/deallocation
  • Array Access: Use efficient iteration patterns for array processing
  • Profile Guided: Use profiling to identify performance bottlenecks

Integration with NumPy

Array Integration

The runtime classes integrate closely with NumPy:

  • Array Views: Efficient views of Fortran arrays as NumPy arrays
  • Type Mapping: Automatic mapping between Fortran and NumPy types
  • Memory Sharing: Zero-copy sharing where memory layouts are compatible
  • Broadcasting: Support for NumPy broadcasting where applicable

Usage with NumPy

import numpy as np
from myfortrancode import MyType

obj = MyType()

# Get NumPy view of Fortran array (if supported)
arr = obj.get_array_view()
print(f"Array shape: {arr.shape}, dtype: {arr.dtype}")

# Modify through NumPy (changes reflected in Fortran)
arr[0] = 42

# Create from NumPy array
obj.set_data_from_numpy(np.array([1, 2, 3, 4]))

Install with Tessl CLI

npx tessl i tessl/pypi-f90wrap

docs

code-generation.md

command-line.md

index.md

parsing-ast.md

runtime.md

transformation.md

type-system.md

tile.json