Skip to main content
IBM Quantum Platform

Notas de versão do Qiskit 0.28


0.28.0

Terra 0.18.0

Prelúdio

Essa versão inclui muitos recursos novos e correções de bugs. Os destaques dessa versão são a introdução de dois novos passes de transpiladores, BIPMapping e DynamicalDecouplingque, quando combinados com o novo kwarg pulse_optimize na passagem UnitarySynthesis permite recriar os resultados do Quantum Volume 64 usando as técnicas descritas em: https://arxiv.org/abs/2008.08571. Esses novos passes e opções do transpilador também são aplicáveis de modo geral à otimização de qualquer circuito.

Novos Recurso

  • O kwarg measurement_error_mitgation para o construtor QuantumInstance agora pode ser definido como a classe TensoredMeasFitter do qiskit-ignis, além da CompleteMeasFitter que já era suportada. Se você usar o TensoredMeasFitter , também poderá definir o novo kwarg mit_pattern para especificar os qubits nos quais usar o TensoredMeasFitter . Consulte a documentação do mit_pattern na documentação do TensoredMeasFitter para obter o formato esperado.

  • Os métodos de decomposição para portas de um único qubit, especificados por meio do kwarg basis , em OneQubitEulerDecomposer foi ampliado para incluir agora também a base 'ZSXX' , para fazer uso da porta XX direta e da porta X\sqrt{X}.

  • Adicionados dois novos passes AlignMeasures e ValidatePulseGates ao módulo qiskit.transpiler.passes módulo. Essas passagens são uma otimização com reconhecimento de hardware e uma rotina de validação que são usadas para gerenciar restrições de alinhamento na alocação de tempo de instruções para um backend.

    Se um backend tiver uma restrição no alinhamento das instruções do Measure (em termos de quantização no tempo), a AlignMeasures é usada para ajustar os atrasos em um circuito programado para garantir que quaisquer Measure instruções no circuito estejam alinhadas de acordo com as restrições do backend. A passagem ValidatePulseGates é usada para verificar se alguma porta de pulso personalizada (portas que têm uma definição de pulso personalizada no atributo calibrations de um objeto QuantumCircuit ) são válidas, dada uma restrição de alinhamento para o backend de destino.

    No site incorporado preset_passmangers usado pela função transpile() essas passagens são acionadas automaticamente se a restrição de alinhamento, seja por meio do kwarg timing_constraints dedicado em transpile() ou tiver um atributo timing_constraints no objeto BackendConfiguration do backend que está sendo direcionado.

    Os backends de IBM Quantum Services (acessíveis por meio do pacote qiskit-ibmq-provider ) fornecerão as informações de alinhamento em um futuro próximo.

    Por exemplo:

    from qiskit import circuit, transpile
    from qiskit.test.mock import FakeArmonk
    
    backend = FakeArmonk()
    
    qc = circuit.QuantumCircuit(1, 1)
    qc.x(0)
    qc.delay(110, 0, unit="dt")
    qc.measure(0, 0)
    qc.draw('mpl')
    qct = transpile(qc, backend, scheduling_method='alap',
                    timing_constraints={'acquire_alignment': 16})
    qct.draw('mpl')
  • Uma nova classe de passagem de transpilador qiskit.transpiler.passes.BIPMapping que tenta encontrar o melhor layout e roteamento de uma só vez, resolvendo um problema de BIP (programação binária inteira), conforme descrito em arXiv:2106.06446 foi adicionada.

    A etapa BIPMapping (denominada "mapping" para se referir a "layout and routing") representa o problema de mapeamento como um problema BIP (binary integer programming) e conta com o CPLEX (cplex) para resolver o problema BIP. As bibliotecas dependentes, incluindo o CPLEX, podem ser instaladas junto com o qiskit-terra:

    pip install qiskit-terra[bip-mapper]

    Como a versão gratuita do CPLEX pode resolver apenas pequenos problemas de BIP, ou seja, mapeamento de circuitos com menos de 5 qubits, a versão paga do CPLEX pode ser necessária para mapear circuitos maiores.

    O mapeador BIP é mal dimensionado em relação ao número de qubits ou portas. Por exemplo, ele não funcionaria com coupling_map além de 10 qubits porque o solucionador de BIP (CPLEX) não conseguiria encontrar nenhuma solução dentro do limite de tempo padrão.

    Observe que, se quiser fixar os qubits físicos a serem usados no mapeamento (por exemplo, executando circuitos de Volume Quântico (QV)), você precisará especificar coupling_map , que contém apenas os qubits a serem usados.

    Aqui está um código de exemplo mínimo para criar um gerenciador de passagem para transpilar um circuito QV:

    num_qubits = 4  # QV16
    circ = QuantumVolume(num_qubits=num_qubits)
    
    backend = ...
    basis_gates = backend.configuration().basis_gates
    coupling_map = CouplingMap.from_line(num_qubits)  # supply your own coupling map
    
    def _not_mapped(property_set):
        return not property_set["is_swap_mapped"]
    
    def _opt_control(property_set):
        return not property_set["depth_fixed_point"]
    
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    pm = PassManager()
    # preparation
    pm.append([
        Unroll3qOrMore(),
        TrivialLayout(coupling_map),
        FullAncillaAllocation(coupling_map),
        EnlargeWithAncilla(),
        BarrierBeforeFinalMeasurements()
    ])
    # mapping
    pm.append(BIPMapping(coupling_map))
    pm.append(CheckMap(coupling_map))
    pm.append(Error(msg="BIP mapper failed to map", action="raise"),
              condition=_not_mapped)
    # post optimization
    pm.append([
        Depth(),
        FixedPoint("depth"),
        Collect2qBlocks(),
        ConsolidateBlocks(basis_gates=basis_gates),
        UnitarySynthesis(basis_gates),
        Optimize1qGatesDecomposition(basis_gates),
        CommutativeCancellation(),
        UnrollCustomDefinitions(sel, basis_gates),
        BasisTranslator(sel, basis_gates)
    ], do_while=_opt_control)
    
    transpile_circ = pm.run(circ)
  • Um novo método construtor initialize_from() foi adicionado aos métodos Schedule e ScheduleBlock classes. Esse método inicializa uma nova agenda vazia que recebe os atributos de outra agenda. Por exemplo:

    sched = Schedule(name='my_sched')
    new_sched = Schedule.initialize_from(sched)
    
    assert sched.name == new_sched.name
  • Um novo kwarg, line_discipline, foi adicionado à função job_monitor() função. Esse kwarg permite alterar os caracteres de retorno de carro usados na saída do site job_monitor . O kwarg line_discipline tem como padrão '\r', que era o que estava sendo usado anteriormente.

  • A classe abstrata Pulse (que é a classe principal de classes como Waveform, Constant, e Gaussian agora tem um novo kwarg no construtor, limit_amplitude, que pode ser definido como False para desativar o limite de amplitude codificado anteriormente de 1. Isso também pode ser definido diretamente como um atributo de classe para alterar o padrão global de uma classe Pulse. Por exemplo:

    from qiskit.pulse.library import Waveform
    
    # Change the default value of limit_amplitude to False
    Waveform.limit_amplitude = False
    wave = Waveform(2.0 * np.exp(1j * 2 * np.pi * np.linspace(0, 1, 1000)))
  • Uma nova classe, PauliListfoi adicionada ao módulo qiskit.quantum_info módulo. Essa classe é usada para representar com eficiência uma lista de Pauli operadores. Essa nova classe é herdada da mesma classe pai que a existente PauliTable (e, portanto, pode ser usada de forma intercambiável), mas difere da PauliTable porque a classe qiskit.quantum_info.PauliList pode lidar com as fases do Z4.

  • Adicionada uma nova passagem de transpilador, RemoveBarriers, para qiskit.transpiler.passes. Essa passagem é usada para remover todas as barreiras em um circuito.

  • Adicione uma nova classe de otimizador, SciPyOptimizerao módulo qiskit.algorithms.optimizers módulo. Essa classe é um invólucro simples da função scipy.optimize.minimize (documentação ) que permite o uso de todos os solucionadores de otimização e todos os parâmetros (por exemplo, retorno de chamada) compatíveis com scipy.optimize.minimize. Por exemplo:

    from qiskit.algorithms.optimizers import SciPyOptimizer
    
    values = []
    
    def callback(x):
        values.append(x)
    
    optimizer = SciPyOptimizer("BFGS", options={"maxiter": 1000}, callback=callback)
  • O passe HoareOptimizer foi aprimorado de modo que agora pode substituir um ControlledGate em um circuito com a porta base se todos os qubits de controle estiverem no estado 1|1\rangle.

  • Foram adicionados dois novos métodos, is_successor() e is_predecessor()à classe DAGCircuit classe. Essas funções são usadas para verificar se um nó é sucessor ou predecessor de outro nó na tabela DAGCircuit.

  • Um novo passe de transpilador, RZXCalibrationBuilderNoEchofoi adicionada ao módulo qiskit.transpiler.passes módulo. Essa passagem é semelhante à existente RZXCalibrationBuilder existente, pois cria calibrações para um RZXGate(theta), porém RZXCalibrationBuilderNoEcho faz isso sem inserir os pulsos de eco na programação de pulsos. Isso permite expor o eco na sequência de ressonância cruzada como portas para que o transpilador possa simplificá-las. A passagem RZXCalibrationBuilderNoEcho suporta apenas a direção nativa de hardware do CXGate.

  • Um novo kwarg, wrap, foi adicionado ao compose() do método QuantumCircuit. Isso permite escolher se os circuitos compostos devem ser agrupados em uma instrução ou não. Por padrão, isso é False, ou seja, não há envolvimento. Por exemplo:

    from qiskit import QuantumCircuit
    circuit = QuantumCircuit(2)
    circuit.h([0, 1])
    other = QuantumCircuit(2)
    other.x([0, 1])
    print(circuit.compose(other, wrap=True))  # wrapped
    print(circuit.compose(other, wrap=False))  # not wrapped
  • Um novo atributo, control_channelsfoi adicionado à classe PulseBackendConfiguration classe. Esse atributo representa os canais de controle em um backend como um mapeamento de qubits para uma lista de objetos ControlChannel objetos.

  • Um novo kwarg, epsilon, foi adicionado ao construtor da classe Isometry e o método QuantumCircuit correspondente isometry(). Esse kwarg permite definir opcionalmente a tolerância de epsilon usada por uma porta Isometry . Por exemplo:

    import numpy as np
    from qiskit import QuantumRegister, QuantumCircuit
    
    tolerance = 1e-8
    iso = np.eye(2,2)
    num_q_output = int(np.log2(iso.shape[0]))
    num_q_input = int(np.log2(iso.shape[1]))
    q = QuantumRegister(num_q_output)
    qc = QuantumCircuit(q)
    
    qc.isometry(iso, q[:num_q_input], q[num_q_input:], epsilon=tolerance)
  • Adicionado um passe de transpilador, DynamicalDecoupling, para qiskit.transpiler.passes para inserir sequências de desacoplamento dinâmico em períodos ociosos de um circuito (após o mapeamento para qubits físicos e agendamento). A passagem permite o controle sobre a sequência de portas DD, o espaçamento entre elas e os qubits a serem aplicados. Por exemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import XGate
    from qiskit.transpiler import PassManager, InstructionDurations
    from qiskit.transpiler.passes import ALAPSchedule, DynamicalDecoupling
    from qiskit.visualization import timeline_drawer
    
    circ = QuantumCircuit(4)
    circ.h(0)
    circ.cx(0, 1)
    circ.cx(1, 2)
    circ.cx(2, 3)
    circ.measure_all()
    
    durations = InstructionDurations(
        [("h", 0, 50), ("cx", [0, 1], 700), ("reset", None, 10),
         ("cx", [1, 2], 200), ("cx", [2, 3], 300),
         ("x", None, 50), ("measure", None, 1000)]
    )
    
    dd_sequence = [XGate(), XGate()]
    
    pm = PassManager([ALAPSchedule(durations),
                      DynamicalDecoupling(durations, dd_sequence)])
    circ_dd = pm.run(circ)
    timeline_drawer(circ_dd)
  • O método QuantumCircuit method qasm() tem um novo kwarg, encoding, que pode ser usado para definir opcionalmente a codificação de caracteres de um arquivo QASM de saída gerado pela função. Isso pode ser definido como qualquer codec válido ou string de alias do módulo de codec da biblioteca padrão Python.

  • Adicionada uma nova classe, EvolvedOperatorAnsatzao módulo qiskit.circuit.library módulo. Esse circuito de biblioteca, que anteriormente estava localizado no Qiskit Nature, pode ser usado para construir circuitos ansatz que consistem em operadores com evolução temporal, em que o tempo de evolução é um parâmetro variacional. Exemplos de tais circuitos ansatz incluem a classe UCCSD no módulo chemistry do Qiskit Nature ou a classe QAOAAnsatz classe.

  • Uma nova classe de backend falso está disponível em qiskit.test.mock para o backend ibmq_guadalupe . Assim como os outros back-ends falsos, isso inclui um instantâneo dos 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.

  • Um novo método children() para a classe Schedule foi adicionado. Esse método é usado para retornar os componentes da agenda secundária do objeto Schedule como uma tupla. Ele retorna programações aninhadas sem achatamento. Esse método é equivalente ao método privado _children() , mas tem uma interface pública e estável.

  • Uma nova classe de otimizador, GradientDescentfoi adicionada ao módulo qiskit.algorithms.optimizers módulo. Essa classe de otimizador implementa um algoritmo de otimização de descida de gradiente padrão para uso com algoritmos variacionais quânticos, como VQE. Para obter uma descrição detalhada e exemplos de como usar essa classe, consulte a GradientDescent documentação da classe.

  • Uma nova classe de otimizador, QNSPSAfoi adicionada ao módulo qiskit.algorithms.optimizers módulo. Essa classe implementa o algoritmo Quantum Natural SPSA (QN-SPSA), uma generalização do algoritmo 2-SPSA, e estima a Matriz de Informações de Fisher Quântica em vez do Hessiano para obter uma estimativa estocástica do Gradiente Natural Quântico. Para obter exemplos sobre como usar esse novo otimizador, consulte a documentação da classe QNSPSA documentação da classe.

  • Um novo kwarg, second_order, foi adicionado ao construtor da classe SPSA na classe qiskit.algorithms.optimizers módulo. Quando definido como True , permite o uso de SPSA de segunda ordem. O SPSA de segunda ordem, ou 2-SPSA, é uma extensão do algoritmo SPSA comum que permite estimar o Hessiano juntamente com o gradiente, que é usado para pré-condicionar o gradiente antes da etapa de atualização do parâmetro. Como um método de segunda ordem, ele tenta melhorar a convergência do SPSA. Para obter exemplos de como usar essa opção, consulte a documentação da classe SPSA documentação da classe.

  • Ao usar o modo de saída latex ou latex_source de circuit_drawer() ou o draw() de QuantumCircuit o kwarg style agora pode ser usado exatamente como na formatação de saída mpl . No entanto, diferentemente do modo de saída mpl , somente o campo displaytext será usado ao usar os modos de saída latex ou latex_source (porque nenhum deles é compatível com cores).

  • Ao usar os métodos de saída mpl ou latex para a função circuit_drawer() ou a função draw() de QuantumCircuitagora é possível usar a formatação do modo matemático para texto e definir a formatação de cores (somentempl ) definindo o kwarg style como um dict com um nome ou rótulo gerado pelo usuário. Por exemplo, para adicionar subscritos e alterar a cor de uma porta:

    from qiskit import QuantumCircuit
    from qiskit.circuit.library import HGate
    qc = QuantumCircuit(3)
    qc.append(HGate(label='h1'), [0])
    qc.append(HGate(label='h2'), [1])
    qc.append(HGate(label='h3'), [2])
    qc.draw('mpl', style={'displaytext': {'h1': 'H_1', 'h2': 'H_2', 'h3': 'H_3'},
        'displaycolor': {'h2': ('#EEDD00', '#FF0000')}})
  • Foram adicionadas três novas classes, CDKMRippleCarryAdder, ClassicalAdder e DraperQFTAdder, ao módulo qiskit.circuit.library módulo. Essas novas classes de circuito são usadas para realizar a adição clássica de dois registros de qubit de tamanho igual. Para dois registros an|a\rangle_n e bn|b\rangle_n em nn qubits, as três novas classes realizam a operação:

anbnana+bn+1.|a\rangle_n |b\rangle_n \mapsto |a\rangle_n |a + b\rangle_{n + 1}.

Por exemplo:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import CDKMRippleCarryAdder
from qiskit.quantum_info import Statevector

# a encodes |01> = 1
a = QuantumCircuit(2)
a.x(0)

# b encodes |10> = 2
b = QuantumCircuit(2)
b.x(1)

# adder on 2-bit numbers
adder = CDKMRippleCarryAdder(2)

# add the state preparations to the front of the circuit
adder.compose(a, [0, 1], inplace=True, front=True)
adder.compose(b, [2, 3], inplace=True, front=True)

# simulate and get the state of all qubits
sv = Statevector(adder)
counts = sv.probabilities_dict()
state = list(counts.keys())[0]  # we only have a single state

# skip the input carry (first bit) and the register |a> (last two bits)
result = state[1:-2]
print(result)  # '011' = 3 = 1 + 2
  • Adicionadas duas novas classes, RGQFTMultiplier e HRSCumulativeMultiplierao módulo qiskit.circuit.library módulo. Essas classes são usadas para realizar a multiplicação clássica de dois registros de qubit de tamanho igual. Para dois registros an|a\rangle_n e bn|b\rangle_n em nn qubits, as duas novas classes executam a operação
anbn02nanbnab2n.|a\rangle_n |b\rangle_n |0\rangle_{2n} \mapsto |a\rangle_n |b\rangle_n |a \cdot b\rangle_{2n}.

Por exemplo:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import RGQFTMultiplier
from qiskit.quantum_info import Statevector

num_state_qubits = 2

# a encodes |11> = 3
a = QuantumCircuit(num_state_qubits)
a.x(range(num_state_qubits))

# b encodes |11> = 3
b = QuantumCircuit(num_state_qubits)
b.x(range(num_state_qubits))

# multiplier on 2-bit numbers
multiplier = RGQFTMultiplier(num_state_qubits)

# add the state preparations to the front of the circuit
multiplier.compose(a, [0, 1], inplace=True, front=True)
multiplier.compose(b, [2, 3], inplace=True, front=True)

# simulate and get the state of all qubits
sv = Statevector(multiplier)
counts = sv.probabilities_dict(decimals=10)
state = list(counts.keys())[0]  # we only have a single state

# skip both input registers
result = state[:-2*num_state_qubits]
print(result)  # '1001' = 9 = 3 * 3
  • A classe Delay agora pode aceitar um ParameterExpression ou Parameter para o kwarg duration em seu construtor e para seu atributo duration atributo.

    Por exemplo:

    idle_dur = Parameter('t')
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.delay(idle_dur, 0, 'us')
    qc.measure(0, 0)
    print(qc)  # parameterized delay in us (micro seconds)
    
    # assign before transpilation
    assigned = qc.assign_parameters({idle_dur: 0.1})
    print(assigned)  # delay in us
    transpiled = transpile(assigned, some_backend_with_dt)
    print(transpiled)  # delay in dt
    
    # assign after transpilation
    transpiled = transpile(qc, some_backend_with_dt)
    print(transpiled)  # parameterized delay in dt
    assigned = transpiled.assign_parameters({idle_dur: 0.1})
    print(assigned)  # delay in dt
  • Um novo formato de serialização binária, QPY, foi introduzido. Ele foi projetado para ser um formato de serialização binária rápido e compatível com versões anteriores (os arquivos QPY gerados com versões mais antigas do Qiskit podem ser carregados por versões mais recentes do Qiskit) que é nativo do Qiskit. As ferramentas de serialização do QPY estão disponíveis no módulo qiskit.circuit.qpy_serialization . Por exemplo, para gerar um arquivo QPY:

    from datetime import datetime
    
    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit import qpy_serialization
    
    qc = QuantumCircuit(
      2, metadata={'created_at': datetime.utcnow().isoformat()}
    )
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    circuits = [qc] * 5
    
    with open('five_bells.qpy', 'wb') as qpy_file:
        qpy_serialization.dump(circuits, qpy_file)

    Em seguida, os cinco circuitos salvos no arquivo QPY podem ser carregados:

    from qiskit.circuit.qpy_serialization
    
    with open('five_bells.qpy', 'rb') as qpy_file:
        circuits = qpy_serialization.load(qpy_file)

    A especificação do formato de arquivo QPY está disponível na documentação do módulo.

  • A classe TwoQubitBasisDecomposer foi atualizada para realizar decomposições ideais de pulso para uma base com CX, √X e portas Rz virtuais, conforme descrito em https://arxiv.org/pdf/2008.08571. A otimização do pulso aqui significa que a duração das portas entre as portas CX da decomposição é reduzida em troca de possivelmente mais portas locais antes ou depois de todas as portas CX, de modo que, quando compostas em um circuito, há a possibilidade de compressão de um único qubit com portas vizinhas, reduzindo a duração geral da sequência.

    Um novo argumento de palavra-chave, `pulse_optimize, foi adicionado ao construtor de TwoQubitBasisDecomposer para controlar isso:

    • None: Tentativa de decomposição ideal do pulso. Se uma decomposição ideal de pulso for desconhecida para a base do decompositor, volte para a decomposição padrão sem aviso. Essa é a configuração padrão.
    • True: Tentativa de decomposição ideal do pulso. Se uma decomposição ideal de pulso for desconhecida para a base do decompositor, aumente QiskitError.
    • False: Não tente fazer a decomposição ideal do pulso.

    Por exemplo:

    from qiskit.quantum_info import TwoQubitBasisDecomposer
    from qiskit.circuit.library import CXGate
    from qiskit.quantum_info import random_unitary
    
    unitary_matrix = random_unitary(4)
    
    decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="ZSX", pulse_optimize=True)
    circuit = decomposer(unitary_matrix)
  • A passagem do transpiler UnitarySynthesis localizada em qiskit.transpiler.passes foi atualizada para suportar a execução da decomposição ideal do pulso. Isso é feito principalmente com o argumento da palavra-chave pulse_optimize , que foi adicionado ao construtor e usado para controlar se a síntese ideal de pulso é realizada. O comportamento desse kwarg reflete o kwarg pulse_optimize no construtor da classe TwoQubitBasisDecomposer construtor da classe. Além disso, o construtor tem outro novo argumento de palavra-chave, synth_gates, que é usado para especificar a lista de nomes de portas sobre as quais a síntese deve ser tentada. Se None e pulse_optimize forem False ou None, use "unitary". Se None e pulse_optimize for True, use "unitary" e "swap". Como a direção da porta CX na síntese é arbitrária, outro argumento de palavra-chave, natural_direction, é adicionado para considerar primeiro um mapa de acoplamento e depois CXGate durações na escolha da direção do CX para gerar a síntese.

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import PassManager, CouplingMap
    from qiskit.transpiler.passes import TrivialLayout, UnitarySynthesis
    from qiskit.test.mock import FakeVigo
    from qiskit.quantum_info.random import random_unitary
    
    backend = FakeVigo()
    conf = backend.configuration()
    coupling_map = CouplingMap(conf.coupling_map)
    triv_layout_pass = TrivialLayout(coupling_map)
    circ = QuantumCircuit(2)
    circ.unitary(random_unitary(4), [0, 1])
    unisynth_pass = UnitarySynthesis(
        basis_gates=conf.basis_gates,
        coupling_map=None,
        backend_props=backend.properties(),
        pulse_optimize=True,
        natural_direction=True,
        synth_gates=['unitary'])
    pm = PassManager([triv_layout_pass, unisynth_pass])
    optimal_circ = pm.run(circ)
  • Uma nova opção de base, 'XZX', foi adicionada para o argumento basis OneQubitEulerDecomposer classe.

  • Adicionado um novo método, get_instructions()foi adicionado à classe QuantumCircuit classe. Esse método é usado para retornar todos os Instruction objetos no circuito que têm um name que corresponde ao argumento name fornecido, juntamente com suas listas qargs e cargs associadas de Qubit e Clbit associados.

  • Um novo extra opcional all foi adicionado ao pacote qiskit-terra. Isso permite instalar todos os requisitos opcionais com um único extra, por exemplo: pip install 'qiskit-terra[all]' anteriormente, era necessário listar todos os extras individualmente para instalar todas as dependências opcionais simultaneamente.

  • Adicionadas duas novas classes ProbDistribution e QuasiDistribution para lidar com distribuições de probabilidade e distribuições de quase-probabilidade, respectivamente. Esses objetos são subclasses de dicionário que acrescentam métodos adicionais para trabalhar com distribuições de probabilidade e quase-probabilidade.

  • Adicionada uma nova propriedade settings à classe base abstrata Optimizer classe base abstrata na qual todas as classes de otimizador no módulo qiskit.algorithms.optimizers são baseadas. Essa propriedade retornará um dicionário Python das configurações do otimizador que pode ser usado para instanciar outra instância da mesma classe de otimizador. Por exemplo:

    from qiskit.algorithms.optimizers import GradientDescent
    
    optimizer = GradientDescent(maxiter=10, learning_rate=0.01)
    settings = optimizer.settings
    new_optimizer = GradientDescent(**settings)

    O dicionário settings também pode ser útil para serializar objetos do otimizador usando JSON ou outro formato de serialização.

  • Uma nova função, set_config(), foi adicionada ao módulo qiskit.user_config . Essa função permite definir valores em uma configuração de usuário a partir da API do Qiskit. Por exemplo:

    from qiskit.user_config import set_config
    set_config("circuit_drawer", "mpl", section="default", file="settings.conf")

    o que resultará na adição de um valor de circuit_drawer = mpl à seção default no arquivo settings.conf .

    Se nenhum argumento file_path for especificado, o caminho usado atualmente para o arquivo de configuração do usuário (o valor da variável de ambiente QISKIT_SETTINGS , se definida, ou o local padrão ~/.qiskit/settings.conf) será atualizado. No entanto, as alterações no arquivo de configuração existente não serão refletidas na sessão atual, pois o arquivo de configuração é analisado no momento da importação.

  • Adicionada uma nova classe de estado, StabilizerStateao módulo qiskit.quantum_info módulo. Essa classe representa um estado de simulador de estabilizador usando a convenção de Aaronson e Gottesman (2004).

  • Duas novas opções, 'value' e 'value_desc' , foram adicionadas ao kwarg sort da função qiskit.visualization.plot_histogram() função. Quando sort estiver definido como uma dessas opções, a visualização de saída classificará o eixo x com base na probabilidade máxima de cada bitstring. Por exemplo:

    from qiskit.visualization import plot_histogram
    
    counts = {
      '000': 5,
      '001': 25,
      '010': 125,
      '011': 625,
      '100': 3125,
      '101': 15625,
      '110': 78125,
      '111': 390625,
    }
    plot_histogram(counts, sort='value')

Problemas Conhecidos

  • Ao executar parallel_map() (e funções que chamam internamente o parallel_map() como transpile() e assemble()) em Python 3.9 com QISKIT_PARALLEL definido como True em alguns cenários, é possível que o programa entre em um deadlock e nunca termine de ser executado. Para evitar que isso ocorra, o padrão para Python 3.9 foi alterado para não ser executado em paralelo, mas se QISKIT_PARALLEL for explicitamente ativado, isso ainda poderá ocorrer.

Notas da Atualização

  • A versão mínima da dependência do retworkx foi aumentada para a versão 0.9.0. Isso foi feito para usar as novas APIs introduzidas nessa versão, que melhoraram o desempenho de algumas passagens do transpilador.

  • O valor padrão para QISKIT_PARALLEL em ambientes Python 3.9 foi alterado para False, o que significa que, ao ser executado em Python 3.9, o multiprocessamento não será usado por padrão. Isso foi feito para evitar um possível problema de deadlock/hanging que pode ocorrer ao executar o multiprocessamento em Python 3.9 (consulte a seção de problemas conhecidos para obter mais detalhes). Ainda é possível ativá-lo manualmente, definindo explicitamente a variável de ambiente QISKIT_PARALLEL como TRUE.

  • As classes de backend falsas existentes em qiskit.test.mock agora implementam estritamente a interface BackendV1 interface. Isso significa que, se você estivesse construindo manualmente QasmQobj ou PulseQobj para usar com o método run() , isso não funcionará mais. O método run() aceita apenas QuantumCircuit ou Schedule agora. Isso foi necessário para permitir o teste de novos back-ends implementados sem o qobj, que anteriormente não tinham nenhum teste dentro do qiskit terra. Se você precisar aproveitar os back-ends falsos com QasmQobj ou PulseQobj foram adicionados novos objetos de back-end legados falsos para testar explicitamente a interface dos provedores legados. Isso será removido depois que a interface legada for descontinuada e removida. No futuro, os novos back-ends falsos implementarão apenas a interface BackendV1 e não adicionarão novas classes de back-end herdadas para novos back-ends falsos.

  • Ao criar um objeto Pauli com um rótulo de cadeia de caracteres inválido, uma mensagem QiskitError agora é gerado. Essa é uma mudança em relação às versões anteriores, que geravam um AttributeError em um rótulo de string inválido. Essa alteração foi feita para garantir que a mensagem de erro seja mais informativa e distinta de um AttributeError genérico.

  • A representação do programa de saída do construtor de pulsos (qiskit.pulse.builder.build()) foi alterada de um Schedule para um ScheduleBlock. Essa nova representação desativa algumas operações relacionadas ao tempo, como deslocamento e inserção. No entanto, isso permite durações de instrução parametrizadas no contexto do construtor. Por exemplo:

    from qiskit import pulse
    from qiskit.circuit import Parameter
    
    dur = Parameter('duration')
    
    with pulse.build() as sched:
        with pulse.align_sequential():
            pulse.delay(dur, pulse.DriveChannel(1))
            pulse.play(pulse.Gaussian(dur, 0.1, dur/4), pulse.DriveChannel(0))
    
    assigned0 = sched.assign_parameters({dur: 100})
    assigned1 = sched.assign_parameters({dur: 200})

    Você pode passar diretamente as programações atribuídas à duração para o montador (ou backend) ou pode anexá-las ao seu circuito quântico como portas de pulso.

  • A biblioteca tweedledum, que antes era uma dependência opcional, passou a ser um requisito. Isso foi feito devido ao amplo uso do PhaseOracle (que depende de ter o tweedledum instalado) com vários algoritmos do qiskit.algorithms.

  • O extra opcional full-featured-simulators , que podia ser usado anteriormente para instalar o qiskit-aer com algo como pip install qiskit-terra[full-featured-simulators] , foi removido do pacote qiskit-terra. Se isso estivesse sendo usado para instalar o qiskit-aer com o qiskit-terra , você deveria confiar no metapacote do qiskit ou apenas instalar o qiskit-terra e o qiskit-aer junto com o pip install qiskit-terra qiskit-aer.

  • Um novo requisito symengine foi adicionado para os usuários Linux (em x86_64, aarch64 e ppc64le ) e macOS ( x86_64 e arm64 ). É uma dependência opcional do Windows (e está disponível em PyPi como um pacote pré-compilado para 64bit Windows) e de outras arquiteturas. Se estiver instalado, ele oferece um desempenho significativamente melhor para a avaliação de Parameter e ParameterExpression objetos.

  • Todas as classes de circuito da biblioteca, ou seja, todas as QuantumCircuit classes derivadas em qiskit.circuit.libraryestão agora envolvidas em um Instruction (ou Gate, se forem unitárias). Por exemplo, importar e desenhar o QFT circuito:

    antes parecia

                                              ┌───┐
    q_0: ────────────────────■────────■───────┤ H ├─X─
                       ┌───┐ │        │P/2) └───┘ │
    q_1: ──────■───────┤ H ├─┼────────■─────────────┼─
         ┌───┐ │P/2) └───┘ │P/4)
    q_2: ┤ H ├─■─────────────■──────────────────────X─
         └───┘

    e agora se parece com

         ┌──────┐
    q_0:0
         │      │
    q_1:1 QFT ├
         │      │
    q_2:2
         └──────┘

    Para obter o circuito antigo, você pode chamar o método decompose() no circuito

    Essa alteração foi feita principalmente para fins de consistência, pois antes dessa versão algumas classes de circuito em qiskit.circuit.library eram anteriormente agrupadas em um Instruction ou Gate mas não todas.

Notas de descontinuação

  • A classe qiskit.exceptions.QiskitIndexError está obsoleta e será removida em uma versão futura. Essa exceção não estava sendo usada ativamente por nada no Qiskit; se você a estava usando, pode criar uma classe de exceção personalizada para substituí-la.
  • Os kwargs epsilon e factr para o qiskit.algorithms.optimizers.L_BFGS_B construtor e factr kwarg da classe P_BFGS da classe otimizadora estão obsoletos e serão removidos em uma versão futura. Em vez disso, use o eps karg em vez de epsilon. O factr kwarg é substituído por ftol. A relação entre os dois é ftol = factr * numpy.finfo(float).eps. Essa alteração foi feita para ser consistente com o uso do método scipy.optimize.minimize functions 'L-BFGS-B' . Consulte a documentação : scipy.optimize.minimize(method='L-BFGS-B') para obter mais informações sobre como esses novos parâmetros são usados.
  • A interface dos provedores legados, que consistia nas classes abstratas qiskit.providers.BaseBackend, qiskit.providers.BaseJob e qiskit.providers.BaseProvider , foi descontinuada e será removida em uma versão futura. Em vez disso, você deve usar a interface com controle de versão, cujas versões atuais da classe abstrata são qiskit.providers.BackendV1, qiskit.providers.JobV1, e qiskit.providers.ProviderV1. Os objetos do site V1 são, em sua maioria, compatíveis com versões anteriores para facilitar a migração da interface legada para a interface com controle de versão. No entanto, espera-se que as futuras versões das interfaces abstratas divirjam ainda mais. Você pode consultar a qiskit.providers para obter mais detalhes de alto nível sobre a interface com controle de versão.
  • O condition kwarg para o DAGDepNode juntamente com o atributo condition correspondente do construtor DAGDepNode foram descontinuados e serão removidos em uma versão futura. Em vez disso, você pode acessar o condition de um DAGDepNode se o nó for do tipo op, usando DAGDepNode.op.condition.
  • O atributo condition da classe DAGNode foi preterido e será removido em uma versão futura. Em vez disso, você pode acessar o condition de um objeto DAGNode se o nó for do tipo op, usando DAGNode.op.condition.
  • A sintaxe do construtor de pulsos (qiskit.pulse.builder.build()) qiskit.pulse.builder.inline() está obsoleta e será removida em uma versão futura. Em vez de usar esse contexto, você pode simplesmente remover os contextos de alinhamento dentro do contexto em linha.
  • A sintaxe do construtor de pulsos (qiskit.pulse.builder.build()) qiskit.pulse.builder.pad() está obsoleta e será removida em uma versão futura. Isso foi feito porque o ScheduleBlock que está sendo retornado pelo construtor de pulsos não é compatível com o método .insert (e não há sintaxe de inserção no construtor). O uso de espaços reservados de timeslot para bloquear a inserção de outras instruções não é mais necessário.

Correções de bugs

  • O OneQubitEulerDecomposer e TwoQubitBasisDecomposer para a síntese de portas de um e dois qubits foram aprimoradas para reforçar as tolerâncias, melhorar a repetibilidade e a simplificação e corrigir vários erros de rastreamento de fase global.

  • Foi corrigido um problema na atribuição do atributo name ao atributo Gate gerada por várias chamadas ao método inverse`() . Antes dessa correção, quando o inverse`() era chamado, ele anexava incondicionalmente o _dg em cada chamada ao inverso. Isso foi corrigido, portanto, em uma segunda chamada de inverse`() , o sufixo _dg agora é removido.

  • Fixa as condições de verificação de trivialidade de CZGate, CRZGate, CU1Gate e MCU1Gate na HoareOptimizer passe. Anteriormente, em alguns casos, o otimizador removia essas portas, quebrando a equivalência semântica da transformação.

  • Foi corrigido um problema ao converter um objeto ListOp objeto de PauliSumOp objetos usando PauliExpectation ou AerPauliExpectation. Anteriormente, ele emitia um aviso sobre a conversão para uma representação de Pauli, que é potencialmente cara. Isso foi corrigido em vez de converter internamente o ListOp para um SummedOp de objetos PauliOp ele agora cria um objeto PauliSumOp o que é mais eficiente. Corrigido #6159

  • Foi corrigido um problema com a classe NLocal no módulo qiskit.circuit.library em que ela não levantava corretamente uma exceção na inicialização do objeto se um tipo inválido fosse usado para o kwarg reps , o que resultaria em um erro de tempo de execução inesperado posteriormente. Agora, o TypeError será gerado corretamente se o kwarg reps não for um valor int . Corrigido #6515

  • Foi corrigido um problema em que a classe TwoLocal no módulo qiskit.circuit.library não aceitava tipos inteiros numpy (por exemplo, numpy.int32, numpy.int64, etc.) como uma entrada válida para o kwarg entanglement . Corrigido #6455

  • Ao carregar um arquivo ou string OpenQASM2 com os construtores from_qasm_file() ou from_qasm_str() para a classe QuantumCircuit classe, se o circuito OpenQASM2 contiver uma instrução com o nome delay , ela será mapeada para uma instrução qiskit.circuit.Delay instrução. Por exemplo:

    from qiskit import QuantumCircuit
    
    qasm = """OPENQASM 2.0;
    include "qelib1.inc";
    opaque delay(time) q;
    qreg q[1];
    delay(172) q[0];
    u3(0.1,0.2,0.3) q[0];
    """
    circuit = QuantumCircuit.from_qasm_str(qasm)
    circuit.draw()

    Corrigido #6510

  • Foi corrigido um problema com a adição entre objetos PauliSumOp objetos que tinham ParameterExpression coeficientes. Anteriormente, isso resultava em uma exceção QiskitError , pois a adição do ParameterExpression não era tratada corretamente. Isso foi corrigido para que a adição possa ser realizada entre PauliSumOp objetos com ParameterExpression coeficientes.

  • Foi corrigido um problema com a inicialização da classe AmplificationProblem classe. O is_good_state kwarg era um campo obrigatório, mas estava sendo tratado incorretamente como opcional (e documentado como tal). Isso foi corrigido e também atualizado para que, a menos que a entrada oracle seja um objeto PhaseOracle (que fornece seu próprio método de avaliação), o campo é obrigatório e gerará um TypeError quando construído sem is_good_state.

  • Foi corrigido um problema em que a adição de um controle a um arquivo ControlledGate com controles abertos desmarcava os controles abertos internos. Correções #5857

  • Foi corrigido um problema com o método convert() da classe PauliExpectation em que chamá-lo em um operador que não era hermitiano retornava um resultado incorreto. Corrigido #6307

  • Foi corrigido um problema com a função qiskit.pulse.transforms.inline_subroutines() que anteriormente não removia incorretamente todos os componentes aninhados quando chamada em programações aninhadas. Corrigido #6321

  • Foi corrigido um problema ao passar um chamável parcialmente vinculado criado com a função functools.partial() da biblioteca padrão Python como o kwarg schedule para o método add() do método InstructionScheduleMap que anteriormente resultava em um erro. Corrigido #6278

  • Foi corrigido um problema com o PiecewiseChebyshev ao definir o breakpoints para None em um objeto existente estava sendo tratado incorretamente como um ponto de interrupção. Isso foi corrigido para que, quando definido como None , volte ao comportamento padrão de aproximação no intervalo completo. Corrigido #6198

  • Foi corrigido um problema com o método num_connected_components() método de QuantumCircuit que retornava o número incorreto de componentes quando o circuito continha duas ou mais portas condicionadas em registros clássicos. Corrigido #6477

  • Foi corrigido um problema com o módulo qiskit.opflow.expectations em que os coeficientes de uma função de estado não estavam sendo multiplicados corretamente. Isso também corrigiu os cálculos de Gradientes e QFIs ao usar a opção PauliExpectation ou AerPauliExpectation classes. Por exemplo, anteriormente:

    from qiskit.opflow import StateFn, I, One
    
    exp = ~StateFn(I) @ (2 * One)

    avaliado em 2 para AerPauliExpectation e em 4 para outros conversores de expectativa. Como ~StateFn(I) @ (2 * One) é uma notação abreviada para ~(2 * One) @ I @ (2 * One), o coeficiente agora correto de 4 é retornado para todos os conversores de expectativa. Corrigido #6497

  • Foi corrigido o erro que fazia com que o to_circuit() falhasse quando o PauliOp tinha uma fase. Ao mesmo tempo, o uso do PauliGate se tornou mais eficiente.

  • Foi corrigido um problema em que a saída do QASM gerada pelo método qasm() método de QuantumCircuit para portas compostas, como MCXGate e suas variantes ( MCXGrayCode, MCXRecursive, e MCXVChain) seria incorreto. Agora, se um Gate no circuito não estiver presente em qelib1.inc, sua definição será adicionada à string QASM de saída. Corrigido #4943 e #3945

  • Foi corrigido um problema com a função circuit_drawer() função e draw() do método QuantumCircuit. Ao usar os modos de saída mpl ou latex , com o kwarg cregbundle definido como False e o kwarg reverse_bits definido como True, os bits nos registros clássicos são exibidos na mesma ordem de quando reverse_bits foi definido como False.

  • Foi corrigido um problema ao usar a instrução qiskit.extensions.Initialize que não estava configurando corretamente a fase global da definição sintetizada quando construída. Corrigido #5320

  • Foi corrigido um problema em que a ordem de bits em qiskit.circuit.library.PhaseOracle.evaluate_bitstring() não estava de acordo com a ordem da bitstring medida. Essa correção também afeta a execução da classe de algoritmo Grover se o oráculo for especificado como um PhaseOracleque agora identificará corretamente a bitstring correta. Corrigido #6314

  • Corrige um bug no Optimize1qGatesDecomposition() que fazia com que certas sequências curtas de portas não fossem reescritas erroneamente.

  • Foi corrigido um problema no método qiskit.opflow.gradients.Gradient.gradient_wrapper() com o cálculo do gradiente. Anteriormente, se o operador não fosse diagonal, um resultado incorreto seria retornado em algumas situações. Isso foi corrigido com o uso de um conversor de expectativa para garantir que o resultado esteja sempre correto.

  • Foi corrigido um problema com a função circuit_drawer() função e draw() do método QuantumCircuit com todos os modos de saída, em que ele renderizava incorretamente uma instrução personalizada que incluía bits clássicos em algumas circunstâncias. Corrigidos os números 3201, 3202 e 6178

  • Corrigido um problema em circuit_drawer() e o método draw() da classe QuantumCircuit ao usar o modo de saída mpl , as portas controladas-Z eram incorretamente desenhadas como assimétricas. Corrigido #5981

  • Foi corrigido um problema com a passagem do transpilador OptimizeSwapBeforeMeasure em que, em algumas situações, um SwapGate que continha uma condição clássica era removido. Corrigido #6192

  • Foi corrigido um problema com a fase da classe qiskit.opflow.gradients.QFI quando o qfi_method é definido como lin_comb_full , o que fazia com que o observável incorreto fosse avaliado.

  • Foi corrigido um problema com a classe VQE quando executada com os botões L_BFGS_B ou P_BFGS e gradientes são usados, o gradiente era incorretamente passado como uma matriz numpy em vez da lista esperada de floats, resultando em um erro. Isso foi resolvido para que você possa usar gradientes com VQE e o L_BFGS_B ou P_BFGS otimizadores.

Outras observações

  • A depreciação do método parameters() para a classe Instruction foi revertida. Esse método foi originalmente descontinuado no site 0.17.0, mas ainda é necessário para vários aplicativos, inclusive ao executar experimentos de calibração. Esse método continuará a ser suportado e não será removido.

Aer 0.8.2

Nenhuma mudança

Ignis 0.6.0

Nenhuma mudança

Aqua 0.9.4

Nenhuma mudança

IBM 0.15.0

Novos Recurso

  • Adicionar suporte ao novo método qiskit.providers.ibmq.runtime.RuntimeJob.error_message() que retornará uma cadeia de caracteres representando o motivo da falha do trabalho.

  • O parâmetro de entrada do método qiskit.providers.ibmq.runtime.IBMRuntimeService.run() agora pode ser especificado como uma instância de qiskit.providers.ibmq.runtime.ParameterNamespace que oferece suporte aos recursos de preenchimento automático. Você pode usar qiskit.providers.ibmq.runtime.RuntimeProgram.parameters() para recuperar uma instância de ParameterNamespace .

    Por exemplo:

    from qiskit import IBMQ
    
    provider = IBMQ.load_account()
    
    # Set the "sample-program" program parameters.
    params = provider.runtime.program(program_id="sample-program").parameters()
    params.iterations = 2
    
    # Configure backend options
    options = {'backend_name': 'ibmq_qasm_simulator'}
    
    # Execute the circuit using the "circuit-runner" program.
    job = provider.runtime.run(program_id="sample-program",
                               options=options,
                               inputs=params)
  • O usuário agora pode definir a visibilidade (privada/pública) de um programa Qiskit Runtime usando qiskit.providers.ibmq.runtime.IBMRuntimeService.set_program_visibility().

  • Um parâmetro booleano opcional pending (pendente) foi adicionado a qiskit.providers.ibmq.runtime.IBMRuntimeService.jobs() e permite filtrar trabalhos por seu status. Se pending não for especificado, todos os trabalhos serão retornados. Se pending for definido como True, os trabalhos "QUEUED" e "RUNNING" serão retornados. Se pending for definido como False, os trabalhos "DONE", "ERROR" e "CANCELLED" serão retornados.

  • Adicionar suporte ao sinalizador use_measure_esp no método qiskit.providers.ibmq.IBMQBackend.run() . Se True, o backend usará a leitura ESP para todas as medições que são a instrução terminal nesse qubit. Se for usado e o backend não for compatível com a leitura de ESP, será gerado um erro.

Notas da Atualização

  • qiskit.providers.ibmq.runtime.RuntimeProgram.parameters() agora é um método que retorna uma instância qiskit.providers.ibmq.runtime.ParameterNamespace , que você pode usar para preencher os valores de parâmetro do programa em tempo de execução e passar para qiskit.providers.ibmq.runtime.IBMRuntimeService.run().
  • O sinalizador open_pulse na configuração do backend não indica mais se um backend é compatível com o controle de nível de pulso. Como resultado, qiskit.providers.ibmq.IBMQBackend.configuration() pode retornar uma instância PulseBackendConfiguration mesmo que seu sinalizador open_pulse seja False.
  • O nível de compartilhamento de trabalho não é mais suportado devido à baixa adoção e a interface correspondente será removida em uma versão futura. Isso significa que você não deve mais passar share_level ao criar um trabalho ou usar o método qiskit.providers.ibmq.job.IBMQJob.share_level() para obter o nível de compartilhamento de um trabalho.

Notas de descontinuação

  • A instrução id foi descontinuada nos backends de hardware IBM. Em vez disso, use a instrução delay que implementa atrasos de comprimento variável, especificados em unidades de dt. Ao executar um circuito que contenha uma instrução id , um aviso será emitido no envio do trabalho e todas as instruções id no trabalho serão automaticamente substituídas pela instrução equivalente delay .
Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.