Displaying Embedding Generated by EmbeddingComposite
I have the following code, where I provide a QUBO to an EmbeddingComposite wrapped DWaveSampler.
from dwave.system.samplers import DWaveSampler
from dwave.system.composites import EmbeddingComposite
sampler = DWaveSampler()
response = EmbeddingComposite(sampler).sample_qubo(qubo, num_reads=200)
How do I retrieve the actual embedding that was used on the hardware? I want to see what how the size of the model changed while embedding.
Comments
The best way to see the embedding is to use the FixedEmbeddingComposite:
https://docs.ocean.dwavesys.com/projects/system/en/stable/reference/composites.html#fixedembeddingcomposite
This is a simple example illustrating how to use it:
The verbose parameter is optional.
Note that if you save the embedding, it will use the same embedding every time, unlike when you use the EmbeddingComposite, which generates a new one every time.
You can easily regenerate the embedding if you desire this behaviour.
I hope this was helpful!
It was, thank you! Does the "FixedEmbeddingComposite" use majority voting to resolve chain breaks by default?
Does it allow for a customization of the chain-break resolution method?
At the moment, you cannot customize the chain-break resolution method, however there is a feature request to add it!
Here's a link to the feature request for reference:
https://github.com/dwavesystems/dwave-system/issues/182
For the time being, you can also do the embedding and unembedding in separate steps.
Here is a code example of how to do this:
The chain_break_method can be replaced with one of the generators listed in the documentation here:
https://docs.ocean.dwavesys.com/projects/system/en/latest/reference/embedding.html#chain-break-resolution
Here is a link to the documentation for the unembed function:
https://docs.ocean.dwavesys.com/projects/system/en/latest/reference/generated/dwave.embedding.unembed_sampleset.html
I hope this was helpful.
Please let us know if you have any questions or need more information.
Thanks David. I actually arrived at that same solution myself. I'm finding that the output of that code is significantly less diverse than the output I get from the FixedCompositeEmbedding. Do you know how that module resolves chain-breaks by default?
I was unable to produce the same looking results (as FCE) with any of the custom chain-break resolution methods.
My apologies!
I forgot to mention that the default chain break method is indeed majority_vote.
So, you tried using majority_vote and are seeing different behaviour?
How is the behaviour differing?
Maybe we can offer an explanation or find a place for further investigation.
I've created a minimum working example that shows the discrepancy between the two modes of operation. In this example "manual_embed" can be switched between True and False. If majority voting was the only thing being used, I would expect the output of the two methods to be identical. As you can see in the results I provide, they are not identical.
Code
Results
manual_embed = False
manual_embed = True
Conclusion
The results of the FixedCompositeEmbedding do not appear to be the same as a majority vote. Perhaps I've coded something incorrectly. Barring errors, it looks like the behavior of the two is indeed different when executing on the real hardware. It also looks like the results of the manual embedding are significantly worse!
Is it possible that you are actually just seeing the differences between embeddings?
The embedding should be generated and then stored somewhere else so that it can be used with each of the methods.
It's possible that you are doing this, but with the code example, it seems that a new embedding is generated on each run of the code body.
This line needs to be outside of the function call or loop:
You will see differences between sets of runs, but the rates should average off to be the same between the methods (assuming they are using the same embedding and the same chain break method).
Please let me know if this makes sense, and if you had used the same embedding for both.
Notice the parameter
which ensures that the same embedding is always generated.
I repeated this experiment numerous times beforehand (using identical embeddings) and consistently obtained similar results to what I posted above. I have always observed the FixedCompositeEmbedding to produce better solutions (in both variety and energy).
That is why I am assuming that a different chain break method is used by FCE (or there is some other difference).
Ah! My apologies! I missed the random seed.
I am just reviewing the two methods with some colleagues to see if there are any other steps that are missing.
Maybe changing these lines to use embed qubo might show similar results:
Like this:
Or alternatively have the FixedEmbeddingComposite use a BQM:
It's strange that converting it to a BQM might have differing results, but it might be one area to look into.
According to the code there really isn't a difference between the two methods.
You might be seeing a difference in probabilistic distribution, and with larger numbers of samples it will not be visible.
Here is a link to the sample function code of FixedEmbeddingComposite:
https://docs.ocean.dwavesys.com/projects/system/en/latest/_modules/dwave/system/composites/embedding.html#FixedEmbeddingComposite.sample
Here is a link to the unembed function which shows all of the default values, etc:
https://docs.ocean.dwavesys.com/projects/system/en/latest/_modules/dwave/embedding/transforms.html#unembed_sampleset
Good news!
We found the difference.
You also need to set the smear_vartype in the call to embed_bqm like this:
This is the default being set in the FixedEmbeddingComposite.
Sorry for the confusion!
Here is a link to the relevant code:
https://github.com/dwavesystems/dwave-system/blob/master/dwave/system/composites/embedding.py#L199
Specifically, here is where the two diverge:
https://github.com/dwavesystems/dwave-system/blob/master/dwave/system/composites/embedding.py#L401
And here is a link to the explanation of smear_type:
https://docs.ocean.dwavesys.com/projects/system/en/latest/reference/generated/dwave.embedding.embed_bqm.html
I will be following up on this and be back to you with more information.
Thank you for your patience and understanding.
In the meantime, please let us know if you have any more questions.
Another thing I wanted to mention is that you can remove the couplers that have 0 for their bias.
Including them causes them to get embedded, and causes more potential for chain breaks.
Removing them produces simpler embeddings.
So for example, your example from above would look like this:
Hi, so I have tried to follow the steps to include chain_break_method when I sample. It seems to work for the generators specified on https://docs.ocean.dwavesys.com/projects/system/en/latest/reference/embedding.html#chain-break-resolution.
I am trying to use MinimizeEnergy now. I am not sure how to use it because MinimizeEnergy needs to have access to the unembedded samples. How can one get the unembedded response?
Note: Corrected unembed_sampleset call.
Hello,
You might need to provide a minimal code example so that we can see what you are trying to do.
Here is the code example I provided above, but modified to use MinimizeEnergy.
Thanks for your reply. I really appreciate it. Yeah, it works! I missed that the chain_break_method has this function as the parameter. Just updating things for future reference.
Hello,
The chain_break_method parameter is a method, as you can see on the first link:
The embedding parameter is the dictionary:
But! I did find out what the issue was.
I had mistakenly just used the method reference, and the correct way to use it is like this:
I apologize for the misprint.
I will correct it above as well.
Please let us know if you have any further problems!!
Just a note.
There is a known issue in dwave-system 0.7.5, which is causing an error when calling the unembed_sampleset function, and will be fixed in dwave-system 0.7.6
We apologize for the inconvenience!
Hi David, I have a follow-up question:
Is there a simple way to implement chain_break_method=majority_vote or chain_break_method=discard?
I tried this and it does not work:
Hello,
In the above example you are actually calling the majority_vote function call, and then assigning the returned value to the chain_break_method input parameter.
What you want to do is leave all of the parentheses portion out, and just provide the function itself, like this:
I hope this was helpful!
Please let us know if you have any further questions!
Please sign in to leave a comment.