@@ -333,6 +333,169 @@ function _dnx_working_graph(arch::WorkingGraph)
333333 return nothing
334334end
335335
336+ function _dnx_hardware_graph (arch:: Pegasus )
337+ return _dnx (). pegasus_graph (
338+ arch. size;
339+ node_list = _py (arch. nodes),
340+ edge_list = _py (arch. edges),
341+ )
342+ end
343+
344+ function _dnx_hardware_graph (arch:: Zephyr )
345+ return _dnx (). zephyr_graph (
346+ arch. size,
347+ arch. shore_size;
348+ node_list = _py (arch. nodes),
349+ edge_list = _py (arch. edges),
350+ )
351+ end
352+
353+ function _dnx_hardware_graph (arch:: WorkingGraph )
354+ graph = _dnx_working_graph (arch)
355+
356+ graph === nothing && throw (ArgumentError (
357+ " D-Wave drawing helpers require Pegasus or Zephyr topology metadata with a nonempty shape" ,
358+ ))
359+
360+ return graph
361+ end
362+
363+ function _hardware_topology (source)
364+ source isa DWaveHardwareTopology && return source
365+ source isa AbstractDict && return WorkingGraph (source)
366+ source isa QUBOTools. SampleSet && return WorkingGraph (QUBOTools. metadata (source))
367+ source isa PythonCall. Py && return WorkingGraph (source)
368+
369+ throw (ArgumentError (
370+ " expected a D-Wave hardware topology, metadata dictionary, sample set, or sampler" ,
371+ ))
372+ end
373+
374+ _draw_topology_function (:: Pegasus ) = _dnx (). draw_pegasus
375+ _draw_topology_function (:: Zephyr ) = _dnx (). draw_zephyr
376+
377+ function _draw_topology_function (arch:: WorkingGraph )
378+ arch. topology_type == " pegasus" && return _dnx (). draw_pegasus
379+ arch. topology_type == " zephyr" && return _dnx (). draw_zephyr
380+
381+ throw (ArgumentError (" D-Wave drawing helpers only support Pegasus and Zephyr topologies" ))
382+ end
383+
384+ _draw_embedding_function (:: Pegasus ) = _dnx (). draw_pegasus_embedding
385+ _draw_embedding_function (:: Zephyr ) = _dnx (). draw_zephyr_embedding
386+
387+ function _draw_embedding_function (arch:: WorkingGraph )
388+ arch. topology_type == " pegasus" && return _dnx (). draw_pegasus_embedding
389+ arch. topology_type == " zephyr" && return _dnx (). draw_zephyr_embedding
390+
391+ throw (ArgumentError (" D-Wave embedding drawing helpers only support Pegasus and Zephyr topologies" ))
392+ end
393+
394+ function _matplotlib_figure_axes ()
395+ figure_axes = PythonCall. pyimport (" matplotlib.pyplot" ). subplots ()
396+
397+ return figure_axes[0 ], figure_axes[1 ]
398+ end
399+
400+ function _draw_result (draw_function, graph, args... ; ax = nothing , kwargs... )
401+ if ax === nothing
402+ figure, draw_axis = _matplotlib_figure_axes ()
403+ draw_function (graph, args... ; ax = draw_axis, kwargs... )
404+
405+ return figure
406+ else
407+ draw_function (graph, args... ; ax = ax, kwargs... )
408+
409+ return ax
410+ end
411+ end
412+
413+ function _normalise_embedding_for_drawing (embedding_data)
414+ normal_embedding = _normalise_embedding (embedding_data)
415+
416+ normal_embedding === nothing && throw (ArgumentError (
417+ " embedding must be a dictionary mapping variables to integer qubit chains" ,
418+ ))
419+
420+ return normal_embedding
421+ end
422+
423+ function _embedding_from_metadata (metadata:: AbstractDict )
424+ normal_embedding = embedding (metadata)
425+
426+ normal_embedding === nothing && throw (ArgumentError (
427+ " metadata does not contain a D-Wave embedding; sample with return_embedding=true" ,
428+ ))
429+
430+ return normal_embedding
431+ end
432+
433+ @doc raw """
434+ DWave.draw_topology(source; kwargs...)
435+
436+ Draw a Pegasus or Zephyr hardware topology with D-Wave NetworkX.
437+
438+ `source` may be a `Pegasus`, `Zephyr`, `WorkingGraph`, D-Wave sampler,
439+ `QUBOTools.SampleSet`, or metadata dictionary accepted by `WorkingGraph`.
440+ Keyword arguments are forwarded to `dwave_networkx.draw_pegasus` or
441+ `dwave_networkx.draw_zephyr`.
442+
443+ By default this creates and returns a Matplotlib figure, which notebooks can
444+ display directly. If `ax` is supplied, drawing is performed on that axis and
445+ the same axis is returned.
446+ """
447+ function draw_topology (arch:: DWaveHardwareTopology ; kwargs... )
448+ return _draw_result (
449+ _draw_topology_function (arch),
450+ _dnx_hardware_graph (arch);
451+ kwargs... ,
452+ )
453+ end
454+
455+ function draw_topology (source; kwargs... )
456+ return draw_topology (_hardware_topology (source); kwargs... )
457+ end
458+
459+ @doc raw """
460+ DWave.draw_embedding(source, embedding; kwargs...)
461+ DWave.draw_embedding(sampleset_or_metadata; kwargs...)
462+
463+ Draw a returned minor embedding over the full Pegasus or Zephyr working graph
464+ with D-Wave NetworkX.
465+
466+ The two-argument form accepts any topology source supported by
467+ `draw_topology` plus an embedding dictionary of the form
468+ `Dict{Int,Vector{Int}}`. The one-argument form extracts both the working graph
469+ and embedding from a `QUBOTools.SampleSet` or metadata dictionary, preserving
470+ compatibility with `DWave.WorkingGraph(QUBOTools.metadata(sampleset))`.
471+
472+ Keyword arguments are forwarded to `dwave_networkx.draw_pegasus_embedding` or
473+ `dwave_networkx.draw_zephyr_embedding`. By default this creates and returns a
474+ Matplotlib figure; if `ax` is supplied, that axis is returned.
475+ """
476+ function draw_embedding (arch:: DWaveHardwareTopology , embedding_data:: AbstractDict ; kwargs... )
477+ return _draw_result (
478+ _draw_embedding_function (arch),
479+ _dnx_hardware_graph (arch),
480+ _py (_normalise_embedding_for_drawing (embedding_data));
481+ kwargs... ,
482+ )
483+ end
484+
485+ function draw_embedding (source, embedding_data:: AbstractDict ; kwargs... )
486+ return draw_embedding (_hardware_topology (source), embedding_data; kwargs... )
487+ end
488+
489+ function draw_embedding (metadata:: AbstractDict ; kwargs... )
490+ return draw_embedding (WorkingGraph (metadata), _embedding_from_metadata (metadata); kwargs... )
491+ end
492+
493+ function draw_embedding (sampleset:: QUBOTools.SampleSet ; kwargs... )
494+ metadata = QUBOTools. metadata (sampleset)
495+
496+ return draw_embedding (WorkingGraph (metadata), _embedding_from_metadata (metadata); kwargs... )
497+ end
498+
336499function _dnx_layout_points (layout, nodes:: Vector{Int} )
337500 points = Vector {QUBOTools.Point{2,Float64}} (undef, length (nodes))
338501
0 commit comments