Comment écrivez-vous un programme simple pour un appareil D-Wave?

27

Je voudrais savoir comment un travail pour un appareil D-Wave est écrit en code et soumis à l'appareil.

Dans la réponse, il serait préférable de voir un exemple spécifique de cela pour un problème simple. Je suppose que le "Hello World" d'un appareil D-Wave serait quelque chose comme trouver les états fondamentaux d'un simple modèle 2D Ising , car c'est le genre de problème directement réalisé par le matériel. Ce serait donc peut-être un bel exemple à voir. Mais si ceux qui ont une expertise, un exemple alternatif conviendrait, je serais heureux de voir une alternative.

James Wootton
la source

Réponses:

24

L'équivalent de «Hello World» dans le monde D-Wave est l'exemple de damier 2D. Dans cet exemple, vous obtenez le graphique carré suivant à 4 nœuds:

                                                  square_graph

Définissons que nous colorions le sommet noir si et le blanc si . Le but est de créer un motif en damier avec les quatre sommets du graphique. Il existe différentes manières de définir et pour obtenir ce résultat. Tout d'abord, il existe deux solutions possibles à ce problème:σiσi=1σi=+1hJ

               checkerboard_solutions

Le recuit quantique D-Wave minimise l'hamiltonien d'Ising que nous définissons et il est important de comprendre l'effet des différents réglages du coupleur. Considérons par exemple le coupleur :J0,1

Si nous le sur , l'hamiltonien est minimisé si les deux qubits prennent la même valeur. Nous disons que les coupleurs négatifs sont corrélés . Alors que si nous le à , l'hamiltonien est minimisé si les deux qubits prennent des valeurs opposées. Ainsi, les coupleurs positifs sont anti-corrélés .J0,1=1J0,1=+1

Dans l'exemple en damier, nous voulons anti-corréler chaque paire de qubits voisins ce qui donne le hamiltonien suivant:

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

Par souci de démonstration, nous ajoutons également un terme de biais sur le ème qubit de sorte que nous n'obtenions que la solution # 1. Cette solution nécessite et nous définissons donc son biais . Le hamiltonien final est maintenant:0σ0=1h0=1

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

Alors codons-le!

REMARQUE: vous AVEZ BESOIN d'un accès au service cloud de D-Wave pour que tout fonctionne.

Tout d'abord, assurez-vous que le package Python dwave_sapi2( https://cloud.dwavesys.com/qubist/downloads/ ) est installé. Tout va être Python 2.7 puisque D-Wave ne prend actuellement en charge aucune version Python supérieure. Cela étant dit, importons l'essentiel:

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

Pour vous connecter à l'API D-Wave Solver, vous aurez besoin d'un jeton d'API valide pour leur solveur SAPI, de l'URL SAPI et vous devez décider quel processeur quantique vous souhaitez utiliser:

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

Je recommande d'utiliser la chimère D-Wave 2000Q Virtual Full Yield Chimera (VFYC) qui est une puce entièrement fonctionnelle sans aucun qubits morts! Voici la disposition des puces Chimera:

dwave_chimera

À ce stade, je divise le didacticiel en deux parties distinctes. Dans la première section, nous intégrons manuellement le problème dans le graphique matériel Chimera et dans la deuxième section, nous utilisons l'heuristique d'intégration de D-Wave pour trouver une intégration matérielle.

Incorporation manuelle


La cellule unitaire dans le coin supérieur gauche de la disposition des puces D-Wave 2000Q ci-dessus ressemble à ceci:

physique_qubits

Notez que tous les coupleurs ne sont pas visualisés sur cette image. Comme vous pouvez le voir, il n'y a pas de coupleur entre qubit et qubit dont nous aurions besoin pour implémenter directement notre graphique carré ci-dessus. C'est pourquoi nous redéfinissons maintenant , , et . Nous continuons ensuite et définissons comme une liste et comme un dictionnaire: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 a 8 entrées depuis que nous utilisons les qubits 0 à 7. Nous établissons maintenant la connexion à l'API Solver et demandons le solveur D-Wave 2000Q VFYC:

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

Maintenant, nous pouvons définir le nombre de lectures et choisir answer_moded'être "histogramme" qui trie déjà les résultats par le nombre d'occurrences pour nous. Nous sommes maintenant prêts à résoudre l'instance d'Ising avec le recuit quantique D-Wave:

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

Vous devriez obtenir le résultat suivant:

{
  '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}]]}

Comme vous pouvez le voir, nous avons obtenu la bonne énergie d'état fondamental ( energies) de . La chaîne de solution est pleine de , ce qui est le résultat par défaut pour les qubits inutilisés / non mesurés et si nous appliquons les transformations inverses - , , et - nous obtenons la chaîne de solution correcte . Terminé!5.0300417233[1,1,1,1]

Incorporation heuristique


Si vous commencez à créer des instances Ising de plus en plus grandes, vous ne pourrez pas effectuer d'incorporation manuelle. Supposons donc que nous ne pouvons pas incorporer manuellement notre exemple de damier 2D. et restent alors inchangés par rapport à nos définitions initiales:Jh

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

Nous établissons à nouveau la connexion à distance et obtenons l'instance de solveur D-Wave 2000Q VFYC:

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

Afin de trouver une intégration de notre problème, nous devons d'abord obtenir la matrice d'adjacence du graphe matériel actuel:

adjacency = get_hardware_adjacency(solver)

Essayons maintenant de trouver une intégration de notre problème:

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

Si vous avez affaire à de grandes instances Ising, vous pouvez rechercher des incorporations dans plusieurs threads (parallélisées sur plusieurs processeurs), puis sélectionner l'incorporation avec la plus petite longueur de chaîne! Une chaîne, c'est lorsque plusieurs qubits sont forcés d'agir comme un seul qubit afin d'augmenter le degré de connectivité. Cependant, plus la chaîne est longue, plus elle risque de se casser. Et les chaînes cassées donnent de mauvais résultats!

Nous sommes maintenant prêts à intégrer notre problème dans le graphique:

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

j0contient les couplages d'origine que nous avons définis et jccontient les couplages qui renforcent l'intégrité des chaînes (ils corrèlent les qubits au sein des chaînes). Ainsi, nous devons les combiner à nouveau dans un grand dictionnaire :J

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

Maintenant, nous sommes prêts à résoudre le problème intégré:

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'])

Le raw_resultsne sera pas de sens pour nous à moins que nous le problème annuler l' incorporation. Dans le cas où certaines chaînes se sont rompues, nous les réparons par un vote majoritaire tel que défini par l'argument facultatif broken_chains:

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

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

Si vous exécutez ceci, vous devriez obtenir le résultat correct dans toutes les lectures:

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

J'espère que cela a répondu à votre question et je vous recommande fortement de vérifier tous les paramètres supplémentaires que vous pouvez passer à la solve_isingfonction pour améliorer la qualité de vos solutions telles que num_spin_reversal_transformsou postprocess.

Mark Fingerhuth
la source
9

Le titre et le corps de la question semblent poser deux questions différentes. Dans le titre, vous demandez «Comment écrivez-vous un programme simple pour un appareil D-Wave? périphérique, et quel serait le code correspondant (ce qui est une question plus spécifique).

Je répondrai à la première, car c'est la question la plus générale.

Selon la page du logiciel D-Wave :

Le système D-Wave 2000Q fournit une API Internet standard (basée sur les services RESTful), avec des bibliothèques clientes disponibles pour C / C ++, Python et MATLAB. Cette interface permet aux utilisateurs d'accéder au système en tant que ressource cloud sur un réseau ou intégrés dans leurs environnements de calcul haute performance (HPC) et centres de données. L'accès est également disponible via le service cloud hébergé de D-Wave. À l'aide des outils de développement et des bibliothèques clientes de D-Wave, les développeurs peuvent créer des algorithmes et des applications dans leurs environnements existants à l'aide d'outils standard de l'industrie.

Alors que les utilisateurs peuvent soumettre des problèmes au système de différentes manières, un problème représente finalement un ensemble de valeurs qui correspondent aux poids des qubits et à la force des coupleurs. Le système prend ces valeurs avec d'autres paramètres spécifiés par l'utilisateur et envoie une seule instruction de machine quantique (QMI) à la QPU. Les solutions aux problèmes correspondent à la configuration optimale des qubits trouvés; c'est-à-dire les points les plus bas du paysage énergétique. Ces valeurs sont renvoyées au programme utilisateur sur le réseau.

Parce que les ordinateurs quantiques sont probabilistes plutôt que déterministes, plusieurs valeurs peuvent être renvoyées, fournissant non seulement la meilleure solution trouvée, mais aussi d'autres très bonnes alternatives parmi lesquelles choisir. Les utilisateurs peuvent spécifier le nombre de solutions qu'ils souhaitent que le système renvoie.

Les utilisateurs peuvent soumettre des problèmes à l'ordinateur quantique D-Wave de plusieurs manières:

  1. Utilisation d'un programme en C, C ++, Python ou MATLAB pour créer et exécuter des QMI
  2. Utilisation d'un outil D-Wave tel que:

    • QSage , un traducteur conçu pour les problèmes d'optimisation

    • ToQ , un traducteur de langage de haut niveau utilisé pour les problèmes de satisfaction des contraintes et conçu pour permettre aux utilisateurs de «parler» dans la langue de leur domaine de problème

    • qbsolv , un solveur d'optimisation de partitionnement hybride open source pour les problèmes qui sont plus importants que ceux qui s'intègrent nativement sur le QPU. Qbsolv peut
      être téléchargé ici .

    • dw , qui exécute les QMI créés via un éditeur de texte

  3. En programmant directement le système via des QMI

Téléchargez ce livre blanc pour en savoir plus sur le modèle de programmation d'un système D-Wave

Sanchayan Dutta
la source
5

Les entrées de la D-Wave sont une liste d'interactions et plus récemment le temps de recuit des qubits.

Comme vous l'avez mentionné, le problème d'Ising est l'un des plus faciles avec dans le problème hamiltonien mais ce n'est pas très intéressant.Jij=1

Je recommande les annexes de ce document pour une description concise du fonctionnement du matériel D-Wave. (Divulgation complète: je suis coauteur.)

Andrew O
la source
2
Cela pourrait être encore mieux si vous incluez une plus grande partie de la réponse ici, plutôt que dans le lien? En tant que co-auteur de l'article, vous êtes probablement le mieux placé pour faire un bon résumé.
agaitaarino