Partilhar via


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 bloco de azure-quantumPython anotações do Azure Quantum, que tem pacote interno, ou de sua máquina local.

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

Nota

O Microsoft Quantum Development Kit (Classic QDK) não será mais suportado após 30 de junho de 2024. Se você for um desenvolvedor QDK existente, recomendamos que faça a transição para o novo Kit de Desenvolvimento Quântico do Azure (QDK Moderno) para continuar desenvolvendo soluções quânticas. Para obter mais informações, consulte Migrar seu código Q# para o QDK moderno.

Pré-requisitos

Para obter detalhes da instalação, consulte Instalando o QDK moderno 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 do Azure Quantum.

  • Um Python ambiente com Python e Pip instalado.

  • VS Code com o Azure Quantum Development Kit Pythone as extensões Jupyter instaladas.

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

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

    Nota

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

Criar um novo Jupyter Notebook

  1. No VS Code, selecione View > Command palette e selecione Create: New Jupyter Notebook.
  2. No canto superior direito, o VS Code detetará 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 detetado, consulte Jupyter Notebooks no VS Code para obter informações de configuração.

Carregue as importações necessárias

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

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

Conectar-se ao serviço Azure Quantum

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

  1. Inicie sessão na sua conta do Azure, https://portal.azure.com,

  2. Selecione seu espaço de trabalho 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 seu Quantum Workspace.

Adicione uma nova célula e use as informações da sua conta para criar Workspace e AzureQuantumService objetos para se conectar ao seu espaço de trabalho 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 espaço de trabalho que podem executar seu circuito, incluindo o tempo de fila atual e a disponibilidade.

Nota

Todos os targets que estão no seu espaço de trabalho podem não estar listados - apenas os 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.qpu", avg. queue time=229 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. Este circuito usa a raiz quadrada do portão X, nativa do sistema de hardware 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 o programa

Executar no simulador IonQ

Agora você pode executar o programa por meio do serviço Azure Quantum e obter o resultado. A célula a seguir envia um trabalho (para o simulador 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")

Isso retorna um cirq.Result objeto.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Estimar o custo do trabalho

Antes de executar um trabalho na QPU, você pode estimar quanto custará para ser executado. Para estimar o custo de execução de um trabalho na QPU, você pode usar o estimate_cost método:

cost = service.estimate_cost(
    program=circuit,
    repetitions=100,
    target="ionq.qpu"
)

print(f"Estimated cost: {cost.estimated_total}")

Isto imprime o custo estimado em dólares americanos.

Para obter os detalhes de preços mais atuais, consulte Preços IonQ ou encontre seu espaço de trabalho e veja as opções de preços na guia "Provedor" do seu espaço de trabalho via: aka.ms/aq/myworkspaces.

Executar em IonQ QPU

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 unidade de processador quântico (QPU)). Para executar na QPU IonQ, forneça "ionq.qpu" como argumento target :

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

Novamente, isso retorna um cirq.Result objeto.

print(result)
b=0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111, 0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111

Modelo assíncrono usando trabalhos

Para circuitos de longa duração, pode ser útil executá-los de forma assíncrona. O service.create_job método retorna um Job objeto, que você pode usar para obter os resultados depois que o trabalho foi 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, em seguida, obter os resultados, use a chamada job.results()de bloqueio :

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

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

type(result)
cirq_ionq.results.SimulatorResult

Para convertê-lo em um cirq.Result objeto, use result.to_cirq_result():

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

Pré-requisitos

  • Uma conta do Azure com uma subscrição ativa. Se não tiver uma conta do Azure, registe-se gratuitamente e inscreva-se numa subscrição pré-paga.
  • Um espaço de trabalho do Azure Quantum. Para obter mais informações, consulte Criar um espaço de trabalho do Azure Quantum.

Criar um novo bloco de notas na sua área de trabalho

  1. Faça logon no portal do Azure e selecione o espaço de trabalho na etapa anterior.
  2. Na folha esquerda, selecione Blocos de Notas.
  3. Clique em Meus Blocos de Anotações e clique em Adicionar Novo.
  4. Digite um nome para o arquivo, por exemplo Cirq.ipynb, e clique em Criar arquivo.

Quando o novo bloco de notas é aberto, cria automaticamente o código para a primeira célula, com base na sua subscrição e nas informações da área de trabalho.

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

Nota

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

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

Carregue 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-se ao serviço Azure Quantum

Em seguida, crie um AzureQuantumService objeto usando o workspace objeto da célula anterior para se conectar ao seu espaço de trabalho 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. Este circuito usa a raiz quadrada do portão X, nativa do sistema de hardware 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 espaço de trabalho que podem executar seu circuito, incluindo o tempo de fila atual e a disponibilidade.

Nota

Todos os targets que estão no seu espaço de trabalho podem não estar listados - apenas os 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.qpu", avg. queue time=229 s, Available>
<Target name="ionq.simulator", avg. queue time=3 s, Available>
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>

Nota

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

Selecione um target para executar o programa

Executar no simulador IonQ

Para verificar o seu circuito antes de executá-lo em hardware quântico real, você pode usar o simulador 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"
)

Isso retorna um cirq.Result objeto.

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 uma unidade de processamento quântico (QPU), você pode estimar quanto custará para ser executado. Para estimar o custo de execução de um trabalho na QPU, você pode usar o estimate_cost método:

cost = service.estimate_cost(
    program=circuit,
    repetitions=100,
    target="ionq.qpu"
)

print(f"Estimated cost: {cost.estimated_total}")
Estimated cost: 1

Isto imprime o custo estimado em dólares americanos.

Para obter os detalhes de preços mais atuais, consulte Preços IonQ ou veja as opções de preços na folha Provedores do seu espaço de trabalho. Para ver o seu estado de crédito atual e utilização, selecione Créditos e quotas.

Executar em IonQ QPU

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 Quantum Processor Unit (QPU). Para executar na QPU IonQ, forneça ionq.qpu como argumento target :

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

Nota

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

Novamente, isso retorna um cirq.Result objeto.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Modelo assíncrono usando trabalhos

Para circuitos de longa duração, pode ser útil executá-los de forma assíncrona. O service.create_job método retorna um Job objeto, que você pode usar para obter os resultados depois que o trabalho foi 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, em seguida, obter os resultados, use a chamada job.results()de bloqueio :

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

Nota

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

type(result)
cirq_ionq.results.SimulatorResult

Para convertê-lo em um cirq.Result objeto, 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 um único trabalho. Como solução alternativa, você pode chamar o método para enviar cada circuito de forma assíncrona backend.run e, em seguida, 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())

Próximos passos