Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parallel_embeddings.py and feasibility.py minor corrections #259

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
20 changes: 0 additions & 20 deletions minorminer/utils/feasibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,26 +110,6 @@ def embedding_feasibility_filter(
return True


def lattice_size(T: nx.Graph = None) -> int:
"""Determines the cellular (square) dimension of a lattice

The lattice size is the parameter ``m`` of a dwave_networkx graph, also
called number of rows, or in the case of a chimera graph max(m,n). This
upper bounds the ``sublattice_size`` for ``find_sublattice_embeddings``.

Args:
T: The target graph in which to embed. The graph must be of type
zephyr, pegasus or chimera and constructed by dwave_networkx.
Returns:
int: The maximum possible size of a tile
"""
# Possible feature enhancement, determine a stronger upper bound akin
# to lattice_size_lower_bound, accounting for defects, the
# degree distribution and other simple properties.

return max(T.graph.get("rows"), T.graph.get("columns"))


def lattice_size_lower_bound(
S: nx.Graph,
T: nx.Graph = None,
Expand Down
42 changes: 34 additions & 8 deletions minorminer/utils/parallel_embeddings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import dwave_networkx as dnx
import networkx as nx
import numpy as np
from typing import Union
from typing import Union, Optional

from minorminer.subgraph import find_subgraph

Expand Down Expand Up @@ -105,7 +105,7 @@ def find_multiple_embeddings(
S: nx.Graph,
T: nx.Graph,
*,
max_num_emb: int = 1,
max_num_emb: Optional[int] = 1,
use_filter: bool = False,
embedder: callable = None,
embedder_kwargs: dict = None,
Expand All @@ -128,7 +128,7 @@ def find_multiple_embeddings(
S: The source graph to embed.
T: The target graph in which to embed.
max_num_emb: Maximum number of embeddings to find.
Defaults to 1, set to float('Inf') to find the maximum possible
Defaults to 1, set to None to find the maximum possible
number.
use_filter: Specifies whether to check feasibility
of embedding arguments independently of the embedder method.
Expand Down Expand Up @@ -166,8 +166,10 @@ def find_multiple_embeddings(
_T = shuffle_graph(T, seed=prng)
else:
_T = T

max_num_emb = min(int(T.number_of_nodes() / S.number_of_nodes()), max_num_emb)
if max_num_emb is None:
max_num_emb = T.number_of_nodes() // S.number_of_nodes()
else:
max_num_emb = min(T.number_of_nodes() // S.number_of_nodes(), max_num_emb)

if shuffle_all_graphs:
_S = shuffle_graph(S, seed=prng)
Expand Down Expand Up @@ -197,13 +199,33 @@ def find_multiple_embeddings(
return embs


def lattice_size(T: nx.Graph = None) -> int:
"""Determines the cellular (square) dimension of a dwave_networkx lattice

The lattice size is the parameter ``m`` of a dwave_networkx graph, also
called number of rows, or in the case of a chimera graph max(m,n). This
upper bounds the ``sublattice_size`` for ``find_sublattice_embeddings``.

Args:
T: The target graph in which to embed. The graph must be of type
zephyr, pegasus or chimera and constructed by dwave_networkx.
Returns:
int: The maximum possible size of a tile
"""
# Possible feature enhancement, determine a stronger upper bound akin
# to lattice_size_lower_bound, accounting for defects, the
# degree distribution and other simple properties.

return max(T.graph.get("rows"), T.graph.get("columns"))


def find_sublattice_embeddings(
S: nx.Graph,
T: nx.Graph,
*,
tile: nx.Graph = None,
sublattice_size: int = None,
max_num_emb: int = 1,
max_num_emb: Optional[int] = 1,
use_filter: bool = False,
seed: Union[int, np.random.RandomState, np.random.Generator] = None,
embedder: callable = None,
Expand Down Expand Up @@ -246,7 +268,8 @@ def find_sublattice_embeddings(
family matching T). ``lattice_size_lower_bound()``
provides a lower bound based on a fast feasibility filter.
max_num_emb: Maximum number of embeddings to find.
Defaults to inf (unbounded).
Defaults to 1, set to None for unbounded (try unlimited search on
all lattice offsets).
use_filter: Specifies whether to check feasibility of arguments for
embedding independently of the embedder routine. Defaults to False.
embedder: Specifies the embedding search method, a callable taking ``S``, ``T`` as
Expand Down Expand Up @@ -333,7 +356,10 @@ def find_sublattice_embeddings(
"source graphs must a graph constructed by "
"dwave_networkx as chimera, pegasus or zephyr type"
)

if max_num_emb is None:
max_num_emb = T.number_of_nodes() // S.number_of_nodes()
else:
max_num_emb = min(T.number_of_nodes() // S.number_of_nodes(), max_num_emb)
tiling = tile == S
embs = []
if max_num_emb == 1 and seed is None:
Expand Down
10 changes: 0 additions & 10 deletions tests/utils/test_feasibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

from minorminer.utils.feasibility import (
embedding_feasibility_filter,
lattice_size,
lattice_size_lower_bound,
)

Expand Down Expand Up @@ -154,15 +153,6 @@ def test_embedding_feasibility_filter(self):
"it's always infeasible to embed into an empty graph",
)

def test_lattice_size_subgraph_upper_bound(self):
L = np.random.randint(2) + 2
T = dnx.zephyr_graph(L - 1)
self.assertEqual(L - 1, lattice_size(T=T))
T = dnx.pegasus_graph(L)
self.assertEqual(L, lattice_size(T=T))
T = dnx.chimera_graph(L, L - 1, 1)
self.assertEqual(L, lattice_size(T=T))

def test_lattice_size_lower_bound(self):
L = np.random.randint(2) + 2
T = dnx.zephyr_graph(L - 1)
Expand Down
27 changes: 20 additions & 7 deletions tests/utils/test_parallel_embeddings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,26 @@
from minorminer import find_embedding

from minorminer.utils.parallel_embeddings import (
lattice_size,
shuffle_graph,
embeddings_to_array,
find_multiple_embeddings,
find_sublattice_embeddings,
)


class TestLatticeSize(unittest.TestCase):
# This is a very basic helper function
def test_lattice_size(self):
L = np.random.randint(2) + 2
T = dnx.zephyr_graph(L - 1)
self.assertEqual(L - 1, lattice_size(T=T))
T = dnx.pegasus_graph(L)
self.assertEqual(L, lattice_size(T=T))
T = dnx.chimera_graph(L, L - 1, 1)
self.assertEqual(L, lattice_size(T=T))


class TestEmbeddings(unittest.TestCase):

def test_shuffle_graph(self):
Expand Down Expand Up @@ -129,9 +142,9 @@ def test_find_multiple_embeddings_basic(self):
for e in square
}
T = nx.from_edgelist(squares) # Room for 4!
embs = find_multiple_embeddings(S, T, max_num_emb=float("inf"))

self.assertLess(len(embs), 5, "Impossibly many")
for max_num_emb in [None, 6]: # None means unbounded
embs = find_multiple_embeddings(S, T, max_num_emb=max_num_emb)
self.assertLess(len(embs), 5, "Impossibly many")
self.assertTrue(
all(set(emb.keys()) == set(S.nodes()) for emb in embs),
"bad keys in embedding(s)",
Expand Down Expand Up @@ -249,7 +262,7 @@ def test_find_sublattice_embeddings_basic(self):
self.assertEqual(len(embs), 1, "mismatched number of embeddings")

embs = find_sublattice_embeddings(
S, T, sublattice_size=min_sublattice_size, max_num_emb=float("Inf")
S, T, sublattice_size=min_sublattice_size, max_num_emb=None
)
self.assertEqual(len(embs), num_emb, "mismatched number of embeddings")
self.assertTrue(
Expand All @@ -275,7 +288,7 @@ def test_find_sublattice_embeddings_tile(self):
S,
T,
sublattice_size=min_sublattice_size,
max_num_emb=float("Inf"),
max_num_emb=None,
tile=tile,
)
self.assertEqual(len(embs), 4)
Expand All @@ -289,7 +302,7 @@ def test_find_sublattice_embeddings_tile(self):
S,
T,
sublattice_size=min_sublattice_size,
max_num_emb=float("Inf"),
max_num_emb=None,
tile=tile5,
)
self.assertEqual(len(embs), 0, "Tile is too small")
Expand All @@ -299,7 +312,7 @@ def test_find_sublattice_embeddings_tile(self):
S,
T,
sublattice_size=min_sublattice_size,
max_num_emb=float("Inf"),
max_num_emb=None,
tile=tile,
embedder=lambda x: "without S=tile trigger error",
)
Expand Down