Notas de versão do Qiskit SDK 1.1
1.1.2
Prelúdio
O Qiskit 1.1.2 é uma versão menor de correção de bugs para a série 1.1.
Correções de bugs
-
Corrigido um bug no
BitArray.from_counts()eBitArray.from_samples(). Anteriormente, isso gerava um erro se fossem fornecidos dados contendo apenas zeros e nenhum valor para o argumento opcionalnum_bits. Agora eles produzem umBitArraycomBitArray.num_bitsdefinido como 1. -
Corrigido um decorador ausente no
C3SXGateque fazia com que ele falhasse se oGate.to_matrix()fosse chamado. A matriz de porta agora está retornando como esperado. -
Adicionados os portões de Clifford ausentes à passagem do
CollectCliffordspassagem do transpilador. Em particular, adicionamos os portõesECRGate,DCXGate,iSWAPGate,SXGateeSXdgGatea essa passagem do transpilador. -
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. -
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 problema com
dag_drawer()eDAGCircuit.draw()quando se tentava visualizar uma instânciaDAGCircuitque continhaVarfios. O visualizador gerava uma exceção ao tentar fazer isso, o que foi corrigido para que a visualização esperada seja gerada. -
O construtor
GenericBackendV2permitia anteriormente a construção de backends malformados porque aceitava portas de base que não podiam ser alocadas devido ao tamanho do backend. Por exemplo, um backend com um único qubit poderia aceitar anteriormente uma base com portas de dois qubits. -
O analisador OpenQASM 2 (
qiskit.qasm2) agora pode tratar condicionais com números inteiros que não cabem em um número inteiro de 64 bits. Corrigido #12773. -
Anteriormente,
DAGCircuit.replace_block_with_op()permitia que uma operação den-qubit fosse colocada em um bloco demqubits, deixando o DAG em um estado inválido. Esse comportamento foi corrigido, e qualquer tentativa de fazer isso agora gerará um erroDAGCircuitErrorcomo esperado.
1.1.1
Prelúdio
O Qiskit 1.1.1 é uma versão menor de correção de bugs para a série 1.1.
Correções de bugs
-
Corrigir um bug no
Isometrydevido a uma asserção desnecessária, que levou a um erro emUnitaryGate.control()quando oUnitaryGatetinha mais de dois qubits. -
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. -
Foi corrigido um bug no site
qiskit.visualization.pulse_v2.interface.draw()que 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. -
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. -
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. -
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. -
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.
1.1.0
Prelúdio
A versão do Qiskit 1.1.0 é uma versão de recursos secundários que inclui uma infinidade de novos recursos e correções de bugs. Os destaques desse lançamento são:
O suporte a variáveis clássicas tipadas foi adicionado ao
QuantumCircuit. Essas variáveis clássicas podem ser especificadas como entradas ou como variáveis de escopo em um sistema de controle de fluxoQuantumCircuitonde, por exemplo, armazenam a saída de medições de qubit ou operações de fluxo de controle de destino. O suporte para, por exemplo, definir parâmetros de porta ou variáveis de saída será adicionado no futuro.Os dois métodos padrão de síntese de qubit que são usados internamente pelo transpilador na passagem
UnitarySynthesisforam reimplementados em Rust. Isso resulta em uma aceleração significativa do tempo de execução ao decompor duas matrizes unitárias de qubit. Como consequência, o tempo de execução da transpilação com o nível de otimização 3 foi significativamente aprimorado onde a execuçãoUnitarySynthesisincorria em uma grande sobrecarga de tempo de execução historicamente. Essa versão também começa a ser executadaUnitarySynthesiscomo parte do estágio de otimização no nível de otimização 2 devido a essas melhorias no desempenho do tempo de execução.Além disso, os métodos numéricos usados em
Isometryforam transferidos para o Rust, permitindo grandes aumentos de velocidade no tempo de execução, especialmente para a síntese de portas unitárias controladas. A decomposição para os sistemas multicontroladosXGateePhaseGatefoi aprimorada, resultando em uma redução no número de portas usadas na síntese em mais de duas ordens de magnitude.Várias novas passagens de transpilação foram introduzidas no Qiskit, o que gera aumentos significativos na velocidade de execução e, ao mesmo tempo, diminui o tamanho dos circuitos quânticos transpilados em muitos casos. Especificamente,
ElidePermutationseStarPreRoutingdemonstraram ter um impacto significativo na qualidade da saída do roteamento e no tempo de execução eRemoveFinalResetpodem melhorar os circuitos quânticos que incluem redefinições.Os gerenciadores de passes padrão foram aprimorados, estendendo-os com os recém-introduzidos passes do transpilador. Em particular, o gerenciador de passagens predefinido de nível 2 de otimização do site
generate_preset_pass_managere usado internamente pelotranspile()foi refatorado para ter uma melhor relação entre o tempo de execução e o esforço de otimização, a fim de servir como um gerenciador de passes padrão em versões futuras. Embora essa versão não altere o padrão para usar o nível 2, ela é normalmente uma opção melhor do que usar o nível 1 ou 3.Novas implementações primitivas genéricas do V2 foram adicionadas,
BackendEstimatorV2eBackendSamplerV2para complementar as implementações existentes baseadas em vetor de estado completo.Alterações no suporte à plataforma: Python 3.8 está obsoleto a partir do Qiskit 1.1.0 e não terá mais suporte em 1.3.0, e arm64 macOS foi promovido a suporte de nível 1.
Recursos dos circuitos
-
Os métodos
QuantumCircuit.power(),Gate.power(), bem como os métodos similares em subclasses de subclasses deGate(como o deSGate), todos têm um novo argumento adicionalannotatedque é usado para retornar um objetoAnnotatedOperationao aplicar uma potência a uma porta ou circuito. O valor padrão deFalsecorresponde ao comportamento existente. Além disso, para portas padrão com um métodopowerexplicitamente definido, o argumentoannotatednão tem efeito. Por exemplo, tantoSGate().power(1.5, annotated=False)quantoSGate().power(1.5, annotated=True)retornam umPhaseGate. Uma diferença no valor deannotatedse manifesta para portas sem um método de potência explicitamente definido. O valor deFalseretorna umUnitaryGate, exatamente como antes, enquanto o valor deTrueretorna umAnnotatedOperationque representa a instrução modificada com o "modificador de potência". -
Adicionado um novo argumento
ctrl_stateaoQuantumCircuit.mcp()eMCPhaseGate.O
QuantumCircuit.mcp()e a classeMCPhaseGateforam atualizados para incluir um parâmetroctrl_state. Esse aprimoramento permite que os usuários especifiquem o estado de controle da porta de fase multicontrolada. O parâmetro pode aceitar um valor inteiro ou uma cadeia de bits e, por padrão, controla o estado "1" se não for fornecido.from qiskit import QuantumCircuit qc = QuantumCircuit(4) qc.mcp(0.2,[0,1,2],3,ctrl_state=2) -
Adicionado um novo argumento
ctrl_stateaoQuantumCircuit.mcx().O método
QuantumCircuit.mcx()na biblioteca de circuitos quânticos foi aprimorado para incluir um parâmetro ctrl_state, permitindo que os usuários especifiquem o estado de controle da porta X multicontrolada. Esse parâmetro pode aceitar um valor decimal ou uma cadeia de bits e, por padrão, controla o estado "1" se não for fornecido.from qiskit import QuantumCircuit qc = QuantumCircuit(3, 3) qc.mcx([0, 1], 2, ctrl_state="00") -
A
QuantumCircuitagora pode conter variáveis clássicas tipadas:from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister from qiskit.circuit.classical import expr, types qr = QuantumRegister(2, "q") cr = ClassicalRegister(2, "c") qc = QuantumCircuit(qr, cr) # Add two input variables to the circuit with different types. a = qc.add_input("a", types.Bool()) mask = qc.add_input("mask", types.Uint(2)) # Test whether the input variable was true at runtime. with qc.if_test(a) as else_: qc.x(0) with else_: qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Add a typed variable manually, initialized to the same value as the classical register. b = qc.add_var("b", expr.lift(cr)) qc.reset([0, 1]) qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Store some calculated value into the `b` variable. qc.store(b, expr.bit_and(b, cr)) # Test whether we had equality, up to a mask. with qc.if_test(expr.equal(expr.bit_and(b, mask), mask)): qc.x(0)Essas variáveis podem ser especificadas como entradas para o circuito ou como variáveis de escopo. O objeto de circuito ainda não tem suporte para representar saídas de variáveis clássicas tipadas, mas isso será adicionado mais tarde, quando o hardware e as interfaces de resultados estiverem em uma posição mais favorável para suportá-lo. Os circuitos que representam um bloco de um escopo interno também podem capturar variáveis de escopos externos.
Uma variável é um nó
Varque agora pode conter um tipo arbitrário e representa um local de memória exclusivo dentro de seu intervalo ativo quando adicionado a um circuito. Eles podem ser construídos em um circuito usandoQuantumCircuit.add_var()eQuantumCircuit.add_input()ou em um nível inferior usandoVar.new().As variáveis podem ser armazenadas manualmente, usando a instrução
Storee seu método de circuito correspondenteQuantumCircuit.store(). Isso inclui escrever paraClbiteClassicalRegisterenvolvidas em nósVarnós.As variáveis podem ser usadas sempre que as expressões clássicas (consulte
qiskit.circuit.classical.expr) são válidas. Atualmente, essas são as expressões de destino das operações de fluxo de controle, embora planejemos expandi-las para parâmetros de porta no futuro, à medida que o sistema de tipos e expressões for ampliado.Consulte Computação clássica em tempo real para obter mais informações sobre essas variáveis e o modelo de dados associado.
Eles são compatíveis com todo o transpilador, por meio da serialização QPY (
qiskit.qpy), OpenQASM 3 export (qiskit.qasm3) e têm suporte inicial por meio dos visualizadores de circuitos (consulteQuantumCircuit.draw()).NotaAs novas variáveis clássicas e o armazenamento levarão algum tempo para serem compatíveis com o hardware e os back-ends do simulador. Elas não são compatíveis com as interfaces de primitivos (
qiskit.primitives), mas provavelmente informarão essas interfaces à medida que elas evoluírem. -
O módulo clássico de expressões em tempo real
qiskit.circuit.classicalagora pode representar a indexação e o deslocamento de bits de inteiros sem sinal e de bits semelhantes (por exemploClassicalRegister). Por exemplo, agora é possível comparar um registro com a mudança de bits de outro:from qiskit.circuit import QuantumCircuit, ClassicalRegister from qiskit.circuit.classical import expr cr1 = ClassicalRegister(4, "cr1") cr2 = ClassicalRegister(4, "cr2") qc = QuantumCircuit(cr1, cr2) with qc.if_test(expr.equal(cr1, expr.shift_left(cr2, 2))): passO Qiskit também pode representar uma condição que indexa dinamicamente em um registro:
with qc.if_test(expr.index(cr1, cr2)): pass -
O desempenho da construção de
NLocale suas subclasses de biblioteca de circuitos derivadas (por exemploEfficientSU2eRealAmplitudes) melhorou significativamente, quando os sub-blocos de rotação e/ou emaranhamento são aplicações simples de uma única porta da biblioteca padrão Qiskit. Como esses circuitos são construídos de forma preguiçosa, talvez você não veja a melhoria imediatamente na instanciação da classe, mas sim no primeiro acesso à sua estrutura interna. As melhorias no desempenho são da ordem de dez vezes mais rápidas. -
QuantumCircuit.append()agora tem um argumento de palavra-chavecopy, cujo padrão éTrue. Quando uma instrução com parâmetros de tempo de execução (ParameterExpressions) é anexada a um circuito, por padrão, o circuito sempre cria uma cópia da instrução para que, seQuantumCircuit.assign_parameters()tentar alterar a instrução no local, isso não afetará outras referências à mesma instrução. Agora, a configuraçãocopy=Falsepermite que você substitua isso, de modo que você pode evitar a penalidade de cópia se souber que suas instruções não serão usadas em outros locais. -
QuantumCircuit.compose()agora tem um argumento de palavra-chavecopy, cujo padrão éTrue. Por padrão,compose()copia todas as instruções, de modo que as mutações de um circuito não afetem nenhum outro. Secopy=False, as instruções do outro circuito passarão a pertencer diretamente ao novo circuito, o que pode envolver a mutação delas no local. O outro circuito não deve ser usado posteriormente, nesse caso. -
O tempo de construção de
QuantumVolumefoi significativamente aprimorado, na ordem de 10x ou um pouco mais. As portas internas do SU4 agora também usarão mais bits de aleatoriedade durante sua geração, o que resulta em circuitos de volume mais representativos, especialmente em grandes larguras e profundidades. -
QuantumVolumeagora tem um argumento de palavra-chaveflatten. O padrão éFalse, em que o circuito construído contém uma única instrução que, por sua vez, contém a estrutura real do volume. Se definido comoTrue, o circuito terá diretamente as matrizes SU4 volumétricas. -
UnitaryGateagora aceita um argumento opcionalnum_qubits. O único efeito disso é pular a inferência da contagem de qubits, o que pode ser útil para o desempenho quando muitas portas estão sendo construídas. -
QuantumCircuittem vários métodos novos para trabalhar e inspecionar variáveis manuaisVarvariáveis manuais.Consulte Trabalhando com dados clássicos digitados em tempo real para obter uma discussão mais aprofundada sobre todos eles.
Os novos métodos são:
add_var()add_input()add_capture()add_uninitialized_var()get_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()store()
Além disso, há vários novos atributos dinâmicos em
QuantumCircuitem torno dessas variáveis: -
ControlFlowOpe suas subclasses agora têm um métodoiter_captured_vars()que retornará um iterador sobre as variáveis exclusivas capturadas em qualquer um de seus blocos imediatos. -
DAGCircuittem vários métodos novos para trabalhar e inspecionar variáveis manuaisVarvariáveis manuais. Elas são amplamente equivalentes às suasQuantumCircuitexceto pelo fato de que osDAGCircuitsão otimizados para acesso programático com objetos já definidos, enquanto os métodosQuantumCircuitsão mais focados no uso humano interativo.Os novos métodos são:
add_input_var()add_captured_var()add_declared_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()
Há também novos atributos públicos:
-
DAGCircuit.wiresagora também conterá quaisquerVarvariáveis manuais no circuito, já que elas também são fluxos de dados clássicos. -
Um novo método,
Var.new()é adicionado para construir manualmente uma variável clássica em tempo real que possui sua própria memória. -
QuantumCircuit.compose()tem dois argumentos de palavra-chave necessários,var_remapeinline_captures, para oferecer melhor suporte a variáveis clássicas em tempo real.var_remappode ser usado para reescrever os nósVarnós no argumento do circuito à medida que suas instruções são incorporadas ao circuito básico. Isso pode ser usado para evitar conflitos de nomes.inline_capturespode ser definido comoTrue(o padrão éFalse) para vincular todos os nósVarnós rastreados como "capturas" no circuito do argumento com os mesmosVarnós no circuito base, sem tentar redeclarar as variáveis. Isso pode ser usado, em combinação com o manuseio deQuantumCircuit.copy_empty_like()vars_mode="captures", para construir um circuito camada por camada, contendo variáveis. -
DAGCircuit.compose()tem um novo argumento de palavra-chave,inline_captures, que pode ser definido comoTruepara incorporar nós "capturados"Varno circuito do argumento para o circuito base sem redeclará-los. Em conjunto com a opçãovars_mode="captures"de vários métodosDAGCircuitisso pode ser usado para combinar DAGs que operam nas mesmas variáveis. -
QuantumCircuit.copy_empty_like()eDAGCircuit.copy_empty_like()têm um novo argumento de palavra-chave,vars_mode, que controla como os nós que possuem memóriaVarsão rastreados na saída. Por padrão ("alike"), as variáveis são declaradas no mesmo modo de entrada/capturado/local que a fonte. Isso pode ser definido como"captures"para converter todas as variáveis em capturas (útil comcompose()) ou"drop"para removê-las. -
Um novo argumento da palavra-chave
vars_modefoi adicionado aosDAGCircuitmethods:que tem o mesmo significado que tem para
copy_empty_like(). -
Todas as "portas padrão" na biblioteca de circuitos (
qiskit.circuit.library) agora podem ser especificadas pelo nome da string para as operações de entrelaçamento em circuitosTwoLocalcircuitos, comoRealAmplitudeseEfficientSU2.
Recursos primitivos
-
A implementação
BackendEstimatorV2deBaseEstimatorV2foi adicionada. Esse estimador suportaBackendV1eBackendV2.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import SparsePauliOp, random_hermitian backend = Fake7QPulseV1() estimator = BackendEstimatorV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) observable = SparsePauliOp("Z" * n_qubits) isa_circuit = transpile(circuit, backend=backend, optimization_level=1) isa_observable = observable.apply_layout(isa_circuit.layout) job = estimator.run([(isa_circuit, isa_observable)], precision=0.01) result = job.result() print(f"> Expectation value: {result[0].data.evs}") print(f"> Standard error: {result[0].data.stds}") print(f"> Metadata: {result[0].metadata}") -
A implementação
BackendSamplerV2deBaseSamplerV2foi adicionada. Esse sampler é compatível comBackendV1eBackendV2que permitem a opçãomemorypara computar bitstrings.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendSamplerV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import random_hermitian backend = Fake7QPulseV1() sampler = BackendSamplerV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) circuit.measure_all() isa_circuit = transpile(circuit, backend=backend, optimization_level=1) job = sampler.run([isa_circuit], shots=100) result = job.result() print(f"> bitstrings: {result[0].data.meas.get_bitstrings()}") print(f"> counts: {result[0].data.meas.get_counts()}") print(f"> Metadata: {result[0].metadata}") -
Foram adicionados métodos para unir vários objetos
BitArrayobjetos ao longo de vários eixos.concatenate()juntar matrizes ao longo de um eixo existente das matrizes.concatenate_bits(): une matrizes ao longo do eixo de bits.concatenate_shots(): une matrizes ao longo do eixo de disparos.
ba = BitArray.from_samples(['00', '11']) print(ba) # BitArray(<shape=(), num_shots=2, num_bits=2>) # reshape the bit array because `concatenate` requires an axis. ba_ = ba.reshape(1, 2) print(ba_) # BitArray(<shape=(1,), num_shots=2, num_bits=2>) ba2 = BitArray.concatenate([ba_, ba_]) print(ba2.get_bitstrings()) # ['00', '11', '00', '11'] # `concatenate_bits` and `concatenates_shots` do not require any axis. ba3 = BitArray.concatenate_bits([ba, ba]) print(ba3.get_bitstrings()) # ['0000', '1111'] ba4 = BitArray.concatenate_shots([ba, ba]) print(ba4.get_bitstrings()) # ['00', '11', '00', '11'] -
Foram adicionados métodos para gerar um subconjunto do objeto
BitArraycortando ao longo de vários eixos.__getitem__()corte a matriz ao longo de um eixo existente da matriz.slice_bits(): corta a matriz ao longo do eixo de bits.slice_shots(): corta a matriz ao longo do eixo de disparo.
ba = BitArray.from_samples(['0000', '0001', '0010', '0011'], 4) print(ba) # BitArray(<shape=(), num_shots=4, num_bits=4>) print(ba.get_bitstrings()) # ['0000', '0001', '0010', '0011'] ba2 = ba.reshape(2, 2) print(ba2) # BitArray(<shape=(2,), num_shots=2, num_bits=2>) print(ba2[0].get_bitstrings()) # ['0000', '0001'] print(ba2[1].get_bitstrings()) # ['0010', '0011'] ba3 = ba.slice_bits([0, 2]) print(ba3.get_bitstrings()) # ['00', '01', '00', '01'] ba4 = ba.slice_shots([0, 2]) print(ba3.get_bitstrings()) # ['0000', '0010'] -
Adicionado um método
transpose()para transpor umBitArray.ba = BitArray.from_samples(['00', '11']).reshape(2, 1, 1) print(ba) # BitArray(<shape=(2, 1), num_shots=1, num_bits=2>) print(ba.transpose()) # BitArray(<shape=(1, 2), num_shots=1, num_bits=2>) -
Adicionado um método
expectation_values()para calcular os valores de expectativa dos operadores diagonais.ba = BitArray.from_samples(['01', '11']) print(ba.expectation_values(["IZ", "ZI", "01"])) # [-1. 0. 0.5] -
DataBinagora satisfaz o protocoloShapedprotocolo. Isso significa que cadaDataBinagora tem os atributos adicionaisshape(tupleint[,...]): a forma principal de cada entrada na instânciandim(int): o comprimento deshapesize(int): o produto das entradas deshape
A forma pode ser passada para o construtor.
-
Adicionados recursos semelhantes ao mapeamento para
DataBinou seja,__getitem__,__contains__,__iter__,keys(),values(), eitems().from qiskit import QuantumCircuit from qiskit.primitives import StatevectorSampler circuit = QuantumCircuit(1) circuit.h(0) circuit.measure_all() sampler = StatevectorSampler() result = sampler.run([circuit]).result() databin = result[0].data for creg, arr in databin.items(): print(creg, arr) for creg in databin: print(creg, databin[creg]) -
A subclasse
SamplerPubResultdePubResultfoi adicionada, a qual as implementações doBaseSamplerV2implementações podem retornar. O principal recurso adicionado nessa nova subclasse éjoin_data()que junta (um subconjunto de) o conteúdo dedataem um único objeto. Isso permite os seguintes padrões:job_result = sampler.run([pub1, pub2, pub3], shots=123).result() # assuming all returned data entries are BitArrays counts1 = job_result[0].join_data().get_counts() bistrings2 = job_result[1].join_data().get_bitstrings() array3 = job_result[2].join_data().array
Recursos dos provedores
- O
BasicSimulatorbaseado em python incluído nobasic_provideragora suporta a execução de todas as portas padrão de até 3 qubits definidas emqiskit.circuit.library.
Recursos do Pulse
-
Agora é possível atribuir parâmetros ao pulso
ScheduleeScheduleBlockespecificando o nome do parâmetro como uma cadeia de caracteres. O nome do parâmetro pode ser usado para atribuir valores a todos os parâmetros dentro dos camposScheduleouScheduleBlockque tenham o mesmo nome. Além disso, o nome do parâmetro de umParameterVectorpode ser usado para atribuir todos os valores do vetor simultaneamente (a lista de valores deve, portanto, corresponder ao comprimento do vetor). -
Os métodos
assign_parametersdeScheduleeScheduleBlockagora suportam a atribuição de umParameterVectora uma lista de valores de parâmetros simultaneamente, além de atribuir instâncias individuais deParametera valores individuais.
OpenQASM Características
- O exportador OpenQASM 3 oferece suporte a nós de armazenamento manual
Varem circuitos.
Recursos do QPY
- O FORMATO QPY (
qiskit.qpy) foi adicionada a versão 12 do formato, que inclui suporte para variáveisVarde memória. Consulte a Versão 12 para obter mais detalhes sobre as alterações de formato.
Recursos de informação quântica
-
Foi adicionado um novo método
apply_layout()que é equivalente aapply_layout(). Esse método é usado para aplicar um layoutTranspileLayoutlayout do transpilador a umPauliobservável que foi criado para um circuito de entrada. Isso permite trabalhar com implementaçõesBaseEstimator/BaseEstimatorV2e a transpilação local quando a entrada é do tipoPauli. Por exemplo:from qiskit.circuit.library import RealAmplitudes from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import GenericBackendV2 from qiskit.quantum_info import Pauli from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager psi = RealAmplitudes(num_qubits=2, reps=2) H1 = Pauli("XI") backend = GenericBackendV2(num_qubits=7) estimator = BackendEstimatorV2(backend=backend) thetas = [0, 1, 1, 2, 3, 5] pm = generate_preset_pass_manager(optimization_level=3, backend=backend) transpiled_psi = pm.run(psi) permuted_op = H1.apply_layout(transpiled_psi.layout) res = estimator.run([(transpiled_psi, permuted_op, thetas)]).result()onde um circuito de entrada é transpilado localmente antes de ser passado para
run(). A transpilação expande o circuito original de 2 para 7 qubits (o tamanho debackend) e altera seu layout, que é então aplicado aH1usandoapply_layout()para refletir as transformações realizadas pelopm.run(). -
Adiciona o
PauliList.noncommutation_graph()eSparsePauliOp.noncommutation_graph()expondo a construção de gráficos sem comutação, reformulando o problema de agrupamento do operador de medição em um problema de coloração de gráfico. Isso permite que os usuários trabalhem diretamente com esses gráficos, por exemplo, para explorar algoritmos de coloração diferentes do usado peloSparsePauliOp.group_commuting(). -
O desempenho do
SparsePauliOp.to_matrix()foi bastante aprimorado para as formas densas e esparsas. Por padrão, ambos agora aproveitarão o paralelismo de threads disponível em seu sistema, sujeito à variável de ambienteRAYON_NUM_THREADS. Você pode forçar temporariamente a execução em série usando o novo argumento booleanoforce_serialparato_matrix().
Recursos de síntese
-
O
KMSSynthesisLinearFunctionplugin para sintetizar objetosLinearFunctionagora aceita duas opções adicionais:use_invertedeuse_transposed. Essas opções modificam a matriz na qual o algoritmo de síntese subjacente é executado, possivelmente invertendo-a e/ou transpondo-a, e depois ajustam adequadamente o circuito sintetizado. Ao variar essas opções, geralmente obtemos circuitos sintetizados diferentes e, em alguns casos, podemos obter resultados melhores do que com seus valores padrão. -
O
PMHSynthesisLinearFunctionplugin para sintetizar objetosLinearFunctionagora aceita várias opções adicionais. A opçãosection_sizeé passada para o método de síntese subjacente. As opçõesuse_invertedeuse_transposedmodificam a matriz na qual o algoritmo de síntese subjacente é executado, possivelmente invertendo-a e/ou transpondo-a, e depois ajustam adequadamente o circuito sintetizado. Ao variar essas opções, geralmente obtemos circuitos sintetizados diferentes e, em alguns casos, podemos obter resultados melhores do que com seus valores padrão. -
Adicionado um novo argumento,
use_dag, aoTwoQubitBasisDecomposer.__call__()eXXDecomposer.__call__()métodos. Esse argumento é usado para controlar se umDAGCircuité retornado ao chamar umTwoQubitBasisDecomposerouXXDecomposerem vez da instância padrãoQuantumCircuit. Por exemplo:from qiskit.circuit.library import CXGate from qiskit.quantum_info import random_unitary from qiskit.synthesis import TwoQubitBasisDecomposer decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="PSX") decomposer(random_unitary(4), use_dag=True)retornará um
DAGCircuitao chamar a instânciaTwoQubitBasisDecomposerinstânciadecomposer. -
LieTrotter.synthesize()agora usaQuantumCircuit.repeat()para gerar repetições adicionais de uma etapa de Trotter após a primeira etapa de Trotter. Isso reduz o número deQuantumCircuit.compose()chamadas em um fator derepse reduz significativamente o tempo de execução de operadores maiores. -
Adicionar um novo método de síntese
synth_permutation_reverse_lnn_kms()de permutações reversas para arquiteturas lineares do vizinho mais próximo usando o método Kutin, Moulton e Smithline. Esse algoritmo sintetiza a permutação reversa em qubits em uma arquitetura linear do vizinho mais próximo usando portas CX com profundidade . -
A classe
TwoQubitBasisDecomposerfoi reescrita em Rust, o que melhora muito o desempenho do tempo de execução. -
A classe
TwoQubitWeylDecompositionfoi reescrita em Rust para melhorar o desempenho.
Recursos do Transpiler
-
Estendeu a análise de comutação realizada por
CommutationCheckerpara trabalhar também com circuitos abstratos, ou seja, cada operação no circuito quântico de entrada é agora verificada quanto à sua representação matricial antes de prosseguir para a etapa de análise. Anteriormente, a análise de comutação era realizada apenas em circuitos físicos. Além disso, cada operação agora é verificada quanto à sua capacidade de ser armazenada em cache na biblioteca de comutação da sessão. Por exemplo, isso agora permite computar seAnnotatedOperationcomutar. Isso permite que as passagens do transpilador que dependem doCommutationCheckerinternamente, comoCommutativeCancellationsejam executadas durante os estágios iniciais de um pipeline de transpilação padrão (antes da tradução da base). -
A passagem do transpilador
ElidePermutationsé executado por padrão no estágio de inicialização para os níveis de otimização 2 e 3. Intuitivamente, a remoção deSwapGates ePermutationGates em um circuito virtual é quase sempre benéfica, pois torna o circuito mais curto e mais fácil de rotear. Como oOptimizeSwapBeforeMeasureé um caso especial deElidePermutationsele foi substituído pelo passeElidePermuationscomo parte do estágio de inicialização nos gerentes de passe de nível 3 de otimização. -
Adicionado um novo passe de otimização do transpilador,
ElidePermutationsque foi projetado para ser executado antes do Layout Stage e otimizará qualquerSwapGates ePermutationGates em um circuito por meio da permutação de qubits virtuais. Por exemplo, ao pegar um circuito comSwapGates:
removerá as trocas quando a passagem for executada:
from qiskit.transpiler.passes import ElidePermutations from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3) qc.h(0) qc.swap(0, 1) qc.swap(2, 0) qc.cx(1, 0) qc.measure_all() ElidePermutations()(qc).draw("mpl")
A passagem também define o conjunto de propriedades
virtual_permutation_layout, armazenando a permutação dos qubits virtuais no final do circuito que foi otimizado. -
O
HLSConfigagora tem dois argumentos opcionais adicionais. O argumentoplugin_selectionpode ser definido como"sequential"ou"all". Se definido como "sequencial" (padrão), para cada objeto de nível superior, aHighLevelSynthesisconsiderará os métodos especificados sequencialmente, na ordem em que aparecem na lista, parando no primeiro método capaz de sintetizar o objeto. Se for definido como "all", todos os métodos especificados serão considerados, e o melhor circuito sintetizado, de acordo complugin_evaluation_fn, será escolhido. O argumentoplugin_evaluation_fné um chamável opcional que avalia a qualidade do circuito quântico sintetizado; um valor menor significa um circuito melhor. Quando definido comoNone, a qualidade do circuito é o seu tamanho (ou seja, o número de portas que ele contém).O exemplo a seguir ilustra a nova funcionalidade:
from qiskit import QuantumCircuit from qiskit.circuit.library import LinearFunction from qiskit.synthesis.linear import random_invertible_binary_matrix from qiskit.transpiler.passes import HighLevelSynthesis, HLSConfig # Create a circuit with a linear function mat = random_invertible_binary_matrix(7, seed=37) qc = QuantumCircuit(7) qc.append(LinearFunction(mat), [0, 1, 2, 3, 4, 5, 6]) # Run different methods with different parameters, # choosing the best result in terms of depth. hls_config = HLSConfig( linear_function=[ ("pmh", {}), ("pmh", {"use_inverted": True}), ("pmh", {"use_transposed": True}), ("pmh", {"use_inverted": True, "use_transposed": True}), ("pmh", {"section_size": 1}), ("pmh", {"section_size": 3}), ("kms", {}), ("kms", {"use_inverted": True}), ], plugin_selection="all", plugin_evaluation_fn=lambda circuit: circuit.depth(), ) # synthesize qct = HighLevelSynthesis(hls_config=hls_config)(qc)No exemplo, executamos vários métodos de síntese com parâmetros diferentes, escolhendo o melhor circuito em termos de profundidade. Observe que, ao otimizar o site
circuit.size(), você escolheria um circuito diferente. -
Adicionado o passe
CommutativeCancellationao estágioinitdos gerenciadores de passagem predefinidos para os níveis de otimização 2 e 3. Isso permite que os gerenciadores de passagem predefinidos cancelem operações lógicas adicionais no início do pipeline de compilação. -
As seguintes passagens de análise agora aceitam restrições codificadas em um
Targetgraças a um novo argumento de entradatarget:As restrições de destino terão prioridade sobre as restrições fornecidas pelo usuário, para que haja coerência com o restante do pipeline do transpilador.
-
Adicionado um novo método
Layout.inverse()que é usado para obter o inverso de um objetoLayoutobjeto. Adicionado um novo métodoLayout.compose()que é usado para compor doisLayoutobjetos juntos. Adicionado um novo métodoLayout.to_permutation()que é usado para criar uma permutação correspondente a um objetoLayoutobjeto. -
Adicionada uma nova redução à passagem do
OptimizeAnnotatedpassagem do transpilador. Essa redução procura por operações anotadas (objetos do tipoAnnotatedOperationque consistem em uma operação de base e uma lista de modificadores de controle, inversos e de potência) com as seguintes propriedades:- a operação básica precisa ser sintetizada (ou seja, ainda não é compatível com o destino ou pertence à biblioteca de equivalência)
- o circuito de definição para pode ser expresso como - - com
Nesse caso, os modificadores podem ser movidos apenas para a parte . Como exemplo específico, os somadores controlados baseados em QFT têm a forma
control - [QFT -- U -- IQFT], que pode ser simplificada paraQFT -- control-[U] -- IQFT. Ao remover os controles sobreQFTeIQFTpartes do circuito, obtém-se um número significativamente menor de portas no circuito transpilado. -
Foram adicionados dois novos métodos à classe
DAGCircuitclasse:qiskit.dagcircuit.DAGCircuit.op_successors()retorna um iterador paraDAGOpNodesucessores de um nó, eqiskit.dagcircuit.DAGCircuit.op_successors()retorna um iterador para osDAGOpNodepredecessores de um nó. -
Adicionado um novo passe de transpilador,
RemoveFinalResetque removerá qualquer operaçãoResetque seja a instrução final em um fio de qubit. Por exemplo, um circuito com finalResets:
removerá as redefinições finais quando a passagem for executada:
from qiskit.transpiler.passes import RemoveFinalReset from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3, 1) qc.reset(0) qc.h(range(3)) qc.cx(1, 0) qc.measure(0, 0) qc.reset(range(3)) RemoveFinalReset()(qc).draw("mpl")
-
Adicionada uma nova passagem de transpilador
StarPreRoutingprojetada para identificar subcircuitos de conectividade em estrela e, em seguida, substituí-los por um roteamento linear ideal. Isso é útil para determinados circuitos que são compostos por essa conectividade de circuito, como Bernstein-Vazirani e QFT. Por exemplo:
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import StarPreRouting qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) StarPreRouting()(qc).draw("mpl")
Como alternativa, um gerenciador de passagens predefinidas existente pode ser ampliado:
from qiskit import QuantumCircuit from qiskit.transpiler import CouplingMap from qiskit.transpiler.passes import StarPreRouting from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager cm = CouplingMap.from_line(5) qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) pm = generate_preset_pass_manager(2, coupling_map=cm) pm.init += StarPreRouting() result = pm.run(qc) result.draw("mpl")
Recursos de visualização
- O texto e as Matplotlib gavetas de circuito (
QuantumCircuit.draw()) têm suporte mínimo para a exibição de expressões que envolvem variáveis manuais em tempo real. A operaçãoStoree as inicializações de variáveis ainda não são compatíveis; para circuitos dinâmicos de grande escala, recomendamos usar os recursos de exportação do OpenQASM 3 (qasm3.dumps()) para obter uma representação textual de um circuito.
Páginas Recursos
- Esta versão do Qiskit finaliza o suporte para NumPy 2.0. O Qiskit continuará a oferecer suporte aos sites NumPy 1.x e 2.x em um futuro próximo.
Notas da Atualização
-
Remove a codificação física das opções de estilo para o
plot_histogram(). Isso permite que os arquivos de estilo do Matplotlib sejam fielmente aplicados às figuras. Os usuários que desejarem ir além dos padrões definidos por Matplotlib podem criar seus próprios arquivos de estilo ou passar um objeto MatplotlibAxesparaplot_histograme pós-aplicar as personalizações. -
A função
transpile()foi atualizada para converter internamente entradas de backend do tipoBackendV1paraBackendV2o que permite que o pipeline de transpilação agora acesse as restrições de backend por meio de umTarget. Essa alteração não exige nenhuma ação do usuário.
Notas sobre atualização de circuitos
-
O uso do número aleatório de
QuantumVolumefoi alterado, portanto, você obterá um circuito diferente para uma semente fixa entre as versões mais antigas do Qiskit e esta versão. A geração aleatória-unitária agora usa mais bits de entropia, portanto, os circuitos grandes serão menos tendenciosos. -
As instâncias
UnitaryGatena definição de um circuitoQuantumVolumecircuito não terão mais um campolabeldefinido. Anteriormente, isso era definido como a stringsu4_<seed>, em que<seed>era um número de três dígitos que denotava a semente de uma instância interna do Numpy pRNG para esse portão. Fazer isso era um problema sério de desempenho, e a semente não deveria ter sido útil; se você precisar recuperar a matriz do gate, basta usar o métodoGate.to_matrix()método.
Notas sobre a atualização dos primitivos
- A função
make_data_bin()não cria mais e retorna umaDataBinsubclasse. Em vez disso, ele sempre retorna aDataBinclasse. No entanto, ele continua existindo para fins de compatibilidade com versões anteriores, embora acabe sendo descontinuado. Todos os usuários devem migrar para construir instânciasDataBindiretamente, em vez de instanciar subclasses como resultado demake_data_bin().
Notas de atualização dos fornecedores
-
Implementações de
BackendV2(eBackendV1) podem querer atualizar seus métodosrun()para rejeitar avidamente entradas que contenham variáveis clássicas tipadas (consulteqiskit.circuit.classical) e a instruçãoStorese não tiverem suporte para elas. A nova instruçãoStoreé tratada pelo transpilador como uma "diretriz" sempre disponível (comoBarrier); se os seus backends não suportarem essa instrução, ela não será detectada pela funçãotranspiler.Consulte Variáveis em tempo real para obter mais informações.
Notas de atualização do QPY
- O valor de
qiskit.qpy.QPY_VERSIONé agora 12.QPY_COMPATIBILITY_VERSIONpermanece inalterado em 10.
Notas sobre a atualização da síntese
- O
TwoQubitWeylDecompositionnão mais se auto-especializará em uma subclasse na criação. Esse era um detalhe interno da classeTwoQubitWeylDecompositionanteriormente, e não era um comportamento público documentado, pois todas as subclasses se comportavam da mesma forma e eram usadas apenas para despacho interno. No entanto, como esse comportamento foi descoberto, esta nota de versão serve para documentar que isso não ocorrerá mais e que todas as instâncias deTwoQubitWeylDecompositionserão do mesmo tipo. Não há alteração no comportamento dos métodos públicos da classe.
Notas sobre a atualização do Transpiler
- A predefinição
StagedPassManagerretornada para o nível de otimização 2 porgenerate_preset_pass_manager()elevel_2_pass_manager()foram reformuladas para oferecer um melhor equilíbrio entre tempo de execução e otimização. Isso significa que os circuitos de saída serão alterados em comparação com as versões anteriores. Se você precisar de um gerenciador de passes exato do nível 2 em versões anteriores, poderá criá-lo manualmente ou usá-lo em uma versão anterior e salvar os circuitos comqpypara carregar com uma versão mais recente.
Páginas Notas da Atualização
- A versão mínima suportada do Windows agora é o Windows 10. Em versões anteriores, não listamos explicitamente uma versão mínima compatível do Windows e, implicitamente, o Windows 7, 8 e 8.1 podem ter funcionado (mas nunca foram testados). Mas, devido ao fato de o Rust 1.78 ter deixado de oferecer suporte a versões mais antigas do Windows, os binários publicados do Qiskit em PyPI não oferecerão suporte a versões mais antigas do Windows a partir desta versão. Se você estiver usando uma versão mais antiga do Windows, provavelmente ainda poderá compilar o Qiskit a partir do código-fonte usando um compilador Rust mais antigo (a versão mínima do Rust suportada pelo Qiskit para compilação a partir do código-fonte é atualmente 1.70 ), mas as versões mais antigas do Windows não são uma plataforma suportada e não foram testadas.
Notas de descontinuação
-
O suporte para a execução do Qiskit com Python 3.8 foi descontinuado e será removido na versão do Qiskit 1.3.0. O 1.3.0 é a primeira versão após o Python 3.8 entrar em fim de vida útil e não ter mais suporte. [1] Isso significa que, a partir da versão 1.3.0, será necessário atualizar a versão Python que você está usando para Python 3.9 ou superior.
Descontinuidade de provedores
-
As classes básicas abstratas
ProvidereProviderV1agora estão obsoletas e serão removidas no Qiskit 2.0.0. A abstração oferecida por essas definições de interface não estava fornecendo um valor substancial; ela apenas encapsulava os atributosname,backendse umget_backend(). Um _provider_, como um conceito, continuará existindo como uma coleção de back-ends. Se você estiver implementando um provedor atualmente, poderá ajustar seu código simplesmente removendoProviderV1como a classe pai da sua implementação. Como parte disso, você provavelmente gostaria de adicionar uma implementação doget_backendpara compatibilidade com versões anteriores. Por exemplo:def get_backend(self, name=None, **kwargs): backends = self.backends(name, **kwargs) if len(backends) > 1: raise QiskitBackendNotFoundError("More than one backend matches the criteria") if not backends: raise QiskitBackendNotFoundError("No backend matches the criteria") return backends[0]
Depreciações de síntese
- O método
TwoQubitWeylDecomposition.specialize()está obsoleto e será removido na versão do Qiskit 2.0.0. Esse método nunca teve uma finalidade pública e não era seguro para ser chamado por um usuário final, pois alteraria a decomposição calculada no objeto e produziria campos inválidos no objeto. Ele só foi usado internamente para construir um novoTwoQubitWeylDecompositionobjeto. Apesar disso, ainda era uma parte documentada da API pública da classe e agora está sendo descontinuada sem nenhuma substituição em potencial. Nesta versão, ele sempre gerará umNotImplementedErrorquando chamado porque a subclasse de especialização foi removida como parte da reescrita do Rust da classe.
Depreciações do Transpiler
-
O passe
qiskit.transpiler.passes.CXCancellationfoi preterido em favor deInverseCancellationque é mais genérico.CXCancellationé totalmente equivalente semanticamente aInverseCancellation([CXGate()]). -
A passagem de transpilação
qiskit.transpiler.passes.ALAPScheduleagora está obsoleta. Sua descontinuação estava pendente desde o Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022. O passe é substituído porALAPScheduleAnalysisque é uma passagem de análise. -
A passagem de transpilação
qiskit.transpiler.passes.ASAPScheduleagora está obsoleta. Sua descontinuação estava pendente desde o Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022. Ele foi substituído peloASAPScheduleAnalysise o novo fluxo de trabalho de agendamento. -
A passagem de transpilação
qiskit.transpiler.passes.DynamicalDecouplingagora está obsoleta. Sua descontinuação estava pendente desde o Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022. Em vez disso, use oPadDynamicalDecouplingque executa a mesma função, mas exige que os passes de agendamento e análise de alinhamento sejam executados antes dele. -
A passagem de transpilação
qiskit.transpiler.passes.AlignMeasuresagora está obsoleta. Sua descontinuação estava pendente desde o Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022. Em vez disso, useConstrainedRescheduleque executa a mesma função e também suporta o alinhamento a restrições de tempo adicionais.
Descontinuidade da visualização
- Os parâmetros
show_idleeshow_barriernas gavetas da linha do tempo foram substituídos poridle_wireseplot_barriers, respectivamente, para corresponder aos parâmetros da gaveta do circuito. Seus nomes anteriores estão obsoletos e serão removidos na próxima versão principal. Os novos parâmetros são totalmente equivalentes.
Correções de bugs
-
Foi corrigido um problema com a função
qpy.dump()em que, quando o sinalizadoruse_symengineera definido como um objeto verdadeiro que era avaliado comoTrue, mas não era realmente o booleanoTrue, a carga útil QPY gerada era corrompida. Por exemplo, se você definiruse_symenginecomoHAS_SYMENGINEesse objeto é avaliado comoTruequando convertido como bool, mas não é de fatoTrue. -
Foi corrigido um problema com a função
circuit_drawer()function andQuantumCircuit.draw()ao carregar um estilo matplotlib por meio do arquivo de configuração do usuário. -
Foi corrigido um problema em que a passagem do
ConstrainedReschedulepass do transpilador anteriormente dava erro se o circuito contivesse uma instruçãoResetinstrução. Isso foi corrigido para que a passagem não apresente mais erros; no entanto, um hardware real pode se comportar de forma diferente do que o agendador do Qiskit supõe, especialmente para medições e redefinições no meio do circuito. O agendador do Qiskit levanta o endereçoRuntimeWarningse encontrar um circuito que contenha um dos dois. Corrigido #10354 -
Foi corrigido um problema com a classe
CommutationCheckerem que ocorria um erro se o atributonamede um portão fosse codificado em UTF8. Anteriormente, apenas nomes de portões com codificação ascii funcionavam. Corrigido #12501 -
Foi corrigido um problema com o
SparsePauliOp.apply_layout()ePauli.apply_layout()quando uma matriz inválida com índices duplicados ou negativos era passada para o argumentolayout. Anteriormente, isso não resultava em um erro e a transformação realizada não era válida. Esses métodos agora gerarão um erroQiskitErrorse índices duplicados ou índices negativos forem fornecidos como parte de um layout. -
Foi corrigido um problema de desempenho no
BackendSamplerV2eBackendEstimatorV2. Corrigido #12290 -
Foi corrigido um problema com o atributo
convert_to_target()em que o conversor ignorava incorretamente as instruções de fluxo de controle se elas fossem especificadas no atributoBackendConfiguration.supported_instructions, que é o local típico em que as instruções de fluxo de controle são especificadas em um objetoBackendConfigurationobjeto. Corrigido #11872. -
Foi corrigido um problema com o
circuit_drawer()ouQuantumCircuit.draw()ao usar a opção de saídampl, em que o programa travava se o circuito que estava sendo desenhado tivesse uma operação ControlFlow e a opçãofoldestivesse definida como -1 (ou seja, sem dobra). Corrigido #12012. -
Foi corrigido um erro na conversão de instruções de pulso personalizadas para o formato legado
qiskit.qobjlegado. O bug foi introduzido no Qiskit 1.0.0 e fez com que a conversão de instruções com formas de pulso personalizadas gerasse um erro. Após a correção, a conversão é realizada corretamente e o pulso personalizado é convertido paraWaveformcomo deveria. Corrigido #11828. -
Foi corrigido um bug em
transpile()foi corrigido quando as restrições personalizadasinstruction_durations,dtebackend_propertieseram ignoradas quando fornecidas ao mesmo tempo que um backend do tipoBackendV2. O comportamento após a correção agora é independente do fato de o backend fornecido ser do tipoBackendV1ou do tipoBackendV2. Da mesma forma, otiming_constraintspersonalizado agora é substituído pelas entradas dotarget, mas tem precedência sobre oBackendV1eBackendV2entradas. -
Chamada
EquivalenceLibrary.set_entry()agora atualizará corretamente o objeto gráfico interno da biblioteca. Anteriormente, os metadados eram atualizados, mas a estrutura do gráfico não era alterada, o que significa que usuários comoBasisTranslatorainda usariam as regras antigas. Corrigido #11958. -
O
EvolvedOperatorAnsatzagora lida corretamente com o caso em que o argumento do operador é uma lista vazia. Anteriormente, isso resultava em um erro. -
De agora em diante,
EvolvedOperatorAnsatznão terá nenhuma qregs quando houver zero qubits, em vez de ter uma instânciaQuantumRegistercom zero qubits. Esse comportamento se alinha de forma mais consistente com sua superclasseQuantumCircuit. -
O método
Instruction.repeat()agora move um conjuntoconditionpara o retorno externoInstructione deixa os portões internos de sua definição incondicionais. Anteriormente, o método deixava as instânciasClassicalRegisterdentro da definição interna, que era um estado inválido, e se manifestava como bugs aparentemente não relacionados posteriormente, como durante a transpilação ou exportação. Corrigido #11935. -
Foi corrigido um problema na passagem do
InverseCancellationem que, em alguns casos, ele cancelava incorretamente uma porta parametrizada auto-inversa mesmo que o valor do parâmetro não correspondesse. Corrigido #11815 -
Melhorar a decomposição das portas
MCXGateeMCPhaseGatesem usar qubits de ancilla, de modo que o número deCXGatecresça quadraticamente com o número de qubits e não exponencialmente. -
Foi corrigido um erro que travava a função
convert_to_target()quando as propriedades do qubit ( T1, T2 ou frequência) estão ausentes foi corrigido. Os valores de propriedade ausentes emQubitPropertiessão preenchidos comNone. -
BasePassManager.run()não vazará mais oPropertySetanterior em novos fluxos de trabalho quando chamado mais de uma vez. Anteriormente, o mesmoPropertySetcomo antes era usado para inicializar execuções subsequentes, o que poderia significar que informações de propriedade inválidas estavam sendo fornecidas às tarefas. O comportamento agora corresponde ao do Qiskit 0.44. Corrigido #11784. -
Pauli.evolve()agora trata corretamente os circuitos quânticos que contêm portas ECR. Anteriormente, eles não eram reconhecidos como portões Clifford, e um erro foi cometido. -
Corrigido um erro em
Pauli.evolve()em que a evolução por um circuito com um nome que correspondesse a certas portas de Clifford ('cx', 'cz' etc.) evoluiria o Pauli de acordo com o nome do circuito, e não pelo conteúdo do circuito. Esse erro ocorreu somente com a opção não padrãoframe='s'. -
Foi corrigido um problema de desempenho na função
qpy.load()ao desserializar cargas úteis QPY com um grande número de qubits ou clbits em um circuito. -
Foi corrigido um erro no tratamento do argumento
default_alignmentdobuild(). As entradas do tipoAlignmentKindagora são processados corretamente como alinhamentos padrão. -
Foi corrigido um bug na função
qiskit.pulse.utils.format_parameter_value()que convertia involuntariamente números inteiros grandes o suficiente em valores flutuantes ou causava arredondamentos inesperados. Consulte #11971 para obter detalhes. -
Corrigir um problema na classe
QDriftem que os coeficientes do Hamiltoniano eram anteriormente forçados a serem positivos, tomando o valor absoluto de cada coeficiente. Isso foi corrigido para que os sinais dos coeficientes negativos sejam adicionados novamente. -
Foi corrigido um bug no site
convert_durations_to_dt()em que a função aplicava cegamente uma conversão de segundos paradtem durações de circuitos, independentemente das unidades originais do atributo. Isso pode levar a ordens de magnitude erradas nas durações de circuito relatadas. -
Corrigido
SparsePauliOp.apply_layout()para funcionar corretamente com operadores de zero qubit. Por exemplo, se você criou anteriormente um qubit 0 e aplicou um layout como:op = SparsePauliOp("") op.apply_layout(None, 3)isso teria gerado um erro anteriormente. Agora, isso retornará corretamente um operador no formato:
SparsePauliOp(['III'], coeffs=[1.+0.j]) -
Foi corrigido um descuido na passagem do
Commuting2qGateRouteronde as permutações qreg não eram adicionadas ao conjunto de propriedades da passagem, de modo que precisavam ser rastreadas manualmente pelo usuário. Agora é possível acessar a permutação por meio da propriedadelayoutdo circuito de saída e conectar a passagem em qualquer pipeline de transpilação sem perda de informações. -
Correção de uma imprecisão de ponto flutuante ao dimensionar determinadas unidades de pulso entre segundos e nanossegundos. Se o pulso fosse definido simbolicamente, um erro desnecessário de ponto flutuante poderia ser introduzido pelo escalonamento de determinadas construções do site
symengine, o que poderia se manifestar em resultados inesperados quando os símbolos estivessem totalmente vinculados. Corrigido #12392. -
Os gerenciadores de passagem predefinidos de
transpile()não falharão mais em circuitos com fluxo de controle, se nenhum alvo de hardware ou conjunto de base-gate for especificado. Agora, eles tratarão esses alvos abstratos como se permitissem todas as operações de fluxo de controle. Corrigido #11906. -
O método
qiskit.instruction.Instruction.soft_compare()tem o objetivo de comparar se duas portas correspondem em seu nome, número de qubits, número de clbits e número de parâmetros. No entanto, havia um erro de digitação em que ele não verificava o número de qubits e o número de clbits para uma correspondência. Isso resolve o erro de digitação aparente. -
O plug-in padrão
initnão estava gerando corretamente uma mensagemTranspilerErrorquando chamado com um nível de otimização inválido. -
Foi corrigido um problema com o método
Operator.from_circuit()em que ele interpretava incorretamente a permutação final do layout, resultando em umOperatorinválido sendo construído. Anteriormente, o layout final era processado sem levar em conta o layout inicial, ou seja, a inicialização era incorreta para todos os circuitos quânticos que tinham um layout inicial não trivial. -
Foi corrigido um problema de desempenho no
PassManager.run()quando ele está sendo executado em vários circuitos em paralelo. Ele não gastará mais tempo serializando oPassManager(que é um requisito para a execução paralela) quando receber várias entradas, se for processar as entradas apenas em série. -
Parameterfoi atualizado para que as instâncias que se comparam iguais sempre tenham o mesmo hash. Anteriormente, apenas oParameter.uuidera comparado, portantoParametercom nomes diferentes poderiam ser comparadas igualmente se tivessem sido construídas usando um valor comum para o parâmetrouuid(que normalmente não é passado explicitamente). -
Corrigido um bug no site
plot_coupling_map()que fazia com que as bordas do mapa de acoplamento fossem coloridas incorretamente. Corrigido #12369. -
O analisador OpenQASM 2.0 (
qasm2.load()eqasm2.loads()) agora pode avaliar expressões de gate-angle incluindo operandos inteiros que transbordariam o inteiro de tamanho do sistema. Elas serão avaliadas em um contexto de ponto flutuante de precisão dupla, assim como o restante da expressão sempre foi. No entanto, um número inteiro arbitrariamente grande não será necessariamente representável com exatidão em ponto flutuante de precisão dupla, portanto, há uma chance de que, independentemente de como o circuito foi gerado, ele já tenha perdido toda a precisão numérica no módulo . -
Parameteras instâncias usadas como substitutos para as variáveis deinputnos programas de OpenQASM 3 agora terão seus nomes escapados para evitar colisões com portas incorporadas durante a exportação para OpenQASM 3. Anteriormente, poderia haver um conflito de nomes e o exportador geraria um OpenQASM 3 inválido. -
Corrigido o bug no
QuantumCircuit.draw()que fazia com que os dicionários de estilo personalizados da gaveta Matplotlib fossem modificados durante a execução. -
QuantumCircuit.append()comcopy=True(seu padrão) agora copiará corretamente as instruções parametrizadas porParameterExpressione não apenas por instânciasParameterinstâncias. -
O manuseio interno de calibrações de circuitos personalizados e
InstructionDurationsfoi transferido da funçãotranspile()para os passes individuais do transpilador:DynamicalDecoupling,DynamicalDecoupling. Antes, as durações das instruções das calibrações de circuito não eram levadas em conta, a menos que fossem incorporadas manualmente ao argumento de entrada instruction_durations, mas as passagens que precisam disso agora analisam o circuito e escolhem o valor de duração mais relevante de acordo com a seguinte ordem de prioridade: alvo > entrada personalizada > calibrações de circuito. -
Corrigido um erro no
transpile()em que o argumentonum_processessó seria usado sedtouinstruction_durationsfossem fornecidos.
Outras observações
-
O suporte para a plataforma arm64 macOS foi promovido de Tier 3 para Tier 1. Anteriormente, a plataforma estava no Nível 3 porque não havia um ambiente de CI disponível para testar o Qiskit na plataforma. Agora que o Github disponibilizou um ambiente arm64 macOS para projetos de código aberto [1], estamos testando a plataforma junto com as outras plataformas compatíveis com a Camada 1.
[ 1 ]
1.0.0rc1
Notas de atualização dos fornecedores
-
O módulo
qiskit.providers.fake_providerfoi migrado para o pacoteqiskit-ibm-runtimePython. Por esse motivo, os seguintes elementos na seçãoqiskit.providers.fake_providerforam removidos após sua descontinuação no Qiskit 0.46:qiskit.providers.fake_provider.FakeProviderqiskit.providers.fake_provider.FakeProviderForBackendV2qiskit.providers.fake_provider.FakeProviderFactoryqiskit.providers.fake_provider.fake_backends.FakeBackendV2- qualquer backend falso contido em
qiskit.providers.fake_provider.backends(acessível por meio do provedor) qiskit.providers.fake_provider.FakeQasmSimulatorqiskit.providers.fake_provider.FakeJobqiskit.providers.fake_provider.FakeQobj
Para usar o novo módulo de provedor falso, você pode executar
pip install qiskit-ibm-runtimee substituir o caminho de importação do qiskit (qiskit.providers.fake_provider) pelo novo caminho de importação (qiskit_ibm_runtime.fake_provider). Exemplo de migração:# Legacy path from qiskit.providers.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke() # New path # run "pip install qiskit-ibm-runtime" from qiskit_ibm_runtime.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke()Além disso, os seguintes backends falsos projetados para fins de testes especiais foram substituídos pela nova classe
GenericBackendV2e também foram removidos após sua descontinuação no Qiskit 0.46:qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2`qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2LegacyQubitPropsqiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple
Exemplo de migração para a nova
GenericBackendV2classe:# Legacy path from qiskit.providers.fake_provider import FakeBackend5QV2 backend = FakeBackend5QV2() # New path from qiskit.providers.fake_provider import GenericBackendV2 backend = GenericBackendV2(num_qubits=5) # note that this class will generate 5q backend with generic # properties that serves the same purpose as FakeBackend5QV2 # but will generate different results