Skip to content

Add example and tests for fully yielded Zephyr subgraph search#45

Open
VolodyaCO wants to merge 2 commits intodwavesystems:mainfrom
VolodyaCO:zephyr_quotient_search
Open

Add example and tests for fully yielded Zephyr subgraph search#45
VolodyaCO wants to merge 2 commits intodwavesystems:mainfrom
VolodyaCO:zephyr_quotient_search

Conversation

@VolodyaCO
Copy link
Copy Markdown

Continuation of dwavesystems/dwave-graphs#261

Adds a routine to find embeddings of Zephyr[m, tp] into Zephyr[m, t] with tp < t.

Copy link
Copy Markdown

@kevinchern kevinchern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added minor questions and comments



def _extract_graph_properties(source: nx.Graph, target: nx.Graph) -> tuple[int, int, int]:
"""Extract and validate Zephyr graph properties, returning ``(m, tp, t)``.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest something more descriptive rather than variable names, e.g.,

Suggested change
"""Extract and validate Zephyr graph properties, returning ``(m, tp, t)``.
"""Extract and validate Zephyr graph properties (rows, tile count, and target tile count).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +79 to +80
tuple[int, int, int]: ``(m, tp, t)`` where ``m`` is rows,
``tp`` is source tile count, and ``t`` is target tile count.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tuple[int, int, int]: ``(m, tp, t)`` where ``m`` is rows,
``tp`` is source tile count, and ``t`` is target tile count.
tuple[int, int, int]: source Zephyr rows, source tile count, and target tile count.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


Raises:
TypeError: If metadata values are not integers.
ValueError: If graph metadata is missing or incompatible.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I this should detail what it means to be incompatible; incompatibility is implied by ValueError, e.g., positive int or ...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

for n in _source.nodes()
if n in working_embedding
)
else:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
else:
elif yield_type == "edges":
# do stuff
else:
raise ValueError("blah blah")

I recommend being explicit about checking yield type.

Edit: maybe this is fine since validity of yield type has been validated previously...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other two options are edge and rail-edge. This is fine, as you say, because the type has been validated.

Comment on lines +29 to +30
YieldType = Literal["node", "edge", "rail-edge"]
QuotientSearchType = Literal["by_quotient_rail", "by_quotient_node", "by_rail_then_node"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question!!
I think most of these are only ever used in type-hinting. Should we still define these constant type hints here? Is there a best-practice or principle that recommends this pattern?
Subjectively, I find it less readable than writing the types out explicitly in the type hints.

cc @thisac

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. in vscode all it takes is to hover over the constant type hint and it will show more details, though.

__all__ = ["zephyr_quotient_search"]

ZephyrNode = tuple[int, int, int, int, int] # (u, w, k, j, z) coordinate tuple
Embedding = dict[ZephyrNode, ZephyrNode] # Internal single-node format
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for considering a different name: dwave.embedding has an EmbeddedStructure class. Might be worth following that pattern but tailored for Zephyr. e.g., ZephyrEmbeddedStructure (ok maybe this is too long lol)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Embedding is just a short-hand typing tool. The EmbeddedStructure is a bit more convoluted.


pruned_embedding = {
to_source(k): to_target(v) for k, v in working_embedding.items() if v in target_nodeset
} # TODO:?: why would a target node in the working_embedding not be in the target_nodeset?
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VolodyaCO has this question been addressed with @jackraymond ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It hasn't AFAIR.

Copy link
Copy Markdown
Contributor

@SebastianGitt SebastianGitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just have some minor comments.

tiles. It is designed for defective targets where a direct identity map may lose
nodes or edges.

The search is organised around the **quotient graph** of the Zephyr topology, formed by
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The search is organised around the **quotient graph** of the Zephyr topology, formed by
The search is organized around the **quotient graph** of the Zephyr topology, formed by

minor issue but US English should be used

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I will have a bunch of these. thanks

# Phase 1: uniform random deletion
n_uniform = round(proportion * uniform_proportion * N)
uniform_indices = rng.choice(N, size=n_uniform, replace=False)
deleted = {all_nodes[i] for i in uniform_indices}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider renaming this to something more clear

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to deleted_nodes.

"""Validate that source and target are Zephyr NetworkX graphs.

Both source and target graphs must be networkx graph instances with a 'family' metadata key
set to 'zephyr'. Each graph must also contain 'rows', 'tile' and 'labels metadata keys.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set to 'zephyr'. Each graph must also contain 'rows', 'tile' and 'labels metadata keys.
set to 'zephyr'. Each graph must also contain 'rows', 'tile' and 'labels' metadata keys.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if expand_boundary_search:
if w == 0:
ksymmetric = False
# brrow candidates from adjacent internal column
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# brrow candidates from adjacent internal column
# borrow candidates from adjacent internal column

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

\{(u, w_t, k_t, j, z) : j \in \{0,1\},\ z \in \{0,\dots,m-1\}\}.

We can define its objective for ``yield_type='edge'`` as the number of edges preserved within
that rail, i.e., the numbe of edges in the target subgraph induced by the proposed rail, or
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
that rail, i.e., the numbe of edges in the target subgraph induced by the proposed rail, or
that rail, i.e., the number of edges in the target subgraph induced by the proposed rail, or

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


F_q = \{m \in V(S) \setminus B_q : m \in \operatorname{dom}(\phi)\},

where :math:`\phi` is the current embedding`. Then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
where :math:`\phi` is the current embedding`. Then
where :math:`\phi` is the current embedding. Then

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


Args:
quotient_search (str): Search mode.
yield_type (str): Optimization objective.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
yield_type (str): Optimization objective.
yield_type (YieldType): Optimization objective.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a str, as it validates the search parameters. If it is not a YieldType, then an error is raised.

:math:`w` is at a boundary. Defaults to ``True``.
ksymmetric (bool): If ``True``, treat source :math:`k` order as interchangeable when scoring
rails. Defaults to ``False``.
yield_type (str): ``"node"``, ``"edge"``, or ``"rail-edge"``. Defaults to ``"edge"``.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
yield_type (str): ``"node"``, ``"edge"``, or ``"rail-edge"``. Defaults to ``"edge"``.
yield_type (YieldType): ``"node"``, ``"edge"``, or ``"rail-edge"``. Defaults to ``"edge"``.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, thanks

)


def _validate_graph_inputs(source: nx.Graph, target: nx.Graph):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def _validate_graph_inputs(source: nx.Graph, target: nx.Graph):
def _validate_graph_inputs(source: nx.Graph, target: nx.Graph) -> None:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

ZephyrSearchMetadata, zephyr_quotient_search)


def generate_faulty_zephyr_graph(m, t, proportion, uniform_proportion, seed=None):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider adding type hinting here since this function is non-trivial and used in multiple places

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added type hinting

Copy link
Copy Markdown

@kevinchern kevinchern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a few passes with focus on usability and some design patterns 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants