Conversation
|
Proof of concept that this works is already finished, IP approved and discussed publicly 2026-06-24-AQC-Jack Raymond.pptx . Codebase is already in public pull request dwavesystems/dwave-experimental#54. Just some differences in the training and archiecture conventions to understand (and test). |
|
Since this pull request was made there have been some method developments relative to fully_yielded_zephyr_subgraph. That need to be incorporated |
thisac
left a comment
There was a problem hiding this comment.
Apart for some minor comments, LGTM. Would be good to have someone more familiar with the defect zephyr subgraph embedding implementation to review and approve before merging though.
| subgraph = greedy_get_subgraph(n_nodes=n_latents, random_seed=random_seed, graph=qpu_graph) | ||
| _, mapping = get_graph_mapping(subgraph) | ||
| latent_mapping = [mapping[node] for node in subgraph.nodes()] | ||
| except Exception: |
There was a problem hiding this comment.
Specify exception caught, or at least print error message? I assume you're trying to catch a specific error here for when greedy_get_subgraph fails for find a subgraph?
| raise | ||
| fallback = _try_zephyr_sublattice_fallback( | ||
| n_nodes=n_latents, qpu_graph=qpu_graph, random_seed=random_seed | ||
| ) | ||
| if fallback is None: | ||
| raise |
There was a problem hiding this comment.
Missing exceptions and messages.
| try: | ||
| samples = self._grbm.sample( # type: ignore | ||
| sampler=self.sampler, | ||
| prefactor=self.PREFACTOR, | ||
| linear_range=self.linear_range, | ||
| quadratic_range=self.quadratic_range, | ||
| device=spins.device, | ||
| sample_params=self.sampler_kwargs, | ||
| ) | ||
| except BinaryQuadraticModelStructureError: | ||
| self._rebuild_sampler() | ||
| samples = self._grbm.sample( # type: ignore | ||
| sampler=self.sampler, | ||
| prefactor=self.PREFACTOR, | ||
| linear_range=self.linear_range, | ||
| quadratic_range=self.quadratic_range, | ||
| device=spins.device, | ||
| sample_params=self.sampler_kwargs, | ||
| ) |
There was a problem hiding this comment.
For the sake of not copying this twice, you could:
| try: | |
| samples = self._grbm.sample( # type: ignore | |
| sampler=self.sampler, | |
| prefactor=self.PREFACTOR, | |
| linear_range=self.linear_range, | |
| quadratic_range=self.quadratic_range, | |
| device=spins.device, | |
| sample_params=self.sampler_kwargs, | |
| ) | |
| except BinaryQuadraticModelStructureError: | |
| self._rebuild_sampler() | |
| samples = self._grbm.sample( # type: ignore | |
| sampler=self.sampler, | |
| prefactor=self.PREFACTOR, | |
| linear_range=self.linear_range, | |
| quadratic_range=self.quadratic_range, | |
| device=spins.device, | |
| sample_params=self.sampler_kwargs, | |
| ) | |
| for _ in range(2): | |
| try: | |
| samples = self._grbm.sample( # type: ignore | |
| sampler=self.sampler, | |
| prefactor=self.PREFACTOR, | |
| linear_range=self.linear_range, | |
| quadratic_range=self.quadratic_range, | |
| device=spins.device, | |
| sample_params=self.sampler_kwargs, | |
| ) | |
| except BinaryQuadraticModelStructureError: | |
| self._rebuild_sampler() |
| try: | ||
| subgraph = greedy_get_subgraph(n_nodes=n_latents, random_seed=random_seed, graph=qpu_graph) | ||
| mapped_graph, mapping = get_graph_mapping(subgraph) | ||
| sampler = FixedEmbeddingComposite(qpu, {l_: [p] for p, l_ in mapping.items()}) | ||
| except Exception: | ||
| qpu_topology = qpu.properties["topology"]["type"] | ||
| if qpu_topology != "zephyr": | ||
| raise | ||
| fallback = _try_zephyr_sublattice_fallback( | ||
| n_nodes=n_latents, qpu_graph=qpu_graph, random_seed=random_seed | ||
| ) | ||
| if fallback is None: | ||
| raise | ||
| mapped_graph, chain_embedding = fallback | ||
| sampler = FixedEmbeddingComposite(qpu, chain_embedding) |
There was a problem hiding this comment.
Should this just be put into a helper function and imported into callback_helpers.py?
| import random | ||
| from typing import Callable, Literal, Optional | ||
|
|
||
| import dwave_networkx as dnx |
There was a problem hiding this comment.
Better use dwave-graphs here instead, since dnx is deprecated.
There was a problem hiding this comment.
Yeah I have this update locally along with the new implementation of Jacks changes I was just waiting for his PR to be merged so I can test before making a commit
There was a problem hiding this comment.
Although maybe it just worth merging these changes and making a followup PR once his PR is merged? Let me know your thoughts
| latent_mapping = [mapping[node] for node in subgraph.nodes()] | ||
| except Exception: | ||
| if qpu_topology != "zephyr": | ||
| raise |
There was a problem hiding this comment.
The new code(s) support all processor topologies.
jackraymond
left a comment
There was a problem hiding this comment.
As far as I can tell a processor subgraph is found, in combination with a 1:1 embedding, greedily as a subgraph of the processor to maximize connectivity. If the greedy search fails, a zephyr-quotient subgraph is sought, but I'm not sure under what conditions this fallback would be invoked on brief inspection.
If the graph_id changes then a new embedding is sought using minorminer find_embedding.
I think we could improve this workflow to better align with the concept I showed at AQC 2026 (much of which was developed after this pull request was created), and to incorporate more solid quotient code pending pull requests dwavesystems/minorminer#292 and dwavesystems/dwave-experimental#54.
|
|
||
| # EmbeddingComposite finds a valid minor embedding of the GRBM's logical | ||
| # graph on the current working QPU topology without requiring retraining. | ||
| self.sampler = EmbeddingComposite(qpu_sampler) |
There was a problem hiding this comment.
Does this not mean that minorminer find_embeddings will be called rather than the higher performance options (find_subgraph, find_labeled_subgraph or quotient_embedding_search?).
| from minorminer.utils.parallel_embeddings import find_sublattice_embeddings | ||
|
|
||
|
|
||
| def greedy_get_subgraph( |
There was a problem hiding this comment.
I don't think this is the best way to define a defect tolerant graph.
| return subgraph | ||
|
|
||
|
|
||
| def _try_zephyr_sublattice_fallback( |
There was a problem hiding this comment.
Seems like quotient search code is only used as a fall back, but isn't greedy_search guaranteed to succeed?
Feature Implemented
Losing a qubit from the Advantage2 typically renders the models (trained on the Advantage2) unusable. The changes in this PR allow for these models to continue to be used even after a qubit or two has been lost.
Note: The Advantage2 models in this branch are old and have not been updated to the new models. These models were trained prior to the last qubit loss and therefore should be helpful for testing.
AI Generation Disclosure
Copilot was given the fully_yielded_zephyr_subgraph file and implemented this guided but mostly unaided. I have reviewed it and tested it. Please review carefully.