Wie schreibt man ein einfaches Programm für ein D-Wave-Gerät?


27

Ich möchte wissen, wie ein Auftrag für ein D-Wave-Gerät in Code geschrieben und an das Gerät gesendet wird.

In der Antwort ist es am besten, ein bestimmtes Beispiel für ein einfaches Problem zu sehen. Ich vermute, dass die "Hello World" eines D-Wave-Geräts so etwas wie das Auffinden der Grundzustände eines einfachen 2D-Ising-Modells ist , da dies das Problem ist, das von der Hardware direkt erkannt wird. Vielleicht wäre dies ein schönes Beispiel. Aber wenn die mit Sachkenntnis etwas anderes als ein Beispiel wären, würde ich mich freuen, eine Alternative zu sehen.

Antworten:


24

Das 'Hello World'-Äquivalent in der D-Wave-Welt ist das 2D-Schachbrett-Beispiel. In diesem Beispiel erhalten Sie das folgende quadratische Diagramm mit 4 Knoten:

                                                  square_graph

Definieren wir, dass wir den Vertex schwarz färben, wenn und weiß, wenn . Ziel ist es, ein Schachbrettmuster mit den vier Eckpunkten im Diagramm zu erstellen. Es gibt verschiedene Möglichkeiten, und zu definieren , um dieses Ergebnis zu erzielen. Erstens gibt es zwei mögliche Lösungen für dieses Problem: σ i = - 1σichσich=-1h Jσich=+1hJ

               checkerboard_solutions

Der D-Wave-Quanten-Annealer minimiert den von uns definierten Ising-Hamilton-Operator, und es ist wichtig, den Effekt der verschiedenen Kopplereinstellungen zu verstehen. Betrachten Sie zum Beispiel den -Koppler:J0,1

Wenn wir es auf setzen , wird der Hamilton-Operator minimiert, wenn beide Qubits den gleichen Wert annehmen. Wir sagen, negative Koppler korrelieren . Wenn wir es auf , wird der Hamilton-Operator minimiert, wenn die beiden Qubits entgegengesetzte Werte annehmen. Somit korrelieren positive Kuppler nicht miteinander .J 0 , 1 = + 1J0,1=-1J0,1=+1

Im Schachbrett-Beispiel möchten wir jedes Paar benachbarter Qubits antikorrelieren, wodurch der folgende Hamilton-Operator entsteht:

H=σ0σ1+σ0σ2+σ1σ3+σ2σ3

Zur Veranschaulichung fügen wir auch einen Bias-Term für das te Qubit hinzu, sodass wir nur die Lösung Nr. 1 erhalten. Diese Lösung benötigt und wir setzen daher die Vorspannung . Der letzte Hamiltonianer ist jetzt:σ 0 = - 1 h 0 = 10σ0=-1h0=1

H=σ0+σ0σ1+σ0σ2+σ1σ3+σ2σ3

Also lasst es uns programmieren!

HINWEIS: Sie MÜSSEN auf den Cloud-Service von D-Wave zugreifen, damit alles funktioniert.

Stellen Sie zunächst sicher, dass Sie das Python-Paket dwave_sapi2( https://cloud.dwavesys.com/qubist/downloads/ ) installiert haben. Alles wird Python 2.7 sein, da D-Wave derzeit keine höhere Python-Version unterstützt. Vor diesem Hintergrund wollen wir das Wesentliche importieren:

from dwave_sapi2.core import solve_ising
from dwave_sapi2.embedding import find_embedding, embed_problem, unembed_answer
from dwave_sapi2.util import get_hardware_adjacency
from dwave_sapi2.remote import RemoteConnection

Um eine Verbindung zur D-Wave Solver-API herzustellen, benötigen Sie ein gültiges API-Token für den SAPI-Solver, die SAPI-URL und müssen entscheiden, welchen Quantenprozessor Sie verwenden möchten:

DWAVE_SAPI_URL = 'https://cloud.dwavesys.com/sapi'
DWAVE_TOKEN = [your D-Wave API token]
DWAVE_SOLVER = 'DW_2000Q_VFYC_1'

Ich empfehle die Verwendung der D-Wave 2000Q VFYC (Virtual Full Yield Chimera), eines voll funktionsfähigen Chips ohne tote Qubits! Hier ist das Chimera-Chip-Layout:

dwave_chimera

An dieser Stelle teile ich das Tutorial in zwei Teile auf. Im ersten Abschnitt wird das Problem manuell in das Chimera-Hardware-Diagramm eingebettet, und im zweiten Abschnitt werden die Einbettungsheuristiken von D-Wave verwendet, um eine Hardware-Einbettung zu finden.

Manuelles Einbetten


Die Einheitszelle in der oberen linken Ecke des obigen D-Wave 2000Q-Chip-Layouts sieht folgendermaßen aus:

physical_qubits

Beachten Sie, dass in diesem Bild nicht alle Koppler sichtbar sind. Wie Sie sehen, gibt es zwischen Qubit und Qubit keinen Koppler, den wir für die direkte Implementierung unseres obigen quadratischen Diagramms benötigen würden. Deshalb definieren wir jetzt , , und . Dann definieren wir als Liste und als Wörterbuch:0100142733hJ

J = {(0,4): 1, (4,3): 1, (3,7): 1, (7,0): 1}
h = [-1,0,0,0,0,0,0,0,0]

h hat 8 Einträge, da wir die Qubits 0 bis 7 verwenden. Wir stellen nun eine Verbindung zur Solver-API her und fordern den D-Wave 2000Q VFYC-Solver an:

connection = RemoteConnection(DWAVE_SAPI_URL, DWAVE_TOKEN)
solver = connection.get_solver(DWAVE_SOLVER)

Jetzt können wir die Anzahl der Auslesungen definieren und answer_modeals "Histogramm" auswählen , das die Ergebnisse bereits nach der Anzahl der Vorkommen sortiert. Wir sind jetzt bereit, die Ising-Instanz mit dem D-Wave-Quanten-Annealer zu lösen:

params = {"answer_mode": 'histogram', "num_reads": 10000}
results = solve_ising(solver, h, J, **params)
print results

Sie sollten das folgende Ergebnis erhalten:

{
  'timing': {
    'total_real_time': 1655206,
    'anneal_time_per_run': 20,
    'post_processing_overhead_time': 13588,
    'qpu_sampling_time': 1640000,
    'readout_time_per_run': 123,
    'qpu_delay_time_per_sample': 21,
    'qpu_anneal_time_per_sample': 20,
    'total_post_processing_time': 97081,
    'qpu_programming_time': 8748,
    'run_time_chip': 1640000,
    'qpu_access_time': 1655206,
    'qpu_readout_time_per_sample': 123
  },
  'energies': [-5.0],
  'num_occurrences': [10000],
  'solutions': [
      [1, 3, 3, 1, -1, 3, 3, -1, {
          lots of 3 's that I am omitting}]]}

Wie Sie sehen, haben wir die richtige Grundzustandsenergie ( energies) von . Die Lösung String ist voll von ‚s , die die Standard - Ergebnis für nicht verwendete / ungemessene Qubits ist und wenn wir anwenden , um die Reverse - Transformationen - , , und - wir die richtige Lösung String bekommen . Getan!-5.0300417233[1,-1,-1,1]

Heuristische Einbettung


Wenn Sie beginnen, immer größere Ising-Instanzen zu erstellen, können Sie keine manuelle Einbettung durchführen. Nehmen wir also an, wir können unser 2D-Schachbrettbeispiel nicht manuell einbetten. und bleiben dann unverändert von unseren ursprünglichen Definitionen:Jh

J = {(0,1): 1, (0,2): 1, (1,3): 1, (2,3): 1}
h = [-1,0,0,0]

Wir stellen erneut die Remote-Verbindung her und erhalten die D-Wave 2000Q VFYC-Solver-Instanz:

connection = RemoteConnection(DWAVE_SAPI_URL, DWAVE_TOKEN)
solver = connection.get_solver(DWAVE_SOLVER)

Um eine Einbettung unseres Problems zu finden, müssen wir zuerst die Adjazenzmatrix des aktuellen Hardware-Graphen abrufen:

adjacency = get_hardware_adjacency(solver)

Versuchen wir nun, eine Einbettung unseres Problems zu finden:

embedding = find_embedding(J.keys(), adjacency)

Wenn Sie mit großen Ising-Instanzen arbeiten, möchten Sie möglicherweise nach Einbettungen in mehreren Threads (parallelisiert über mehrere CPUs) suchen und dann die Einbettung mit der geringsten Kettenlänge auswählen! Eine Kette ist, wenn mehrere Qubits gezwungen werden, als ein einziges Qubit zu fungieren, um den Konnektivitätsgrad zu erhöhen. Je länger die Kette ist, desto wahrscheinlicher ist es, dass sie bricht. Und gebrochene Ketten führen zu schlechten Ergebnissen!

Wir sind jetzt bereit, unser Problem in das Diagramm einzubetten:

[h, j0, jc, embeddings] = embed_problem(h, J, embedding, adjacency)

j0enthält die von uns definierten ursprünglichen Kopplungen und jcenthält die Kopplungen, die die Integrität der Ketten erzwingen (sie korrelieren die Qubits innerhalb der Ketten). Daher müssen wir sie erneut in einem großen Wörterbuch kombinieren :J

J = j0.copy()
J.update(jc)

Jetzt sind wir bereit, das eingebettete Problem zu lösen:

params = {"answer_mode": 'histogram', "num_reads": 10000}
raw_results = solve_ising(solver, h, J, **params)

print 'Lowest energy found: {}'.format(raw_results['energies'])
print 'Number of occurences: {}'.format(raw_results['num_occurrences'])

Das raw_resultsergibt für uns keinen Sinn, wenn wir das Problem nicht gelöst haben. Für den Fall, dass einige Ketten gerissen sind, korrigieren wir sie durch eine Mehrheitsabstimmung, wie im optionalen Argument definiert broken_chains:

unembedded_results = unembed_answer(raw_results['solutions'],
                                    embedding, broken_chains='vote')

print 'Solution string: {}'.format(unembedded_results)

Wenn Sie dies ausführen, sollten Sie in allen Anzeigen das richtige Ergebnis erhalten:

Lowest energy found: [-5.0]
Number of occurences: [10000]
Solution string: [[1, -1, -1, 1]]

Ich hoffe, dies hat Ihre Frage beantwortet, und ich empfehle dringend, alle zusätzlichen Parameter zu prüfen, die Sie an die solve_isingFunktion übergeben können, um die Qualität Ihrer Lösungen wie num_spin_reversal_transformsoder zu verbessern postprocess.


9

Der Titel und der Fragenkörper scheinen zwei verschiedene Fragen zu stellen. Im Titel fragen Sie "Wie schreibe ich ein einfaches Programm für ein D-Wave-Gerät?" Gerät, und was der entsprechende Code wäre (was eine spezifischere Frage ist).

Ich werde das erstere beantworten, da es die allgemeinere Frage ist.

Laut der D-Wave Software-Seite :

Das D-Wave 2000Q-System bietet eine Standard-Internet-API (basierend auf RESTful-Diensten) mit Client-Bibliotheken für C / C ++, Python und MATLAB. Diese Schnittstelle ermöglicht Benutzern den Zugriff auf das System entweder als Cloud-Ressource über ein Netzwerk oder integriert in ihre HPC-Umgebungen (High Performance Computing) und Rechenzentren. Der Zugriff ist auch über den gehosteten Cloud-Service von D-Wave möglich. Mit den Entwicklungstools und Client-Bibliotheken von D-Wave können Entwickler mithilfe von branchenüblichen Tools Algorithmen und Anwendungen in ihren vorhandenen Umgebungen erstellen.

Während Benutzer Probleme auf verschiedene Arten an das System senden können, stellt ein Problem letztendlich eine Reihe von Werten dar, die den Gewichten der Qubits und der Stärke der Koppler entsprechen. Das System nimmt diese Werte zusammen mit anderen benutzerdefinierten Parametern und sendet eine einzelne Quantenmaschinenanweisung (QMI) an die QPU. Problemlösungen entsprechen der optimalen Konfiguration der gefundenen Qubits; das sind die tiefsten Punkte in der Energielandschaft. Diese Werte werden über das Netzwerk an das Anwenderprogramm zurückgegeben.

Da Quantencomputer eher probabilistisch als deterministisch sind, können mehrere Werte zurückgegeben werden. Dies bietet nicht nur die beste Lösung, sondern auch andere sehr gute Alternativen zur Auswahl. Benutzer können die Anzahl der Lösungen angeben, die das System zurückgeben soll.

Benutzer können Probleme auf verschiedene Arten an den D-Wave-Quantencomputer senden:

  1. Verwenden eines Programms in C, C ++, Python oder MATLAB zum Erstellen und Ausführen von QMIs
  2. Verwenden eines D-Wave-Tools wie:

    • QSage , ein Übersetzer für Optimierungsprobleme

    • ToQ , ein hochqualifizierter Sprachübersetzer , der bei Problemen mit der Einschränkungszufriedenheit verwendet wird und den Benutzern ermöglicht, in der Sprache ihrer Problemdomäne zu „sprechen“

    • qbsolv , ein Open-Source-Optimierungslöser für Hybrid-Partitionierungen für Probleme, die größer sind, als sie von Haus aus auf die QPU passen. Qbsolv kann
      hier heruntergeladen werden .

    • dw führt QMIs aus, die mit einem Texteditor erstellt wurden

  3. Durch direkte Programmierung des Systems über QMIs

Laden Sie dieses Whitepaper herunter , um mehr über das Programmiermodell für ein D-Wave-System zu erfahren


5

Die Eingaben in die D-Welle sind eine Liste von Wechselwirkungen und in jüngerer Zeit die Glühzeit der Qubits.

Jichj=1

Ich empfehle die Anhänge in diesem Dokument, um eine kurze Beschreibung der Funktionsweise der D-Wave-Hardware zu erhalten. (Vollständige Offenlegung: Ich bin Mitautor.)


2
Vielleicht ist es sogar besser, wenn Sie einen größeren Teil der Antwort hier und nicht im Link einfügen? Als Mitautor der Zeitung sind Sie wahrscheinlich am besten geeignet, um eine gute Zusammenfassung zu erstellen.
Agaitaarino
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.