Skip to content

Migration

kfactory 3.0

What's New in 3.0

New Features

  • Routing constraints & path-length matching — the new PathLengthMatch constraint API enables length-matched bundle routing directly. See Path-Length Matching.
  • Asymmetrical cross-sectionsAsymmetricCrossSection allows non-symmetric waveguide profiles. See Cross-Sections.
  • Netlist extraction as a separate package — netlist generation now lives in kfnetlist, a standalone package. See Netlist & I/O.

Improved Features

  • Schematics — tighter pin integration, virtual schematic connections, and the @kcl.routing_strategy registry for schematic-driven routing. See Schematics Overview.
  • Bundle routing — expanded documentation and tutorial. See Bundle Routing Tutorial.

Infrastructure

  • Python 3.12+ is now required (up from 3.11).
  • Complete documentation overhaul — new zensical-based build, restructured navigation, and auto-generated API reference.

Migrating from 2.5.x

The sections below cover breaking changes and how to update your code.

Change Summary

Area What changed Before (2.x) After (3.0)
Module virtual.utils moved kfactory.factories.virtual.utils kfactory.factories.utils
Routing route_L / route_elec removed route_elec(cell, p1, p2) route_bundle(cell, [p1], [p2])
Routing routing.optical.route removed route(cell, p1, p2, ...) route_bundle(cell, [p1], [p2], ...)
Routing place90 deprecated place90(cell, p1, p2, pts) place_manhattan(cell, p1, p2, pts)
Parameters start_straights deprecated start_straights=100 starts=100
Parameters end_straights deprecated end_straights=100 ends=100
Schematics Routing via KCLayout registry @kcl.routing_strategy + schematic.add_route(...)

Module Reorganization

  • kfactory.factories.virtual.utils has been moved to kfactory.factories.utils to unify it with other factory utilities.
# Before (2.x)
from kfactory.factories.virtual.utils import extrude_backbone, extrude_backbone_dynamic

# After (3.0)
from kfactory.factories.utils import extrude_backbone, extrude_backbone_dynamic

Removed Routing Functions

The following routing functions have been removed. Use route_bundle instead.

  • routing.electrical.route_L — removed
  • routing.electrical.route_elec — removed
  • routing.optical.route — removed
# Before (2.x) — electrical
from kfactory.routing.electrical import route_L, route_elec
route_elec(cell, port1, port2, ...)

# After (3.0) — electrical
from kfactory.routing.electrical import route_bundle
route_bundle(cell, start_ports=[port1], end_ports=[port2], separation=..., ...)

# Before (2.x) — optical
from kfactory.routing.optical import route
route(cell, port1, port2, straight_factory=..., bend90_cell=..., ...)

# After (3.0) — optical
from kfactory.routing.optical import route_bundle
route_bundle(
    cell,
    start_ports=[port1],
    end_ports=[port2],
    separation=...,
    straight_factory=...,
    bend90_cell=...,
)

Deprecated Parameters in route_bundle

In both routing.optical.route_bundle and routing.electrical.route_bundle:

  • start_straights is deprecated — use starts instead
  • end_straights is deprecated — use ends instead
# Before (2.x)
route_bundle(cell, start_ports, end_ports, separation=..., start_straights=100, end_straights=100, ...)

# After (3.0)
route_bundle(cell, start_ports, end_ports, separation=..., starts=100, ends=100, ...)

Deprecated place90

routing.optical.place90 is deprecated. Use place_manhattan instead.

# Before (2.x)
from kfactory.routing.optical import place90
place90(cell, p1, p2, pts, ...)

# After (3.0)
from kfactory.routing.optical import place_manhattan
place_manhattan(cell, p1, p2, pts, ...)

Routing Interface for Schematics

In order to enable routing in schematics, routing strategy functions must be registered on the KCLayout instance. Registered strategies can then be referenced by name in Schematic.add_route.

Registering a Routing Strategy

Use the @kcl.routing_strategy decorator or assign directly to kcl.routing_strategies:

import kfactory as kf

kcl = kf.KCLayout("MY_PDK")

@kcl.routing_strategy
def route_bundle(cell, start_ports, end_ports, **kwargs):
    ...

# Or register directly:
kcl.routing_strategies["my_custom_route"] = my_routing_function
Using Routes in a Schematic

The Schematic.add_route method creates a route bundle connecting start and end ports using a named routing strategy:

schematic = kf.Schematic(kcl=kcl)

# Add instances
mmi1 = schematic.add_instance("mmi1", mmi_factory, settings={...})
mmi2 = schematic.add_instance("mmi2", mmi_factory, settings={...})

# Place instances
mmi1.place(...)
mmi2.place(...)

# Route between instances
schematic.add_route(
    name="optical_route",
    start_ports=[mmi1.ports["o2"]],
    end_ports=[mmi2.ports["o1"]],
    routing_strategy="route_bundle",
    separation=10_000,
    # additional **settings are forwarded to the routing strategy function
)

# Build the cell
cell = schematic.create_cell(output_type=kf.KCell)

When create_cell is called, the schematic looks up the routing strategy by name from kcl.routing_strategies (or from the routing_strategies argument to create_cell) and calls it with the resolved ports and settings.


kfactory 2.0

kfactory 2.0 was a full rewrite of the library on top of KLayout, replacing the earlier 1.x codebase. There is no supported migration path from 1.x to 2.0.