@@ -104,6 +104,81 @@ function _dwave_chip_info(dwave_sampler)
104104 return chip_info
105105end
106106
107+ function _normalise_embedding_index (value)
108+ value isa Integer && return Int (value)
109+
110+ if value isa AbstractString
111+ index = tryparse (Int, value)
112+ index === nothing || return index
113+ end
114+
115+ return nothing
116+ end
117+
118+ function _normalise_embedding_chain (chain)
119+ chain isa AbstractVector || chain isa Tuple || return nothing
120+
121+ normal_chain = Int[]
122+ sizehint! (normal_chain, length (chain))
123+
124+ for qubit in chain
125+ index = _normalise_embedding_index (qubit)
126+ index === nothing && return nothing
127+
128+ push! (normal_chain, index)
129+ end
130+
131+ return normal_chain
132+ end
133+
134+ function _normalise_embedding (embedding)
135+ embedding isa AbstractDict || return nothing
136+
137+ normal_embedding = Dict {Int,Vector{Int}} ()
138+
139+ for (variable, chain) in pairs (embedding)
140+ normal_variable = _normalise_embedding_index (variable)
141+ normal_variable === nothing && return nothing
142+ normal_chain = _normalise_embedding_chain (chain)
143+ normal_chain === nothing && return nothing
144+
145+ normal_embedding[normal_variable] = normal_chain
146+ end
147+
148+ return normal_embedding
149+ end
150+
151+ function _normalise_dwave_embedding! (dwave_info:: AbstractDict )
152+ context = get (dwave_info, " embedding_context" , nothing )
153+ context isa AbstractDict || return dwave_info
154+
155+ normal_embedding = _normalise_embedding (get (context, " embedding" , nothing ))
156+ normal_embedding === nothing || (context[" embedding" ] = normal_embedding)
157+
158+ return dwave_info
159+ end
160+
161+ @doc raw """
162+ DWave.embedding(sampleset_or_metadata)
163+
164+ Return the minor embedding recorded in D-Wave sample-set metadata, or `nothing`
165+ when no embedding was returned. Embeddings are normalized as
166+ `Dict{Int,Vector{Int}}`.
167+ """
168+ function embedding (metadata:: AbstractDict )
169+ dwave_info = haskey (metadata, " dwave_info" ) ? metadata[" dwave_info" ] : metadata
170+ dwave_info isa AbstractDict || return nothing
171+
172+ context = get (dwave_info, " embedding_context" , nothing )
173+ context isa AbstractDict || return nothing
174+
175+ return _normalise_embedding (get (context, " embedding" , nothing ))
176+ end
177+
178+ function embedding (sampleset:: QUBOTools.SampleSet )
179+ return embedding (QUBOTools. metadata (sampleset))
180+ end
181+
107182function QUBODrivers. sample (sampler:: Optimizer{T} ) where {T}
108183 # Ising Model
109184 n, h, J, α, β = QUBOTools. ising (sampler, :dict ; sense = :min )
@@ -112,8 +187,9 @@ function QUBODrivers.sample(sampler::Optimizer{T}) where {T}
112187 num_reads = MOI. get (sampler, DWave. NumberOfReads ())
113188 final_num_reads = MOI. get (sampler, QUBODrivers. FinalNumberOfReads ())
114189 sample_params = Dict {Symbol,Any} (
115- :num_reads => final_num_reads,
116- :annealing_time => MOI. get (sampler, DWave. AnnealingTime ()),
190+ :num_reads => final_num_reads,
191+ :annealing_time => MOI. get (sampler, DWave. AnnealingTime ()),
192+ :return_embedding => MOI. get (sampler, DWave. ReturnEmbedding ()),
117193 )
118194 dwave_sampler = MOI. get (sampler, DWave. Sampler ())
119195
@@ -123,15 +199,14 @@ function QUBODrivers.sample(sampler::Optimizer{T}) where {T}
123199 token = get (ENV , " DWAVE_API_TOKEN" , nothing )
124200 )
125201 )
126-
127- sample_params[:return_embedding ] = MOI. get (sampler, DWave. ReturnEmbedding ())
128202 end
129203
130204 # Results
131205 samples = QUBOTools. Sample{T,Int}[]
132206 results = @timed dwave_sampler. sample_ising (h, J; sample_params... )
133207 var_map = pyconvert .(Int, [var for var in results. value. variables])
134208 dw_info = jl_object (results. value. info)
209+ _normalise_dwave_embedding! (dw_info)
135210 chip_info = _dwave_chip_info (dwave_sampler)
136211
137212 if ! isempty (chip_info)
0 commit comments