¿Cómo se escribe un programa simple para un dispositivo D-Wave?

27

Me gustaría saber cómo un trabajo para un dispositivo D-Wave se escribe en código y se envía al dispositivo.

En la respuesta, sería mejor ver un ejemplo específico de esto para un problema simple. Supongo que el "Hello World" de un dispositivo D-Wave sería algo así como encontrar los estados fundamentales de un modelo 2D Ising simple , ya que este es el tipo de problema que el hardware realiza directamente. Quizás este sería un buen ejemplo para ver. Pero si las personas con experiencia consideran que un ejemplo alternativo sería adecuado, estaría feliz de ver una alternativa.

James Wootton
fuente

Respuestas:

24

El equivalente de 'Hello World' en el mundo D-Wave es el ejemplo del tablero de ajedrez 2D. En este ejemplo, se le da el siguiente gráfico cuadrado con 4 nodos:

                                                  cuadrado_grafo

Definamos que vértice negro si y blanco si . El objetivo es crear un patrón de tablero de ajedrez con los cuatro vértices en el gráfico. Hay varias formas de definir y para lograr este resultado. En primer lugar, hay dos posibles soluciones a este problema: σ i = - 1 σ i = + 1 h Jσyoσyo=-1σyo=+1hJ

               checkerboard_solutions

El anillador cuántico D-Wave minimiza el Ising Hamiltoniano que definimos y es importante comprender el efecto de los diferentes ajustes del acoplador. Considere, por ejemplo, el acoplador :J0 0,1

Si lo establecemos en , el Hamiltoniano se minimiza si ambos qubits toman el mismo valor. Decimos que los acopladores negativos se correlacionan . Mientras que si lo establecemos en , el hamiltoniano se minimiza si los dos qubits toman valores opuestos. Por lo tanto, los acopladores positivos anti-correlacionan .J 0 , 1 = + 1J0 0,1=-1J0 0,1=+1

En el ejemplo del tablero de ajedrez, queremos anti-correlacionar cada par de qubits vecinos que da lugar al siguiente hamiltoniano:

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

En aras de la demostración, añadimos también un término de sesgo en el qubit -ésimo de tal manera que sólo tenemos la solución # 1. Esta solución requiere y, por lo tanto, establecemos su sesgo . El Hamiltoniano final es ahora:σ 0 = - 1 h 0 = 10 0σ0 0=-1h0 0=1

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

¡Así que codifíquelo!

NOTA: NECESITA acceso al servicio en la nube de D-Wave para que cualquier cosa funcione.

En primer lugar, asegúrese de tener instalado el paquete de Python dwave_sapi2( https://cloud.dwavesys.com/qubist/downloads/ ). Todo será Python 2.7 ya que D-Wave actualmente no es compatible con ninguna versión superior de Python. Dicho esto, importemos lo esencial:

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

Para conectarse a la API de D-Wave Solver, necesitará un token de API válido para su solucionador de SAPI, la URL de SAPI y deberá decidir qué procesador cuántico desea utilizar:

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

¡Recomiendo usar la D-Wave 2000Q Virtual Full Yield Chimera (VFYC), que es un chip completamente funcional sin qubits muertos! Aquí está el diseño del chip Chimera:

dwave_chimera

En este punto estoy dividiendo el tutorial en dos partes distintas. En la primera sección, estamos incrustando manualmente el problema en el gráfico de hardware de Chimera y en la segunda sección estamos usando la heurística de incrustación de D-Wave para encontrar una incrustación de hardware.

Inclusión manual


La celda de la unidad en la esquina superior izquierda en el diseño del chip D-Wave 2000Q anterior se ve así:

físicos_qubits

Tenga en cuenta que no todos los acopladores se visualizan en esta imagen. Como puede ver, no hay un acoplador entre qubit y qubit , que necesitaríamos para implementar directamente nuestro gráfico cuadrado anterior. Es por eso que ahora estamos redefiniendo , , y . Luego continuamos y definimos como una lista y como un diccionario:0 010 00 014 427 733hJ

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

h tiene 8 entradas ya que usamos qubits de 0 a 7. Ahora establecemos conexión con la API de Solver y solicitamos el solucionador D-Wave 2000Q VFYC:

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

Ahora, podemos definir el número de lecturas y elegir answer_modeser "histograma" que ya ordena los resultados por el número de ocurrencias para nosotros. Ahora estamos listos para resolver la instancia de Ising con el anillador cuántico D-Wave:

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

Deberías obtener el siguiente resultado:

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

Como puede ver, obtuvimos la energía correcta del estado fundamental ( energies) de . La cadena de solución está llena de , que es el resultado predeterminado para qubits no utilizados / no medidos y si aplicamos las transformaciones inversas - , , y - obtenemos la cadena de solución correcta . ¡Hecho!-5.030 00 04 417 7233[1,-1,-1,1]

Incrustación heurística


Si comienza a crear instancias de Ising cada vez más grandes, no podrá realizar la incrustación manual. Supongamos que no podemos incrustar manualmente nuestro ejemplo de tablero de ajedrez 2D. y luego permanecen sin cambios desde nuestras definiciones iniciales:Jh

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

Nuevamente establecemos la conexión remota y obtenemos la instancia del solucionador D-Wave 2000Q VFYC:

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

Para encontrar una incrustación de nuestro problema, primero debemos obtener la matriz de adyacencia del gráfico de hardware actual:

adjacency = get_hardware_adjacency(solver)

Ahora intentemos encontrar una incrustación de nuestro problema:

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

Si se trata de grandes instancias de Ising, es posible que desee buscar incrustaciones en varios subprocesos (en paralelo en varias CPU) y luego seleccionar la incrustación con la longitud de cadena más pequeña. Una cadena es cuando múltiples qubits se ven obligados a actuar como un solo qubit para aumentar el grado de conectividad. Sin embargo, cuanto más larga sea la cadena, más probable es que se rompa. ¡Y las cadenas rotas dan malos resultados!

Ahora estamos listos para insertar nuestro problema en el gráfico:

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

j0jcJ

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

Ahora, estamos listos para resolver el problema incrustado:

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

No raw_resultstendrá sentido para nosotros a menos que hayamos descifrado el problema. En caso de que algunas cadenas se rompan, las estamos arreglando a través de un voto mayoritario según lo define el argumento opcional broken_chains:

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

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

Si ejecuta esto, debería obtener el resultado correcto en todas las lecturas:

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

Espero que esto haya respondido a su pregunta y le recomiendo que consulte todos los parámetros adicionales que puede pasar a la solve_isingfunción para mejorar la calidad de sus soluciones, como num_spin_reversal_transformso postprocess.

Mark Fingerhuth
fuente
9

El título y el cuerpo de la pregunta parecen hacer dos preguntas diferentes. En el título, pregunta "¿Cómo escribir un programa simple para un dispositivo D-Wave?", Mientras que en el cuerpo de la pregunta pregunta cómo encontrar los estados fundamentales de un modelo de Ising 2D simple utilizando el hardware subyacente del D-Wave dispositivo y cuál sería el código correspondiente (que es una pregunta más específica).

Contestaré a la primera, ya que es la pregunta más general.

Según la página del software D-Wave :

El sistema D-Wave 2000Q proporciona una API de Internet estándar (basada en servicios RESTful), con bibliotecas de clientes disponibles para C / C ++, Python y MATLAB. Esta interfaz permite a los usuarios acceder al sistema como un recurso en la nube a través de una red o integrado en sus entornos de cómputo de alto rendimiento (HPC) y centros de datos. El acceso también está disponible a través del servicio en la nube alojado de D-Wave. Utilizando las herramientas de desarrollo y las bibliotecas de clientes de D-Wave, los desarrolladores pueden crear algoritmos y aplicaciones dentro de sus entornos existentes utilizando herramientas estándar de la industria.

Si bien los usuarios pueden enviar problemas al sistema de diferentes maneras, en última instancia, un problema representa un conjunto de valores que corresponden a los pesos de los qubits y la fuerza de los acopladores. El sistema toma estos valores junto con otros parámetros especificados por el usuario y envía una única instrucción de máquina cuántica (QMI) a la QPU. Las soluciones de problemas corresponden a la configuración óptima de qubits encontrados; es decir, los puntos más bajos en el panorama energético. Estos valores se devuelven al programa de usuario a través de la red.

Debido a que las computadoras cuánticas son probabilísticas en lugar de deterministas, se pueden devolver múltiples valores, proporcionando no solo la mejor solución encontrada, sino también otras muy buenas alternativas para elegir. Los usuarios pueden especificar la cantidad de soluciones que desean que regrese el sistema.

Los usuarios pueden enviar problemas a la computadora cuántica D-Wave de varias maneras:

  1. Usar un programa en C, C ++, Python o MATLAB para crear y ejecutar QMI
  2. Usando una herramienta D-Wave como:

    • QSage , un traductor diseñado para problemas de optimización

    • ToQ , un traductor de idiomas de alto nivel utilizado para problemas de satisfacción de restricciones y diseñado para permitir a los usuarios "hablar" en el idioma de su dominio del problema

    • qbsolv , un solucionador de optimización de particionamiento híbrido de código abierto para problemas que son más grandes que los que caben de forma nativa en la QPU. Qbsolv se
      puede descargar aquí .

    • dw , que ejecuta los QMI creados a través de un editor de texto

  3. Mediante la programación directa del sistema a través de QMI

Descargue este documento técnico para obtener más información sobre el modelo de programación para un sistema D-Wave

Sanchayan Dutta
fuente
5

Las entradas a la D-Wave son una lista de interacciones y, más recientemente, el tiempo de recocido de los qubits.

Jyoj=1

Recomiendo los apéndices en este documento para una descripción concisa de cómo funciona el hardware D-Wave. (Divulgación completa: soy coautor).

Andrew O
fuente
2
¿Podría ser aún mejor si incluye una mayor parte de la respuesta aquí, en lugar de en el enlace? Al ser coautor del artículo, probablemente sea el más adecuado para hacer un buen resumen.
agaitaarino