gdsfactory can build a full layout from a YAML netlist that describes instances, placements, and routing links. To use a DoRoutes router as the link strategy, register it under a name on the active PDK:

PDK.routing_strategies["doroute_astar"] = add_bundle_astar

After that, any route in the YAML with routing_strategy: doroute_astar will be routed by add_bundle_astar with the arguments under settings:. This lets you describe an entire circuit declaratively and rebuild it from text.

This is optical routing: bends are bend_euler at the PDK minimum radius, and the obstacle layer is WG.

Imports

import gdsfactory as gf
from gdsfactory.gpdk import PDK

PDK.activate()

from doroutes import add_bundle_astar, util

PDK.routing_strategies["doroute_astar"] = add_bundle_astar

Two MMI Splitters Linked by a Single-Wire Bundle

The simplest case: two mmi1x2 Y-splitters (one input, two outputs each) and one routing link, mmi1.o3 → mmi2.o1. The same add_bundle_astar call applies — a one-wire "bundle" is a fine starting point to confirm the strategy is registered and the YAML wiring is what you expect, before scaling up to a real bundle.

yaml = """
instances:
  mmi1:
    component: mmi1x2
    settings: {}
  mmi2:
    component: mmi1x2
    settings: {}
connections: {}
routes:
  bundle:
    links:
      mmi1,o3: mmi2,o1
    routing_strategy: doroute_astar
    settings:
        spacing: 1.0
        bend:
            component: bend_euler
            settings:
                radius: 5
        straight: straight
        layers:
            - WG
nets: []
ports:
  o1: mmi1,o1
  o2: mmi2,o2
  o3: mmi2,o3
placements:
  mmi1:
    mirror: 0
    rotation: 0
    x: 0
    y: 0
  mmi2:
    dx: 100
    dy: 100
    mirror: 0
    rotation: 0
    x: mmi1,o2
    y: 0
"""

Build the Layout

c = gf.read.from_yaml(yaml)
util.show_cell(c)
API key for organization 'DoPlayDo' found.

Two-Wire Bundle Across a Crossing

This second netlist places four straight stubs on a 2×2 grid and asks DoRoutes to bundle-route s3-4.o1 → s1-2.o2. The s3-4 / s1-2 notation is gdsfactory shorthand for a port range — handy when you don't want to enumerate every port name. The bundle has to cross the layout from right to left while the obstacle straights sit in the middle, so A* finds a route that clears them.

yaml2 = """
instances:
  s1:
    component: straight
    settings: {}
  s2:
    component: straight
    settings: {}
  s3:
    component: straight
    settings: {}
  s4:
    component: straight
    settings: {}
connections: {}
routes:
  my_bundle:
    links:
      s3-4,o1: s1-2,o2
    routing_strategy: 'doroute_astar'
    settings:
        spacing: 1.0
        bend:
            component: bend_euler
            settings:
                radius: 5
        straight: straight
        layers:
            - WG
nets: []
ports: {}
placements:
  s1:
    y: 100
  s2:
    y: -100
  s3:
    x: 200
    y: 100
  s4:
    x: 200
    y: -100
"""
c = gf.read.from_yaml(yaml2)
c.show()
util.show_cell(c)
API key for organization 'DoPlayDo' found.

Next steps