Add example and tests for fully yielded Zephyr subgraph search#45
Add example and tests for fully yielded Zephyr subgraph search#45VolodyaCO wants to merge 2 commits intodwavesystems:mainfrom
Conversation
kevinchern
left a comment
There was a problem hiding this comment.
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)``. |
There was a problem hiding this comment.
I suggest something more descriptive rather than variable names, e.g.,
| """Extract and validate Zephyr graph properties, returning ``(m, tp, t)``. | |
| """Extract and validate Zephyr graph properties (rows, tile count, and target tile count). |
| tuple[int, int, int]: ``(m, tp, t)`` where ``m`` is rows, | ||
| ``tp`` is source tile count, and ``t`` is target tile count. |
There was a problem hiding this comment.
| 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. |
|
|
||
| Raises: | ||
| TypeError: If metadata values are not integers. | ||
| ValueError: If graph metadata is missing or incompatible. |
There was a problem hiding this comment.
I this should detail what it means to be incompatible; incompatibility is implied by ValueError, e.g., positive int or ...
| for n in _source.nodes() | ||
| if n in working_embedding | ||
| ) | ||
| else: |
There was a problem hiding this comment.
| 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...
There was a problem hiding this comment.
Other two options are edge and rail-edge. This is fine, as you say, because the type has been validated.
| YieldType = Literal["node", "edge", "rail-edge"] | ||
| QuotientSearchType = Literal["by_quotient_rail", "by_quotient_node", "by_rail_then_node"] |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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? |
There was a problem hiding this comment.
@VolodyaCO has this question been addressed with @jackraymond ?
SebastianGitt
left a comment
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
| 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
There was a problem hiding this comment.
Oh I will have a bunch of these. thanks
tests/test_zephyr_quotient_search.py
Outdated
| # 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} |
There was a problem hiding this comment.
consider renaming this to something more clear
| """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. |
There was a problem hiding this comment.
| 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. |
| if expand_boundary_search: | ||
| if w == 0: | ||
| ksymmetric = False | ||
| # brrow candidates from adjacent internal column |
There was a problem hiding this comment.
| # brrow candidates from adjacent internal column | |
| # borrow candidates from adjacent internal column |
| \{(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 |
There was a problem hiding this comment.
| 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 |
|
|
||
| F_q = \{m \in V(S) \setminus B_q : m \in \operatorname{dom}(\phi)\}, | ||
|
|
||
| where :math:`\phi` is the current embedding`. Then |
There was a problem hiding this comment.
| where :math:`\phi` is the current embedding`. Then | |
| where :math:`\phi` is the current embedding. Then |
|
|
||
| Args: | ||
| quotient_search (str): Search mode. | ||
| yield_type (str): Optimization objective. |
There was a problem hiding this comment.
| yield_type (str): Optimization objective. | |
| yield_type (YieldType): Optimization objective. |
There was a problem hiding this comment.
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"``. |
There was a problem hiding this comment.
| yield_type (str): ``"node"``, ``"edge"``, or ``"rail-edge"``. Defaults to ``"edge"``. | |
| yield_type (YieldType): ``"node"``, ``"edge"``, or ``"rail-edge"``. Defaults to ``"edge"``. |
| ) | ||
|
|
||
|
|
||
| def _validate_graph_inputs(source: nx.Graph, target: nx.Graph): |
There was a problem hiding this comment.
| def _validate_graph_inputs(source: nx.Graph, target: nx.Graph): | |
| def _validate_graph_inputs(source: nx.Graph, target: nx.Graph) -> None: |
tests/test_zephyr_quotient_search.py
Outdated
| ZephyrSearchMetadata, zephyr_quotient_search) | ||
|
|
||
|
|
||
| def generate_faulty_zephyr_graph(m, t, proportion, uniform_proportion, seed=None): |
There was a problem hiding this comment.
consider adding type hinting here since this function is non-trivial and used in multiple places
kevinchern
left a comment
There was a problem hiding this comment.
Did a few passes with focus on usability and some design patterns 🚀
Continuation of dwavesystems/dwave-graphs#261
Adds a routine to find embeddings of Zephyr[m, tp] into Zephyr[m, t] with tp < t.