Notas de versão do Qiskit SDK 1.3
1.3.3
Prelúdio
O Qiskit 1.3.3 é uma versão menor de correção de bugs para a série 1.3.
Correções de bugs
-
Foi corrigido um erro que fazia com que os rótulos das barreiras fossem posicionados incorretamente ao usar o parâmetro
reverse_bits = Trueno métodoQuantumCircuit.draw()método. O bug fazia com que os rótulos das operações de barreira ficassem desalinhados, o que poderia causar confusão nas visualizações de circuitos. Corrigido #13609. -
Aplicou um pequeno fator de regularização contra matrizes hermitianas mal condicionadas em representações de superoperadores.
-
As comparações de
Delayincluindo aquelas dentro de circuitos, agora exigem que as unidades e o valor de duração sejam iguais. Correções #13812. -
Corrigido um bug no
CommutationCheckerque poderia falhar ao verificar a relação de comutação de uma rotação Pauli de dois qubits com uma porta que não está no cache de comutação. Por exemplo:import numpy as np from qiskit.circuit.library import RXXGate, RGate from qiskit.circuit.commutation_library import SessionCommutationChecker as scc res = scc.commute(RGate(2, 2), [1], [], RXXGate(np.pi / 2), [0, 1], [])Esse comportamento foi resolvido e a relação de comutação foi calculada corretamente. Corrigido #13742.
-
Foi corrigido um bug em que
QuantumCircuit.qubit_stop_time()eQuantumCircuit.qubit_duration()retornava um tempo (duração) incorreto. O problema era acionado quando alguns qubits tinham instruções, mas outros qubits estavam ociosos. Correções #8729. -
Foi corrigido um bug na passagem do
RemoveIdentityEquivalentem que as portas próximas à identidade até uma fase global eram removidas do circuito, mas a fase global do circuito não era atualizada. Em particular,RemoveIdentityEquivalentagora remove osGlobalPhaseGatenão parametrizados. Correções #13778. -
Corrigido um erro no
random_clifford()que impedia a amostragem do grupo Clifford completo. Correções #13606. -
Quando
SabreLayouté usado para fazer o layout e o roteamento simultaneamente (como é o caso das opções padrão paratranspile()egenerate_preset_pass_manager()) em um arquivoTargetouCouplingMapcom conectividade disjunta, e o circuito de entrada se encaixa em um único componente do mapa de acoplamento, a permutação de roteamento agora será rastreada corretamente.Anteriormente, quaisquer qubits no mapa de acoplamento que não estivessem conectados, mesmo que indiretamente, a um qubit usado pelo circuito roteado não seriam incluídos na permutação de roteamento final. Isso pode causar um comportamento surpreendente a uma grande distância do ponto de falha, mesmo que a compilação pareça ter sido bem-sucedida, como chamadas para
TranspileLayout.final_index_layout()raisingKeyError.Esse bug não afetou os back-ends que estavam totalmente conectados, como a maioria deles. Correções #13732.
1.3.2
Prelúdio
O Qiskit 1.3.2 é uma versão menor de correção de bugs para a série 1.3.
Notas sobre a atualização da síntese
- Os plug-ins de síntese de alto nível para
LinearFunctionnão geram mais um erro quando um objeto diferente deLinearFunctioné passado para o métodorun. Em vez disso, eles agora retornamNone, o que é consistente com outros plug-ins. Se você confiou na ocorrência desse erro, pode executar manualmente uma verificação de instância.
Correções de bugs
-
Anteriormente, o
CommutationCheckerarmazenava em cache as relações de comutação deInstructions com float-onlyparamscomo chave para consultar a relação. Isso poderia levar a resultados incorretos se a definição da instrução dependesse de informações adicionais além do atributoparamscomo, por exemplo, no caso do atributoPauliEvolutionGate. Esse comportamento foi corrigido, e o verificador de comutação armazena em cache as comutações apenas para portas padrão nativas do Qiskit. Para portas personalizadas, essa alteração pode acarretar um custo de desempenho; no entanto, garante resultados corretos ao evitar o armazenamento em cache inseguro. -
Foi corrigido um bug no
CommutationCheckeronde a verificação das relações de comutação de uma instrução com valores não numéricos no atributoparams(como no caso dePauliGate) poderia gerar um erro. Corrigido #13570. -
O
CommutationCheckernão lidou corretamente com as comutações deCRXGate,CRYGateeCRZGatepara ângulos de rotação da forma , com . Nesses casos, presumiu-se incorretamente que essas portas comutam com qualquer porta. Agora, esse comportamento foi corrigido e essas portas são comutadas corretamente com qualquer porta somente quando o ângulo de rotação é um múltiplo de . -
Foi corrigido um bug que fazia com que as seguintes funções da biblioteca de circuitos produzissem erros quando chamadas com
num_qubits=1:efficient_su2(),real_amplitudes(),excitation_preserving()epauli_two_design()(para um único qubit, esses circuitos não contêm nenhuma porta de 2 qubit). Corrigido #13480. -
Foi corrigido um bug em que qualquer instrução chamada
"mcmt"era incorretamente passada para a rotina de síntese de alto nível para umMCMTGatelevando a uma falha ou a um resultado inválido. Esse problema pode ocorrer, por exemplo, ao manipular o circuitoMCMTchamado"mcmt", e convertendo-o implicitamente em uma instrução (por exemplo, ao anexá-lo a outro circuito ). Corrigido #13563. -
Foi corrigido um bug em que a síntese de fórmula de produto padrão para
PauliEvolutionGatenão lidava corretamente com todos os termos de identidade no operador. O termo de identidade total deveria introduzir uma fase global igual a-evolution_time, mas estava fora de um fator de 2 e poderia quebrar em tempos parametrizados. Corrigido #13625. Corrigido #13675. Corrigido #13644. -
Foi corrigida uma inconsistência no circuito gerado pela síntese de evolução de Pauli usando
SuzukiTrotterouLieTrotter(o método padrão). Para tempos de evolução parametrizados, os circuitos resultantes continham parâmetros com uma parte complexa zero espúria, que afetava a saída deParameterExpression.sympify(). A saída agora contém corretamente apenas valores reais. Corrigido #13642. -
Corrigido um bug que fazia com que o
PauliList.insert()comqubit=Trueproduzisse um atributo de fase com a forma errada quando o objeto original tinha comprimento 1. Corrigido #13623. -
Foi corrigido um bug no
qasm3.Exporterque fazia com que o exportador travasse ao lidar com uma porta unitária devido a um processamento incorreto de seu campoparams. Corrigido #13362. -
Foi corrigido um erro no método
Target.instruction_supported()em que os alvos comself.num_qubits==Nonesempre retornavamFalse, independentemente do conjunto de base suportado. -
Foi corrigido um bug na passagem do
UnitarySynthesisonde blocos deUnitaryGates em 3 qubits ou mais não eram sintetizados corretamente. Isso levou, por exemplo, ao fato de o circuito ser substituído pelo último bloco processado ou a panes internas ao encontrar medições após esse bloco. Corrigido #13586. -
Corrigido um bug na passagem do
UnitarySynthesisem que non-2-qubit gates seriam incluídos na base de 2 qubit disponível, fazendo com que oTwoQubitWeylDecompositionentrasse em pânico devido à incompatibilidade de dimensão. -
Corrigido um bug em que a inicialização de
SparsePauliOpcom um grande número de termos de Pauli-Y(normalmente ) e nenhumcoeffsexplícito resultava em um coeficiente próximo a 1, mas com um erro de ponto flutuante. O coeficiente agora é corretamente 1 por padrão. Corrigido #13522.
1.3.1
Prelúdio
O Qiskit 1.3.1 é uma versão menor de correção de bugs para a série 1.3.
Notas sobre atualização de circuitos
- O método de controle genérico para portões agora evita a tentativa de traduzir portões em uma base compatível quando o portão já é compatível. Isso pode alterar ligeiramente a síntese da porta controlada, mas não deve aumentar a contagem da porta de dois qubits.
Correções de bugs
-
Foi corrigido um bug em que chamar
QuantumCircuit.decompose()em uma instrução que não tinha definição dentro de um blococ_ifgerava um erro. Corrigido #13493. -
Operações dentro de uma operação de fluxo de controle (por exemplo
QuantumCircuit.for_loop()) não foram decompostos corretamente ao chamar oQuantumCircuit.decompose(). Corrigido #13544. -
Adicionadas definições padrão para
FullAdderGate,HalfAdderGate,ModularAdderGateeMultiplierGatepermitindo queOperators sejam construídos a partir de circuitos quânticos contendo essas portas. -
Corrigido o número de qubits de ancilla limpos exigidos por
FullAdderSynthesisV95,HalfAdderSynthesisV95, eModularAdderSynthesisV95plugins. -
Adicionado o plug-in
FullAdderSynthesisDefaultque escolhe a melhor decomposição paraFullAdderGatecom base no número de qubits de ancilla limpos disponíveis. -
Fixo
HalfAdderSynthesisDefaulteModularAdderSynthesisDefaultplugins, paraHalfAdderGateeModularAdderGaterespectivamente, para escolher a melhor decomposição com base no número de qubits de ancilla limpos disponíveis. -
Foi corrigido um comportamento incorreto de armazenamento em cache durante a atribuição de parâmetros que poderia resultar na corrupção das definições dentro do
EquivalenceLibraryfossem corrompidas. Isso resolve problemas inesperados ao executar a tradução de base em paralelo. Corrigido #13504. -
Correção de uma série de erros ao processar circuitos com fases globais parametrizadas, nos quais a fase global não era atribuída corretamente durante a atribuição de parâmetros. Os casos conhecidos afetados incluem:
- atribuir parâmetros após chamar
QuantumCircuit.decompose()em um circuito, onde a decomposição introduz uma fase global - atribuição de parâmetros em um circuito construído a partir de um DAG por meio de
dag_to_circuit() - atribuição de parâmetros em circuitos criados com
pauli_twirl_2q_gates()onde o circuito a ser girado tinha uma fase global parametrizada
Corrigido #13534.
- atribuir parâmetros após chamar
-
Corrigido um bug no
RZGate.control()para mais de 1 qubit de controle, que usava uma decomposição desnecessariamente cara. Corrigido #13473.
1.3.0
Prelúdio
A versão do Qiskit 1.3.0 traz grandes melhorias de desempenho e qualidade para o transpilador. Foram introduzidos muitos novos recursos, correções e aprimoramentos nessa nova versão do Qiskit, com destaque para os seguintes:
As principais estruturas de dados para transpilação no Qiskit foram portadas internamente para o Rust. Isso inclui componentes como o
DAGCircuit,Target,EquivalenceLibrary, e outros. As APIs públicas para todas essas estruturas de dados permanecem inalteradas, mas o desempenho após as reescritas melhorou.A maioria das passagens do transpilador usadas pelo gerenciador de passagens predefinidas foi portada para o Rust, resultando em uma melhoria média de 6x no tempo de execução geral em comparação com o Qiskit 1.2.4 ao executar os benchmarks de benchpress. Alguns dos passes particularmente impactantes que se beneficiaram muito com as reescritas foram o
BasisTranslator,CommutationAnalysis,ConsolidateBlocks, eUnitarySynthesis. Você pode consultar as notas de versão do recurso para obter uma lista completa dos passes portados.Aprimoramentos na biblioteca de circuitos que aumentam a qualidade da compilação e a velocidade de construção de circuitos. As operações agora são diferenciadas em:
- Operações estruturais, que têm uma decomposição exclusiva e são representadas como funções que retornam um
QuantumCircuit(por exemplo:real_amplitudes()). A maioria dessas funções é construída em Rust, resultando em um tempo de execução de construção de circuito significativamente mais rápido.- As operações abstratas, que podem ser implementadas usando diferentes decomposições, são representadas como
GateouInstruction(por exemplo:PauliEvolutionGate). Isso permite criar um circuito quântico abstrato e deixar que o compilador escolha a decomposição ideal.O uso de uma descrição abstrata do circuito é especialmente eficiente em combinação com os aprimoramentos da passagem do
HighLevelSynthesisque agora pode levar em conta os qubits auxiliares ociosos para encontrar a melhor decomposição disponível para uma determinada porta.A versão mínima compatível com Python agora é 3.9, pois Python 3.8 teve sua vida útil encerrada em 2024-10. O suporte oficial para Python 3.13 também foi adicionado nesta versão.
Recursos dos circuitos
-
Aprimoramos a funcionalidade do
CommutationCheckerpara incluir suporte às seguintes portas parametrizadas com parâmetros livres:RXXGate,RYYGate,RZZGate,RZXGate,RXGate,RYGate,RZGate,PhaseGate,U1Gate,CRXGate,CRYGate,CRZGate,CPhaseGate. Antes, eles eram compatíveis apenas com parâmetros vinculados. -
Adicionada uma nova função
quantum_volume()para gerar um objeto de volume quânticoQuantumCircuitconforme definido em A. Cross et al. Validação de computadores quânticos usando circuitos de modelos aleatórios, Phys. Rev. A 100, 032328 (2019). Essa nova função difere da classeQuantumVolumeexistente, pois retorna um objetoQuantumCircuitem vez de criar um objeto de subclasse. A segunda é que essa nova função é multithread e implementada em rust, portanto, gera o circuito de saída ~10x mais rápido do que a classeQuantumVolumeclasse. -
Melhorou o desempenho do tempo de execução da construção da classe
QuantumVolumecom o argumentoclassical_permutationdefinido comoTrue. Internamente, ele agora chama a funçãoquantum_volume()que é escrita em Rust e é ~10x mais rápida ao gerar um circuito de volume quântico. -
Adicionada uma nova função de manipulação de circuito
pauli_twirl_2q_gates()que pode ser usada para aplicar o giro de Pauli a um determinado circuito. Isso só funciona para girar um conjunto fixo de portas de dois qubits, atualmenteCXGate,ECRGate,CZGate,iSwapGate. Por exemplo:from qiskit.circuit import QuantumCircuit, pauli_twirl_2q_gates qc = QuantumCircuit(2) qc.cx(0, 1) twirled_circuit = pauli_twirl_2q_gates(qc, seed=123456) twirled_circuit.draw("mpl")
-
Adicionadas portas aritméticas binárias para adição no local de dois registros -qubit, ou seja, . A porta
ModularAdderGateimplementa o módulo de adição , oHalfAdderGateinclui um qubit de carry-out, e oFullAdderGateinclui um qubit de carry-in e um qubit de carry-out. Consulte a respectiva documentação para obter detalhes e exemplos.Em contraste com os circuitos de biblioteca existentes, como o
CDKMRippleCarryAddero manuseio da porta abstrata permite que o compilador (ou usuário) selecione a síntese de porta ideal, dependendo do contexto do circuito. -
Adicionado o
MultiplierGatepara multiplicação de dois registros -qubit, ou seja, . Consulte a documentação da classe para obter detalhes e exemplos. -
Os circuitos quânticos de lógica booleana em
qiskit.circuit.libraryagora têm representações equivalentes como objetosGatepermitindo seu uso com aHighLevelSynthesispassagem de transpilador e infraestrutura de plug-in.AndGate, representandoAND,OrGate, representandoOR,BitwiseXorGate, representandoXOR,InnerProductGate, representandoInnerProduct.
-
Implementações especializadas de
__eq__()foram adicionadas para todas as portas de circuito da biblioteca padrão. A maioria dos portões padrão já era especializada nesse método, mas alguns não eram, o que poderia causar lentidão significativa em locais inesperados. -
Adicionado
evolved_operator_ansatz(),hamiltonian_variational_ansatz(), eqaoa_ansatz()à biblioteca de circuitos para implementar circuitos variacionais com base em evoluções de operadores.evolved_operator_ansatz()eqaoa_ansatz()são funcionalmente equivalentes aEvolvedOperatorAnsatzeQAOAAnsatzmas geralmente com melhor desempenho.O
hamiltonian_variational_ansatz()foi projetado para pegar um único Hamiltoniano e dividi-lo automaticamente em termos comutáveis para implementar um ansatz variacional Hamiltoniano. Isso já podia ser feito manualmente usando o botãoEvolvedOperatorAnsatzmas agora é mais conveniente de usar. -
Adicionado
grover_operator()para construir um circuito de operador de Grover, usado no algoritmo de Grover e na estimativa/amplificação de amplitude, por exemplo. Essa função é semelhante àGroverOperatormas não exige que você escolha a implementação da porta X multicontrolada e, em vez disso, permite que o compilador determine a decomposição ideal. Além disso, ele não envolve o circuito em uma porta opaca e é mais rápido porque são necessárias menos decomposições para a transpilação.from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import grover_operator oracle = QuantumCircuit(2) oracle.z(0) # good state = first qubit is |1> grover_op = grover_operator(oracle, insert_barriers=True) grover_op.draw('mpl')
-
Um novo atributo de dados,
qiskit.circuit.CONTROL_FLOW_OP_NAMESestá disponível para localizar e verificar facilmente se uma determinadaInstructioné uma operação de fluxo de controle por nome. -
A biblioteca de equivalência padrão (
SessionEquivalenceLibrary) agora tem regras que podem converter diretamente entre a biblioteca padrão do Qiskit 2q interações contínuas do tipo Ising (por exemploCPhaseGate,RZZGate,RZXGate, e assim por diante) usando relações de equivalência local. Anteriormente, várias dessas conversões eram feitas por meio de um formulário 2-CX, o que resultava em uma geração de circuitos menos eficiente.NotaEm geral, o
BasisTranslatornão tem a garantia de encontrar a "melhor" relação de equivalência para um determinadoTargetmas sempre encontrará uma equivalência se ela existir. Contamos com passagens de ressíntese e otimização de porta mais caras no transpilador para melhorar o resultado. Atualmente, essas passagens não são tão eficazes para conjuntos de bases com uma interação de dois qubits continuamente parametrizada quanto para interações discretas de dois qubits supercontroladas. -
Foi adicionado um novo argumento
"apply_synthesis"aDecomposeque permite que a passagem do transpilador aplique a síntese de alto nível para decompor objetos que são definidos apenas por uma rotina de síntese. Por exemplo:from qiskit import QuantumCircuit from qiskit.quantum_info import Clifford from qiskit.transpiler.passes import Decompose cliff = Clifford(HGate()) circuit = QuantumCircuit(1) circuit.append(cliff, [0]) # Clifford has no .definition, it is only defined by synthesis nothing_happened = Decompose()(circuit) # this internally runs the HighLevelSynthesis pass to decompose the Clifford decomposed = Decompose(apply_synthesis=True)(circuit) -
Adicionada a função
iqp()para construir circuitos de tempo polinomial quântico instantâneo (IQP). Além da classeIQPexistente, a função também permite a construção de circuitos IQP aleatórios:from qiskit.circuit.library import random_iqp random_iqp = random_iqp(num_qubits=4) random_iqp.draw('mpl')
-
Adicionado o
MCMTGatepara representar uma operação de vários controles e vários alvos como uma porta. Essa representação de porta do circuito existenteMCMTpermite que o compilador selecione a melhor implementação disponível de acordo com o número e o estado dos qubits auxiliares presentes no circuito.A implementação desejada pode ser escolhida especificando-se o plug-in de síntese de alto nível:
from qiskit import QuantumCircuit, transpile from qiskit.circuit.library import MCMTGate, HGate from qiskit.transpiler.passes import HLSConfig # used for the synthesis config mcmt = MCMTGate(HGate(), num_ctrl_qubits=5, num_target_qubits=3) circuit = QuantumCircuit(20) circuit.append(mcmt, range(mcmt.num_qubits)) config = HLSConfig(mcmt=["vchain"]) # alternatively use the "noaux" method synthesized = transpile(circuit, hls_config=config)Além disso, o
MCMTGatetambém suporta estados de controle personalizados (ou seja, abertos) dos qubits de controle. -
Como parte da modernização da biblioteca de circuitos, cada um dos seguintes circuitos quânticos também é representado como um objeto
Gateou pode ser construído usando um método de síntese:GraphStateé representado porGraphStateGate,FourierCheckingpode ser construído usandofourier_checking(),UnitaryOverlappode ser construído usandounitary_overlap(),HiddenLinearFunctionpode ser construído usandohidden_linear_function(),PhaseEstimationpode ser construído usandophase_estimation().
-
A classe
CommutationCheckerfoi reescrita em Rust. Essa classe mantém a mesma funcionalidade e API pública de antes, mas agora é significativamente mais rápida na maioria dos casos. -
PauliFeatureMapeZZFeatureMapagora suportam a especificação do emaranhamento como um dicionário em que as chaves representam o número de qubits e os valores são listas de tuplas de números inteiros que definem quais qubits estão emaranhados uns com os outros. Isso permite mais flexibilidade na construção de mapas de recursos adaptados a algoritmos quânticos específicos. Exemplo de uso:from qiskit.circuit.library import PauliFeatureMap entanglement = { 1: [(0,), (2,)], 2: [(0, 1), (1, 2)], 3: [(0, 1, 2)], } qc = PauliFeatureMap(3, reps=2, paulis=['Z', 'ZZ', 'ZZZ'], entanglement=entanglement, insert_barriers=True) qc.decompose().draw('mpl') -
O método
count_ops()emQuantumCircuitfoi reescrito em Rust. Agora, ele é executado de 3 a 9 vezes mais rápido. -
Funções de biblioteca de circuitos adicionadas
pauli_feature_map(),z_feature_map(),zz_feature_map()para construir circuitos de mapas de recursos de Pauli. Essas funções são aproximadamente 8x mais rápidas do que os objetos atuais da biblioteca de circuitos,PauliFeatureMap,ZFeatureMap, eZZFeatureMape as substituirão no futuro.As funções podem ser usadas como substitutos:
from qiskit.circuit.library import pauli_feature_map, PauliFeatureMap fm = pauli_feature_map(20, paulis=["z", "xx", "yyy"]) also_fm = PauliFeatureMap(20, paulis=["z", "xx", "yyy"]).decompose()
Recursos primitivos
-
O suporte para dados de nível 1 foi adicionado ao
BackendSamplerV2assim como o suporte para a passagem de opções para o métodorun()do pacoteBackendV2. As opções de execução podem ser especificadas por meio de uma entrada"run_options"dentro do dicionáriooptionspassado paraBackendSamplerV2. A entrada"run_options"deve ser um dicionário que mapeia os nomes dos argumentos para valores a serem passados para o métodorun()do backend. Quando um"meas_level = 1 "for definido nas opções de execução, os resultados do backend serão tratados como resultados de nível 1 em vez de matrizes de bits (o formato de nível 2). -
EstimatoreStatevectorEstimatorretornam valores de expectativa de forma estocástica se o circuito de entrada incluir uma reinicialização para alguns subsistemas. O resultado não era reproduzível anteriormente, mas agora pode ser reproduzido se uma semente aleatória for definida. Por exemplo:from qiskit.primitives import StatevectorEstimator estimator = StatevectorEstimator(seed=123)ou:
from qiskit.primitives import Estimator estimator = Estimator(options={"seed":123})
OpenQASM Características
- A classe
qasm3.CustomGateagora pode ser inspecionada programaticamente. Seuconstructor,name,num_paramsenum_qubitspodem agora ser visualizados em Python depois que o objeto tiver sido construído. Isso permite que você inspecione o conteúdo dos atributos de dados fornecidos, comoSTDGATES_INC_GATES.
Recursos do QPY
- Adição de um novo formato QPY versão 13 que adiciona uma representação nativa do Qiskit de
ParameterExpressionobjetos.
Recursos de informação quântica
-
O desempenho do
SparsePauliOp.from_operator()foi otimizado com base nos métodos de aprimoramento do algoritmo introduzidos no Qiskit 1.0. Agora é aproximadamente cinco vezes mais rápido do que antes para matrizes totalmente densas, levando aproximadamente 40ms para decompor um operador 10q envolvendo todos os termos Pauli. -
Foi adicionado um novo argumento
assume_unitaryaoqiskit.quantum_info.Operator.power(). QuandoTrue, usamos um método mais rápido baseado na decomposição de Schur para elevar umOperatora uma potência fracionária. -
Adicionado
SparsePauliOp.to_sparse_list()para converter um operador em um formato de lista esparsa. Isso funciona de forma inversa aSparsePauliOp.from_sparse_list(). Por exemplo:from qiskit.quantum_info import SparsePauliOp op = SparsePauliOp(["XIII", "IZZI"], coeffs=[1, 2]) sparse = op.to_sparse_list() # [("X", [3], 1), ("ZZ", [1, 2], 2)] other = SparsePauliOp.from_sparse_list(sparse, op.num_qubits) print(other == op) # True -
O desempenho do
Pauli.to_label()melhorou significativamente para Paulis grandes. -
O método
Operator.power()tem um novo parâmetrobranch_cut_rotation. Isso pode ser usado para deslocar o ponto de corte da raiz, o que pode afetar qual matriz é escolhida como raiz principal. Por padrão, ele é definido como uma pequena rotação positiva para tornar as raízes dos operadores com um valor próprio real negativo (como os operadores Pauli) mais estáveis em relação às diferenças de precisão numérica. -
Uma nova classe observável foi adicionada.
SparseObservablerepresenta observáveis como uma soma de termos, semelhante aSparsePauliOpmas com duas diferenças fundamentais:- Cada termo completo é armazenado como (efetivamente) uma série de pares
(qubit, bit_term), sem armazenar qubits que passam pela identidade desse termo. Isso melhora significativamente o uso da memória de observáveis, como a soma ponderada de Paulis . - O alfabeto de termos de um único qubit é supercompleto para o espaço do operador; ele pode representar operadores Pauli (como
SparsePauliOp), mas também projetores nos estados próprios dos operadores de Pauli, como . Esses projetores podem ser medidos em hardware com a mesma eficiência que seu operador Pauli correspondente, masSparsePauliOpexigiria um número exponencial de termos para representar em qubits, enquantoSparseObservableprecisa de apenas um único termo.
Você pode construir e manipular
SparseObservableusando uma interface familiar aos usuários deSparsePauliOp:from qiskit.quantum_info import SparseObservable obs = SparseObservable.from_sparse_list([ ("XZY", (2, 1, 0), 1.5j), ("+-", (100, 99), 0.5j), ("01", (50, 49), 0.5), ])SparseObservablenão é suportado atualmente como um formato de entrada para as primitivas (qiskit.primitives), mas esperamos expandir essas interfaces para incluí-las no futuro. - Cada termo completo é armazenado como (efetivamente) uma série de pares
Recursos de síntese
-
Funções de síntese adicionadas
synth_mcx_gray_code()esynth_mcx_noaux_v24()que sintetizam portas X multicontroladas. Essas funções não requerem qubits de ancilla adicionais. -
Funções de síntese adicionadas
synth_c3x()esynth_c4x()que sintetizam X-gates com 3 e 4 controles, respectivamente. -
Adicione uma função de síntese
synth_mcx_n_dirty_i15()que sintetiza uma porta X multicontrolada com controles usando qubits auxiliares sujos, produzindo um circuito com no máximo portas CX, por Iten et. al. (arXiv:1501.06911). -
Adicione uma função de síntese
synth_mcx_n_clean_m15()que sintetiza um portão X multicontrolado com controles usando qubits auxiliares limpos, produzindo um circuito com no máximo portões CX, por Maslov ( arXiv:1508.03273 ). -
Adicione uma função de síntese
synth_mcx_1_clean_b95()que sintetiza um portão X multicontrolado com controles usando um único qubit auxiliar limpo, produzindo um circuito com no máximo portões CX, por Barenco et al. ( arXiv:quant-ph/9503016 ). -
Adicionado
adder_qft_d00(),adder_ripple_c04(), eadder_ripple_v95()para sintetizar as portas do somador,ModularAdderGate,HalfAdderGate, eFullAdderGate. -
Adicionado
multiplier_cumulative_h18()emultiplier_qft_r17()para sintetizar oMultiplierGate. -
Adicionado
synth_mcmt_vchain()para sintetizar a porta multialvo de controle múltiplo com um número linear de portas Toffoli e k-1 qubits auxiliares para k qubits de controle, juntamente com o plug-in de síntese de alto nívelMCMTSynthesisVChain. -
Adicionada uma estrutura de plug-in de síntese de alto nível para o
MCMTGateincluindo oMCMTSynthesisNoAux(para nenhum qubits auxiliar), o já mencionadoMCMTSynthesisVChain(usandonum_control - 1qubits auxiliares) e oMCMTSynthesisDefaultpara permitir que o compilador escolha a decomposição ideal. -
A função
random_clifford()foi portada para o Rust, melhorando o tempo de execução em um fator de 3. -
Adicionado
ProductFormula.expand()que permite visualizar a expansão de uma fórmula de produto em um formato Pauli esparso. Por exemplo, podemos consultar o formato de uma expansão de Trotter de segunda ordem de um Hamiltoniano como:from qiskit.quantum_info import SparsePauliOp from qiskit.circuit.library import PauliEvolutionGate from qiskit.synthesis.evolution import SuzukiTrotter hamiltonian = SparsePauliOp(["IX", "XI", "ZZ"], coeffs=[-1, -1, 1]) evo = PauliEvolutionGate(hamiltonian, time=3.14) trotter = SuzukiTrotter(order=2) print(trotter.expand(evo))que imprimirá
[('X', [0], -3.14), ('X', [1], -3.14), ('ZZ', [0, 1], 6.28), ('X', [1], -3.14), ('X', [0], -3.14)] -
Adicionada a estrutura do plug-in para o arquivo
PauliEvolutionGate. O plug-in padrão,PauliEvolutionSynthesisDefaultconstrói o circuito como antes, mas com mais rapidez, pois usa internamente o Rust. Quanto maior o circuito (por exemplo. pelo tamanho do hamiltoniano, pelo número de intervalos de tempo ou pela ordem de Suzuki-Trotter), maior será o aumento de velocidade. Por exemplo, um Hamiltoniano de Heisenberg de 100 qubits com 10 passos de tempo e uma fórmula de Trotter de 4ª ordem agora é construído ~9.4x mais rápido. O novo plug-in,PauliEvolutionSynthesisRustiqusa o algoritmo de síntese descrito no artigo " Faster and shorter synthesis of Hamiltonian simulation circuits" de (de) Brugière e Martiel " e está implementado no Rustiq. Por exemplo:from qiskit.circuit import QuantumCircuit from qiskit.quantum_info import SparsePauliOp from qiskit.circuit.library import PauliEvolutionGate from qiskit.compiler import transpile from qiskit.transpiler.passes import HLSConfig op = SparsePauliOp(["XXX", "YYY", "IZZ"]) qc = QuantumCircuit(4) qc.append(PauliEvolutionGate(op), [0, 1, 3]) config = HLSConfig(PauliEvolution=[("rustiq", {"upto_phase": False})]) tqc = transpile(qc, basis_gates=["cx", "u"], hls_config=config) tqc.draw(output='mpl')
Esse trecho de código usa o plug-in do Rustiq para sintetizar
PauliEvolutionGateobjetos no circuito quântico qc. O plug-in é chamado com a opção adicionalupto_phase = False, permitindo que você obtenha circuitos menores à custa da possibilidade de não preservar a fase global. Para obter a lista completa de opções compatíveis, consulte a documentação doPauliEvolutionSynthesisRustiq. -
Porto
synth_cz_depth_line_mr()para Rust. Essa função sintetiza um circuito CZ para conectividade linear do vizinho mais próximo (LNN), com base no método de Maslov e Roetteler. Em uma matriz binária 350x350, a implementação do Rust produz um aumento de velocidade de cerca de 30x. -
Port
synth_permutation_reverse_lnn_kms()para o Rust, que sintetiza uma permutação reversa para a arquitetura LNN usando o método Kutin, Moulton, Smithline. -
Adicionado um novo argumento
preserve_orderaProductFormulaque permite reordenar os termos de Pauli no Hamiltoniano antes da expansão da fórmula do produto, para comprimir a profundidade do circuito final. Ao definir isso comoFalse, um termo da forma
serão reordenados para
o que fará com que as rotações RZZ e RYY sejam aplicadas em paralelo, em vez de três rotações sequenciais na primeira parte.
Essa opção pode ser definida por meio da interface do plug-in:
from qiskit import QuantumCircuit, transpile
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.quantum_info import SparsePauliOp
from qiskit.synthesis.evolution import SuzukiTrotter
from qiskit.transpiler.passes import HLSConfig
op = SparsePauliOp(["XXII", "IYYI", "IIZZ"])
time, reps = 0.1, 1
synthesis = SuzukiTrotter(order=2, reps=reps)
hls_config = HLSConfig(PauliEvolution=[("default", {"preserve_order": False})])
circuit = QuantumCircuit(op.num_qubits)
circuit.append(PauliEvolutionGate(op, time), circuit.qubits)
tqc = transpile(circuit, basis_gates=["u", "cx"], hls_config=hls_config)
tqc.draw('mpl')
Recursos do Transpiler
-
Adicione o argumento
matrix_basedà passagem doCollectCliffordstranspiler pass. Se o novo parâmetromatrix_based=True, a passagem doCollectCliffordspode coletar portas unitárias que são portas de Clifford para determinados parâmetros, por exemploRZGateportas com ângulos que são múltiplos de . -
A passagem
RemoveIdentityEquivalenta passagem do transpilador agora é executada como parte dos gerenciadores de passagem predefinidos nos níveis de otimização 2 e 3. A passagem é executada durante os estágiosiniteoptimization, porque as otimizações que ela aplica são válidas em ambos os estágios e a passagem é rápida de executar. -
Foram adicionados vários plug-ins de síntese de alto nível para sintetizar um
MCXGate:MCXSynthesisNCleanM15, com base emsynth_mcx_n_clean_m15().MCXSynthesisNDirtyI15, com base emsynth_mcx_n_dirty_i15().MCXSynthesis1CleanB95, com base emsynth_mcx_1_clean_b95().MCXSynthesisNoAuxV24, com base emsynth_mcx_noaux_v24().MCXSynthesisGrayCode, com base emsynth_mcx_gray_code().
Assim como:
MCXSynthesisDefaultpara escolher o método de síntese mais eficiente com base no número de qubits de ancilla limpos e sujos disponíveis.
Como exemplo, considere a transpilação do circuito a seguir:
from qiskit.circuit import QuantumCircuit from qiskit.compiler import transpile qc = QuantumCircuit(7) qc.x(0) qc.mcx([0, 1, 2, 3], [4]) qc.mcx([0, 1, 2, 3, 4], [5]) qc.mcx([0, 1, 2, 3, 4, 5], [6]) transpile(qc).draw('mpl', fold=-1)
Para a primeira porta MCX, os qubits
5e6podem ser usados como ancilares limpos, e o melhor método de síntese disponívelsynth_mcx_n_clean_m15será escolhido. Para a segunda porta MCX, o qubit6pode ser usado como um ancilla limpo, o métodosynth_mcx_n_clean_m15não se aplica mais, portanto, o métodosynth_mcx_1_clean_b95será escolhido. Para a terceira porta MCX, não há qubits de ancilla, e o métodosynth_mcx_noaux_v24será escolhido. -
A passagem do
SabreLayoutfoi atualizada para executar mais duas ou três tentativas de layout por padrão, independentemente do valor do argumento da palavra-chavelayout_trials. Um layout trivial e seu reverso estão incluídos para todos os backends, assim como oDenseLayoutque foi adicionado em 1.2.0. Além disso, os maiores anéis em um gráfico de conectividade hexagonal pesado do backend IBM são adicionados se os backends tiverem 127, 133 ou 156 qubits. Isso pode fornecer um bom ponto de partida para alguns circuitos nesses backends comumente executados, enquanto para todos os outros é apenas um "teste aleatório" adicional. -
O
DAGCircuitfoi reimplementado em Rust. Essa reescrita da classe Python deve ser totalmente compatível com a API da implementação anterior do Python. Embora a classe tenha sido implementada anteriormente usando o rustworkx, para o qual a estrutura de gráfico de dados subjacente existe no Rust, a implementação da classe e de todos os dados foi feita em Python. Essa nova versão doDAGCircuitarmazena representações nativas do Rust para todos os seus dados e é mais eficiente em termos de memória devido à representação comprimida de qubit e clbit projetada para instruções em repouso. Ele também permite que as passagens do transpilador manipulem totalmente umDAGCircuitdo Rust, permitindo melhorias no desempenho. -
Um novo argumento
qubits_initially_zerofoi adicionado aqiskit.compiler.transpile(),generate_preset_pass_manager(), e paraPassManagerConfig. Se definido com o valor padrão deTrue, presume-se que os qubits estejam inicialmente no estado , o que pode permitir oportunidades adicionais de otimização para passagens individuais do transpilador. Em particular, a passagem doHighLevelSynthesistranspilador escolherá uma decomposição melhor para cadaMCXGateporta em um circuito quando um qubit auxiliar ocioso no estado estiver disponível.No entanto, há casos em que
qubits_initially_zerodeve ser definido comoFalse, como ao transpilar para backends que não inicializam corretamente os qubits ou ao chamar manualmente as passagens do transpilador em subcircuitos de um circuito quântico maior. -
O construtor da passagem
HighLevelSynthesistranspiler pass agora aceita um argumento adicional:qubits_initially_zero. Se definido comoTrue, o passe assume que os qubits estão inicialmente no estado . Além disso, a passagem mantém o controle dos qubits auxiliares limpos e sujos durante a execução e passa essas informações para os plug-ins usando os kwargsnum_clean_ancillasenum_dirty_ancillas. -
Melhoria no tratamento de qubits ancilla na passagem do
HighLevelSynthesispassagem do transpilador. Por exemplo, um circuito pode ter portas personalizadas cujas definições incluemMCXGates. Agora, os algoritmos de síntese para osMCXGates podem usar os qubits ancilla disponíveis no circuito global, mas fora das definições das portas personalizadas. -
Adicionado um novo método
DAGCircuit.control_flow_op_nodes()que fornece um caminho rápido para obter todos osDAGOpNodeem umDAGCircuitque contêm umControlFlowOp. Isso era possível antes de usar o métodoDAGCircuit.op_nodes()e passando a classeControlFlowOpcomo um filtro, mas essa nova função executará a operação mais rapidamente. -
A maioria das passagens do transpilador usadas nos gerenciadores de passagem predefinidos retornados por
generate_preset_pass_manager()e usados internamente portranspile()foi portada para o Rust. Isso melhorou significativamente o desempenho do tempo de execução de cada passagem, o que levou a uma melhoria significativa na eficiência operacional geral do transpilador. A lista de passes portados para o Rust nesta versão é a seguinte:ConsolidateBlocksBasisTranslatorCommutationAnalysisCommutativeCancellationElidePermutationsOptimize1qGatesDecompositionUnitarySynthesisGateDirectionCheckGateDirectionRemoveDiagonalGatesBeforeMeasureCheckMapSplit2QUnitariesFilterOpNodesDepthSizeGatesInBasisInverseCancellationBarrierBeforeFinalMeasurements
-
Adicionada uma nova passagem de transpilador,
RemoveIdentityEquivalentque é usada para remover portas que são equivalentes a uma identidade até uma certa tolerância. Por exemplo, se você tivesse um circuito como:
a execução do passe eliminaria a
CPhaseGate:from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import RemoveIdentityEquivalent qc = QuantumCircuit(2) qc.cp(1e-20, 0, 1) removal_pass = RemoveIdentityEquivalent() result = removal_pass(qc) result.draw("mpl")
-
A passagem
ConsolidateBlocksagora executará o equivalente à passagemCollect2qBlocksinternamente, caso não tenha sido executada em um gerenciador de passagens antes da passagem. Anteriormente,Collect2qBlocksouCollect1qRunsteve que ser executado antes deConsolidateBlocksparaConsolidateBlockspara fazer qualquer coisa. Ao fazer a coleta internamente, a sobrecarga da passagem é reduzida. SeCollect2qBlocksouCollect1qRunsforem executados antes deConsolidateBlocksas execuções coletadas por esses passes do conjunto de propriedades serão usadas e não haverá alteração no comportamento do passe. -
O
RemoveDiagonalGatesBeforeMeasurea passagem do transpilador foi atualizada para incluir mais portas diagonais:PhaseGate,CPhaseGate,CSGate,CSdgGateeCCZGate. Além disso, o código doRemoveDiagonalGatesBeforeMeasurefoi portado para o Rust e agora é x20 mais rápido para um circuito de 20 qubits.
Recursos de visualização
- A função
timeline_drawer()visualization tem um novo argumentotarget, usado para especificar umTargetobjeto para a visualização. Por padrão, a função usou oInstruction.durationpara obter a duração de uma determinada instrução, mas a especificação do destino aproveitará os detalhes de tempo dentro do destino.
Problemas Conhecidos
- Ao usar os formatos QPY 10, 11 ou 12 com circuitos que contêm
ParameterExpressions, se a versão do pacotesymengineinstalada no ambiente que gerou a carga útil (qpy.dump()) não corresponder à versão dosymengineinstalada no ambiente em que a carga é carregada (qpy.load()), você receberá um erro. Se você encontrar esse erro, instale a versãosymengineda mensagem de erro antes de chamarqpy.load(). As versões 13 ou posteriores do formato QPY (ou anteriores à 10) não terão esse problema. Portanto, se você estiver serializandoParameterExpressioncomo parte de seu circuito ou qualquer objetoScheduleBlockobjetos, é recomendável que você use a versão 13 para evitar esse problema no futuro.
Notas da Atualização
-
As classes a seguir agora usam a operação para diagonalizar o operador Pauli-Y:
PauliEvolutionGate,EvolvedOperatorAnsatz, ePauliFeatureMap. Anteriormente, essas classes usavam ou como transformação de base. Usar a operação , representada pelo símboloSXGateé mais eficiente, pois usa apenas uma única porta implementada como singleton.Se você estava confiando no uso anterior do portão, recomendamos construir os circuitos com o Qiskit 1.2 e exportá-los com
qpy.dump()ou escrever um código personalizadoTransformationPassque realize a tradução para sua porta de mudança de base desejada. -
A versão mínima compatível do Python agora é 3.9, que foi aumentada em relação à versão mínima de suporte anterior de 3.8. Essa alteração foi necessária porque o projeto cPython upstream não é mais compatível com Python 3.8.
Notas sobre atualização de circuitos
- A classe
QuantumVolumegerará circuitos com diferentes matrizes unitárias e permutações para um determinado valor de semente da versão anterior do Qiskit. Isso se deve ao uso de um novo gerador interno de números aleatórios para a geração do circuito, que gerará o circuito mais rapidamente. Se você precisar de um circuito exato com a mesma semente, poderá usar a versão anterior do Qiskit e gerar o circuito com o argumentoflatten=Truee exportar o circuito comqpy.dump()e, em seguida, carregá-lo com esta versão.
Notas sobre a atualização dos primitivos
- Ao usar
BackendSamplerV2os metadados do circuito não são mais limpos antes de passar os circuitos para o métodorun()da instânciaBackendV2da instância envolvida. Se você estava confiando nesse comportamento, pode limpar manualmente os metadados antes de chamar oBackendSamplerV2.run()chamandocircuit.metadata.clear()
Notas de atualização do QPY
- A função
qpy.dump()agora emite a versão 13 do formato por padrão. Isso significa que as cargas úteis geradas com essa função por padrão são compatíveis apenas com o Qiskit 1.3.0 ou posterior. Se a carga útil precisar ser carregada por uma versão anterior do Qiskit, use o sinalizadorversionemqpy.dump()para emitir a versão apropriada. Consulte Compatibilidade do QPY para obter mais detalhes.
Notas sobre a atualização do Transpiler
-
DAGNode(e suas subclassesDAGInNode,DAGOutNode, eDAGOpNode) não retornam mais referências ao mesmo objeto subjacente dos métodosDAGCircuitmétodos. Isso nunca foi uma garantia de que todos os nós retornados seriam referências compartilhadas ao mesmo objeto. No entanto, com a migração doDAGCircuitpara o Rust, uma nova instância doDAGNodeé gerada em tempo real quando um nó é retornado para Python. Esses objetos serão avaliados como iguais usando==ou verificações semelhantes que dependem de__eq__, mas não serão mais identificados como o mesmo objeto. -
As
DAGOpNoderetornadas doDAGCircuitnão são mais referências compartilhadas aos dados subjacentes armazenados no DAG. Na versão anterior, era possível fazer algo como:for node in dag.op_nodes(): node.op = new_opno entanto, esse tipo de mutação sempre foi insalubre, pois poderia quebrar o cache interno do DAG e causar corrupção da estrutura de dados. Em vez disso, você deve usar a API fornecida pelo
DAGCircuitpara mutação, comoDAGCircuit.substitute_node()ouDAGCircuit.substitute_node_with_dag(). Por exemplo, o bloco de código acima se tornaria:for node in dag.op_nodes(): dag.substitute_node(node, new_op)Isso é semelhante a uma nota de atualização de 1.2.0 em que isso foi observado para a mutação do atributo
DAGOpNode.ope não do atributoDAGOpNodeem si. No entanto, em 1.3 isso se estende a todo o objeto, não apenas ao atributoopinterno. Em geral, esse tipo de mutação sempre foi infundado e não foi apoiado, mas poderia ter funcionado anteriormente em alguns casos. -
O
transpile()agora pressupõe que os qubits estão inicialmente no estado . Para evitar essa suposição, é possível definir o argumentoqubits_initially_zerocomoFalse.
Notas de descontinuação
-
O módulo
qiskit.pulsee todos os seus recursos associados agora estão obsoletos e serão removidos no Qiskit 2.0.0. Isso ocorre porque o principal provedor de back-end com suporte a pulso é o IBM e o acesso em nível de pulso é atualmente compatível apenas com um subconjunto de back-ends do IBM e não é compatível com suas arquiteturas mais recentes. Da mesma forma, eles anunciaram que o acesso em nível de pulso será removido em 2025. Sem o maior provedor que usa o recurso com suporte ao acesso de pulso, a importância do recurso para a Qiskit é significativamente reduzida e, em comparação com a sobrecarga de manutenção contínua do pacote que está sendo removido.A descontinuação inclui todo o código de pulso em
qiskit.pulsebem como a funcionalidade dependente ou relacionada ao pulse, como visualização de pulso, serialização e suporte à calibração personalizada. Para obter mais detalhes, consulte as seções de depreciação abaixo.O pacote Pulse como um todo, juntamente com os componentes diretamente relacionados no Qiskit, será movido para o repositório Qiskit Dynamics para permitir ainda mais a simulação de pulso e controle de baixo nível. A Qiskit 1.x continuará a oferecer suporte ao
qiskit.pulseaté o fim de sua vida útil.
Circuitos obsoletos
-
O atributo
Instruction.conditione o métodoInstruction.c_if()método. Eles serão removidos no Qiskit 2.0, juntamente com quaisquer usos no modelo de dados do Qiskit. Essa funcionalidade foi substituída pela classeIfElseOpque pode ser usada para descrever uma condição clássica em um circuito. Por exemplo, um circuito que usaInstruction.c_if()como:from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(2, 2) qc.h(0) qc.x(0).c_if(0, 1) qc.z(1.c_if(1, 0) qc.measure(0, 0) qc.measure(1, 1)Pode ser reescrito como:
qc = QuantumCircuit(2, 2) qc.h(0) with qc.if_test((qc.clbits[0], True)): qc.x(0) with qc.if_test((qc.clbits[1], False)): qc.z(1) qc.measure(0, 0) qc.measure(1, 1)A agora obsoleta passagem
ConvertConditionsToIfOpspode ser usado para automatizar essa conversão para circuitos existentes. -
Como parte da descontinuação do pacote Qiskit Pulse, as seguintes dependências também estão descontinuadas:
qiskit.circuit.QuantumCircuit.calibrationsqiskit.circuit.QuantumCircuit.has_calibration_for()qiskit.circuit.QuantumCircuit.add_calibration()qiskit.dagcircuit.DAGCircuit.calibrationsqiskit.dagcircuit.DAGCircuit.has_calibration_for()qiskit.dagcircuit.DAGCircuit.add_calibration()qiskit.dagcircuit.DAGDependency.calibrations
-
O
QuantumCircuit.uniteQuantumCircuit.durationforam descontinuados e serão removidos no Qiskit 2.0.0. Esses atributos foram usados para rastrear a duração estimada e a unidade dessa duração a ser executada no circuito. No entanto, os valores desses atributos sempre foram limitados, pois só seriam preenchidos corretamente se o transpilador fosse executado com as configurações corretas. A duração também era apenas uma suposição baseada no caminho mais longo na soma da duração deDAGCircuite nunca levaria em conta corretamente o fluxo de controle ou as condicionais no circuito. -
O
DAGCircuit.uniteDAGCircuit.durationforam descontinuados e serão removidos no Qiskit 2.0.0. Esses atributos foram usados para rastrear a duração estimada e a unidade dessa duração a ser executada no circuito. No entanto, os valores desses atributos sempre foram limitados, pois só seriam preenchidos corretamente se o transpilador fosse executado com as configurações corretas. A duração também era apenas uma suposição baseada no caminho mais longo na soma da duração deDAGCircuite nunca levaria em conta corretamente o fluxo de controle ou as condicionais no circuito. -
O
Instruction.durationeInstruction.unitforam descontinuados e serão removidos no Qiskit 2.0.0. Isso inclui a configuração dos argumentosunitoudurationpara qualquerqiskit.circuit.Instructionou subclasse. Esses atributos foram usados para anexar uma duração de execução personalizada e uma unidade para essa duração a uma instrução individual. No entanto, a fonte de verdade da duração de um portão é oBackendV2Targetque contém a duração de cada instrução suportada no backend. A duração de uma instrução não é algo que normalmente pode ser ajustado pelo usuário e é uma propriedade imutável do backend. Se você estava usando esse recurso anteriormente para experimentar diferentes durações de gates, poderá alterar o campoInstructionProperties.durationem um determinado campoTargetpara definir uma duração personalizada para uma instrução em um backend (a unidade está sempre em segundos no campoTarget).
Descontinuidade de provedores
-
O método
BasicSimulator.configuration()está obsoleto e será removido em 2.0.0. Esse método retornou uma instância herdada deproviders.models.BackendConfigurationque faz parte do modelo obsoleto deBackendV1. Esse modelo foi substituído porBackendV2em que as restrições são armazenadas diretamente na instância de back-end ou noTarget(backend.target).Aqui está um guia rápido para acessar os atributos mais comuns do
BackendConfigurationnoBackendV2modelo:BackendV1 model (deprecated) ------------> BackendV2 model ---------------------------- --------------- backend.configuration().backend_name backend.name backend.configuration().backend_version backend.backend_version backend.configuration().n_qubits backend.num_qubits backend.configuration().num_qubits backend.num_qubits backend.configuration().basis_gates backend.target.operation_names (*) backend.configuration().coupling_map backend.target.build_coupling_map() backend.configuration().local No representation backend.configuration().simulator No representation backend.configuration().conditional No representation backend.configuration().open_pulse No representation backend.configuration().memory No representation backend.configuration().max_shots No representation(*) Observe que
Backend.target.operation_namesincluibasis_gatese instruções adicionais que não são de porta; em algumas implementações, pode ser necessário filtrar a saída.Consulte este guia para obter mais informações sobre a migração para o modelo
BackendV2modelo. -
Como parte da descontinuação do pacote Qiskit Pulse, todas as funcionalidades relacionadas ao pulso na
qiskit.providers.BackendV2classe estão sendo descontinuadas. Isso inclui os seguintes métodos:Consequentemente, os métodos de canal correspondentes no
qiskit.providers.BackendV2Convertereqiskit.providers.fake_provider.GenericBackendV2também estão sendo descontinuados.Além disso, os argumentos
pulse_channelsecalibrate_instructionsno métodoBackendV2estão sendo descontinuados. -
O argumento
defaultsestá sendo preterido da funçãoqiskit.providers.convert_to_target()função.
Depreciações do QPY
- Como parte da descontinuação do pacote Qiskit Pulse, a serialização de cargas úteis baseadas em
qiskit.pulse.ScheduleBlock-também está sendo descontinuada. Em particular, a passagem de objetosqiskit.pulse.ScheduleBlockpara o argumento dos programas na funçãoqiskit.qpy.dump().
Depreciações do Transpiler
-
Depreciado
StochasticSwapque foi substituído porSabreSwap. Se a classe for chamada a partir da função transpile, a alteração seria, por exemplo:from qiskit import transpile from qiskit.circuit import QuantumCircuit from qiskit.transpiler import CouplingMap from qiskit.providers.fake_provider import GenericBackendV2 qc = QuantumCircuit(4) qc.h(0) qc.cx(0, range(1, 4)) qc.measure_all() cmap = CouplingMap.from_heavy_hex(3) backend = GenericBackendV2(num_qubits=cmap.size(), coupling_map=cmap) tqc = transpile( qc, routing_method="stochastic", layout_method="dense", seed_transpiler=12342, target=backend.target )para:
tqc = transpile( qc, routing_method="sabre", layout_method="sabre", seed_transpiler=12342, target=backend.target )Já para um gerente de passes, a mudança seria:
passmanager = PassManager(StochasticSwap(coupling, 20, 13)) new_qc = passmanager.run(qc)para:
passmanager = PassManager(SabreSwap(backend.target, "basic")) new_qc = passmanager.run(qc) -
A passagem do transpilador
ConvertConditionsToIfOpsfoi descontinuado e será removido no Qiskit 2.0.0. Essa classe está obsoleta porque o modelo de dados subjacente paraInstruction.conditiondo qual essa passagem está convertendo foi descontinuada e será removida em 2.0.0. -
O fornecimento de portas personalizadas por meio do argumento
basis_gatesestá obsoleto tanto para otranspile()egenerate_preset_pass_manager(). Essa funcionalidade será removida no Qiskit 2.0. As portas personalizadas ainda são compatíveis com o modeloTargete podem ser fornecidas por meio do argumentotarget. É possível criar umaTargetdo zero ou usar o métodoTarget.from_configuration()com o argumentocustom_name_mapping. Por exemplo:from qiskit.circuit.library import XGate from qiskit.transpiler.target import Target basis_gates = ["my_x", "cx"] custom_name_mapping = {"my_x": XGate()} target = Target.from_configuration( basis_gates=basis_gates, num_qubits=2, custom_name_mapping=custom_name_mapping ) -
Como parte da descontinuação do pacote Qiskit Pulse, os aspectos relacionados ao pulso na
qiskit.transpiler.Targetclasse estão sendo descontinuados. Dentre eles:update_from_instruction_schedule_map()has_calibration()get_calibration()instruction_schedule_map()
Além disso, as seguintes passagens do transpiler também estão sendo descontinuadas:
-
O argumento
inst_mapemgenerate_preset_pass_manager(),from_configuration(),PassManagerConfiginicializador egenerate_scheduling()está sendo preterido. -
O argumento
calibrationem métodosInstructionProperties()está sendo preterido. -
O seguinte
transpile()egenerate_preset_pass_manager()são preteridos em favor da definição de um argumento personalizadoTarget:instruction_durations,timing_constraints, ebackend_properties. Esses argumentos podem ser usados para criar um alvo comTarget.from_configuration():Target.from_configuration( ... backend_properties = backend_properties, instruction_durations = instruction_durations, timing_constraints = timing_constraints ) -
O método
PassManagerConfig.from_backend()deixará de oferecer suporte a entradas do tipoBackendV1no parâmetro backend em uma versão futura, não antes de 2.0.BackendV1está obsoleto e as implementações devem migrar paraBackendV2.
Páginas Obsoletos
-
O módulo
qiskit.result.mitigationfoi descontinuado e será removido no Qiskit 2.0. A descontinuação inclui os atributosLocalReadoutMitigatoreCorrelatedReadoutMitigatorbem como as funções utilitárias associadas. Sua funcionalidade foi substituída pelo pacote mthree, encontrado em https://github.com/Qiskit/qiskit-addon-mthree. -
Como parte da descontinuação do pacote Qiskit Pulse, as seguintes funções e classes também estão sendo descontinuadas:
Correções de bugs
-
Foi corrigida uma regressão de desempenho em
QuantumCircuit.assign_parameters()introduzida no Qiskit 1.2.0 ao chamar o método em um loop apertado, o que fazia com que apenas um pequeno número de parâmetros de um circuito altamente paramétrico fosse vinculado a cada iteração. Se possível, é ainda mais eficiente chamarassign_parameters()apenas uma vez, com todas as atribuições ao mesmo tempo, pois isso reduz a proporção de tempo gasto na normalização da entrada e na sobrecarga de verificação de erros. -
Para
BasicSimulatora entradabasis_gatesna instância de configuração retornada pelo métodoconfiguration()agora é uma lista em vez de uma instânciadict_keys, correspondendo ao tipo esperado e permitindo que a instância de configuração seja copiada em profundidade. -
Foi corrigido um problema com
DAGCircuit.apply_operation_back()eDAGCircuit.apply_operation_front()onde, anteriormente, se você definisse um objetoClbitpara a entrada do argumentoqargs, ele seria aceito silenciosamente. Isso foi corrigido para que a incompatibilidade de tipos seja identificada corretamente e uma exceção seja levantada. -
Corrigido um decorador ausente no
C3SXGateque o fazia falhar se oGate.to_matrix()fosse chamado. A matriz de porta agora está retornando como esperado. -
Foi corrigido um erro no
QuantumCircuit.assign_parameters()que ocorria ao atribuir parâmetros a portas padrão cuja definição já havia sido acionada. Nesse caso, os novos valores não foram propagados corretamente para as instâncias do portão. Embora o circuito em si ainda tenha sido compilado conforme o esperado, a inspeção das operações individuais ainda mostraria o parâmetro antigo.Por exemplo:
from qiskit.circuit.library import EfficientSU2 circuit = EfficientSU2(2, flatten=True) circuit.assign_parameters([1.25] * circuit.num_parameters, inplace=True) print(circuit.data[0].operation.params) # would print θ[0] instead of 1.25Corrigido #13478.
-
Corrigido um bug com o emaranhamento de
"circular"e"sca"paraNLocalcircuitos e seus derivados. Para blocos de emaranhamento de mais de 2 qubits, o emaranhamento circular estava perdendo algumas conexões. Por exemplo, para 4 qubits e um tamanho de bloco de 3, o código usado anteriormente:[(2, 3, 0), (0, 1, 2), (1, 2, 3)]mas agora está adicionando corretamente as conexões
(3, 0, 1):[(2, 3, 0), (3, 0, 1), (0, 1, 2), (1, 2, 3)]Dessa forma, os emaranhados
"circular"e"sca"usam blocos de emaranhamentonum_qubitspor camada. -
Adicione mais portas de Clifford à passagem do
CollectCliffordspassagem do transpilador. Em particular, adicionamos os portõesECRGate,DCXGate,iSwapGate,SXGateeSXdgGatea essa passagem do transpilador. -
Foi corrigido um erro no
QuantumCircuit.decompose()em que os objetos que podiam ser sintetizados comHighLevelSynthesiseram primeiro sintetizados e depois decompostos imediatamente (ou seja, eram decompostos duas vezes em vez de uma). Isso afetou portões comoMCXGateouClifford, entre outros. -
Corrigido um bug no
QuantumCircuit.decompose()em que os objetos de alto nível sem uma definição não eram decompostos se fossem explicitamente definidos por meio do argumento"gates_to_decompose". Por exemplo, anteriormente, o seguinte não executava uma decomposição, mas agora funciona como esperado:from qiskit import QuantumCircuit from qiskit.quantum_info import Clifford from qiskit.transpiler.passes import Decompose cliff = Clifford(HGate()) circuit = QuantumCircuit(1) circuit.append(cliff, [0]) decomposed = Decompose(gates_to_decompose=["clifford"])(circuit) -
Anteriormente, a passagem do
HighLevelSynthesispass do transpilador sintetizava uma instrução para a qual um plug-in de síntese estava disponível, independentemente de a instrução já ser suportada pelo destino ou por uma parte da instrução explicitamente passadabasis_gates. Esse comportamento foi corrigido, de modo que essas instruções já suportadas não são mais sintetizadas. -
A passagem de transpilação
InverseCancellationagora irá recursar emControlFlowOpoperações presentes em umQuantumCircuit. Anteriormente, a passagem ignorava os pares de portas inversas dentro dos blocos de fluxo de controle que poderiam ter sido cancelados. Consulte #13437 para obter mais detalhes. -
Corrigir um bug no
Isometrydevido a uma asserção desnecessária, que levou a um erro emUnitaryGate.control()quando oUnitaryGatetinha mais de dois qubits. -
O atributo
QuantumCircuit.parametersagora estará corretamente vazio ao usarQuantumCircuit.copy_empty_like()em um circuito paramétrico. Anteriormente, um cache interno era copiado sem invalidação. Correção #12617. -
QuantumCircuit.depth()agora tratará corretamente as operações que não têm operandos, comoGlobalPhaseGate. -
QuantumCircuit.depth()agora contará as variáveis e os clbits usados em expressões em tempo real como parte do cálculo de profundidade. -
Corrigir a passagem do
SolovayKitaevao carregar aproximações básicas de um arquivo.npyexistente. Anteriormente, o carregamento de uma aproximação armazenada que permitia reduções adicionais (por exemplo, devido a cancelamentos de portas) podia causar uma falha no tempo de execução. Além disso, a diferença de fase global do produto de porta U(2) e da representação SO(3) foi perdida durante um procedimento de salvar e recarregar. Correções Qiskit/qiskit#12576. -
Foi corrigido um erro quando
SparsePauliOp.paulisé definido como umPauliListcom fase diferente de zero, em que as chamadas subsequentes a vários métodosSparsePauliOpproduziam resultados incorretos. Agora, quandoSparsePauliOp.paulisé definido como umPauliListcom fase diferente de zero, a fase é absorvida emSparsePauliOp.coeffse a fase da entradaPauliListé definida como zero. -
Foi corrigido um bug no site
qiskit.visualization.pulse_v2.interface.drawque não desenhava programações de pulso quando a função draw era chamada com um argumentoBackendV2argumento. Como o backend do V2 não informa as frequências dos canais de hardware, o desenho gerado mostrará "no freq" abaixo do rótulo de cada canal. -
Foi corrigido um problema com
dag_drawer()eDAGCircuit.draw()quando se tentava visualizar uma instânciaDAGCircuitque continhaVarpara a qual o visualizador gerava uma exceção. Esse comportamento foi corrigido e a visualização esperada será gerada. -
O passe
VF2Layoutgeraria uma exceção quando fornecido com uma instânciaTargetsem restrições de conectividade. Esse seria o caso das metas da Aer 0.13. O problema agora está corrigido. -
Corrige um erro ao chamar o método
Gate.repeat(). Consulte #11990 para obter mais detalhes. -
Foi corrigido um bug que fazia com que o
Statevector.expectation_value()produzisse resultados incorretos para o operador de identidade quando o vetor de estado não era normalizado. -
O construtor
GenericBackendV2estava permitindo que você criasse backends malformados porque aceitava basis gates que não podiam ser alocados no tamanho de backend especificado. Ou seja, um backend com um único qubit não deve aceitar uma base com portas de dois qubits. -
ParameterExpressionfoi atualizado de modo que as instâncias totalmente vinculadas que se comparam às instâncias dos tipos numéricos incorporados do Python (comofloateint) também têm valores de hash que correspondem aos das outras instâncias. Essa alteração garante que esses tipos possam ser usados de forma intercambiável como chaves de dicionário. Consulte #12488. -
O analisador OpenQASM 2 (
qiskit.qasm2) agora pode tratar condicionais com inteiros que não cabem em um inteiro de 64 bits. Corrigido #12773. -
As portas personalizadas (aquelas decorrentes de uma instrução
gate) em programas importados do OpenQASM 2 agora terão umaGate.to_matrix()implementação. Anteriormente, eles não tinham definição de matriz, o que significa que as viagens de ida e volta pelo site OpenQASM 2 poderiam perder desnecessariamente a capacidade de derivar a matriz de porta. Observe, no entanto, que a matriz é calculada ao encontrar recursivamente as matrizes das definições de porta interna, como faz oOperatoro que pode ser menos eficiente do que antes da ida e volta. -
Anteriormente,
DAGCircuit.replace_block_with_op()permitia colocar uma operação den-qubit em um bloco demqubits, deixando o DAG em um estado inválido. Esse comportamento foi corrigido, e a tentativa gerará uma mensagem de erroDAGCircuitError. -
Fixo
Operator.power()quando chamado com potências não inteiras em uma matriz cuja forma Schur não é diagonal (por exemplo, a maioria das matrizes não unitárias). -
Operator.power()agora retornará de forma mais confiável o valor principal esperado de uma potência de matriz fracionária de uma matriz unitária com um valor próprio . Isso é complicado em geral, pois os efeitos de arredondamento de ponto flutuante podem fazer com que uma matriz tenha um autovalor no lado negativo do corte de ramificação (mesmo que sua relação matemática exata não tenha), e a imprecisão em várias chamadas BLAS pode encontrar falsamente o lado errado do corte de ramificação.Operator.power()agora desloca o local do corte de ramificação para potências de matriz para uma pequena rotação complexa longe de . Isso não resolve o problema, apenas o desloca para um local onde é muito menos provável que ele seja perceptível para os tipos de operadores que normalmente aparecem. Use o novo parâmetrobranch_cut_rotationpara ter mais controle sobre isso.Consulte #13305.
-
Corrigido um não-determinismo baseado em processo no
SparsePauliOp.to_matrix(). A ordem exata das operações de ponto flutuante na soma variava anteriormente por processo, mas agora será idêntica entre diferentes invocações do mesmo script. Consulte #13413. -
Target.has_calibration()foi atualizado de modo a não gerar uma exceção para uma instrução que tenha sido adicionada ao destino comNonepara suas propriedades de instrução. Correções #12525.