Routine to find zephyr[m,tp] in possibly-faulty zephyr[m,t] with tp < t#261
Routine to find zephyr[m,tp] in possibly-faulty zephyr[m,t] with tp < t#261VolodyaCO wants to merge 1 commit intodwavesystems:mainfrom
Conversation
kevinchern
left a comment
There was a problem hiding this comment.
Nice work Jack&Vlad 🤩!! I did a quick first pass with mostly minor suggestions.
| @@ -0,0 +1,914 @@ | |||
| # Copyright 2026 D-Wave Systems Inc. | |||
There was a problem hiding this comment.
| # Copyright 2026 D-Wave Systems Inc. | |
| # Copyright 2026 D-Wave |
and other occurrences
|
|
||
| from dwave_networkx import zephyr_coordinates, zephyr_graph | ||
|
|
||
| ZephyrNode = tuple[int, int, int, int, int] # (u, w, k, j, z) coordinate tuple |
There was a problem hiding this comment.
Does something similar exist in dnx? @mahdiehmalekian @thisac
| ZephyrNode = tuple[int, int, int, int, int] # (u, w, k, j, z) coordinate tuple | ||
| Embedding = dict[ZephyrNode, ZephyrNode] | ||
| YieldType = Literal["node", "edge", "rail-edge"] | ||
| KSearchType = Literal["by_quotient_rail", "by_quotient_node", "by_rail_then_node"] |
There was a problem hiding this comment.
Is there a more descriptive name for "K"? (if not, consider adding a comment explaining what K refers to)
|
|
||
|
|
||
| def _validate_graph_inputs(source: nx.Graph, target: nx.Graph) -> tuple[int, int, int]: | ||
| """Validate Zephyr graph compatibility and return ``(m, tp, t)``. |
There was a problem hiding this comment.
Can we describe the checklist of requirements? e.g., inputs are required to be networkx graphs.
| TypeError: If inputs are not NetworkX graphs. | ||
| ValueError: If graph metadata is missing or incompatible. | ||
| """ | ||
| if not isinstance(source, nx.Graph) or not isinstance(target, nx.Graph): |
There was a problem hiding this comment.
I think we don't require them to be networkx graphs and we'll be moving away from networkx.
That said, this is fine; just a heads-up
| ``(_source, source_nodes, to_source)`` where ``_source`` is | ||
| coordinate-labelled, ``source_nodes`` is the full canonical coordinate | ||
| node set implied by ``m`` and ``tp``, and ``to_source`` maps | ||
| coordinate nodes back to the original source labelling spcae. |
There was a problem hiding this comment.
| coordinate nodes back to the original source labelling spcae. | |
| coordinate nodes back to the original source labelling space. |
| ) -> tuple[nx.Graph, Callable[[ZephyrNode], int | ZephyrNode]]: | ||
| """Return a coordinate-labelled target graph and conversion callable. | ||
|
|
||
| This is similar to the source version but does not need to return the full canonical node set |
There was a problem hiding this comment.
I would add a standalone description before contrasting with the source version
| ksymmetric: bool = False, | ||
| yield_type: YieldType = "edge", | ||
| ) -> tuple[dict, dict | None, ZephyrSearchMetadata]: | ||
| r"""Compute a high-yield Zephyr-to-Zephyr embedding. |
There was a problem hiding this comment.
| r"""Compute a high-yield Zephyr-to-Zephyr embedding. | |
| r"""Compute a high-yield Zephyr-to-Zephyr embedding. |
😜
| Returns: | ||
| tuple[dict, dict | None, ZephyrSearchMetadata]: | ||
| ``(subgraph_embedding, minor_embedding, metadata)`` | ||
| ``subgraph_embedding`` is a pruned one-to-one node map ``source_node -> target_node``. |
There was a problem hiding this comment.
Can we make the returned embeddings consistent in the sense that the one-to-one embeddings are length-1 chains, e.g., emb[1] == (53,) instead of emb[1] == 53?
cc @jackraymond
| ``source_node -> tuple[target_nodes, ...]`` or ``None``. If the greedy search did not | ||
| achieve full yield and minorminer is disabled, or minorminer was not able to find an | ||
| embedding, then ``minor_embedding`` is ``None``. If full yield is achieved, then |
There was a problem hiding this comment.
I think this interface can be naturally split in two functions. Currently, it attempts to A) embed with one method, and tries B) minorminer with a seeded solution when the first fails. Would having the two functions A and B work? This current function can still exist, just as a wrapper that calls A and B in succession.
This PR adds a heuristic routine written by @jackraymond to find an embedding from a source graph zephyr[m, tp] to a target graph which is a subgraph of zephyr[m,t]. The motivation of this routine is to have a tool to generate zephyr subgraphs that are resilient to possible future qubit/coupler defects in actual QPUs.
Tests are added to make sure that the routine indeed improves the yield of the embedded graph.