Skip to main content
IBM Quantum Platform

Notas de versão do Qiskit 0.33


0.33.1

Terra 0.19.1

Prelúdio

O Qiskit Terra 0.19.1 é uma versão de correção de bugs que resolve alguns problemas em 0.19.0 referentes a circuitos construídos pela interface do construtor de fluxo de controle, portas condicionais e serialização QPY de objetos Terra mais recentes.

Notas de descontinuação

  • As funções soltas qiskit.circuit.measure.measure() e qiskit.circuit.reset.reset() estão obsoletas e serão removidas em uma versão futura. Em vez disso, você deve acessá-los como métodos em QuantumCircuit:

    from qiskit import QuantumCircuit
    circuit = QuantumCircuit(1, 1)
    
    # Replace this deprecated form ...
    from qiskit.circuit.measure import measure
    measure(circuit, 0, 0)
    
    # ... with either of the next two lines:
    circuit.measure(0, 0)
    QuantumCircuit.measure(circuit, 0, 0)

Correções de bugs

  • Correção de um erro nas funções de conversão de circuitos circuit_to_gate() e circuit_to_instruction() (e seus métodos de circuito associados QuantumCircuit.to_gate() e QuantumCircuit.to_instruction()) ao atuar em um circuito com bits sem registro ou bits em mais de um registro. Anteriormente, o número de bits necessários para a porta ou instrução criada era calculado incorretamente, o que geralmente causava uma exceção durante a conversão.

  • Foi corrigido um problema em que chamar QuantumCircuit.copy() nos circuitos "body" de uma operação de fluxo de controle criada com a interface do construtor gerava um erro. Por exemplo, isso era anteriormente um erro, mas agora retornará com êxito:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qreg = QuantumRegister(4)
    creg = ClassicalRegister(1)
    circ = QuantumCircuit(qreg, creg)
    
    with circ.if_test((creg, 0)):
        circ.h(0)
    
    if_else_instruction, _, _ = circ.data[0]
    true_body = if_else_instruction.params[0]
    true_body.copy()
  • A interface do construtor de fluxo de controle agora suporta o uso de ClassicalRegisters como condições em escopos de fluxo de controle aninhados. Anteriormente, fazer isso não gerava um erro imediatamente, mas os blocos de circuitos internos não tinham os registros corretos definidos e, portanto, a lógica posterior que funcionava com os blocos internos falhava.

    Por exemplo, anteriormente, as gavetas falhariam ao tentar desenhar um bloco interno condicionado a um registro clássico, ao passo que agora terão sucesso, como neste exemplo:

    from qiskit import QuantumCircuit
    from qiskit.circuit import QuantumRegister, ClassicalRegister
    
    qreg = QuantumRegister(4)
    creg = ClassicalRegister(1)
    circ = QuantumCircuit(qreg, creg)
    
    with circ.for_loop(range(10)) as a:
        circ.ry(a, 0)
        with circ.if_test((creg, 1)):
            circ.break_loop()
    
    print(circ.draw(cregbundle=False))
    print(circ.data[0][0].blocks[0].draw(cregbundle=False))
  • Corrigido o suporte do site qpy_serialization para serialização de QuantumCircuit que estejam usando ParameterVector ou ParameterVectorElement como parâmetros. Anteriormente, um parâmetro ParameterVectorElement era tratado apenas como um Parameter para a serialização do QPY, o que significava que o contexto ParameterVector era perdido no QPY e a ordem de saída de parameters poderia estar incorreta.

    Para corrigir esse problema, foi necessária uma nova versão do formato QPY, a Versão 3. Essa nova versão do formato inclui uma representação da classe ParameterVectorElement , que é descrita na documentação qpy_serialization em PARAMETER_VECTOR_ELEMENT.

  • Corrigido o suporte do site qpy_serialization para serializar um PauliEvolutionGate objeto. Anteriormente, o PauliEvolutionGate era tratado como uma porta personalizada para serialização e seria desserializado como um objeto Gate que tinha a mesma definição e o mesmo nome que o objeto PauliEvolutionGate. No entanto, isso perderia o estado original do arquivo PauliEvolutionGate. Isso foi corrigido de modo que, a partir desta versão, um PauliEvolutionGate no circuito será preservado 1:1 em toda a serialização QPY agora. A única limitação desse recurso é que ele não oferece suporte a classes EvolutionSynthesis personalizadas. Somente as classes disponíveis em qiskit.synthesis podem ser usadas com um PauliEvolutionGate para serialização qpy.

    Para corrigir esse problema, foi necessária uma nova versão do formato QPY, a Versão 3. Essa nova versão do formato inclui uma representação da classe PauliEvolutionGate que é descrita na documentação do site qpy_serialization em PAULI_EVOLUTION.

  • Duas funções soltas qiskit.circuit.measure.measure() e qiskit.circuit.reset.reset() foram removidas acidentalmente sem um período de depreciação. Eles foram restabelecidos, mas estão marcados como obsoletos em favor dos métodos QuantumCircuit.measure() e QuantumCircuit.reset()respectivamente, e serão removidos em uma versão futura.

Outras observações

  • A nova interface do construtor de fluxo de controle usa vários gerenciadores de contexto e objetos auxiliares para fazer seu trabalho. Elas não devem ser consideradas parte da API pública e podem ser alteradas e removidas sem aviso prévio. O uso da interface do construtor tem garantias de estabilidade, no sentido de que o comportamento descrito por QuantumCircuit.for_loop(), while_loop() e if_test() para a interface do construtor estão sujeitos às políticas de descontinuidade padrão, mas os objetos reais usados para fazer isso não estão. Você não deve confiar que os objetos (como IfContext ou ControlFlowBuilderBlock) existam em seus locais atuais ou que tenham quaisquer métodos ou atributos anexados a eles.

    Isso não estava claro anteriormente na versão 0.19.0. Todos esses objetos agora têm um aviso em suas strings de documentação que explicita isso. É provável que, no futuro, suas localizações e implementações de apoio se tornem bastante diferentes.

Aer 0.9.1

Nenhuma mudança

Ignis 0.7.0

Nenhuma mudança

IBM 0.18.2

Correções de bugs

  • Correção fornecida no número 1065 para o problema em que o trabalho continuava a falhar quando Parameter era passado nos metadados do circuito.
  • Correção fornecida em #1094 para o problema em que qiskit.providers.ibmq.runtime.RuntimeEncoder faz uma decomposição extra() se o circuito que está sendo serializado for um BlueprintCircuit.

0.33.0

Esta versão marca oficialmente o fim do suporte ao projeto Qiskit Aqua no Qiskit. Ele foi originalmente descontinuado na versão 0.25.0 e, como foi documentado nessa versão, o pacote qiskit-aqua foi removido do metapacote Qiskit, o que significa que o pip install qiskit não incluirá mais o qiskit-aqua. No entanto, devido a limitações no empacotamento do python, não podemos remover automaticamente uma instalação pré-existente do qiskit-aqua ao atualizar uma versão anterior do Qiskit para esta versão (ou uma versão futura) com o pip install -U qiskit. Se estiver atualizando de uma versão anterior, é recomendável desinstalar manualmente o Qiskit Aqua com pip uninstall qiskit-aqua ou instalar em um ambiente python novo.

Os módulos de aplicativos fornecidos por qiskit-aqua foram divididos em vários pacotes novos: qiskit-optimization, qiskit-nature, qiskit-machine-learning, e qiskit-finance. Esses pacotes podem ser instalados sozinhos (por meio do comando padrão pip install, por exemplo, pip install qiskit-nature) ou com o restante do metapacote do Qiskit como extras opcionais (por exemplo pip install 'qiskit[finance,optimization]' ou pip install 'qiskit[all]'). Os algoritmos principais e o fluxo do operador agora existem como parte do Qiskit Terra em qiskit.algorithms e qiskit.opflow. Dependendo do seu uso atual do Aqua, você deve usar os pacotes de aplicativos ou os novos módulos no Qiskit Terra. Para obter mais detalhes sobre como migrar do Qiskit Aqua, consulte o Guia de Migração do Aqua.

Essa versão também descontinua oficialmente o projeto Qiskit Ignis. Dessa forma, em uma versão futura, o pacote qiskit-ignis será removido do metapacote do Qiskit, o que significa que, nessa versão futura, o pip install qiskit não incluirá mais o qiskit-ignis. O Qiskit Ignis foi substituído pelo projeto Qiskit Experiments e o desenvolvimento ativo foi interrompido. Embora obsoletas, as correções de bugs críticos e as correções de compatibilidade continuarão a ser feitas para oferecer aos usuários uma oportunidade suficiente para migrar do Ignis. Após o período de depreciação (que não será inferior a 3 meses a partir desta versão), o projeto será retirado e arquivado. Você pode consultar o guia de migração para obter detalhes sobre como mudar do Qiskit Ignis para o Qiskit Experiments.

Terra 0.19.0

Prelúdio

Os destaques da versão do Qiskit Terra 0.19 são:

  • Uma nova versão da interface abstrata Qiskit/hardware, na forma de BackendV2que vem com uma nova estrutura de dados Target para permitir que os backends modelem melhor suas restrições para o transpilador.
  • Uma interface de plug-in extensível para a passagem do UnitarySynthesis permitindo que os usuários ou outros pacotes estendam as rotinas de síntese do Qiskit Terra com novos métodos.
  • Instruções de fluxo de controle, para representar os loops for e while e as instruções if/else em QuantumCircuit. Em breve, os simuladores do Qiskit Aer poderão trabalhar com essas novas instruções, permitindo que você escreva programas quânticos mais dinâmicos.
  • Suporte preliminar para a especificação OpenQASM 3 em evolução. Você pode usar o novo módulo qiskit.qasm3 para serializar seus QuantumCircuits em OpenQASM 3, incluindo as novas construções de fluxo de controle.

Esta versão marca o fim do suporte para Python 3.6 no Qiskit. Esta versão do Qiskit Terra e todas as versões subsequentes de correção de erros da série 0.19.x serão as últimas a funcionar com Python 3.6. A partir da próxima versão secundária ( 0.20.0 ) do Qiskit Terra, a versão mínima exigida Python será 3.7.

Como sempre, há muitos outros recursos e correções nesta versão, sobre os quais você pode ler abaixo.

Novos Recurso

  • QuantumCircuit.decompose() e sua passagem de transpilador correspondente Decompose agora aceitam opcionalmente um parâmetro que contém uma coleção de nomes de portas. Se esse parâmetro for fornecido, somente as portas com nomes correspondentes serão decompostas. Isso suporta correspondências curinga no estilo Unix-shell. Por exemplo:

    qc.decompose(["h", "r[xz]"])

    decomporá qualquer porta h, rx ou rz , mas deixará (por exemplo) as portas x intactas.

  • Foi adicionado o argumento termination_checker ao SPSA otimizador. Isso permite que o usuário implemente um critério de encerramento personalizado.

    import numpy as np
    from qiskit.algorithms.optimizers import SPSA
    
    def objective(x):
        return np.linalg.norm(x) + .04*np.random.rand(1)
    
    class TerminationChecker:
    
        def __init__(self, N : int):
            """
            Callback to terminate optimization when the average decrease over
            the last N data points is smaller than the specified tolerance.
            """
            self.N = N
            self.values = []
    
        def __call__(self, nfev, parameters, value, stepsize, accepted) -> bool:
            """
            Returns:
                True if the optimization loop should be terminated.
            """
            self.values.append(value)
    
            if len(self.values) > self.N:
                last_values = self.values[-self.N:]
                pp = np.polyfit(range(self.N), last_values, 1)
                slope = pp[0] / self.N
    
                if slope > 0:
                    return True
            return False
    
    maxiter = 400
    spsa = SPSA(maxiter=maxiter, termination_checker=TerminationChecker(10))
    parameters, value, niter = spsa.optimize(2, objective, initial_point=np.array([0.5, 0.5]))
  • Adicionada uma nova versão da interface Backend interface, BackendV2. Essa nova versão é uma grande mudança em relação à versão anterior, BackendV1 e altera tanto o padrão de acesso do usuário às propriedades do backend (como o número de qubits etc.) quanto a forma como o backend representa suas restrições para o transpilador. A execução dos circuitos (por meio do método run() ) permanece inalterada. Com um BackendV2 backend em vez de ter um configuration(), properties()e defaults() métodos que constroem BackendConfiguration, BackendProperties, e PulseDefaults respectivamente, como na interface BackendV1 os atributos contidos nesses objetos de saída são acessíveis diretamente como atributos do objeto BackendV2 objeto. Por exemplo, para obter o número de qubits de um backend com BackendV1 você faria isso:

    num_qubits = backend.configuration().n_qubits

    enquanto que com BackendV2 é:

    num_qubits = backend.num_qubits

    A outra mudança em relação a isso é que o número de atributos expostos na classe abstrata BackendV2 foi projetado para ser um conjunto agnóstico de hardware/fornecedor dos campos obrigatórios ou opcionais que o restante do Qiskit pode usar hoje com qualquer backend. As subclasses da classe abstrata BackendV2 podem adicionar suporte a atributos e métodos adicionais além daqueles definidos em BackendV2mas esses não serão suportados universalmente em todo o Qiskit.

    A outra alteração crítica que é importante principalmente para os autores de provedores é como um BackendV2 expõe as propriedades de um backend específico para o transpilador. Com BackendV2 isso é feito por meio de um objeto Target objeto. O Targetque é exposto por meio do atributo target é usado para representar o conjunto de restrições para a execução de circuitos em um backend específico. Ele contém o subconjunto de informações previamente expostas pelo BackendConfiguration, BackendProperties, e PulseDefaults que o transpilador pode usar ativamente. Ao migrar um provedor para usar o BackendV2 (ou ao criar um novo pacote de provedor), a construção de objetos de backend será principalmente em torno da criação de um objeto Target para o backend.

  • Adicionada uma nova classe Target ao módulo transpiler módulo. A classe Target foi projetada para representar as restrições do backend para o compilador. A classe Target destina-se a ser usada com um backend BackendV2 e é como os backends modelarão suas restrições para o transpilador daqui para frente. Ele combina os campos anteriormente distintos usados para controlar o transpile() dispositivo de destino (por exemplo, basis_gates, coupling_map, instruction_durations, etc.) em uma única estrutura de dados. Ele também acrescenta funcionalidades adicionais ao que estava disponível anteriormente, como a representação de conjuntos de portas heterogêneas, conectividade de portas multiqubit e variantes ajustadas das mesmas portas. Atualmente, o transpilador não leva em conta todas essas restrições, mas, com o tempo, ele crescerá para aproveitar a funcionalidade extra.

  • A classe Options agora tem suporte opcional para especificar validadores. Isso permite que os Backend autores especifiquem opcionalmente a validação básica dos valores fornecidos pelo usuário para os campos do Options objeto. Por exemplo, se você tivesse um objeto Options definido com:

    from qiskit.providers.Options
    options = Options(shots=1024)

    você pode definir um validador nos disparos para que ele fique entre 1 e 4096 com:

    options.set_validator('shots', (1, 4096))

    Com o validador definido, qualquer chamada ao método update_options() verificará se, caso o site shots esteja sendo atualizado, o novo valor proposto está dentro do intervalo válido.

  • Adicionada uma nova passagem de análise do transpilador, ContainsInstructionao módulo qiskit.transpiler.passes módulo. Essa passagem é usada para determinar se um circuito contém uma instrução específica. Ele recebe um único parâmetro na inicialização, o nome da instrução a ser verificada, e define um booleano no conjunto de propriedades se o circuito contém essa instrução ou não. Por exemplo:

    from qiskit.transpiler.passes import ContainsInstruction
    from qiskit.circuit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.measure_all()
    
    property_set = {}
    # Contains Hadamard
    contains_h = ContainsInstruction("h")
    contains_h(circuit, property_set)
    assert property_set["contains_h"] == True
    # Not contains SX
    contains_sx = ContainsInstruction("sx")
    contains_sx(circuit, property_set)
    assert property_set["contains_sx"] == False
  • Adicionada uma função de utilidade qiskit.utils.detach_prefix() que é uma contrapartida de apply_prefix(). A nova função retorna uma tupla de valor escalonado e prefixo de um determinado valor flutuante. Por exemplo, um valor 1.3e8 será convertido em (130, "M") , que pode ser usado para exibir um valor no formato amigável, como 130 MHz.

  • Os valores "gate_error" e "balanced" agora estão disponíveis para a opção objective na construção do objeto BIPMapping , e "balanced" agora é o padrão.

    O objetivo "gate_error" requer a passagem de uma BackendProperties no kwarg backend_prop , que contém os erros da porta 2q-gate usados no cálculo dos objetivos. O objetivo do "balanced" usará a instância BackendProperties se ela for fornecida, mas, caso contrário, assumirá uma taxa de erro de CX, conforme indicado no novo parâmetro default_cx_error_rate. Os pesos relativos dos componentes de gate-error e profundidade do objetivo equilibrado podem ser controlados com o novo parâmetro depth_obj_weight .

  • Cada atributo da classe VQE que é definido na inicialização agora está acessível com getters e setters. Além disso, os valores padrão dos atributos VQE ansatz e optimizer podem ser redefinidos atribuindo-se a eles o endereço None :

    vqe = VQE(my_ansatz, my_optimizer)
    vqe.ansatz = None   # reset to default: RealAmplitudes ansatz
    vqe.optimizer = None  # reset to default: SLSQP optimizer
  • Adicionado um novo método PauliList.group_qubit_wise_commuting() que divide a PauliList em conjuntos de operadores comutadores mutuamente qubit-wise Pauli mutuamente comutáveis. Por exemplo:

    from qiskit.quantum_info import PauliList, Pauli
    pauli_list = PauliList([Pauli("IY"), Pauli("XX"), Pauli("YY"), Pauli("YX")])
    pauli_list.group_qubit_wise_commuting()
  • Adicionado um novo método construtor de mapa de acoplamento CouplingMap.from_hexagonal_lattice() para a construção de um mapa de acoplamento de rede hexagonal. Por exemplo, para construir um mapa de acoplamento de rede hexagonal 2x2 :

    from qiskit.transpiler import CouplingMap
    cmap = CouplingMap.from_hexagonal_lattice(2, 2)
    cmap.draw()
  • Novas classes de back-end falsas estão disponíveis em qiskit.test.mock. Isso inclui versões simuladas de ibmq_brooklyn, ibmq_manila, ibmq_jakarta e ibmq_lagos. Assim como os outros back-ends falsos, eles incluem instantâneos de dados de calibração (ou seja, backend.defaults()) e dados de erro (ou seja, backend.properties()) retirados do sistema real e podem ser usados para testes locais, compilação e simulação.

  • Adicionado o método OperatorBase.is_hermitian() para verificar se o operador é hermitiano ou não. NumPyEigensolver e NumPyMinimumEigensolver use eigh ou eigsh para resolver o problema do valor próprio quando o operador for hermitiano.

  • Adicionado um novo método construtor PassManagerConfig.from_backend(). Ele constrói um objeto PassManagerConfig com opções de usuário e a configuração de um backend. Com esse recurso, um gerenciador de senhas predefinido pode ser criado mais facilmente. Por exemplo:

    from qiskit.transpiler.passmanager_config import PassManagerConfig
    from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
    from qiskit.test.mock import FakeMelbourne
    
    pass_manager = level_1_pass_manager(
      PassManagerConfig.from_backend(FakeMelbourne(), seed_transpiler=42)
    )
  • Uma nova passagem de transpilador, PulseGatesque extrai automaticamente as calibrações fornecidas pelo usuário do mapa de programação de instruções e anexa a programação de porta ao circuito quântico fornecido (transpilado) como uma porta de pulso.

    A passagem PulseGates é aplicada a todos os níveis de otimização de 0 a 3. Nenhuma implementação de porta é atualizada, a menos que o usuário final substitua explicitamente o backend.defaults().instruction_schedule_map. Essa passagem evita que os usuários chamem individualmente QuantumCircuit.add_calibration() para cada circuito executado no hardware.

    Para complementar essa nova passagem, um cronograma foi adicionado ao InstructionScheduleMap e é implicitamente atualizado com um campo de metadados "publisher". As programações de porta calibradas pelo backend têm um tipo especial de editor para evitar a substituição de circuitos por calibrações de programações já conhecidas. Normalmente, os usuários finais não precisam cuidar desses metadados, pois eles são aplicados automaticamente. Você pode ligar para InstructionScheduleMap.has_custom_gate() para verificar se o mapa tem calibração de porta personalizada.

    Veja o exemplo de código abaixo para saber como aplicar a implementação de porta personalizada para todos os circuitos em execução.

    from qiskit.test.mock import FakeGuadalupe
    from qiskit import pulse, circuit, transpile
    
    backend = FakeGuadalupe()
    
    with pulse.build(backend, name="x") as x_q0:
        pulse.play(pulse.Constant(160, 0.1), pulse.drive_channel(0))
    
    backend.defaults().instruction_schedule_map.add("x", (0,), x_q0)
    
    circs = []
    for _ in range(100):
        circ = circuit.QuantumCircuit(1)
        circ.sx(0)
        circ.rz(1.57, 0)
        circ.x(0)
        circ.measure_active()
        circs.append(circ)
    
    circs = transpile(circs, backend)
    circs[0].calibrations  # This returns calibration only for x gate

    Observe que o mapa de programação de instruções é um objeto mutável. Se você substituir uma das entradas e usar esse backend para outros experimentos, poderá atualizar acidentalmente a definição da porta.

    backend = FakeGuadalupe()
    
    instmap = backend.defaults().instruction_schedule_map
    instmap.add("x", (0, ), my_x_gate_schedule)
    
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.measure(0, 0)
    
    qc = transpile(qc, backend)  # This backend uses custom X gate

    Se quiser atualizar as definições de porta de um experimento específico, você precisará primeiro fazer uma cópia profunda do mapa de programação de instruções e passá-lo diretamente para o transpilador.

  • Introduziu uma nova opção qubit_subset no construtor de BIPMapping. A opção nos permite especificar os qubits físicos a serem usados (em coupling_map do dispositivo) durante o mapeamento em uma linha:

    mapped_circ = BIPMapping(
        coupling_map=CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]),
        qubit_subset=[1, 3, 4]
    )(circ)

    Anteriormente, para fazer a mesma coisa, tínhamos que fornecer um coupling_map reduzido que contivesse apenas os qubits a serem usados, incorporar o circuito resultante no coupling_map original e atualizar o QuantumCircuit._layout de acordo:

    reduced_coupling = coupling_map.reduce(qubit_to_use)
    mapped = BIPMapping(reduced_coupling)(circ)
    # skip the definition of fill_with_ancilla()
    # recover circuit on original coupling map
    layout = Layout({q: qubit_to_use[i] for i, q in enumerate(mapped.qubits)})
    for reg in mapped.qregs:
        layout.add_register(reg)
    property_set = {"layout": fill_with_ancilla(layout)}
    recovered = ApplyLayout()(mapped, property_set)
    # recover layout
    overall_layout = Layout({v: qubit_to_use[q] for v, q in mapped._layout.get_virtual_bits().items()})
    for reg in mapped.qregs:
        overall_layout.add_register(reg)
    recovered._layout = fill_with_ancilla(overall_layout)
  • Foram adicionados os argumentos ignore_pauli_phase e copy ao construtor de SparsePauliOp. ignore_pauli_phase impede que o atributo phase de uma entrada PauliList seja lido, o que é mais eficiente se o atributo PauliList já é conhecido por ter todas as fases como zero na convenção interna do ZX. copy permite que os usuários evitem a cópia dos dados de entrada quando definem explicitamente copy=False.

  • Melhoria no desempenho das seguintes SparsePauliOp operações:

  • Adicionado o método SparsePauliOp.sum() para somar muitos SparsePauliOps. Esse método tem um desempenho significativamente melhor do que adicionar as instâncias em um loop. Por exemplo, a maneira anterior de adicionar vários SparsePauliOps juntos seria fazer:

    from qiskit.quantum_info import SparsePauliOp, random_pauli_list
    sparse_ops = [SparsePauliOp(random_pauli_list(10, 10)) for _ in [None]*1000]
    
    total = sparse_ops[0]
    for op in sparse_ops[1:]:
        total += op

    Isso agora pode ser feito com muito mais eficiência (tanto em termos de velocidade quanto de digitação!) como:

    SparsePauliOp.sum(sparse_ops)
  • Foi adicionado um argumento limit_amplitude ao construtor de ParametricPulse, que é a classe base de Gaussian, GaussianSquare, Drag e Constantpara permitir a desativação do limite de amplitude de 1 em uma base pulso a pulso. Com limit_amplitude=False, os pulsos individuais podem ter uma amplitude superior à unidade sem aumentar a PulseError. Consulte #6544 para obter mais detalhes.

  • Usando QuantumCircuit.draw() ou circuit_drawer() com a gaveta latex agora gerará um arquivo em um formato de imagem inferido a partir da extensão do nome do arquivo, por exemplo:

    import qiskit
    
    circuit = qiskit.QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.draw('latex', filename='./file.jpg')

    Isso salvará o desenho do circuito no formato JPEG. Anteriormente, a imagem sempre estava no formato PNG. Consulte o número 6448 para obter mais detalhes.

    Agora, se ele encontrar uma extensão de nome de arquivo que não seja compatível, por exemplo:

    circuit.draw('latex', filename='./file.spooky')

    ele exibirá um ValueError para alterar a extensão do nome do arquivo para um formato de imagem compatível.

  • Adicionado o parâmetro filename a plot_gate_map() e plot_coupling_map()que permite salvar as imagens resultantes em um arquivo.

  • Introduziu um compilador quântico aproximado e uma implementação de plug-in de síntese unitária correspondente. A classe principal do AQC é AQC para uma versão autônoma que compila uma matriz unitária em um circuito aproximado. O plug-in pode ser chamado por transpile() quando o argumento unitary_synthesis_method estiver definido como 'aqc'. Veja qiskit.transpiler.synthesis.aqc para obter detalhes completos.

  • Adicionado um argumento filter_function a QuantumCircuit.depth() e QuantumCircuit.size() para analisar as operações do circuito de acordo com alguns critérios.

    Por exemplo, para obter o número de portas de dois qubits, você pode fazer isso:

    circuit.size(lambda x: x[0].num_qubits == 2)

    Ou para obter a profundidade dos portões T que atuam no zerésimo qubit:

    circuit.depth(lambda x: x[0].name == 't' and circuit.qubits[0] in x[1])
  • Adicionado um novo passe de transpilador, CollectMultiQBlocksao módulo qiskit.transpiler.passes módulo. Essa passagem é usada para coletar sequências de portas ininterruptas que atuam em grupos de qubits. Ela oferece uma função semelhante à passagem Collect2qBlocks existente, mas enquanto essa passagem foi projetada e otimizada para encontrar blocos de 2 qubits, essa nova passagem funcionará para encontrar blocos de qualquer tamanho.

  • Há uma interface de construtor para as novas operações de fluxo de controle em QuantumCircuitcomo o novo ForLoopOp, IfElseOp, e WhileLoopOp. A interface usa os mesmos métodos de circuito, ou seja QuantumCircuit.for_loop(), QuantumCircuit.if_test() e QuantumCircuit.while_loop()que são sobrecarregados de modo que, se o parâmetro body não for fornecido, eles retornam um gerenciador de contexto. A entrada em um desses gerenciadores de contexto empurra um escopo para o circuito e captura todas as chamadas de porta (e outros escopos) e os recursos que eles usam, além de criar a operação relevante no final. Por exemplo, agora você pode fazer:

    qc = QuantumCircuit(2, 2)
    with qc.for_loop(range(5)) as i:
        qc.rx(i * math.pi / 4, 0)

    Isso produzirá um ForLoopOp em qc, que sabe que o qubit 0 é o único recurso usado no corpo do loop. Esses gerenciadores de contexto podem ser aninhados e determinarão corretamente suas larguras. Você pode usar QuantumCircuit.break_loop() e QuantumCircuit.continue_loop() dentro de um contexto, e ele se expandirá para ter a largura correta do loop que o contém, mesmo que esteja aninhado em outros blocos QuantumCircuit.if_test() blocos.

    O gerenciador de contexto if_test() fornece um gerenciador encadeado que, se desejado, pode ser usado para criar um bloco else , como by:

    qreg = QuantumRegister(2)
    creg = ClassicalRegister(2)
    qc = QuantumCircuit(qreg, creg)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure(0, 0)
    with qc.if_test((creg, 0)) as else_:
        qc.x(1)
    with else_:
        qc.z(1)

    O gerente garantirá que os corpos if e else sejam definidos no mesmo conjunto de recursos.

  • Introduziu uma nova passagem de transpilador InverseCancellation que generaliza a passagem CXCancellation para cancelar qualquer porta auto-inversa ou pares porta-inversa. Ele pode ser usado ao inicializar InverseCancellation e passando uma porta para cancelar, por exemplo:

    from qiskit.transpiler.passes import InverseCancellation
    from qiskit import QuantumCircuit
    from qiskit.circuit.library import HGate
    from qiskit.transpiler import PassManager
    
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.h(0)
    pass_ = InverseCancellation([HGate()])
    pm = PassManager(pass_)
    new_circ = pm.run(qc)
  • O construtor de RZXCalibrationBuilder tem dois novos kwargs instruction_schedule_map e qubit_channel_mapping que recebem um InstructionScheduleMap e uma lista de listas de nomes de canais para cada qubit, respectivamente. Esses novos argumentos são usados para especificar diretamente as informações necessárias de um destino de backend. Eles devem ser usados em vez de passar um objeto BaseBackend ou BackendV1 diretamente para o pass com o argumento backend .

  • Os Statevectors de estados compostos apenas de qubits podem agora ser desenhados em LaTeX na notação ket. Na notação ket, as entradas do vetor de estado são processadas de modo que fatores exatos, como frações ou raízes quadradas de dois, sejam desenhados como tal. A convenção específica pode ser escolhida passando o argumento da palavra-chave convention como "ket" ou "vector" , conforme apropriado:

    import math
    from qiskit.quantum_info import Statevector
    
    sv = Statevector([math.sqrt(0.5), 0, 0, -math.sqrt(0.5)])
    sv.draw("latex", convention="ket")
    sv.draw("latex", convention="vector")
  • Adicionada uma nova passagem de transpilador EchoRZXWeylDecomposition que permite aos usuários decompor uma porta arbitrária de dois qubits em termos de portas RZX ecoadas, aproveitando a decomposição de Cartan. Em combinação com outras passagens do transpilador, isso pode ser usado para transpilar circuitos arbitrários para circuitos baseados em RZX-gate e eficientes em termos de pulso que implementam a mesma unidade.

  • O SPSA e QNSPSA agora são capazes de agrupar o maior número possível de avaliações de circuito para as iterações e as calibrações iniciais. Isso pode ser aproveitado definindo o kwarg max_evals_grouped no construtor para VQE ao usar SPSA ou QNSPSA como o parâmetro optimizer . Por exemplo:

    from qiskit.circuit.library import TwoLocal
    from qiskit.algorithms import VQE
    from qiskit.algorithms.optimizers import QNSPSA
    from qiskit.test.mock import FakeMontreal
    
    backend = FakeMontreal()
    ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    qnspsa = QNSPSA(fidelity, maxiter=5)
    vqe = VQE(
        ansatz=ansatz,
        optimizer=qnspsa,
        max_evals_grouped=100,
        quantum_instance=backend,
    )
  • Esta versão apresenta um método de decomposição para portas de dois qubits que visa conjuntos definidos pelo usuário de portas RZX. Os usuários do Transpiler podem ativar a decomposição para {RZX(pi/2), RZX(pi/4), and RZX(pi/6)} especificamente incluindo 'rzx' em sua lista basis_gates ao chamar transpile(). Os usuários do pacote de informações Quantum podem encontrar o próprio método na classe XXDecomposer classe.

  • Adicionado um transpiler pass Optimize1qGatesSimpleCommutationque otimiza um circuito de acordo com uma estratégia de comutação de portas de um único qubit para descobrir oportunidades de ressíntese.

  • Adicionado um parâmetro max_job_tries ao QuantumInstancepara limitar o número de vezes que um trabalho tentará ser executado em um backend. Anteriormente, o envio e a obtenção de resultados eram tentados infinitamente, mesmo que o trabalho fosse cancelado ou apresentasse erro no backend. O padrão agora é 50, e o comportamento anterior pode ser obtido com a configuração max_job_tries=-1. Correções #6872 e #6821.

  • O método de saída latex para a função circuit_drawer() e o método QuantumCircuit.draw() agora podem desenhar circuitos que contêm portas com condição de bit único. Isso foi adicionado para compatibilidade da gaveta de látex com o novo recurso de suporte ao condicionamento clássico de portas em bits clássicos únicos.

  • O método de saída "mpl" para a função circuit_drawer() e o método QuantumCircuit.draw() agora podem desenhar circuitos que contêm portas com condição de bit único. Isso foi adicionado para compatibilidade da gaveta "mpl" com o novo recurso de suporte ao condicionamento clássico de portas em bits clássicos únicos.

  • O método de saída text para a função circuit_drawer() e o método QuantumCircuit.draw() agora podem desenhar circuitos que contêm portas com condição de bit único. Isso foi adicionado para compatibilidade da gaveta de texto com o novo recurso de suporte ao condicionamento clássico de portas em bits clássicos únicos.

  • Uma nova passagem de transpilador de análise, GatesInBasisfoi adicionada ao qiskit.transpiler.passes. Essa passagem é usada para verificar se o arquivo DAGCircuit que está sendo transpilado tem todas as portas no conjunto de base configurado ou não. Ele definirá o atributo "all_gates_in_basis" no conjunto de propriedades como True se todos os portões do DAGCircuit estiverem no conjunto de base configurado ou False se não estiverem. Por exemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import GatesInBasis
    
    # Instatiate Pass
    basis_gates = ["cx", "h"]
    basis_check_pass = GatesInBasis(basis_gates)
    # Build circuit
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.measure_all()
    # Run pass on circuit
    property_set = {}
    basis_check_pass(circuit, property_set=property_set)
    assert property_set["all_gates_in_basis"]
  • Foram adicionados dois novos métodos de construção, from_heavy_hex() e from_heavy_square()à classe CouplingMap classe. Esses métodos do construtor são usados para criar um gráfico CouplingMap que são um gráfico hexagonal pesado ou quadrado pesado, conforme descrito em Chamberland et al, 2020.

    Por exemplo:

    from qiskit.transpiler import CouplingMap
    
    cmap = CouplingMap.from_heavy_hex(5)
    cmap.draw()
    from qiskit.transpiler import CouplingMap
    
    cmap = CouplingMap.from_heavy_square(5)
    cmap.draw()
  • O algoritmo HHL agora pode encontrar soluções quando sua matriz tem valores próprios negativos. Para permitir isso, o algoritmo agora adiciona um qubit extra para representar o sinal do valor, e o algoritmo auxiliar ExactReciprocal foi atualizado para processar essas novas informações. Consulte o número 6971 para obter mais detalhes.

  • Adicionadas duas novas classes, CompleteMeasFitter e TensoredMeasFitter ao módulo qiskit.utils.mitigation módulo. Essas classes devem ser usadas somente como valores para o kwarg measurement_error_mitigation_cls da classe QuantumInstance classe. A instanciação e o uso dessas classes (ou qualquer outra coisa em qiskit.utils.mitigation) fora do kwarg measurement_error_mitigation_cls devem ser tratados como uma API privada interna e não devem ser usados.

  • A ListOp em qiskit.opflow agora tem um atributo coeffs que retorna uma lista dos coeficientes da lista de operadores, com o coeficiente geral (ListOp.coeff) distribuído multiplicativamente na lista. Observe que ListOp podem estar aninhados (contidos em oplist de um objeto ListOp ) e, nesses casos, uma exceção será levantada se o método coeffs for chamado. O método ListOp.coeffs convenientemente se compara ao método de propriedade coeffs da classe não aninhada PauliSumOp não aninhada.

  • A classe Statevector agora é subscritível. O usuário pode agora recuperar o enésimo coeficiente em um Statevector pelo índice como statevec[n].

  • Adicionado o método Statevector.inner para calcular produtos internos de instâncias Statevector instâncias. Por exemplo:

    statevec_inner_other = statevec.inner(other)

    retornará o produto interno de statevec com other. Enquanto statevec deve ser um Statevectorother pode ser qualquer coisa que possa ser construída em um Statevectorcomo, por exemplo, uma matriz Numpy.

  • Foi adicionado um novo parâmetro, add_bits, ao QuantumCircuit.measure_all(). Por padrão, ele é definido como True para manter o comportamento anterior de adicionar um novo ClassicalRegister do mesmo tamanho que o número de qubits para armazenar as medições. Se definido como False, as medições serão armazenadas nos bits clássicos já existentes. Por exemplo, se você criou um circuito com bits clássicos existentes, como:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qr = QuantumRegister(2)
    cr = ClassicalRegister(2, "meas")
    circuit = QuantumCircuit(qr, cr)

    a chamada para circuit.measure_all(add_bits=False) usará o registro clássico existente cr como alvo de saída dos objetos Measurement adicionados ao circuito.

  • ParameterExpression agora delega suas conversões numéricas à biblioteca simbólica subjacente, mesmo que haja parâmetros potencialmente não vinculados. Isso permite conversões de expressões como:

    >>> from qiskit.circuit import Parameter
    >>> x = Parameter('x')
    >>> float(x - x + 2.3)
    2.3

    em que a expressão subjacente tem um valor fixo, mas o parâmetro x ainda não está vinculado.

  • Adicionado um método Optimizer.minimize() a todos os otimizadores: Optimizer e classes derivadas. Esse método imita a assinatura da função SciPy’s minimize() e retorna um OptimizerResult.

    Por exemplo:

    import numpy as np
    from qiskit.algorithms.optimizers import COBYLA
    
    def loss(x):
        return -(x[0] - 1) ** 2 - (x[1] + 1) ** 3
    
    initial_point = np.array([0, 0])
    optimizer = COBYLA()
    result = optimizer.minimize(loss, initial_point)
    
    optimal_parameters = result.x
    minimum_value = result.fun
    num_function_evals = result.nfev
  • Adicionado um PauliEvolutionGate à biblioteca de circuitos (qiskit.circuit.library) que define uma porta que realiza a evolução temporal de (somas ou somas de somas de) Paulis. A síntese dessa porta é realizada por EvolutionSynthesis e é desacoplada da própria porta. Os métodos de síntese disponíveis atualmente são:

    Por exemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.synthesis import SuzukiTrotter
    
    operator = SparsePauliOp.from_list([
        ("XIZ", 0.5), ("ZZX", 0.5), ("IYY", -1)
    ])
    time = 0.12  # evolution time
    synth = SuzukiTrotter(order=4, reps=2)
    
    evo = PauliEvolutionGate(operator, time=time, synthesis=synth)
    
    circuit = QuantumCircuit(3)
    circuit.append(evo, range(3))
  • Uma nova função plot_coupling_map() foi introduzida, que amplia a funcionalidade da função existente plot_gate_map()aceitando três parâmetros: num_qubit, qubit_coordinates, e coupling_map (em vez de backend), para permitir que um mapa de acoplamento de qubit arbitrário seja plotado.

  • O Qiskit Terra agora tem suporte inicial para serialização QuantumCircuits para OpenQASM 3 :

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit import qasm3
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    
    print(qasm3.dumps(qc))

    Esta versão inicial tem suporte limitado a registros nomeados, instruções básicas incorporadas (como measure, barrier e reset), portas definidas pelo usuário, instruções definidas pelo usuário (como sub-rotinas) e as novas construções de fluxo de controle também introduzidas nesta versão:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit import qasm3
    import math
    
    composite_circ_qreg = QuantumRegister(2)
    composite_circ = QuantumCircuit(composite_circ_qreg, name="composite_circ")
    composite_circ.h(0)
    composite_circ.x(1)
    composite_circ.cx(0, 1)
    composite_circ_gate = composite_circ.to_gate()
    
    qr = QuantumRegister(2, "qr")
    cr = ClassicalRegister(2, "cr")
    qc = QuantumCircuit(qr, cr)
    with qc.for_loop(range(4)) as i:
        qc.rx(i * math.pi / 4, 0)
        qc.cx(0, 1)
    qc.barrier()
    qc.append(composite_circ_gate, [0, 1])
    qc.measure([0, 1], [0, 1])
    
    print(qasm3.dumps(qc))
  • A classe QDrift foi reformulada como um método de síntese para PauliEvolutionGatederivando de TrotterizationBase.

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.synthesis import QDrift
    from qiskit.opflow import X, Y, Z
    
    qdrift = QDrift(reps=2)
    operator = (X ^ 3) + (Y ^ 3) + (Z ^ 3)
    time = 2.345  # evolution time
    
    evolution_gate = PauliEvolutionGate(operator, time, synthesis=qdrift)
    
    circuit = QuantumCircuit(3)
    circuit.append(evolution_gate, range(3))
  • A serialização QPY agora é capaz de representar global_phase atributos de um QuantumCircuit que são um objeto int, Parameter objeto ou ParameterExpression objeto. As versões anteriores do QPY só aceitavam um global_phase que era um float.

    Isso requer o formato QPY Versão 2, que foi introduzido nesta versão para representar os tipos adicionais.

  • Um novo método find_bit() foi adicionado à classe QuantumCircuit que permite a pesquisa do índice e dos registros de um dispositivo Bit no circuito fornecido. O método retorna um namedtuple de dois elementos contendo 0) o índice do Bit em qubits (para um Qubit) ou clbits (para a Clbit) e 1) uma lista de tuplas length-2 contendo cada circuito Register que contém o Bit, e o índice naquele Register no qual o Bit pode ser encontrado.

    Por exemplo:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, Qubit
    
    reg1 = QuantumRegister(3, 'foo')
    qubit = Qubit()
    reg2 = QuantumRegister(2, 'bar')
    
    qc = QuantumCircuit(reg1, [qubit], reg2)
    
    print(qc.find_bit(reg1[2]))
    print(qc.find_bit(qubit))

    geraria:

    BitLocations(index=2, registers=[(QuantumRegister(3, 'foo'), 2)])
    BitLocations(index=3, registers=[])
  • Três novas Instruction foram adicionadas para dar suporte a operações de fluxo de controle em circuitos dinâmicos: WhileLoopOp, ForLoopOp, e IfElseOp. Além disso, duas subclasses, BreakLoopOpe ContinueLoopOpforam adicionadas para dar suporte à interrupção e à continuação da próxima iteração de um contexto de loop, respectivamente.

    Eles podem ser criados como arquivos Instructionautônomos ou anexados a uma instância QuantumCircuit existente por meio de seus respectivos métodos, QuantumCircuit.while_loop(), for_loop(), if_test(), if_else(), break_loop(), e continue_loop().

  • Adicionada a BaseReadoutMitigator classe base abstrata para implementar atenuadores de erros de medição clássicos. Esses objetos destinam-se à atenuação de erros de medição em objetos Counts objetos retornados da execução de circuitos em backends com erros de medição.

    As classes de atenuadores de leitura têm dois métodos principais:

    Observe que atualmente o módulo qiskit.algorithms e a classe QuantumInstance ainda usam os mitigadores legados migrados do Qiskit Ignis em qiskit.utils.mitigation. Planeja-se atualizar o módulo para usar as novas classes de atenuador e descontinuar o código de atenuação legado em uma versão futura.

  • Adicionada a classe LocalReadoutMitigator para executar a atenuação de erros de leitura de medição de erros de medição locais. Os erros de medição local são aqueles descritos por um produto tensorial de erros de medição de um único qubit.

    Essa classe pode ser inicializada com uma lista de NN matrizes de atribuição de erro de medição de um único qubit ou de um backend usando as informações de erro de leitura nas propriedades do backend.

    A atenuação é implementada usando a inversão da matriz de atribuição local, que tem complexidade de O(2N)O(2^N) para NN - atenuação de qubit de QuasiDistribution e valores de expectativa.

  • Adicionada a classe CorrelatedReadoutMitigator para executar a atenuação de erros de leitura de medição de erros de medição correlacionados. Essa classe pode ser inicializada com uma única 2N×2N2^N \times 2^N matriz de atribuição de erro de medição que descreve as probabilidades de erro. A atenuação é implementada por meio da inversão da matriz de atribuição, que tem a complexidade de atenuação de O(4N)O(4^N) de QuasiDistribution e valores de expectativa.

  • Adicionados um atributo QuasiDistribution.stddev_upper_bound e um kwarg ao construtor da classe QuasiDistribution que é usada para armazenar erros padrão em estimativas de quase-probabilidade. Isso é usado pelas BaseReadoutMitigator para armazenar o erro padrão em quase-probabilidades atenuadas.

  • Adicionado um método shots() ao método qiskit.result.Counts para retornar a soma de todos os resultados nas contagens.

  • Ao executar a classe de algoritmo Grover classe de algoritmo, se a potência ideal for conhecida e apenas um único circuito for executado, a função de retorno de chamada não precisará mais ser definida e a pesquisa de Grover retornará a cadeia de bits mais provável AmplificationProblem.is_good_state não precisará mais ser definida, e a busca de Grover retornará o bitstring mais provável. Em geral, se a potência ideal do operador de Grover não for conhecida, o Grover algoritmo verifica diferentes potências (ou seja, iterações) e aplica a função is_good_state para verificar se uma boa bitstring foi medida. Por exemplo, agora você pode executar algo como:

    from qiskit.algorithms import Grover, AmplificationProblem
    from qiskit.providers.aer import AerSimulator
    from qiskit.quantum_info import Statevector
    
    # Fixed Grover power: 2.
    grover = Grover(iterations=2, quantum_instance=AerSimulator())
    
    # The ``is_good_state`` argument not required here since Grover search
    # will be run only once, with a power of 2.
    problem = AmplificationProblem(Statevector.from_label("111"))
    
    # Run Grover search and print the best measurement
    result = grover.amplify(problem)
    print(result.top_measurement)  # should print 111
  • Método adicionado remove_cregs() à classe DAGCircuit para suportar a remoção do registro clássico.

  • Método adicionado remove_clbits() à classe DAGCircuit para suportar a remoção de bits clássicos ociosos. Todos os registros clássicos que fazem referência a um bit removido também são removidos.

  • Adicionado um novo método, replace_block_with_op()à classe DAGCircuit classe. Esse método é usado para substituir um bloco de nós no DAG com uma única operação. O exemplo canônico é para a passagem ConsolidateBlocks que substitui blocos de nós por nós UnitaryGate equivalentes.

  • Adicionada uma nova passagem de transpilador de análise, Collect1qRunsao módulo qiskit.transpiler.passes módulo. Essa passagem é usada para encontrar sequências de portas ininterruptas que atuam em um único qubit. É semelhante ao Collect2qBlocks e CollectMultiQBlocks mas otimizado para execuções de um único qubit em vez de vários blocos de qubit.

  • Vários componentes internos de transpilação agora usam novos recursos no retworkx 0.10 ao operar na representação do circuito interno. Isso pode resultar em aumentos de velocidade nas chamadas para transpile de cerca de 10 a 40%, com efeitos maiores em níveis de otimização mais altos. Consulte #6302 para obter mais detalhes.

  • O UnitarySynthesis transpiler pass in qiskit.transpiler.passes tem um novo kwarg no construtor, min_qubits. Quando especificado, pode ser definido como um valor int que é o tamanho mínimo do objeto UnitaryGate para executar a síntese unitária. Se um UnitaryGate em um QuantumCircuit usar menos qubits, ele será ignorado por essa instância da passagem.

  • As interfaces Eigensolver e MinimumEigensolver agora suportam o tipo Dict[str, Optional[OperatorBase]] para o parâmetro aux_operators em seus respectivos métodos compute_eigenvalues() e compute_minimum_eigenvalue() . Nesse caso, os valores próprios auxiliares também são armazenados em um dicionário com as mesmas chaves fornecidas pelo dicionário aux_operators . As chaves que correspondem a um operador que não comuta com o operador principal são descartadas.

  • O BasisTranslator, GateDirection, e CheckGateDirection transpiler têm um novo kwarg target em seus construtores, que pode ser usado para definir um objeto Target como o destino da passagem. Se estiver definido, ele será usado em vez de target_basis (no caso do BasisTranslator ) ou coupling_map (no caso do GateDirection e CheckGateDirection passes).

  • Permitir dois estágios de transpilador no QuantumInstanceum para circuitos parametrizados e um segundo para circuitos vinculados (ou seja, sem parâmetros livres) apenas. Se uma instância quântica com passagens para circuitos não vinculados e vinculados for passada para um CircuitSamplero amostrador tentará aplicar a passagem não vinculada uma vez no circuito parametrizado, armazená-la em cache e aplicar apenas a passagem vinculada em todas as avaliações futuras.

    Isso permite que algoritmos variacionais como o VQE executem um gerenciador de passagem personalizado para circuitos parametrizados uma vez e, adicionalmente, outro transpilador com um gerenciador de passagem personalizado diferente nos circuitos vinculados em cada iteração. A capacidade de executar diferentes gerenciadores de passagens é importante porque nem todas as passagens suportam circuitos parametrizados (por exemplo Optimize1qGatesDecomposition só funciona com parâmetros de circuito vinculados).

    Por exemplo, esse recurso permite usar a decomposição CX com eficiência de pulso no VQE, como

    from qiskit.algorithms import VQE
    from qiskit.opflow import Z
    from qiskit.circuit.library.standard_gates.equivalence_library import StandardEquivalenceLibrary as std_eqlib
    from qiskit.transpiler import PassManager, PassManagerConfig, CouplingMap
    from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
    from qiskit.transpiler.passes import (
        Collect2qBlocks, ConsolidateBlocks, Optimize1qGatesDecomposition,
        RZXCalibrationBuilderNoEcho, UnrollCustomDefinitions, BasisTranslator
    )
    from qiskit.transpiler.passes.optimization.echo_rzx_weyl_decomposition import EchoRZXWeylDecomposition
    from qiskit.test.mock import FakeBelem
    from qiskit.utils import QuantumInstance
    
    # Replace by a real backend! If not ensure qiskit-aer is installed to simulate the backend
    backend = FakeBelem()
    
    # Build the pass manager for the parameterized circuit
    rzx_basis = ['rzx', 'rz', 'x', 'sx']
    coupling_map = CouplingMap(backend.configuration().coupling_map)
    config = PassManagerConfig(basis_gates=rzx_basis, coupling_map=coupling_map)
    pre = level_1_pass_manager(config)
    
    # Build a pass manager for the CX decomposition (works only on bound circuits)
    post = PassManager([
        # Consolidate consecutive two-qubit operations.
        Collect2qBlocks(),
        ConsolidateBlocks(basis_gates=['rz', 'sx', 'x', 'rxx']),
    
        # Rewrite circuit in terms of Weyl-decomposed echoed RZX gates.
        EchoRZXWeylDecomposition(backend),
    
        # Attach scaled CR pulse schedules to the RZX gates.
        RZXCalibrationBuilderNoEcho(backend),
    
        # Simplify single-qubit gates.
        UnrollCustomDefinitions(std_eqlib, rzx_basis),
        BasisTranslator(std_eqlib, rzx_basis),
        Optimize1qGatesDecomposition(rzx_basis),
    ])
    
    quantum_instance = QuantumInstance(backend, pass_manager=pre, bound_pass_manager=post)
    
    vqe = VQE(quantum_instance=quantum_instance)
    result = vqe.compute_minimum_eigenvalue(Z ^ Z)
  • Introduziu uma nova interface de plug-in de síntese unitária que é usada para permitir o uso de técnicas de síntese alternativas incluídas em pacotes externos sem problemas com a passagem do UnitarySynthesis passagem do transpilador. Os usuários podem selecionar um plug-in para usar ao chamar transpile() definindo o kwarg unitary_synthesis_method como o nome do plug-in. Uma lista completa dos plug-ins instalados pode ser encontrada usando a função qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names() função. Por exemplo, se você instalou um pacote que inclui um plug-in de síntese chamado special_synth , poderá usá-lo com:

    from qiskit import transpile
    
    transpile(qc, unitary_synthesis_method='special_synth', optimization_level=3)

    Isso substituirá todos os usos do método UnitarySynthesis pelo método incluído no pacote externo que exporta o plug-in special_synth .

    A interface do plug-in é construída em torno de pontos de entrada de setuptools que permitem que pacotes externos ao Qiskit anunciem que incluem um plug-in de síntese. Para obter detalhes sobre como escrever um novo plug-in, consulte a qiskit.transpiler.passes.synthesis.plugin documentação do módulo.

  • Adicionada uma nova passagem de transpilador, VF2Layout. Essa passagem modela o problema de alocação de layout como um problema de isomorfismo de subgrafo e usa a implementação do algoritmo VF2 no rustworkx para encontrar um layout perfeito (um layout que não exigiria roteamento adicional), se houver. A funcionalidade exposta por essa nova passagem é muito semelhante à existente CSPLayout mas VF2Layout é significativamente mais rápida.

Problemas Conhecidos

  • A convenção "ket" na gaveta "latex" de Statevector.draw() só é válida para estados compostos exclusivamente de qubits. Se estiver usando estados com alguns espaços de dimensão maior que dois, você deverá passar convention="vector" ou usar uma gaveta diferente.

  • Os recursos de exportação do OpenQASM 3 estão em um estado beta, e alguns recursos do Qiskit Terra's QuantumCircuit ainda não são compatíveis. Em particular, você poderá ver erros se tentar exportar subrotinas personalizadas com parâmetros clássicos, e ainda não há nenhuma disposição para exportar operações calibradas por pulso para o OpenPulse.

  • Ao executar o BasisTranslator de forma isolada com o argumento target definido como um objeto Target em que algumas portas de qubit único só podem ser aplicadas a conjuntos de qubits não sobrepostos, o circuito de saída pode incluir incorretamente operações em um qubit que não são permitidas pelo argumento Target. Por exemplo, se você executou:

    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit.circuit.library import UGate, RZGate, XGate, SXGate, CXGate
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    
    from qiskit.transpiler import PassManager, Target, InstructionProperties
    from qiskit.transpiler.passes import BasisTranslator
    
    gmap = Target()
    
    # U gate in qubit 0.
    theta = Parameter('theta')
    phi = Parameter('phi')
    lam = Parameter('lambda')
    u_props = {
        (0,): InstructionProperties(duration=5.23e-8, error=0.00038115),
    }
    gmap.add_instruction(UGate(theta, phi, lam), u_props)
    
    # Rz gate in qubit 1.
    phi = Parameter("phi")
    rz_props = {
        (1,): InstructionProperties(duration=0.0, error=0),
    }
    gmap.add_instruction(RZGate(phi), rz_props)
    
    # X gate in qubit 1.
    x_props = {
        (1,): InstructionProperties(
            duration=3.5555555555555554e-08, error=0.00020056469709026198
        ),
    }
    gmap.add_instruction(XGate(), x_props)
    
    # SX gate in qubit 1.
    sx_props = {
        (1,): InstructionProperties(
            duration=3.5555555555555554e-08, error=0.00020056469709026198
        ),
    }
    gmap.add_instruction(SXGate(), sx_props)
    
    cx_props = {
        (0, 1): InstructionProperties(duration=5.23e-7, error=0.00098115),
        (1, 0): InstructionProperties(duration=4.52e-7, error=0.00132115),
    }
    gmap.add_instruction(CXGate(), cx_props)
    
    bt_pass = BasisTranslator(sel, target_basis=None, target=gmap)
    
    qc = QuantumCircuit(2)
    qc.iswap(0, 1)
    output = bt_pass(qc)

    output terá RZGate e SXGate no qubit 0, mesmo que isso seja proibido. Para corrigir isso, normalmente você pode executar o tradutor de base uma segunda vez (ou seja output = bt_pass(output) no exemplo acima) para corrigir isso. Isso não deve afetar o resultado da execução da função transpile() e só é um problema se você executar a passagem por si só.

Notas da Atualização

  • A partir desta versão, o site from qiskit import * não importará submódulos, mas apenas uma lista selecionada de objetos. Isso pode quebrar o código existente usando from qiskit import * e fazendo referência a objetos que não fazem parte do namespace atual. Como lembrete, o site import * é considerado uma prática ruim e não deve ser usado em código de produção. A Qiskit define __all__ em qiskit/__init__.py como uma forma de atenuar os efeitos dessa prática ruim. Se seu código gerar name '<something>' is not defined, adicione from qiskit import <something> e tente novamente.

  • Os gerentes de passagem predefinidos para os níveis de otimização 0, 1, 2 e 3, que são gerados por level_0_pass_manager(), level_1_pass_manager(), level_2_pass_manager(), e level_3_pass_manager() respectivamente, não executarão mais incondicionalmente o processo TimeUnitConversion. Anteriormente, os gerenciadores de passagem predefinidos sempre executavam essa passagem, independentemente das entradas do transpilador e do circuito. Agora, essa passagem só será executada se um parâmetro scheduling_method for definido ou se o circuito contiver uma instrução Delay e o parâmetro instruction_durations estiver definido. Essa alteração foi feita no interesse do desempenho do tempo de execução, pois, em alguns casos transpile() em circuitos com um grande número de portas e sem atrasos, tempo ou agendamento sendo usados, o TimeUnitConversion pode ser o maior gargalo na transpilação.

  • O método padrão para BIPMapping agora é balanced em vez de depth. Esse novo objetivo geralmente alcança um resultado melhor, pois leva em conta a profundidade do circuito e o erro de porta.

  • O endereço sort_parameters_by_name da classe VQE foi removida, após sua descontinuação no Qiskit Terra 0.18. Não há alternativa, pois a nova ordem dos parâmetros é a ordem de classificação mais natural.

  • As gavetas do circuito QuantumCircuit.draw() e circuit_drawer() com a opção latex agora salvarão suas imagens em um formato determinado pela extensão do arquivo (se um nome de arquivo for fornecido). Anteriormente, eles sempre eram salvos no formato PNG. Agora, eles exibem ValueError se o formato da imagem não for conhecido. Isso foi feito para facilitar o salvamento da imagem em diferentes formatos.

  • A dependência principal retworkx teve seu requisito de versão aumentado para 0.10.1, em vez de 0.9. Isso permite várias melhorias de desempenho em diferentes passagens de transpilação.

  • O kwarg condition , anteriormente obsoleto, que foi obsoleto como parte da versão 0.15.0, foi removido do DAGCircuit.apply_operation_back() e DAGCircuit.apply_operation_front(). Em vez disso, defina o atributo condition nas Instruction que estão sendo adicionadas às instâncias DAGCircuit usando Instruction.c_if().

  • O método DAGCircuit.extend_back() foi removido. Ele foi originalmente preterido na versão 0.13.0. Em vez disso, você pode usar o método DAGCircuit.compose() que é mais geral e oferece a mesma funcionalidade.

  • O método DAGCircuit.compose_back() foi removido. Ele foi originalmente preterido na versão 0.13.0. Em vez disso, você pode usar o método DAGCircuit.compose() que é mais geral e oferece a mesma funcionalidade.

  • O edge_map kwarg do DAGCircuit método compose() foi removido. Ele foi originalmente preterido na versão 0.14.0. O método recebe um qubits e clbits kwargs para especificar a ordem posicional dos bits a serem compostos, em vez de usar um mapeamento de dicionário que edge_map forneceu anteriormente.

  • O método DAGCircuit.twoQ_gates() foi removido. Ele foi originalmente preterido na versão 0.13.0. Em vez disso, DAGCircuit.two_qubit_ops() deve ser usado.

  • O método DAGCircuit.threeQ_or_more_gates() foi removido. Ele foi originalmente preterido na versão 0.13.0. Em vez disso, DAGCircuit.multi_qubit_ops() deve ser usado.

  • O acesso nomeado para o primeiro argumento posicional do construtor da classe SingleQubitUnitary com u foi removido. Ele foi originalmente preterido na versão 0.14.0. Em vez disso, o primeiro argumento posicional pode ser definido usando o nome unitary_matrix (ou apenas defini-lo posicionalmente em vez de por nome).

  • Acesso nomeado para o primeiro argumento posicional do QuantumCircuit método squ com u foi removido. Ele foi originalmente preterido na versão 0.14.0. Em vez disso, o primeiro argumento posicional pode ser definido usando o nome unitary_matrix (ou apenas defini-lo posicionalmente em vez de por nome).

  • Os kwargs não utilizados proc e nested_scope para o método qasm() das classes de nós QASM no módulo qiskit.qasm.node foram removidos. Eles foram originalmente descontinuados na versão 0.15.0.

  • Os kwargs não utilizados proc e nested_scope para o método latex() das classes de nós QASM no módulo qiskit.qasm.node foram removidos. Eles foram originalmente descontinuados na versão 0.15.0.

  • Os kwargs não utilizados proc e nested_scope para o método real() das classes de nós QASM no módulo qiskit.qasm.node foram removidos. Eles foram originalmente descontinuados na versão 0.15.0.

  • A saída de Statevector.draw() ao usar a saída "latex" é agora a nova convenção "ket" se estiver plotando um estado composto exclusivamente de qubits. Isso foi alterado para tornar a leitura do resultado mais clara, especialmente em contextos educacionais, porque ele mostra os rótulos de ket e exibe apenas os elementos diferentes de zero.

  • Ao executar execute() com um BackendV1 os valores padrão para os kwargs shots, max_credits, meas_level, meas_return e memory_slot_size serão agora qualquer que seja o padrão definido no atributo options do backend de destino. Anteriormente, esses padrões eram definidos para corresponder aos valores padrão ao chamar execute() com um backend legado do BaseBackend . Por exemplo:

    from qiskit.test.mock import FakeMumbai
    from qiskit import QuantumCircuit, execute
    
    circuit = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    backend = FakeMumbai()
    backend.set_options(shots=4096)
    execute(qc, backend)

    agora será executado com 4096 shots. Em versões anteriores, ele era executado com 1024.

  • A versão mínima compatível do Matplotlib foi aumentada de 2.1.0 para 3.3.0. Agora você precisará ter o Matplotlib 3.3.0 instalado se estiver usando funções de visualização baseadas no Matplotlib, como o backend 'mpl' para a função circuit_drawer() ou a função plot_bloch_vector() função. Isso foi feito por dois motivos: o primeiro é porque as versões recentes do Matplotlib preteriram o uso de APIs em torno das visualizações do 3D que eram compatíveis com versões mais antigas e, segundo, a instalação de versões mais antigas do Matplotlib estava se tornando cada vez mais difícil, pois as dependências upstream do matplotlib causaram incompatibilidades que dificultaram os testes.

  • O uso interno do gerador de números aleatórios no random_circuit() foi ajustado, o que alterará a saída das versões anteriores, mesmo com uma semente fixa. Isso foi feito para melhorar consideravelmente a escala do tempo de execução com o número de qubits que estão sendo usados. Se estiver dependendo de uma saída idêntica de uma versão anterior, é recomendável usar qpy_serialization.dump() para salvar o circuito aleatório gerado com uma versão anterior e, em vez de gerá-lo novamente com a nova versão, usar apenas qpy_serialization.load() para carregar o circuito salvo.

  • O uso de * (__mul__) para o método dot() e @ (__matmul__) para o método compose() de BaseOperator (que é o pai de todas as classes de operadores em qiskit.quantum_info incluindo classes como Operator e Pauli) não é mais suportado. O uso desses operadores já havia sido preterido na versão 0.17.0. Em vez disso, você deve usar o dot() e compose() diretamente, ou o operador & (__and__) pode ser usado para compose(). Por exemplo, se você estava usando anteriormente o operador como:

    from qiskit.quantum_info import random_hermitian
    
    op_a = random_hermitian(4)
    op_b = random_hermitian(4)
    
    new_op = op_a @ op_b

    isso deve ser alterado para:

    from qiskit.quantum_info import random_hermitian
    
    op_a = random_hermitian(4)
    op_b = random_hermitian(4)
    new_op = op_a.compose(op_b)

    ou:

    new_op = op_a & op_b
  • Vários métodos de atribuição de parâmetros a operandos de instruções de programas de pulso foram removidos, pois foram descontinuados no Qiskit Terra 0.17. Dentre eles:

    • o método assign() de pulse.Instruction.
    • o método assign() de Channel, que é a base de AcquireChannel, SnapshotChannel, MemorySlot e RegisterSlot.
    • os métodos assign() e assign_parameters() de ParametricPulse, que é a base de pulse.Gaussian, pulse.GaussianSquare, pulse.Drag e pulse.Constant.

    Esses parâmetros devem ser atribuídos a partir do programa de pulso (pulse.Schedule e pulse.ScheduleBlock) em vez de operandos da instrução do programa de pulso.

  • O método flatten() de pulse.Instruction e qiskit.pulse.Schedule foi removido e não existe mais, de acordo com o aviso de depreciação do Qiskit Terra 0.17. Essa transformação é definida como uma função autônoma em qiskit.pulse.transforms.canonicalization.flatten().

  • qiskit.pulse.interfaces.ScheduleComponent foi removido e não existe mais, de acordo com o aviso de depreciação do Qiskit Terra 0.15. Nenhuma aula alternativa será oferecida.

  • Os argumentos legados da gaveta de pulso foram removidos do site pulse.Waveform.draw(), Schedule.draw() e ScheduleBlock.draw() e não existem mais, de acordo com o aviso de depreciação do Qiskit Terra 0.16. Agora, esses métodos de desenho são compatíveis apenas com os argumentos da gaveta de pulsos V2. Consulte as documentações dos métodos para obter detalhes.

  • O módulo qiskit.pulse.reschedule foi removido e esse caminho de importação não existe mais, de acordo com o aviso de depreciação do Qiskit Terra 0.14. Use qiskit.pulse.transforms em vez disso.

  • Um método protegido Schedule._children() foi removido e substituído por uma variável de instância protegida, de acordo com o aviso de depreciação do Qiskit Terra 0.17. Isso agora é fornecido como um atributo público Schedule.children.

  • Os métodos e as propriedades relevantes do Timeslot foram removidos e não existem mais no ScheduleBlock de acordo com o aviso de depreciação do Qiskit Terra 0.17. Como essa representação não tem noção do tempo de instrução t0, as informações sobre o intervalo de tempo estarão disponíveis depois que ele for transformado em um Schedule. Os atributos correspondentes foram fornecidos após essa conversão, mas não são mais compatíveis. Os seguintes atributos são removidos:

    • timeslots
    • start_time
    • stop_time
    • ch_start_time
    • ch_stop_time
    • shift
    • insert
  • As transformações do cronograma de pulso de alinhamento foram removidas e não existem mais, de acordo com o aviso de depreciação do Qiskit Terra 0.17. Essas transformações são integradas e implementadas no contexto AlignmentKind do bloco de programação. As seguintes funções de transformação explícitas são removidas:

    • qiskit.pulse.transforms.align_equispaced
    • qiskit.pulse.transforms.align_func
    • qiskit.pulse.transforms.align_left
    • qiskit.pulse.transforms.align_right
    • qiskit.pulse.transforms.align_sequential
  • Os comandos redundantes do construtor de pulsos foram removidos e não existem mais, de acordo com o aviso de depreciação do Qiskit Terra 0.17. pulse.builder.call_schedule e pulse.builder.call_circuit foram integrados ao pulse.builder.call().

  • Uma substituição de filtro interno que fazia com que todos os avisos de depreciação do Qiskit fossem exibidos foi removida. Isso significa que o comportamento agora será revertido para o comportamento padrão do site Python para depreciações; você só verá um DeprecationWarning se ele tiver sido acionado pelo código no arquivo de script principal, na sessão do interpretador ou no notebook Jupyter. O usuário não será mais acusado de receber um aviso se as funções internas do Qiskit chamarem um comportamento obsoleto. Se você escreve bibliotecas, deve ocasionalmente executar com os filtros de aviso padrão desativados ou ter testes que sempre são executados com eles desativados. Consulte a documentação Python sobre avisos e, em particular, a seção sobre testes de depreciações para obter mais informações sobre como fazer isso.

  • Alguns avisos costumavam ser emitidos apenas uma vez, mesmo que acionados em vários locais. Esse comportamento foi removido, portanto, é possível que, se você chamar funções obsoletas, receba mais avisos do que antes. Você deve alterar todas as chamadas de função obsoletas para as versões sugeridas, pois os formulários obsoletos serão removidos em versões futuras do Qiskit.

  • O módulo obsoleto qiskit.schemas e o módulo qiskit.validation , que criam o validador de jsonschema a partir dos esquemas, foram removidos. Isso foi descontinuado na versão 0.17.0 e foi substituído por um repositório dedicado para os esquemas de carga útil da API Quantum IBM.

    Se você dependia dos arquivos de esquema previamente empacotados em qiskit.schemas ou dos validadores criados com base neles, deverá usar esse repositório e criar validadores a partir dos arquivos de esquema nele contidos.

  • As funções qiskit.qobj.validate_qobj_against_schema e qiskit.qobj.common.validator , juntamente com o kwarg validate dos métodos QasmQobj.to_dict(), PulseQobj.to_dict(), e Qobj.to_dict() foram removidos. Eles foram descontinuados na versão 0.17.0. Se estiver usando essa função, você terá que criar manualmente funções de validação de jsonschema para objetos Qobj usando os arquivos jsonschema do repositório dedicado para os esquemas de carga útil da API IBM Quantum.

  • Os pacotes fastjsonschema e jsonschema não estão mais na lista de requisitos do qiskit-terra. O uso interno do jsonschema foi removido e não é mais necessário usar o qiskit-terra.

  • A exceção levantada pela função assemble() quando parâmetros inválidos são passados para a construção de um PulseQobj foi alterada de SchemaValidationError para QiskitError. Isso foi necessário porque a classe SchemaValidationError foi removida junto com o restante das obsoletas qiskit.schemas e qiskit.validation. Isso também o torna mais consistente com outras condições de erro de assemble() que já estavam gerando um QiskitError.

  • A passagem de roteamento e a passagem de layout padrão para o nível 3 de otimização do transpilador foram alteradas para usar SabreSwap e SabreLayout respectivamente. Isso foi feito para melhorar a qualidade do resultado de saída, pois o uso das passagens de sabre produz melhores resultados do que o uso de StochasticSwap e DenseLayoutque eram usados como padrão em versões anteriores. Essa alteração melhorará a qualidade dos resultados ao executar o transpile() ou execute() com o kwarg optimization_level definido como 3. Embora isso seja geralmente uma melhoria, se você precisar manter o comportamento anterior por qualquer motivo, poderá fazer isso definindo explicitamente routing_method="stochastic" e layout_method="dense" ao chamar transpile() com optimization_level=3.

  • O tipo de retorno de pauli_basis() será alterado de PauliTable para PauliList em uma versão futura do Qiskit Terra. Para mudar imediatamente para o novo comportamento, passe o argumento de palavra-chave pauli_list=True.

  • O atributo name da classe SingleQubitUnitary foi alterado de unitary para squ. Isso foi necessário para evitar um conflito com o nome da classe UnitaryGate , que também era unitary , pois as duas portas não são iguais e não têm a mesma implementação (e não podem ser usadas de forma intercambiável).

  • A versão mínima do Symengine necessária para a instalação foi aumentada para 0.8.0. Isso foi necessário para corrigir alguns problemas com o manuseio dos valores numpy.float16 e numpy.float32 ao executar bind() para vincular parâmetros em um arquivo ParameterExpression.

  • Uma nova dependência de estivador foi adicionada à lista de requisitos. Isso é necessário para o qiskit-terra, pois ele é usado para criar a interface do plug-in de síntese unitária.

Notas de descontinuação

  • O atributo gate e o parâmetro de inicialização de qiskit.transpiler.passes.Decompose estão obsoletos e serão removidos em uma versão futura. Em vez desse único portão, você deve passar uma lista de nomes de portões para o novo parâmetro gates_to_decompose. Isso foi feito porque o novo formulário permite que você selecione mais de uma porta como alvo de decomposição, o que é mais flexível, e não é necessário executar novamente a passagem várias vezes para decompor um conjunto de portas.

  • Houve uma reorganização significativa do passe do transpiler com relação às calibrações. Os caminhos de importação:

    from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilder
    from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilderNoEcho

    são obsoletos e serão removidos em uma versão futura. O caminho de importação:

    from qiskit.transpiler.passes.scheduling.rzx_templates import rzx_templates

    também está obsoleto e será removido em uma versão futura. Você deve usar os novos caminhos de importação:

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.transpiler.passes import RZXCalibrationBuilderNoEcho
    from qiskit.transpiler.passes.calibration.rzx_templates import rzx_templates
  • A classe DAGNode está sendo descontinuada como uma classe autônoma e será usada no futuro apenas como a classe pai para DAGOpNode, DAGInNode, e DAGOutNode. Como parte dessa descontinuação, os seguintes kwargs e atributos associados em DAGNode também estão sendo descontinuados: type, op, e wire.

  • Para o construtor do RZXCalibrationBuilder passar um backend como o primeiro argumento posicional ou com o kwarg backend nomeado está obsoleto e não funcionará mais em uma versão futura. Em vez disso, um InstructionScheduleMap deve ser passado diretamente para o kwarg instruction_schedule_map e uma lista de listas de nomes de canais para cada qubit deve ser passada diretamente para qubit_channel_mapping. Por exemplo, se você estivesse chamando o passe como:

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.test.mock import FakeMumbai
    
    backend = FakeMumbai()
    cal_pass = RZXCalibrationBuilder(backend)

    em vez disso, você deve chamá-lo assim:

    from qiskit.transpiler.passes import RZXCalibrationBuilder
    from qiskit.test.mock import FakeMumbai
    
    backend = FakeMumbai()
    inst_map = backend.defaults().instruction_schedule_map
    channel_map = self.backend.configuration().qubit_channel_mapping
    cal_pass = RZXCalibrationBuilder(
        instruction_schedule_map=inst_map,
        qubit_channel_mapping=channel_map,
    )

    Essa alteração é necessária porque, como regra geral, os objetos de back-end não são serializáveis por pickle e isso quebraria quando fosse usado com vários processos dentro de transpile() ao compilar vários circuitos de uma só vez.

  • A propriedade label da classe MCMT e subclasse MCMTVChain foi preterida e será removida em uma versão futura. Consequentemente, o kwarg label no construtor de ambas as classes também está obsoleto, juntamente com o kwarg label do método MCMT.control(). Atualmente, a propriedade label é usada para nomear o alvo controlado quando ele é composto por mais de um qubit alvo; no entanto, isso nunca foi planejado para ser especificado pelo usuário e pode resultar em uma porta MCMT incorreta se o nome de uma operação bem conhecida for usado. Após a descontinuação, a propriedade label não poderá mais ser especificada pelo usuário. No entanto, você pode obter o nome gerado do alvo controlado por meio de

    MCMT.data[0][0].base_gate.name
  • O método subgraph() da classe CouplingMap está obsoleto e será removido em uma versão futura. Em vez disso, deve ser usado o método reduce() deve ser usado, o que faz a mesma coisa, exceto que preserva a ordem da lista de nós para a saída CouplingMap (enquanto subgraph() não preserva a ordem da lista).

  • A criação de uma instância de InstructionSet com o argumento da palavra-chave circuit_cregs está obsoleta. Em geral, essas classes nunca precisam ser construídas pelos usuários (mas são usadas internamente), mas, se for necessário, você deve passar um callable como argumento da palavra-chave resource_requester . Por exemplo:

    from qiskit.circuit import Clbit, ClassicalRegister, InstructionSet
    from qiskit.circuit.exceptions import CircuitError
    
    def my_requester(bits, registers):
        bits_set = set(bits)
        bits_flat = tuple(bits)
        registers_set = set(registers)
    
        def requester(specifier):
            if isinstance(specifer, Clbit) and specifier in bits_set:
                return specifier
            if isinstance(specifer, ClassicalRegster) and specifier in register_set:
                return specifier
            if isinstance(specifier, int) and 0 <= specifier < len(bits_flat):
                return bits_flat[specifier]
            raise CircuitError(f"Unknown resource: {specifier}")
    
        return requester
    
    my_bits = [Clbit() for _ in [None]*5]
    my_registers = [ClassicalRegister(n) for n in range(3)]
    
    InstructionSet(resource_requester=my_requester(my_bits, my_registers))
  • O uso das classes de mitigação de medição qiskit.ignis.mitigation.CompleteMeasFitter e qiskit.ignis.mitigation.TensoredMeasFitter de qiskit-ignis como valores para o kwarg measurement_error_mitigation_cls do construtor da classe QuantumInstance está obsoleto e será removido em uma versão futura. Em vez disso, as classes equivalentes de qiskit.utils.mitigation, CompleteMeasFitter e TensoredMeasFitter devem ser usadas. Isso foi necessário porque o projeto qiskit-ignis está obsoleto e não terá mais suporte em um futuro próximo. Vale a pena observar que, ao contrário das classes equivalentes de qiskit-ignis , as versões de qiskit.utils.mitigation são suportadas somente em seu uso com QuantumInstance (ou seja, como uma classe e não como uma instância com o kwarg measurement_error_mitigation_cls ) e não se destinam ao uso autônomo.

  • O método Optimizer.optimize() para todos os otimizadores (Optimizer e classes derivadas) está obsoleto e será removido em uma versão futura. Em vez disso, o método Optimizer.minimize() deve ser usado para imitar a assinatura da função SciPy’s minimize() .

    Para substituir a chamada atual do optimize pelo minimize, você pode substituir

    xopt, fopt, nfev = optimizer.optimize(
        num_vars,
        objective_function,
        gradient_function,
        variable_bounds,
        initial_point,
    )

    com o

    result = optimizer.minimize(
        fun=objective_function,
        x0=initial_point,
        jac=gradient_function,
        bounds=variable_bounds,
    )
    xopt, fopt, nfev = result.x, result.fun, result.nfev
  • A importação do módulo qiskit.util agora emitirá um DeprecationWarning. Em vez disso, os usuários devem importar todas as mesmas funcionalidades do qiskit.utils. O módulo util está obsoleto desde o Terra 0.17, mas anteriormente não emitia um aviso. Ele será removido no Terra 0.20.

  • A propriedade table está obsoleta e será removida em uma versão futura. Isso ocorre porque o SparsePauliOp foi atualizado para usar internamente PauliList em vez de PauliTable. Isso é para melhorar significativamente o desempenho. Agora você deve acessar os PauliList usando o atributo SparsePauliOp.paulis atributo.

Correções de bugs

  • Foi corrigido um bug em que muitos métodos de layout ignoravam portas de 3 ou mais qubits, resultando em decisões inesperadas de alocação de layout. A passagem do transpilador Unroll3qOrMore agora está sendo executada antes da passagem de layout em todos os gerenciadores de passagem predefinidos quando transpile() é chamado. Corrigido #7156.

  • Os circuitos desmontados agora herdam as calibrações dos circuitos montados QasmQobj e dos experimentos. Correções #5348.

  • Foi corrigida a configuração dos atributos ansatz ou optimizer de uma instância VQE para None , o que resultava em um comportamento com erros. Consulte #7093 para obter detalhes.

  • Corrigida a adição de PauliLists com qargs. O método usado para gerar um erro de tempo de execução se os operandos tivessem números diferentes de qubits.

  • Foi corrigido um problema que causava um erro ao tentar calcular um gradiente com a classe CircuitGradient para uma porta que não era uma porta suportada. Essa correção de bug transpila uma determinada porta para o conjunto de portas compatíveis com um método de gradiente solicitado. Correções #6918.

  • Resultados de calibração removidos ao usar a atenuação de erros com o método execute() método de QuantumInstance. Correções #7129.

  • Foi corrigido um aviso de depreciação emitido ao executar o QuantumCircuit.draw() ou circuit_drawer() com o Sympy 1.9 instalado, mencionando a função Sympy expr_free_symbols(). As gavetas de circuito usaram esse método anteriormente para encontrar instâncias de constantes simbólicas.

  • Foi corrigido um problema em que o kwarg ax e a opção figwidth no kwarg style para a gaveta de circuito mpl não eram dimensionados corretamente. Os usuários agora podem passar um ax de um subplot Matplotlib para a gaveta de circuito mpl e o circuito será desenhado dentro dos limites desse subplot. Como alternativa, os usuários podem definir o figwidth em polegadas no style dict kwarg e o desenho será dimensionado para a largura em polegadas que foi definida. Corrigido #6367.

  • Foi corrigido um problema com a função circuit_drawer() função e draw() do método QuantumCircuit. Ao exibir uma instrução measure direcionada a um bit clássico em vez de um registro, usando a opção de gaveta latex , a gaveta falhava.

  • Foi corrigido um problema com a função circuit_drawer() função e draw() do método QuantumCircuit. Com qualquer uma das três opções de gaveta, mpl, latex, ou text, se for encontrada uma porta com uma condição clássica condicionada a um bit clássico sem um registro, a gaveta falhará.

  • Foi corrigido um problema com a função circuit_drawer() função e draw() do método QuantumCircuit. Com qualquer uma das três opções de gaveta, mpl, latex, ou text, se uma porta com uma condição clássica fosse condicionada ao mesmo bit clássico que um measure e o bit que a medida visasse não tivesse um registro, a gaveta falharia.

  • C3SXGate agora tem uma decomposição e uma representação de matriz corretas. Anteriormente, era equivalente a SdgXGate().control(3), em vez do pretendido SXGate().control(3).

  • O membro name de qiskit.test.mock.utils.ConfigurableFakeBackend foi alterado para backend_name. Isso foi feito para evitar um conflito com o método name() herdado da classe abstrata pai BackendV1 da classe abstrata principal. Isso torna o ConfigurableFakeBackend compatível com qualquer coisa que espere um BackendV1 objeto. No entanto, se você estava usando o atributo name diretamente antes, agora precisará chamá-lo como um método ou acessar o atributo backend_name .

  • Foi corrigido um problema em que a chamada de QuantumCircuit.decompose() em um circuito contendo um Instruction cujo atributo definition estava vazio deixava a instrução no lugar, em vez de decompô-la em zero operações. Por exemplo, com um circuito:

    from qiskit.circuit import QuantumCircuit
    empty = QuantumCircuit(1, name="decompose me!")
    circuit = QuantumCircuit(1)
    circuit.append(empty.to_gate(), [0])

    Anteriormente, ligar para circuit.decompose() não alterava o circuito. Agora, a decomposição corrigirá a decomposição de empty em zero instruções. Consulte o número 6997 para saber mais.

  • Foi corrigido um problema com a função circuit_drawer() função e draw() do método QuantumCircuit. Ao exibir uma instrução measure contendo um condition clássico usando as opções mpl ou latex , as informações do condition às vezes substituíam a exibição do measure .

  • Foi corrigido um problema com a função circuit_drawer() função e draw() do método QuantumCircuit. A gaveta mpl usou a notação hexadecimal para exibir o valor condition , enquanto as gavetas text e latex usaram a notação decimal. Agora, todas as três gavetas usam notação hexadecimal.

  • Foi corrigido um bug na passagem de transpilação do otimizador Hoare, que poderia tentar remover um portão duas vezes se ele pudesse ser combinado separadamente com seu predecessor e seu sucessor para formar a identidade. Consulte o número 7271 para obter mais detalhes.

  • Tornar uma instrução condicional com o método padrão InstructionSet.c_if() com índices inteiros agora é consistente com o esquema de numeração usado pelo QuantumCircuit do qual as instruções fazem parte. Anteriormente, se houvesse dois ClassicalRegisters com Clbitsobrepostos, a numeração estaria incorreta. Consulte o número 7246 para obter mais detalhes.

  • Tornar uma instrução condicional com o método padrão InstructionSet.c_if() agora será bem-sucedido, mesmo que não haja ClassicalRegisters no circuito. Consulte #7250 para obter mais detalhes.

  • Tornar uma instrução condicional com o método padrão InstructionSet.c_if() ao usar um Clbit que está contido em um registro ClassicalRegister de tamanho um agora criará corretamente uma condição sobre o bit, não sobre o registro. Consulte #7255 para obter mais detalhes.

  • A tentativa de tornar uma instrução condicional com o método padrão InstructionSet.c_if() agora gerará corretamente um erro se o recurso clássico não estiver presente no circuito. Consulte #7255 para obter mais detalhes.

  • Foi corrigido um problema de compatibilidade com o site Matplotlib 3.5, em que a esfera Bloch não era renderizada se tivesse algum vetor anexado, como, por exemplo, ao usar o plot_bloch_vector. Consulte o número 7272 para obter mais detalhes.

  • Foi corrigido um problema com o método NLocal.add_layer() anexava camadas incorretamente se o objeto NLocal já tivesse sido criado.

  • Foi corrigido um problema com a decapagem do objeto InstructionScheduleMap ao usar Python 3.6. Consulte o número 6944 para obter detalhes.

  • A atribuição de parâmetros de pulso de valor complexo com o symengine foi corrigida. Por exemplo,

    from qiskit import circuit, pulse
    import numpy as np
    
    amp = circuit.Parameter("amp")
    phase = circuit.Parameter("phase")
    
    with pulse.build() as sched:
        pulse.play(pulse.Gaussian(160, amp * np.exp(1j * phase), 40), pulse.DriveChannel(0))
    sched.assign_parameters({amp: 0.1, phase: 1.57}, inplace=True)

    A amplitude atribuída foi mostrada como ParameterExpression(0.1*exp(1.57*I)) depois que o uso de symengine foi introduzido na versão 0.18.0. Isso agora é avaliado corretamente e mostrado como 7.96327e-05 + 0.0999999683j.

  • Foi corrigido um problema em que QAOA.construct_circuit() com operadores diferentes com o mesmo número de qubits gerava o mesmo circuito todas as vezes. Consulte #7223 para obter mais detalhes.

  • Foi corrigido um problema em que o QAOAAnsatz apresentava um número incorreto de parâmetros se as identidades de PauliSumOp fossem fornecidas, por exemplo, PauliSumOp.from_list([("III", 1)]). Consulte o número 7225 para obter mais detalhes.

  • Foi corrigido um bug em que o método QuantumCircuit.qasm() podia retornar instruções OpenQASM 2 com identificadores inválidos. O mesmo erro foi corrigido em UnitaryGate.

  • Foi corrigido um problema em que a tentativa de exibir bits sem registro causava uma falha no site mpl e nas gavetas do circuito latex . Foi removido um _ inicial da exibição dos números de bits sem registro na gaveta text . Corrigido #6732.

  • Para registros de um bit, todas as gavetas de circuito agora exibem apenas o nome do registro e não mostram mais o subscrito 0 . Corrigido #5784.

  • Correção de colisões de nomes de registros implícitos em QuantumCircuit.qasm ao lidar com qubits e clbits sem registro. Anteriormente, os qubits e clbits sem registro eram colocados nos correspondentes qreg e creg , ambos chamados de regless, apesar da colisão. Eles agora terão nomes separados, gerados de forma determinística, que não entrarão em conflito com nenhum nome de registro definido pelo usuário no circuito.

  • Foi corrigido um problema no agendamento de circuitos com operações de clbits, por exemplo, medições, portas condicionais, atualização ASAPSchedule, ALAPSchedule, e AlignMeasures. Os planejadores atualizados assumem que todas as operações de E/S dos clbits não levam tempo, measure grava o valor medido em um clbit no final e c_if lê o valor condicional em clbit(s) no início. Corrigido #7006.

  • Chamar transpile em uma lista vazia agora retornará corretamente uma lista vazia sem emitir um aviso. Corrigido #7287.

  • Foi corrigido um problema em PiecewiseChebyshev quando a função a ser aproximada era constante. Nesses casos, agora você deve passar a constante diretamente como o argumento f_x , em vez de usar uma função, como, por exemplo:

    from qiskit.circuit.library.arithmetic import PiecewiseChebyshev
    
    PiecewiseChebyshev(1.0, degree=3)

    Consulte o número 6707 para obter mais detalhes.

  • Se uma instância do algoritmo HHL foi construída sem um QuantumInstance (o padrão), as tentativas de usar as propriedades getter e setter para ler ou definir uma instância posteriormente falhariam. Os getters e setters agora funcionam como esperado.

  • O método QuantumCircuit.qasm() agora edita os nomes das cópias das instruções presentes no circuito, e não as instruções originais que estão em circuit.data. Consulte o número 6952 para obter mais detalhes.

  • Foi corrigido um bug no PauliSumOp.permute() que causava o erro:

    QiskitError: 'Pauli string label "" is not valid.'

    se a permutação tivesse o mesmo número de termos de Pauli. A chamada de permute([2, 1, 0]) em X ^ Y ^ Z não gera mais um erro e agora retorna Z ^ Y ^ X.

  • Foi corrigido um erro em que os limites dos parâmetros do mixer na seção QAOAAnsatz não eram definidos.

  • Determinação fixa das operações finais (barreiras e medidas) no passe RemoveFinalMeasurements e no método remove_final_measurements() da classe QuantumCircuit que anteriormente considerava apenas os nós imediatamente anteriores a um nó de saída.

  • Determinação fixa das operações finais na passagem RemoveFinalMeasurements e no método remove_final_measurements() da classe QuantumCircuit que poderia considerar erroneamente uma barreira como final, mesmo que outras operações de circuito a seguissem.

  • Correção da remoção do registro clássico de vários bits na passagem RemoveFinalMeasurements e no método remove_final_measurements() da classe QuantumCircuit em que os registros clássicos não eram removidos mesmo que outros bits estivessem ociosos, a menos que uma medida final fosse feita em cada um dos bits. Agora, os registros clássicos que se tornam ociosos como resultado da remoção das medições e barreiras finais são sempre removidos. Os bits clássicos são removidos se forem referenciados apenas por registros removidos ou se não forem referenciados e se tornarem ociosos devido à remoção. Essa correção também adiciona o tratamento adequado de registros com bits subjacentes compartilhados.

  • Foi corrigido um problema com o RemoveFinalMeasurements que podia fazer com que o DAGCircuit resultante se tornasse inválido. Consulte #7196 para obter mais detalhes.

  • Foi corrigido um problema com o método remove_final_measurements() da classe QuantumCircuit que fazia com que o QuantumCircuit.clbits ficasse incorreto após a invocação. Consulte o número 7089 para obter detalhes.

  • Ao afunilar um operador zero vazio em qiskit.opflowo código, ao detectar que era zero, registrava um aviso e retornava o operador original. Esses operadores são comumente encontrados nos operadores auxiliares, quando se usa o Qiskit Nature, e o comportamento acima fez com que o site VQE lançasse uma exceção, pois os operadores não nulos afunilados eram um número diferente de qubits dos operadores nulos afunilados (já que o afunilamento retornou o operador de entrada inalterado). Agora, o código afunilará corretamente um operador zero de modo que o número de qubits seja reduzido conforme o esperado e corresponda aos operadores não zero afunilados, por exemplo, `0*"IIII"` quando estivermos afunilando 3 qubits se tornará 0*"I".

  • Foi corrigido um problema com o método draw() método e função circuit_drawer() em que um estilo personalizado definido por meio do arquivo de configuração do usuário (ou seja, settings.conf) ignoraria o valor definido do campo circuit_mpl_style se o kwarg style na função/método não estivesse definido.

Outras observações

  • A string cast para qiskit.circuit.ParameterExpression não tem mais precisão total. Isso remove o final 0s ao imprimir parâmetros vinculados a floats. Isso tem consequências para a serialização do QASM e a gaveta de texto do circuito:

    >>> from qiskit.circuit import Parameter
    >>> x = Parameter('x')
    >>> str(x.bind({x:0.5}))
    '0.5'   # instead of '0.500000000000000'
  • O QAOAAnsatz foi atualizado para usar o símbolo de parâmetro γ para o operador de custo e β para o operador de misturador, como é a notação padrão na literatura sobre QAOA.

Aer 0.9.1

Nenhuma mudança

Ignis 0.7.0

Prelúdio

Esta versão substitui o projeto Qiskit Ignis, que foi substituído pelo projeto Qiskit Experiments e o desenvolvimento ativo foi interrompido. Embora obsoletas, as correções de bugs críticos e as correções de compatibilidade continuarão a ser feitas para oferecer aos usuários uma oportunidade suficiente para migrar do Ignis. Após o período de depreciação (que não será inferior a 3 meses a partir desta versão), o projeto será retirado e arquivado.

Novos Recurso

  • Atualização do protocolo de credenciamento para usar a rotina de ajuste de https://arxiv.org/abs/2103.06603. AccreditationFitter agora tem os métodos FullAccreditation (protocolo anterior) e MeanAccreditation (novo protocolo). Além disso, a entrada de dados foi alterada para usar o objeto de resultado AppendResult ou uma lista de cadeias de caracteres AppendStrings. qiskit.ignis.verification.QOTPCorrectString() também foi adicionado.

  • Adicionada a opção de geração analítica rápida de gráficos de síndrome. O RepetitionCode agora tem um novo argumento bool brute, que permite ainda usar o método de força bruta. Classe auxiliar RepetitionCodeSyndromeGenerator adicionada para facilitar isso.

  • O RepetitionCode agora tem argumentos de palavra-chave resets e delay. O primeiro determina se as portas de reinicialização são inseridas após a medição. O último permite que um tempo (em dt) seja especificado para um atraso após cada medição (e redefinição, se aplicável).

    O método syndrome_measurement() de RepetitionCode agora tem argumentos de palavra-chave final e delay. O primeiro determina se devem ser adicionadas portas de reinicialização de acordo com o resets global ou se deve ser substituído por um comportamento apropriado para a rodada final de medições de síndrome. O último permite que um tempo (em dt) seja especificado para um atraso após cada medição (e redefinição, se aplicável).

  • A classe RepetitionCode agora oferece suporte à codificação com estados de base x. Isso pode ser usado definindo o argumento da palavra-chave xbasis ao construir um objeto RepetitionCode .

Notas da Atualização

  • O argumento de palavra-chave reset foi removido do método syndrome_measurement() de RepetitionCode. Isso é substituído pelo argumento de palavra-chave global resets para a classe, bem como pelo argumento de palavra-chave final para syndrome_measurement. Nos casos em que anteriormente se adicionava a rodada de medição final usando reset=False para evitar as portas de reinicialização final, agora se deve usar final=True.

  • Remova ParametrizedSchedule de update_u_gates().

    ParametrizedSchedule foi preterido como parte do Qiskit-terra 0.17.0 e será removido na próxima versão. A função agora atualiza as portas u com os programas Schedule que envolvem objetos Parameter não atribuídos.

Notas de descontinuação

  • Métodos obsoletos em AccreditationFitter , a saber, bound_variation_distance e single_protocol_run

  • O projeto Qiskit Ignis como um todo foi descontinuado, e o projeto será retirado e arquivado no futuro. Embora depreciado, somente correções de compatibilidade e correções de bugs críticos serão feitas no projeto. Em vez de usar o Qiskit Ignis, você deve migrar para usar o Qiskit Experiments. Você pode consultar o guia de migração:

    https://github.com/qiskit-community/qiskit-ignis#migration-guide

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.