t1c-bridge 0.0.1
PyTorch Bridge and Runtime for T1C-IR Graphs
Requires Python: >=3.10
Keywords: neuromorphic, spiking-neural-networks, snn, pytorch, deep-learning, machine-learning, hardware-acceleration, intermediate-representation

<div align="center" style="background-color: #08081e; width: 100%; padding: 0;">
  <img alt="T1C Logo" src="https://www.type1compute.com/images/t1c-logo-light.png" style="max-width: 200px; height: auto; display: block;">
</div>

<br>

# T1C-Bridge - PyTorch Bridge for T1C-IR



PyTorch helpers for the [T1C-IR (Type 1 Compute Intermediate Representation)](git@github.com:type1compute/t1cir.git). This package enables PyTorch-based libraries to translate models to and from T1C-IR, providing export, import, and execution capabilities for neuromorphic neural networks.

T1C-Bridge serves as the bridge between PyTorch models and T1C-IR graphs, enabling seamless model portability and deployment to Type 1 Compute hardware.

> Read more about T1C-IR in our [documentation](https://type1compute.github.io/docs/intro)

## Installation

```bash
uv add t1c-bridge@git+ssh://git@github.com:type1compute/t1cir.git
```

Or with pip:

```bash
pip install t1c-bridge
```

## Usage

T1C-Bridge provides two main functions `to_ir` and `ir_to_torch` that map PyTorch models to T1C-IR graphs and vice versa.

### Translating from PyTorch to T1C-IR

T1C-Bridge automatically traces through your PyTorch model and converts each module to the corresponding T1C-IR primitive. You can provide custom converters for unsupported modules via the `custom_map` argument.

```python
import torch
import torch.nn as nn
from t1c import bridge, ir

# Define your model
model = nn.Sequential(
    nn.Linear(784, 128),
    nn.Linear(128, 10)
)

# Export to T1C-IR
graph = bridge.to_ir(model, torch.randn(1, 784))

# Save to file
ir.write("model.t1c", graph)
```

For custom modules, provide a mapping dictionary:

```python
# Define custom PyTorch -> T1C-IR mapping
from t1c import bridge, ir
custom_map = {}
def _extract_custom_module(module: MyCustomModule) -> ir.Node:
    # Convert your custom module to a T1C-IR node
    return ir.Affine(weight=module.weight, bias=module.bias, ...)
custom_map[MyCustomModule] = _extract_custom_module

# Export with custom mapping
graph = bridge.to_ir(model, sample, custom_map=custom_map)
```

### Translating from T1C-IR to PyTorch

T1C-Bridge automatically creates PyTorch modules from T1C-IR nodes. The `ir_to_torch` function combines import with execution, returning an executable `GraphExecutor` module.

```python
from t1c import bridge
import torch

# Load and create executable module
executor = bridge.ir_to_torch("model.t1c")

# Execute
output = executor(input_tensor)
```

For stateful models (SNNs), use `return_state=True`:

```python
# Load with state management
executor = bridge.ir_to_torch("model.t1c", return_state=True)

# Execute with state
state = None
for t in range(100):
    output, state = executor(input_tensor, state)
```

You can also provide custom node converters:

```python
from t1c import bridge, ir
def custom_node_map(node: ir.Node) -> Optional[torch.nn.Module]:
    if isinstance(node, MyCustomNode):
        return MyCustomModule(...)
    return None  # Falls back to default converter

executor = bridge.ir_to_torch(graph, node_map=custom_node_map)
```

## Quick Start

### Basic Export and Execute

```python
import torch
import torch.nn as nn
from t1c import bridge, ir

# Your model
model = nn.Sequential(nn.Linear(784, 128), nn.Linear(128, 10))
sample = torch.randn(1, 784)

# Export to T1C-IR
graph = bridge.to_ir(model, sample)

# Save to file
ir.write("model.t1c", graph)

# Load and execute
executor = bridge.ir_to_torch("model.t1c")
output = executor(sample)
```

### Spiking Neural Network

```python
import torch
import torch.nn as nn
import snntorch as snn
from t1c import bridge

# Define SNN
model = nn.Sequential(
    nn.Linear(784, 128),
    snn.Leaky(beta=0.9, init_hidden=True, output=True),
    nn.Linear(128, 10),
    snn.Leaky(beta=0.9, init_hidden=True, output=True),
)

# Export
graph = bridge.to_ir(model, torch.randn(1, 784))

# Execute with state
executor = bridge.ir_to_torch(graph, return_state=True)
state = None
for t in range(100):
    output, state = executor(input_tensor, state)
```

## Supported Modules

T1C-Bridge automatically converts the following PyTorch modules to T1C-IR:

| PyTorch Module | T1C-IR Node | Notes |
|----------------|------------|-------|
| `nn.Linear` | `Affine` or `SpikingAffine` | Use `spiking=True` for hardware-optimized version |
| `nn.Conv2d` | `Conv2d` | Full 2D convolution support |
| `nn.Flatten` | `Flatten` | Tensor flattening |
| `nn.MaxPool2d` | `MaxPool2d` | 2D max pooling |
| `nn.Identity` | `Skip` | Skip/residual connections |
| `snn.Leaky` | `LIF` | snnTorch LIF neuron |

## For Hardware Teams

T1C-Bridge is for **validation only**. The execution runtime is a PyTorch simulation of what the hardware will do. Use it to verify your IR graph produces correct outputs before deploying to actual hardware.

The `GraphExecutor` handles:
- Topological sorting of graph nodes
- State management for stateful modules (LIF neurons)
- Skip connections and residual paths
- Multiple input/output handling

## Development

From the repo root, install in editable mode (requires [t1c-ir](https://gitlab.com/cvision-dev/type1compute/t1cir) installed first):

```bash
uv pip install -e .
# or: pip install -e .
pytest tests/ -v
```

If you see `AttributeError: module 't1c.bridge' has no attribute 'to_ir'`, you are likely using an old install. Uninstall any legacy `t1ctorch` and reinstall this package in editable mode:

```bash
pip uninstall t1ctorch t1c-bridge 2>/dev/null; uv pip install -e .
```

## Documentation

For more information, visit the [T1C-IR documentation](https://type1compute.github.io/docs/intro).