Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dwave/graphs/generators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
from dwave.graphs.generators.markov import markov_network
from dwave.graphs.generators.pegasus import *
from dwave.graphs.generators.zephyr import *
from dwave.graphs.generators.common import *
2 changes: 1 addition & 1 deletion dwave/graphs/generators/chimera.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from networkx.algorithms.bipartite import color
from networkx import diameter

from .common import _add_compatible_nodes, _add_compatible_edges, _add_compatible_terms
from dwave.graphs.generators.common import _add_compatible_nodes, _add_compatible_edges, _add_compatible_terms

__all__ = ['chimera_graph',
'chimera_coordinates',
Expand Down
26 changes: 26 additions & 0 deletions dwave/graphs/generators/common/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2026 D-Wave
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ================================================================================================

from dwave.graphs.generators.common.common import (
_add_compatible_edges,
_add_compatible_nodes,
_add_compatible_terms,
)
from dwave.graphs.generators.common.coord import *
from dwave.graphs.generators.common.node_edge import *
from dwave.graphs.generators.common.planeshift import *
from dwave.graphs.generators.common.shape import *
from dwave.graphs.generators.common.topology import *
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Copyright 2026 D-Wave
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ================================================================================================


def _add_compatible_edges(G, edge_list):
# Check edge_list defines a subgraph of G and create subgraph.
Expand All @@ -9,7 +25,8 @@ def _add_compatible_edges(G, edge_list):
G.remove_edges_from(list(G.edges))
G.add_edges_from(edge_list)
if G.number_of_edges() < len(edge_list):
raise ValueError('edge_list contains duplicates.')
raise ValueError("edge_list contains duplicates.")


def _add_compatible_nodes(G, node_list):
if node_list is not None:
Expand All @@ -19,11 +36,12 @@ def _add_compatible_nodes(G, node_list):
remove_nodes = set(G) - nodes
G.remove_nodes_from(remove_nodes)
if G.number_of_nodes() < len(node_list):
raise ValueError('node_list contains duplicates.')

raise ValueError("node_list contains duplicates.")


def _add_compatible_terms(G, node_list, edge_list):
_add_compatible_edges(G, edge_list)
_add_compatible_nodes(G, node_list)
#Check node deletion hasn't caused edge deletion:
# Check node deletion hasn't caused edge deletion:
if edge_list is not None and len(edge_list) != G.number_of_edges():
raise ValueError('The edge_list contains nodes absent from the node_list')
raise ValueError("The edge_list contains nodes absent from the node_list")
133 changes: 133 additions & 0 deletions dwave/graphs/generators/common/coord.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Copyright 2026 D-Wave
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ================================================================================================


from __future__ import annotations

from enum import Enum
from functools import total_ordering

from dwave.graphs.generators.common.shape import TopologyShape
from dwave.graphs.tuplelike import TupleLike

__all__ = ["Coord", "CoordKind"]


class CoordKind(Enum): # Kinds of coordinates of nodes in topologies
CARTESIAN = 0
TOPOLOGY = 1


@total_ordering
class Coord(TupleLike):
"""A class to represent the coordinate of a topology node."""

__hash__ = TupleLike.__hash__

@classmethod
def topology_name(cls) -> str:
"""Returns the name of the topology associated with the class.

Raises:
NotImplementedError: To be implemented in subclasses for
specific topologies.

Returns:
str: The name of the topology the class is designed for.
"""
raise NotImplementedError

@classmethod
def kind(cls) -> CoordKind:
"""Returns the kind of the coordinate associated with the class.

Raises:
NotImplementedError: To be implemented in subclasses for
specific coordinates.

Returns:
CoordKind: The kind of class's coordinate.
"""
raise NotImplementedError

def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

def _args_valid_topology(self, *args, **kwargs) -> None:
"""Verifies the given coordinate is a valid coordinate."""
raise NotImplementedError

def is_shape_consistent(self, shape: TopologyShape) -> bool:
"""Tells whether the coordinate is consistent with a topology shape.

Args:
shape: The shape to check the consistency of the coordinate with.

Returns:
bool: Whether the coordinate is consistent with the shape.
"""
raise NotImplementedError

def is_quotient(self) -> bool:
"""Whether the given coordinate is a quotient coordinate."""
raise NotImplementedError

def to_quotient(
self,
) -> Coord:
"""Converts the coordinate to its corresponding coordinate in a quotient graph."""
raise NotImplementedError

def to_non_quotient(
self,
shape: TopologyShape,
**kwargs,
) -> list[Coord]:
"""Expands the coordinate to a non-quotient shape; i.e. it gives
all coordinates in a non-quotient graph whose quotient is the coordinate.

Args:
shape: The non-quotient shape to expand the coordinate to.

Returns:
list[Coord]: The expansion of the coordinate into non-quotient.
"""
raise NotImplementedError

def convert(self, coord_kind: CoordKind) -> Coord:
"""Converts the coordinate to other kinds of coordinate in the same topology.

Args:
coord_kind (CoordKind): The coordinate kind to convert the coordinate to.

Raises:
NotImplementedError: To be implemented in subclasses for
specific coordinates.

Returns:
Coord: The converted coordinate.
"""
raise NotImplementedError

def __eq__(self, other: object) -> bool:
if (type(self) is not type(other)) or (self.is_quotient() != other.is_quotient()):
return NotImplemented
return self._tuple_format == other._tuple_format

def __lt__(self, other: object) -> bool:
if (type(self) is not type(other)) or (self.is_quotient() != other.is_quotient()):
return NotImplemented
return self._tuple_format < other._tuple_format
Loading