Source code for kosmos.topology.predefined_quantum.builders

from abc import ABC, abstractmethod

from kosmos.topology.link import ClassicalLink, LinkId, QuantumLink
from kosmos.topology.net import Network
from kosmos.topology.node import NodeId, NodeRole, QuantumNode

DEFAULT_COHERENCE_TIME: float = 1.0

QUANTUM_LINK_DEFAULT_DISTANCE: float = 10.0
QUANTUM_LINK_DEFAULT_ATTENUATION: float = 0.0
QUANTUM_LINK_DEFAULT_SIGNAL_SPEED: float = 2e-4
QUANTUM_LINK_DEFAULT_REPETITION_RATE: float = 1e6

CLASSICAL_LINK_DEFAULT_DISTANCE: float = 10.0
CLASSICAL_LINK_DEFAULT_ATTENUATION: float = 2e-4
CLASSICAL_LINK_DEFAULT_SIGNAL_SPEED: float = 2e-4
CLASSICAL_LINK_DEFAULT_BANDWIDTH: float = 10e9


def _default_node(i: int, role: NodeRole, num_qubits: int) -> QuantumNode:
    """Create a default quantum node for predefined quantum topologies.

    Args:
        i (int): Index to convert to a NodeId.
        role (NodeRole): Assigned role of the node.
        num_qubits (int): Number of qubits for the node.

    Returns:
        QuantumNode: Quantum node instance.

    """
    return QuantumNode(
        id=NodeId(str(i)),
        roles=[role],
        num_qubits=num_qubits,
        coherence_time=DEFAULT_COHERENCE_TIME,
    )


def _default_quantum_link(src: QuantumNode, dst: QuantumNode) -> QuantumLink:
    """Create a default quantum link for predefined quantum topologies.

    Args:
        src (QuantumNode): Source node.
        dst (QuantumNode): Destination node.

    Returns:
        QuantumLink: Quantum link instance.

    """
    return QuantumLink(
        id=LinkId(f"Q_{src.id.value}-{dst.id.value}"),
        src=src,
        dst=dst,
        distance=QUANTUM_LINK_DEFAULT_DISTANCE,
        attenuation=QUANTUM_LINK_DEFAULT_ATTENUATION,
        signal_speed=QUANTUM_LINK_DEFAULT_SIGNAL_SPEED,
        repetition_rate=QUANTUM_LINK_DEFAULT_REPETITION_RATE,
    )


def _default_classical_link(src: QuantumNode, dst: QuantumNode) -> ClassicalLink:
    """Create a default classical link for predefined quantum topologies.

    Args:
        src (QuantumNode): Source node.
        dst (QuantumNode): Destination node.

    Returns:
        ClassicalLink: Classical link instance.

    """
    return ClassicalLink(
        id=LinkId(f"C_{src.id.value}-{dst.id.value}"),
        src=src,
        dst=dst,
        distance=CLASSICAL_LINK_DEFAULT_DISTANCE,
        attenuation=CLASSICAL_LINK_DEFAULT_ATTENUATION,
        signal_speed=CLASSICAL_LINK_DEFAULT_SIGNAL_SPEED,
        bandwidth=CLASSICAL_LINK_DEFAULT_BANDWIDTH,
    )


[docs] class PredefinedQuantumTopology(ABC): """Abstract base class for predefined quantum topologies."""
[docs] @abstractmethod def build(self) -> Network: """Construct the topology and return a Network instance. Returns: Network: Constructed network instance. """
[docs] class LineTopology(PredefinedQuantumTopology): """Line quantum topology. Attributes: num_nodes (int): Number of nodes in the line. num_qubits (int): Number of qubits per node. """ def __init__(self, num_nodes: int, num_qubits: int) -> None: """Initialize the line quantum topology. Args: num_nodes (int): Number of nodes (must be >= 2). num_qubits (int): Number of qubits for the node. """ min_num_nodes = 2 if num_nodes < min_num_nodes: msg = "Line topology requires at least 2 nodes." raise ValueError(msg) self.num_nodes = num_nodes self.num_qubits = num_qubits
[docs] def build(self) -> Network: """Build the line quantum topology. Returns: Network: Network with nodes connected in a linear chain. """ network = Network() # endpoints = END_USER, inner nodes = REPEATER nodes: list[QuantumNode] = [] for i in range(self.num_nodes): role = NodeRole.END_USER if i == 0 or i == self.num_nodes - 1 else NodeRole.REPEATER node = _default_node(i, role, self.num_qubits) network.add_node(node) nodes.append(node) # Create links between consecutive nodes for i in range(self.num_nodes - 1): q_link = _default_quantum_link(nodes[i], nodes[i + 1]) c_link = _default_classical_link(nodes[i], nodes[i + 1]) network.add_link(q_link) network.add_link(c_link) return network
[docs] class RingTopology(PredefinedQuantumTopology): """Ring quantum topology. Attributes: num_nodes (int): Number of nodes in the ring. num_qubits (int): Number of qubits per node. """ def __init__(self, num_nodes: int, num_qubits: int) -> None: """Initialize the ring quantum topology. Args: num_nodes (int): Number of nodes (must be >= 3). num_qubits (int): Number of qubits for the node. """ min_num_nodes = 3 if num_nodes < min_num_nodes: msg = "Ring topology requires at least 3 nodes." raise ValueError(msg) self.num_nodes = num_nodes self.num_qubits = num_qubits
[docs] def build(self) -> Network: """Build the ring quantum topology. Returns: Network: Network forming a closed cycle. """ network = Network() # All nodes in a ring are ROUTERs. nodes: list = [] for i in range(self.num_nodes): node = _default_node(i, NodeRole.ROUTER, self.num_qubits) network.add_node(node) nodes.append(node) for i in range(self.num_nodes): src = nodes[i] dst = nodes[(i + 1) % self.num_nodes] q_link = _default_quantum_link(src, dst) c_link = _default_classical_link(src, dst) network.add_link(q_link) network.add_link(c_link) return network
[docs] class StarTopology(PredefinedQuantumTopology): """Star quantum topology. Attributes: num_nodes (int): Number of nodes in the star (including center). num_qubits (int): Number of qubits per node. """ def __init__(self, num_nodes: int, num_qubits: int) -> None: """Initialize the star quantum topology. Args: num_nodes (int): Number of nodes (must be >= 2). num_qubits (int): Number of qubits for the node. """ min_num_nodes = 2 if num_nodes < min_num_nodes: msg = "Star topology requires at least 2 nodes." raise ValueError(msg) self.num_nodes = num_nodes self.num_qubits = num_qubits
[docs] def build(self) -> Network: """Build the star quantum topology. Returns: Network: Network with one central node and all other nodes connected to the center. """ network = Network() # The center node is a ROUTER, all other nodes are END_USERS nodes: list = [] node_center = _default_node(0, NodeRole.ROUTER, self.num_qubits) network.add_node(node_center) nodes.append(node_center) for i in range(1, self.num_nodes): node = _default_node(i, NodeRole.END_USER, self.num_qubits) network.add_node(node) nodes.append(node) for i in range(1, self.num_nodes): q_link = _default_quantum_link(nodes[0], nodes[i]) c_link = _default_classical_link(nodes[0], nodes[i]) network.add_link(q_link) network.add_link(c_link) return network