Como enviar um circuito com o Cirq para o Azure Quantum

Saiba como enviar um circuito quântico Cirq usando o azure-quantumPython pacote. Você pode enviar circuitos Cirq para o Azure Quantum usando o notebook do Azure Quantum, que tem um pacote interno azure-quantumPython , ou do computador local.

Para mais informações, consulte Circuitos quânticos.

Pré-requisitos

Para obter detalhes de instalação, consulte Instalando o QDK no VS Code.

  • Um espaço de trabalho do Azure Quantum em sua assinatura do Azure. Para criar um espaço de trabalho, consulte Criar um espaço de trabalho no Azure Quantum.

  • Um Python ambiente com Python e Pip instalado.

  • VS Code com o Kit de Desenvolvimento do Azure Quantum, Pythono , e as extensões Jupyter instaladas.

  • O pacote do Azure Quantum azure-quantum com a marca [cirq] e os qsharp pacotes e .ipykernel

    python -m pip install --upgrade azure-quantum[cirq] qsharp ipykernel 
    

    Observação

    Se o kernel ipykernel Jupyter Python não for detectado, o VS Code solicitará que você o instale.

Criar um novo Jupyter Notebook

  1. No VS Code, selecione Exibir > Paleta de comandos e selecione Criar: Novo Jupyter Notebook.
  2. No canto superior direito, o VS Code detectará e exibirá a versão e Python o ambiente virtual Python que foi selecionado para o notebook. Se você tiver vários Python ambientes, talvez seja necessário selecionar um kernel usando o seletor de kernel no canto superior direito. Se nenhum ambiente foi detectado, consulte Jupyter Notebooks no VS Code para obter informações de configuração.

Carregar as importações necessárias

Na primeira célula do seu notebook, execute o seguinte código para carregar as importações necessárias:

import azure.quantum
from azure.quantum.cirq import AzureQuantumService

Conectar ao serviço do Azure Quantum

Para se conectar ao serviço do Azure Quantum, seu programa precisará da ID do recurso e do local do workspace do Azure Quantum.

  1. Faça login em sua conta do Azure, https://portal.azure.com,

  2. Selecione seu workspace do Azure Quantum e navegue até Visão geral.

  3. Copie os parâmetros nos campos.

    Captura de tela do Visual Studio Code mostrando como expandir o painel de visão geral do workspace do Quantum.

Adicione uma nova célula e use as informações da sua conta para criar Workspace objetos e AzureQuantumService se conectar ao workspace do Azure Quantum.

workspace = Workspace(  
    resource_id = "", # Add the resourceID of your workspace
    location = "" # Add the location of your workspace (for example "westus")
    )

service = AzureQuantumService(workspace)

Listar tudo targets

Use o targets()método para listar todos os targets itens em seu workspace que podem executar seu circuito, incluindo o tempo de fila atual e a disponibilidade.

Observação

Todos os targets em seu espaço de trabalho podem não estar listados - apenas aqueles targets que podem aceitar um circuito Cirq ou OpenQASM serão listados aqui.

print(service.targets())
[<Target name="quantinuum.qpu.h1-1", avg. queue time=0 s, Degraded>,
<Target name="quantinuum.sim.h1-1sc", avg. queue time=1 s, Available>,
<Target name="quantinuum.sim.h1-1e", avg. queue time=40 s, Available>,
<Target name="ionq.simulator", avg. queue time=3 s, Available>,
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>]

Crie um circuito simples

Em seguida, crie um circuito Cirq simples para executar. Esse circuito usa a raiz quadrada da porta X, nativa do sistema de hardware do IonQ.

import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.X(q0)**0.5,             # Square root of X
    cirq.CX(q0, q1),              # CNOT
    cirq.measure(q0, q1, key='b') # Measure both qubits
)
print(circuit)
0: ───X^0.5───@───M────────
              │   │
1: ───────────X───M────────

Selecione um target para executar seu programa

Executar no simulador IonQ

Agora você pode executar o programa por meio do serviço do Azure Quantum e obter o resultado. A célula a seguir envia um trabalho (para o simulador do IonQ padrão) que executa o circuito com 100 disparos, aguarda até que o trabalho seja concluído e retorna os resultados.

result = service.run(program=circuit, repetitions=100, target="ionq.simulator")

Será retornado um objeto cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Estimar o custo do trabalho

Antes de executar um trabalho na QPU, você deve estimar quanto custará para ser executado.

Para obter os detalhes de preços mais atuais, consulte Preços do IonQ ou localize seu workspace e exiba as opções de preço na guia "Provedor" do workspace por meio de: aka.ms/aq/myworkspaces.

Executar na QPU do IonQ

O trabalho anterior foi executado no simulador padrão, "ionq.simulator". No entanto, você também pode executá-lo no processador de hardware do IonQ – uma QPU (Unidade de Processador Quântico). Para executar na QPU do IonQ, forneça "ionq.qpu.aria-1" como o argumento target:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu.aria-1",
    timeout_seconds=500 # Set timeout to accommodate queue time on QPU
)

Será retornado novamente um objeto cirq.Result.

print(result)
b=0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111, 0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111

Modelo assíncrono usando trabalhos

Para circuitos de execução longa, pode ser útil executar os circuitos de maneira assíncrona. O método service.create_job retorna um objeto Job, que você pode usar para obter os resultados depois que o trabalho for executado com êxito.

job = service.create_job(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Para verificar o status do trabalho, use job.status():

print(job.status())
'completed'

Para aguardar a conclusão do trabalho e obter os resultados, use a chamada de bloqueio job.results():

result = job.results()
print(result)
00: 0.5
11: 0.5

Observe que isso não retorna um objeto cirq.Result. Em vez disso, ela retorna um objeto de resultado específico do simulador do IonQ e usa probabilidades de estado em vez de dados de disparo.

type(result)
cirq_ionq.results.SimulatorResult

Para converter isso em um objeto cirq.Result, use result.to_cirq_result():

print(result.to_cirq_result())
b=1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100, 1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100

Pré-requisitos

  • Uma conta do Azure com uma assinatura ativa. Se você não tiver uma conta do Azure, registre-se gratuitamente e inscreva-se para uma assinatura paga conforme o uso.
  • Um workspace do Azure Quantum. Para obter mais informações, confira Criar um workspace do Azure Quantum.

Criar um notebook em seu workspace

  1. Faça logon no portal do Azure e selecione o workspace da etapa anterior.
  2. No painel à esquerda, selecione Notebooks.
  3. Clique em Meus Notebooks e em Adicionar Novo.
  4. Digite um nome para o arquivo, por exemplo, Cirq.ipynb, e clique em Criar arquivo.

Quando o novo notebook é aberto, ele cria automaticamente o código da primeira célula com base na assinatura e nas informações do workspace.

from azure.quantum import Workspace
workspace = Workspace ( 
  resource_id = "", # Add your resource_id 
  location = ""  # Add your workspace location (for example, "westus") 
)

Observação

Salvo indicação em contrário, você deve executar cada célula na ordem em que a cria para evitar problemas de compilação.

Clique no ícone triangular "reproduzir" à esquerda da célula para executar o código.

Carregar as importações necessárias

Primeiro, você precisará importar um módulo adicional.

Clique em + Código para adicionar uma nova célula e, em seguida, adicione e execute o seguinte código:

from azure.quantum.cirq import AzureQuantumService

Conectar ao serviço do Azure Quantum

Em seguida, crie um AzureQuantumService objeto usando o workspace objeto da célula anterior para se conectar ao workspace do Azure Quantum. Adicione uma nova célula com o seguinte código:

provider = AzureQuantumService(workspace)

Definir um circuito simples

Em seguida, crie um circuito Cirq simples para executar. Esse circuito usa a raiz quadrada da porta X, nativa do sistema de hardware do IonQ.

import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.X(q0)**0.5,             # Square root of X
    cirq.CX(q0, q1),              # CNOT
    cirq.measure(q0, q1, key='b') # Measure both qubits
)
print(circuit)
0: ───X^0.5───@───M────────
              │   │
1: ───────────X───M────────

Listar tudo targets

Use o targets()método para listar todos os targets itens em seu workspace que podem executar seu circuito, incluindo o tempo de fila atual e a disponibilidade.

Observação

Todos os targets em seu espaço de trabalho podem não estar listados - apenas aqueles targets que podem aceitar um circuito Cirq ou OpenQASM serão listados aqui.

print("This workspace's targets:")
for target in service.targets():
     print(target)
This workspace's targets:
<Target name="quantinuum.qpu.h1-1", avg. queue time=0 s, Degraded>
<Target name="quantinuum.sim.h1-1sc", avg. queue time=1 s, Available>
<Target name="quantinuum.sim.h1-1e", avg. queue time=40 s, Available>
<Target name="ionq.simulator", avg. queue time=3 s, Available>
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>

Observação

A lista completa de pode ser diferente para o seu espaço de target trabalho.

Selecione um target para executar seu programa

Executar no simulador do IonQ

Para verificar o circuito antes de ser executado no hardware quântico real, você pode usar o simulador de IonQ, ionq.simulator.

A célula a seguir envia um trabalho que executa o circuito com 100 disparos, aguarda até que o trabalho seja concluído e retorna os resultados.

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Será retornado um objeto cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Você pode plotar os resultados em um histograma:

import pylab as pl

pl.hist(result.data)
pl.ylabel("Counts")
pl.xlabel("Result")

Estimar o custo do trabalho

Antes de executar um trabalho em hardware quântico real ou em uma unidade de processamento quântico (QPU), você deve estimar quanto custará para ser executado.

Para obter os detalhes de preços mais atuais, consulte Preços do IonQ ou exibir opções de preços na folha Provedores do seu workspace. Para ver o status e o uso do crédito atual, selecione Créditos e cotas.

Executar na QPU do IonQ

O trabalho anterior foi executado no simulador padrão, ionq.simulator. No entanto, você também pode executá-lo no processador de hardware do IonQ ou em uma QPU (unidade de processamento quântico). Para executar na QPU do IonQ, forneça ionq.qpu.aria-1 como o argumento target:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu.aria-1",
    timeout_seconds=500 # Set timeout to accommodate queue time on QPU
)

Observação

O tempo necessário para executar um circuito na QPU pode variar dependendo dos tempos de fila atuais. Você pode exibir o tempo médio de fila para um target selecionando a folha Provedores do seu workspace.

Será retornado novamente um objeto cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Modelo assíncrono usando trabalhos

Para circuitos de execução longa, pode ser útil executar os circuitos de maneira assíncrona. O método service.create_job retorna um objeto Job, que você pode usar para obter os resultados depois que o trabalho for executado com êxito.

job = service.create_job(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Para verificar o status do trabalho, use job.status():

print(job.status())
'completed'

Para aguardar a conclusão do trabalho e obter os resultados, use a chamada de bloqueio job.results():

result = job.results()
print(result)
00: 0.5
11: 0.5

Observação

A função job.results() não retorna um objeto cirq.Result. Em vez disso, ela retorna um objeto de resultado específico do simulador do IonQ e usa probabilidades de estado em vez de dados de disparo.

type(result)
cirq_ionq.results.SimulatorResult

Para converter isso em um objeto cirq.Result, use result.to_cirq_result():

print(result.to_cirq_result())
b=1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100, 1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100

Importante

Atualmente, não há suporte para o envio de vários circuitos em apenas um trabalho. Como solução alternativa, você pode chamar o método backend.run para enviar cada circuito de modo assíncrono e buscar os resultados de cada trabalho. Por exemplo:

jobs = []
for circuit in circuits:
    jobs.append(backend.run(circuit, shots=N))

results = []
for job in jobs:
    results.append(job.result())