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_mitgationpara o construtorQuantumInstanceagora pode ser definido como a classeTensoredMeasFitterdo qiskit-ignis, além daCompleteMeasFitterque já era suportada. Se você usar oTensoredMeasFitter, também poderá definir o novo kwargmit_patternpara especificar os qubits nos quais usar oTensoredMeasFitter. Consulte a documentação domit_patternna documentação doTensoredMeasFitterpara obter o formato esperado. -
Os métodos de decomposição para portas de um único qubit, especificados por meio do kwarg
basis, emOneQubitEulerDecomposerfoi ampliado para incluir agora também a base'ZSXX', para fazer uso da porta direta e da porta . -
Adicionados dois novos passes
AlignMeasureseValidatePulseGatesao móduloqiskit.transpiler.passesmó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), aAlignMeasuresé usada para ajustar os atrasos em um circuito programado para garantir que quaisquerMeasureinstruções no circuito estejam alinhadas de acordo com as restrições do backend. A passagemValidatePulseGatesé usada para verificar se alguma porta de pulso personalizada (portas que têm uma definição de pulso personalizada no atributocalibrationsde um objetoQuantumCircuit) são válidas, dada uma restrição de alinhamento para o backend de destino.No site incorporado
preset_passmangersusado pela funçãotranspile()essas passagens são acionadas automaticamente se a restrição de alinhamento, seja por meio do kwargtiming_constraintsdedicado emtranspile()ou tiver um atributotiming_constraintsno objetoBackendConfigurationdo 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.BIPMappingque 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_mapalé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étodosScheduleeScheduleBlockclasses. 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çãojob_monitor()função. Esse kwarg permite alterar os caracteres de retorno de carro usados na saída do sitejob_monitor. O kwargline_disciplinetem como padrão'\r', que era o que estava sendo usado anteriormente. -
A classe abstrata
Pulse(que é a classe principal de classes comoWaveform,Constant, eGaussianagora tem um novo kwarg no construtor,limit_amplitude, que pode ser definido comoFalsepara desativar o limite de amplitude codificado anteriormente de1. 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óduloqiskit.quantum_infomódulo. Essa classe é usada para representar com eficiência uma lista dePaulioperadores. Essa nova classe é herdada da mesma classe pai que a existentePauliTable(e, portanto, pode ser usada de forma intercambiável), mas difere daPauliTableporque a classeqiskit.quantum_info.PauliListpode lidar com as fases do Z4. -
Adicionada uma nova passagem de transpilador,
RemoveBarriers, paraqiskit.transpiler.passes. Essa passagem é usada para remover todas as barreiras em um circuito. -
Adicione uma nova classe de otimizador,
SciPyOptimizerao móduloqiskit.algorithms.optimizersmódulo. Essa classe é um invólucro simples da funçãoscipy.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 comscipy.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
HoareOptimizerfoi aprimorado de modo que agora pode substituir umControlledGateem um circuito com a porta base se todos os qubits de controle estiverem no estado . -
Foram adicionados dois novos métodos,
is_successor()eis_predecessor()à classeDAGCircuitclasse. Essas funções são usadas para verificar se um nó é sucessor ou predecessor de outro nó na tabelaDAGCircuit. -
Um novo passe de transpilador,
RZXCalibrationBuilderNoEchofoi adicionada ao móduloqiskit.transpiler.passesmódulo. Essa passagem é semelhante à existenteRZXCalibrationBuilderexistente, pois cria calibrações para umRZXGate(theta), porémRZXCalibrationBuilderNoEchofaz 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 passagemRZXCalibrationBuilderNoEchosuporta apenas a direção nativa de hardware doCXGate. -
Um novo kwarg,
wrap, foi adicionado aocompose()do métodoQuantumCircuit. 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 à classePulseBackendConfigurationclasse. Esse atributo representa os canais de controle em um backend como um mapeamento de qubits para uma lista de objetosControlChannelobjetos. -
Um novo kwarg,
epsilon, foi adicionado ao construtor da classeIsometrye o métodoQuantumCircuitcorrespondenteisometry(). Esse kwarg permite definir opcionalmente a tolerância de epsilon usada por uma portaIsometry. 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, paraqiskit.transpiler.passespara 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
QuantumCircuitmethodqasm()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óduloqiskit.circuit.librarymó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 classeUCCSDno módulochemistrydo Qiskit Nature ou a classeQAOAAnsatzclasse. -
Uma nova classe de backend falso está disponível em
qiskit.test.mockpara o backendibmq_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 classeSchedulefoi adicionado. Esse método é usado para retornar os componentes da agenda secundária do objetoSchedulecomo 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óduloqiskit.algorithms.optimizersmódulo. Essa classe de otimizador implementa um algoritmo de otimização de descida de gradiente padrão para uso com algoritmos variacionais quânticos, comoVQE. Para obter uma descrição detalhada e exemplos de como usar essa classe, consulte aGradientDescentdocumentação da classe. -
Uma nova classe de otimizador,
QNSPSAfoi adicionada ao móduloqiskit.algorithms.optimizersmó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 classeQNSPSAdocumentação da classe. -
Um novo kwarg,
second_order, foi adicionado ao construtor da classeSPSAna classeqiskit.algorithms.optimizersmódulo. Quando definido comoTrue, 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 classeSPSAdocumentação da classe. -
Ao usar o modo de saída
latexoulatex_sourcedecircuit_drawer()ou odraw()deQuantumCircuito kwargstyleagora pode ser usado exatamente como na formatação de saídampl. No entanto, diferentemente do modo de saídampl, somente o campodisplaytextserá usado ao usar os modos de saídalatexoulatex_source(porque nenhum deles é compatível com cores). -
Ao usar os métodos de saída
mploulatexpara a funçãocircuit_drawer()ou a funçãodraw()deQuantumCircuitagora é possível usar a formatação do modo matemático para texto e definir a formatação de cores (somentempl) definindo o kwargstylecomo 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,ClassicalAddereDraperQFTAdder, ao móduloqiskit.circuit.librarymó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 e em qubits, as três novas classes realizam a operação:
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,
RGQFTMultipliereHRSCumulativeMultiplierao móduloqiskit.circuit.librarymódulo. Essas classes são usadas para realizar a multiplicação clássica de dois registros de qubit de tamanho igual. Para dois registros e em qubits, as duas novas classes executam a operação
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
Delayagora pode aceitar umParameterExpressionouParameterpara o kwargdurationem seu construtor e para seu atributodurationatributo.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
TwoQubitBasisDecomposerfoi 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 deTwoQubitBasisDecomposerpara 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
UnitarySynthesislocalizada emqiskit.transpiler.passesfoi atualizada para suportar a execução da decomposição ideal do pulso. Isso é feito principalmente com o argumento da palavra-chavepulse_optimize, que foi adicionado ao construtor e usado para controlar se a síntese ideal de pulso é realizada. O comportamento desse kwarg reflete o kwargpulse_optimizeno construtor da classeTwoQubitBasisDecomposerconstrutor 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. SeNoneepulse_optimizeforemFalseouNone, use"unitary". Se None e pulse_optimize forTrue, 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 depoisCXGateduraçõ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 argumentobasisOneQubitEulerDecomposerclasse. -
Adicionado um novo método,
get_instructions()foi adicionado à classeQuantumCircuitclasse. Esse método é usado para retornar todos osInstructionobjetos no circuito que têm umnameque corresponde ao argumentonamefornecido, juntamente com suas listasqargsecargsassociadas deQubiteClbitassociados. -
Um novo extra opcional
allfoi 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
ProbDistributioneQuasiDistributionpara 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 abstrataOptimizerclasse base abstrata na qual todas as classes de otimizador no móduloqiskit.algorithms.optimizerssã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
settingstambé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óduloqiskit.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çãodefaultno arquivosettings.conf.Se nenhum argumento
file_pathfor especificado, o caminho usado atualmente para o arquivo de configuração do usuário (o valor da variável de ambienteQISKIT_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óduloqiskit.quantum_infomó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 kwargsortda funçãoqiskit.visualization.plot_histogram()função. Quandosortestiver 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 oparallel_map()comotranspile()eassemble()) em Python 3.9 comQISKIT_PARALLELdefinido 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 seQISKIT_PARALLELfor 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_PARALLELem ambientes Python 3.9 foi alterado paraFalse, 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 ambienteQISKIT_PARALLELcomoTRUE. -
As classes de backend falsas existentes em
qiskit.test.mockagora implementam estritamente a interfaceBackendV1interface. Isso significa que, se você estivesse construindo manualmenteQasmQobjouPulseQobjpara usar com o métodorun(), isso não funcionará mais. O métodorun()aceita apenasQuantumCircuitouScheduleagora. 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 comQasmQobjouPulseQobjforam 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 interfaceBackendV1e não adicionarão novas classes de back-end herdadas para novos back-ends falsos. -
Ao criar um objeto
Paulicom um rótulo de cadeia de caracteres inválido, uma mensagemQiskitErroragora é gerado. Essa é uma mudança em relação às versões anteriores, que geravam umAttributeErrorem 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 umAttributeErrorgenérico. -
A representação do programa de saída do construtor de pulsos (
qiskit.pulse.builder.build()) foi alterada de umSchedulepara umScheduleBlock. 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 doqiskit.algorithms. -
O extra opcional
full-featured-simulators, que podia ser usado anteriormente para instalar oqiskit-aercom algo comopip install qiskit-terra[full-featured-simulators], foi removido do pacote qiskit-terra. Se isso estivesse sendo usado para instalar oqiskit-aercom oqiskit-terra, você deveria confiar no metapacote do qiskit ou apenas instalar o qiskit-terra e o qiskit-aer junto com opip 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
ParametereParameterExpressionobjetos. -
Todas as classes de circuito da biblioteca, ou seja, todas as
QuantumCircuitclasses derivadas emqiskit.circuit.libraryestão agora envolvidas em umInstruction(ouGate, se forem unitárias). Por exemplo, importar e desenhar oQFTcircuito: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 circuitoEssa alteração foi feita principalmente para fins de consistência, pois antes dessa versão algumas classes de circuito em
qiskit.circuit.libraryeram anteriormente agrupadas em umInstructionouGatemas não todas.
Notas de descontinuação
- A classe
qiskit.exceptions.QiskitIndexErrorestá 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
epsilonefactrpara oqiskit.algorithms.optimizers.L_BFGS_Bconstrutor efactrkwarg da classeP_BFGSda classe otimizadora estão obsoletos e serão removidos em uma versão futura. Em vez disso, use oepskarg em vez deepsilon. Ofactrkwarg é substituído porftol. 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étodoscipy.optimize.minimizefunctions'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.BaseJobeqiskit.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ãoqiskit.providers.BackendV1,qiskit.providers.JobV1, eqiskit.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 aqiskit.providerspara obter mais detalhes de alto nível sobre a interface com controle de versão. - O
conditionkwarg para oDAGDepNodejuntamente com o atributoconditioncorrespondente do construtorDAGDepNodeforam descontinuados e serão removidos em uma versão futura. Em vez disso, você pode acessar oconditionde umDAGDepNodese o nó for do tipoop, usandoDAGDepNode.op.condition. - O atributo
conditionda classeDAGNodefoi preterido e será removido em uma versão futura. Em vez disso, você pode acessar oconditionde um objetoDAGNodese o nó for do tipoop, usandoDAGNode.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 oScheduleBlockque 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
OneQubitEulerDecomposereTwoQubitBasisDecomposerpara 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
nameao atributoGategerada por várias chamadas ao métodoinverse`(). Antes dessa correção, quando oinverse`()era chamado, ele anexava incondicionalmente o_dgem cada chamada ao inverso. Isso foi corrigido, portanto, em uma segunda chamada deinverse`(), o sufixo_dgagora é removido. -
Fixa as condições de verificação de trivialidade de
CZGate,CRZGate,CU1GateeMCU1GatenaHoareOptimizerpasse. 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
ListOpobjeto dePauliSumOpobjetos usandoPauliExpectationouAerPauliExpectation. 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 oListOppara umSummedOpde objetosPauliOpele agora cria um objetoPauliSumOpo que é mais eficiente. Corrigido #6159 -
Foi corrigido um problema com a classe
NLocalno móduloqiskit.circuit.libraryem que ela não levantava corretamente uma exceção na inicialização do objeto se um tipo inválido fosse usado para o kwargreps, o que resultaria em um erro de tempo de execução inesperado posteriormente. Agora, oTypeErrorserá gerado corretamente se o kwargrepsnão for um valorint. Corrigido #6515 -
Foi corrigido um problema em que a classe
TwoLocalno móduloqiskit.circuit.librarynão aceitava tipos inteiros numpy (por exemplo,numpy.int32,numpy.int64, etc.) como uma entrada válida para o kwargentanglement. Corrigido #6455 -
Ao carregar um arquivo ou string OpenQASM2 com os construtores
from_qasm_file()oufrom_qasm_str()para a classeQuantumCircuitclasse, se o circuito OpenQASM2 contiver uma instrução com o nomedelay, ela será mapeada para uma instruçãoqiskit.circuit.Delayinstruçã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
PauliSumOpobjetos que tinhamParameterExpressioncoeficientes. Anteriormente, isso resultava em uma exceçãoQiskitError, pois a adição doParameterExpressionnão era tratada corretamente. Isso foi corrigido para que a adição possa ser realizada entrePauliSumOpobjetos comParameterExpressioncoeficientes. -
Foi corrigido um problema com a inicialização da classe
AmplificationProblemclasse. Ois_good_statekwarg 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 entradaoracleseja um objetoPhaseOracle(que fornece seu próprio método de avaliação), o campo é obrigatório e gerará umTypeErrorquando construído semis_good_state. -
Foi corrigido um problema em que a adição de um controle a um arquivo
ControlledGatecom controles abertos desmarcava os controles abertos internos. Correções #5857 -
Foi corrigido um problema com o método
convert()da classePauliExpectationem 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 kwargschedulepara o métodoadd()do métodoInstructionScheduleMapque anteriormente resultava em um erro. Corrigido #6278 -
Foi corrigido um problema com o
PiecewiseChebyshevao definir obreakpointsparaNoneem um objeto existente estava sendo tratado incorretamente como um ponto de interrupção. Isso foi corrigido para que, quando definido comoNone, 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 deQuantumCircuitque 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.expectationsem 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çãoPauliExpectationouAerPauliExpectationclasses. Por exemplo, anteriormente:from qiskit.opflow import StateFn, I, One exp = ~StateFn(I) @ (2 * One)avaliado em
2paraAerPauliExpectatione em4para outros conversores de expectativa. Como~StateFn(I) @ (2 * One)é uma notação abreviada para~(2 * One) @ I @ (2 * One), o coeficiente agora correto de4é retornado para todos os conversores de expectativa. Corrigido #6497 -
Foi corrigido o erro que fazia com que o
to_circuit()falhasse quando oPauliOptinha uma fase. Ao mesmo tempo, o uso doPauliGatese tornou mais eficiente. -
Foi corrigido um problema em que a saída do QASM gerada pelo método
qasm()método deQuantumCircuitpara portas compostas, comoMCXGatee suas variantes (MCXGrayCode,MCXRecursive, eMCXVChain) seria incorreto. Agora, se umGateno circuito não estiver presente emqelib1.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 edraw()do métodoQuantumCircuit. Ao usar os modos de saídamploulatex, com o kwargcregbundledefinido comoFalsee o kwargreverse_bitsdefinido comoTrue, os bits nos registros clássicos são exibidos na mesma ordem de quandoreverse_bitsfoi definido comoFalse. -
Foi corrigido um problema ao usar a instrução
qiskit.extensions.Initializeque 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 algoritmoGroverse o oráculo for especificado como umPhaseOracleque 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 edraw()do métodoQuantumCircuitcom 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étododraw()da classeQuantumCircuitao usar o modo de saídampl, as portas controladas-Z eram incorretamente desenhadas como assimétricas. Corrigido #5981 -
Foi corrigido um problema com a passagem do transpilador
OptimizeSwapBeforeMeasureem que, em algumas situações, umSwapGateque continha uma condição clássica era removido. Corrigido #6192 -
Foi corrigido um problema com a fase da classe
qiskit.opflow.gradients.QFIquando oqfi_methodé definido comolin_comb_full, o que fazia com que o observável incorreto fosse avaliado. -
Foi corrigido um problema com a classe
VQEquando executada com os botõesL_BFGS_BouP_BFGSe 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 comVQEe oL_BFGS_BouP_BFGSotimizadores.
Outras observações
- A depreciação do método
parameters()para a classeInstructionfoi 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 deqiskit.providers.ibmq.runtime.ParameterNamespaceque oferece suporte aos recursos de preenchimento automático. Você pode usarqiskit.providers.ibmq.runtime.RuntimeProgram.parameters()para recuperar uma instância deParameterNamespace.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_espno métodoqiskit.providers.ibmq.IBMQBackend.run(). SeTrue, 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ânciaqiskit.providers.ibmq.runtime.ParameterNamespace, que você pode usar para preencher os valores de parâmetro do programa em tempo de execução e passar paraqiskit.providers.ibmq.runtime.IBMRuntimeService.run().- O sinalizador
open_pulsena 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ânciaPulseBackendConfigurationmesmo que seu sinalizadoropen_pulsesejaFalse. - 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
idfoi descontinuada nos backends de hardware IBM. Em vez disso, use a instruçãodelayque implementa atrasos de comprimento variável, especificados em unidades dedt. Ao executar um circuito que contenha uma instruçãoid, um aviso será emitido no envio do trabalho e todas as instruçõesidno trabalho serão automaticamente substituídas pela instrução equivalentedelay.