Skip to main content
IBM Quantum Platform

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() e BitArray.from_samples(). Anteriormente, isso gerava um erro se fossem fornecidos dados contendo apenas zeros e nenhum valor para o argumento opcional num_bits. Agora eles produzem um BitArray com BitArray.num_bits definido como 1.

  • Corrigido um decorador ausente no C3SXGate que fazia com que ele falhasse se o Gate.to_matrix() fosse chamado. A matriz de porta agora está retornando como esperado.

  • Adicionados os portões de Clifford ausentes à passagem do CollectCliffords passagem do transpilador. Em particular, adicionamos os portões ECRGate, DCXGate, iSWAPGate, SXGate e SXdgGate a essa passagem do transpilador.

  • O atributo QuantumCircuit.parameters agora estará corretamente vazio ao usar QuantumCircuit.copy_empty_like() em um circuito paramétrico. Anteriormente, um cache interno era copiado sem invalidação. Correção #12617.

  • Corrigir a passagem do SolovayKitaev ao carregar aproximações básicas de um arquivo .npy existente. 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() e DAGCircuit.draw() quando se tentava visualizar uma instância DAGCircuit que continha Var fios. O visualizador gerava uma exceção ao tentar fazer isso, o que foi corrigido para que a visualização esperada seja gerada.

  • O construtor GenericBackendV2 permitia 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 de n-qubit fosse colocada em um bloco de m qubits, deixando o DAG em um estado inválido. Esse comportamento foi corrigido, e qualquer tentativa de fazer isso agora gerará um erro DAGCircuitError como 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 Isometry devido a uma asserção desnecessária, que levou a um erro em UnitaryGate.control() quando o UnitaryGate tinha mais de dois qubits.

  • QuantumCircuit.depth() agora tratará corretamente as operações que não têm operandos, como GlobalPhaseGate.

  • 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 argumento BackendV2 argumento. 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 VF2Layout geraria uma exceção quando fornecido com uma instância Target sem restrições de conectividade. Esse seria o caso das metas da Aer 0.13. O problema agora está corrigido.

  • ParameterExpression foi atualizado de modo que as instâncias totalmente vinculadas que se comparam às instâncias dos tipos numéricos incorporados do Python (como float e int) 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 uma Gate.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 o Operator o 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 com None para 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 fluxo QuantumCircuit onde, 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 UnitarySynthesis foram 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ção UnitarySynthesis incorria em uma grande sobrecarga de tempo de execução historicamente. Essa versão também começa a ser executada UnitarySynthesis como 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 Isometry foram 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 multicontrolados XGate e PhaseGate foi 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, ElidePermutations e StarPreRouting demonstraram ter um impacto significativo na qualidade da saída do roteamento e no tempo de execução e RemoveFinalReset podem 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_manager e usado internamente pelo transpile() 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, BackendEstimatorV2 e BackendSamplerV2para 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 de Gate (como o de SGate), todos têm um novo argumento adicional annotated que é usado para retornar um objeto AnnotatedOperation ao aplicar uma potência a uma porta ou circuito. O valor padrão de False corresponde ao comportamento existente. Além disso, para portas padrão com um método power explicitamente definido, o argumento annotated não tem efeito. Por exemplo, tanto SGate().power(1.5, annotated=False) quanto SGate().power(1.5, annotated=True) retornam um PhaseGate. Uma diferença no valor de annotated se manifesta para portas sem um método de potência explicitamente definido. O valor de False retorna um UnitaryGate, exatamente como antes, enquanto o valor de True retorna um AnnotatedOperation que representa a instrução modificada com o "modificador de potência".

  • Adicionado um novo argumento ctrl_state ao QuantumCircuit.mcp() e MCPhaseGate.

    O QuantumCircuit.mcp() e a classe MCPhaseGate foram atualizados para incluir um parâmetro ctrl_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_state ao QuantumCircuit.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 QuantumCircuit agora 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ó Var que 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 usando QuantumCircuit.add_var() e QuantumCircuit.add_input()ou em um nível inferior usando Var.new().

    As variáveis podem ser armazenadas manualmente, usando a instrução Store e seu método de circuito correspondente QuantumCircuit.store(). Isso inclui escrever para Clbit e ClassicalRegister envolvidas em nós Var nó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 (consulte QuantumCircuit.draw()).

    Nota

    As 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.classical agora pode representar a indexação e o deslocamento de bits de inteiros sem sinal e de bits semelhantes (por exemplo ClassicalRegister). 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))):
        pass

    O 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 NLocal e suas subclasses de biblioteca de circuitos derivadas (por exemplo EfficientSU2 e RealAmplitudes) 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-chave copy , 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, se QuantumCircuit.assign_parameters() tentar alterar a instrução no local, isso não afetará outras referências à mesma instrução. Agora, a configuração copy=False permite 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-chave copy , 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. Se copy=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 QuantumVolume foi 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.

  • QuantumVolume agora tem um argumento de palavra-chave flatten . 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 como True, o circuito terá diretamente as matrizes SU4 volumétricas.

  • UnitaryGate agora aceita um argumento opcional num_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.

  • QuantumCircuit tem vários métodos novos para trabalhar e inspecionar variáveis manuais Var variá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:

    Além disso, há vários novos atributos dinâmicos em QuantumCircuit em torno dessas variáveis:

  • ControlFlowOp e suas subclasses agora têm um método iter_captured_vars() que retornará um iterador sobre as variáveis exclusivas capturadas em qualquer um de seus blocos imediatos.

  • DAGCircuit tem vários métodos novos para trabalhar e inspecionar variáveis manuais Var variáveis manuais. Elas são amplamente equivalentes às suas QuantumCircuit exceto pelo fato de que os DAGCircuit são otimizados para acesso programático com objetos já definidos, enquanto os métodos QuantumCircuit são mais focados no uso humano interativo.

    Os novos métodos são:

    Há também novos atributos públicos:

  • DAGCircuit.wires agora também conterá quaisquer Var variá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_remap e inline_captures , para oferecer melhor suporte a variáveis clássicas em tempo real.

    var_remap pode ser usado para reescrever os nós Var nó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_captures pode ser definido como True (o padrão é False) para vincular todos os nós Var nós rastreados como "capturas" no circuito do argumento com os mesmos Var nós no circuito base, sem tentar redeclarar as variáveis. Isso pode ser usado, em combinação com o manuseio de QuantumCircuit.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 como True para incorporar nós "capturados" Var no circuito do argumento para o circuito base sem redeclará-los. Em conjunto com a opção vars_mode="captures" de vários métodos DAGCircuit isso pode ser usado para combinar DAGs que operam nas mesmas variáveis.

  • QuantumCircuit.copy_empty_like() e DAGCircuit.copy_empty_like() têm um novo argumento de palavra-chave, vars_mode , que controla como os nós que possuem memória Var sã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 com compose()) ou "drop" para removê-las.

  • Um novo argumento da palavra-chave vars_mode foi adicionado aos DAGCircuit methods:

    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 circuitos TwoLocal circuitos, como RealAmplitudes e EfficientSU2.

Recursos primitivos

  • A implementação BackendEstimatorV2 de BaseEstimatorV2 foi adicionada. Esse estimador suporta BackendV1 e BackendV2.

    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 BackendSamplerV2 de BaseSamplerV2 foi adicionada. Esse sampler é compatível com BackendV1 e BackendV2 que permitem a opção memory para 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 BitArray objetos ao longo de vários eixos.

    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 BitArray cortando 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 um BitArray.

    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]
  • DataBin agora satisfaz o protocolo Shaped protocolo. Isso significa que cada DataBin agora tem os atributos adicionais

    • shape (tupleint[,...]): a forma principal de cada entrada na instância
    • ndim (int): o comprimento de shape
    • size (int): o produto das entradas de shape

    A forma pode ser passada para o construtor.

  • Adicionados recursos semelhantes ao mapeamento para DataBinou seja, __getitem__, __contains__, __iter__, keys(), values(), e items().

    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 SamplerPubResult de PubResult foi adicionada, a qual as implementações do BaseSamplerV2 implementações podem retornar. O principal recurso adicionado nessa nova subclasse é join_data()que junta (um subconjunto de) o conteúdo de data em 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

Recursos do Pulse

  • Agora é possível atribuir parâmetros ao pulso Schedule e ScheduleBlock especificando 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 campos Schedule ou ScheduleBlock que tenham o mesmo nome. Além disso, o nome do parâmetro de um ParameterVector pode 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_parameters de Schedule e ScheduleBlock agora suportam a atribuição de um ParameterVector a uma lista de valores de parâmetros simultaneamente, além de atribuir instâncias individuais de Parameter a valores individuais.

OpenQASM Características

  • O exportador OpenQASM 3 oferece suporte a nós de armazenamento manual Var em circuitos.

Recursos do QPY

  • O FORMATO QPY (qiskit.qpy) foi adicionada a versão 12 do formato, que inclui suporte para variáveis Var de 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 a apply_layout(). Esse método é usado para aplicar um layout TranspileLayout layout do transpilador a um Pauli observável que foi criado para um circuito de entrada. Isso permite trabalhar com implementações BaseEstimator / BaseEstimatorV2 e a transpilação local quando a entrada é do tipo Pauli. 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 de backend) e altera seu layout, que é então aplicado a H1 usando apply_layout() para refletir as transformações realizadas pelo pm.run().

  • Adiciona o PauliList.noncommutation_graph() e SparsePauliOp.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 pelo SparsePauliOp.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 ambiente RAYON_NUM_THREADS . Você pode forçar temporariamente a execução em série usando o novo argumento booleano force_serial para to_matrix().

Recursos de síntese

  • O KMSSynthesisLinearFunction plugin para sintetizar objetos LinearFunction agora aceita duas opções adicionais: use_inverted e use_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 PMHSynthesisLinearFunction plugin para sintetizar objetos LinearFunction agora aceita várias opções adicionais. A opção section_size é passada para o método de síntese subjacente. As opções use_inverted e use_transposed 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.

  • Adicionado um novo argumento, use_dag, ao TwoQubitBasisDecomposer.__call__() e XXDecomposer.__call__() métodos. Esse argumento é usado para controlar se um DAGCircuit é retornado ao chamar um TwoQubitBasisDecomposer ou XXDecomposer em vez da instância padrão QuantumCircuit. 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 DAGCircuit ao chamar a instância TwoQubitBasisDecomposer instância decomposer.

  • LieTrotter.synthesize() agora usa QuantumCircuit.repeat() para gerar repetições adicionais de uma etapa de Trotter após a primeira etapa de Trotter. Isso reduz o número de QuantumCircuit.compose() chamadas em um fator de reps e 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 nn qubits em uma arquitetura linear do vizinho mais próximo usando portas CX com profundidade 2n+22 * n + 2.

  • A classe TwoQubitBasisDecomposer foi reescrita em Rust, o que melhora muito o desempenho do tempo de execução.

  • A classe TwoQubitWeylDecomposition foi reescrita em Rust para melhorar o desempenho.

Recursos do Transpiler

  • Estendeu a análise de comutação realizada por CommutationChecker para 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 se AnnotatedOperation comutar. Isso permite que as passagens do transpilador que dependem do CommutationChecker internamente, como CommutativeCancellationsejam 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 de SwapGates e PermutationGates em um circuito virtual é quase sempre benéfica, pois torna o circuito mais curto e mais fácil de rotear. Como o OptimizeSwapBeforeMeasure é um caso especial de ElidePermutationsele foi substituído pelo passe ElidePermuations como 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á qualquer SwapGates e PermutationGates em um circuito por meio da permutação de qubits virtuais. Por exemplo, ao pegar um circuito com SwapGates:

    _images/release_notes-1.png

    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")
    _images/release_notes-2.png

    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 HLSConfig agora tem dois argumentos opcionais adicionais. O argumento plugin_selection pode ser definido como "sequential" ou "all". Se definido como "sequencial" (padrão), para cada objeto de nível superior, a HighLevelSynthesis considerará 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 com plugin_evaluation_fn , será escolhido. O argumento plugin_evaluation_fn é um chamável opcional que avalia a qualidade do circuito quântico sintetizado; um valor menor significa um circuito melhor. Quando definido como None, 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 CommutativeCancellation ao estágio init dos 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 Target graças a um novo argumento de entrada target :

    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 objeto Layout objeto. Adicionado um novo método Layout.compose() que é usado para compor dois Layout objetos juntos. Adicionado um novo método Layout.to_permutation() que é usado para criar uma permutação correspondente a um objeto Layout objeto.

  • Adicionada uma nova redução à passagem do OptimizeAnnotated passagem do transpilador. Essa redução procura por operações anotadas (objetos do tipo AnnotatedOperation que consistem em uma operação de base BB e uma lista MM de modificadores de controle, inversos e de potência) com as seguintes propriedades:

    • a operação básica BB 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 BB pode ser expresso como PP - QQ - RR com R=P1R = P^{-1}

    Nesse caso, os modificadores podem ser movidos apenas para a parte QQ. Como exemplo específico, os somadores controlados baseados em QFT têm a forma control - [QFT -- U -- IQFT], que pode ser simplificada para QFT -- control-[U] -- IQFT. Ao remover os controles sobre QFT e IQFT partes do circuito, obtém-se um número significativamente menor de portas no circuito transpilado.

  • Foram adicionados dois novos métodos à classe DAGCircuit classe: qiskit.dagcircuit.DAGCircuit.op_successors() retorna um iterador para DAGOpNode sucessores de um nó, e qiskit.dagcircuit.DAGCircuit.op_successors() retorna um iterador para os DAGOpNode predecessores de um nó.

  • Adicionado um novo passe de transpilador, RemoveFinalResetque removerá qualquer operação Reset que seja a instrução final em um fio de qubit. Por exemplo, um circuito com final Resets:

    _images/release_notes-3.png

    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")
    _images/release_notes-4.png
  • Adicionada uma nova passagem de transpilador StarPreRouting projetada 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:

    _images/release_notes-5.png
    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")
    _images/release_notes-6.png

    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")
    _images/release_notes-7.png

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ção Store e 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 Matplotlib Axes para plot_histogram e pós-aplicar as personalizações.

  • A função transpile() foi atualizada para converter internamente entradas de backend do tipo BackendV1 para BackendV2o que permite que o pipeline de transpilação agora acesse as restrições de backend por meio de um Target. 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 QuantumVolume foi 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 UnitaryGate na definição de um circuito QuantumVolume circuito não terão mais um campo label definido. Anteriormente, isso era definido como a string su4_<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étodo Gate.to_matrix() método.

Notas sobre a atualização dos primitivos

  • A função make_data_bin() não cria mais e retorna uma DataBin subclasse. Em vez disso, ele sempre retorna a DataBin classe. 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âncias DataBin diretamente, em vez de instanciar subclasses como resultado de make_data_bin().

Notas de atualização dos fornecedores

  • Implementações de BackendV2 (e BackendV1) podem querer atualizar seus métodos run() para rejeitar avidamente entradas que contenham variáveis clássicas tipadas (consulte qiskit.circuit.classical) e a instrução Store se não tiverem suporte para elas. A nova instrução Store é tratada pelo transpilador como uma "diretriz" sempre disponível (como Barrier); se os seus backends não suportarem essa instrução, ela não será detectada pela função transpiler.

    Consulte Variáveis em tempo real para obter mais informações.

Notas de atualização do QPY

Notas sobre a atualização da síntese

  • O TwoQubitWeylDecomposition não mais se auto-especializará em uma subclasse na criação. Esse era um detalhe interno da classe TwoQubitWeylDecomposition anteriormente, 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 de TwoQubitWeylDecomposition serã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 StagedPassManager retornada para o nível de otimização 2 por generate_preset_pass_manager() e level_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 com qpy para 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.

    [1] https://devguide.python.org/versions/

Descontinuidade de provedores

  • As classes básicas abstratas Provider e ProviderV1 agora 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 atributos name, backends e um get_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 removendo ProviderV1 como a classe pai da sua implementação. Como parte disso, você provavelmente gostaria de adicionar uma implementação do get_backend para 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 novo TwoQubitWeylDecomposition objeto. 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á um NotImplementedError quando 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.CXCancellation foi preterido em favor de InverseCancellationque é mais genérico. CXCancellation é totalmente equivalente semanticamente a InverseCancellation([CXGate()]).

  • A passagem de transpilação qiskit.transpiler.passes.ALAPSchedule agora 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 por ALAPScheduleAnalysisque é uma passagem de análise.

  • A passagem de transpilação qiskit.transpiler.passes.ASAPSchedule agora 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 pelo ASAPScheduleAnalysis e o novo fluxo de trabalho de agendamento.

  • A passagem de transpilação qiskit.transpiler.passes.DynamicalDecoupling agora 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 o PadDynamicalDecouplingque 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.AlignMeasures agora 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 ConstrainedRescheduleque 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_idle e show_barrier nas gavetas da linha do tempo foram substituídos por idle_wires e plot_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 sinalizador use_symengine era definido como um objeto verdadeiro que era avaliado como True , mas não era realmente o booleano True, a carga útil QPY gerada era corrompida. Por exemplo, se você definir use_symengine como HAS_SYMENGINEesse objeto é avaliado como True quando convertido como bool, mas não é de fato True.

  • Foi corrigido um problema com a função circuit_drawer() function and QuantumCircuit.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 ConstrainedReschedule pass do transpilador anteriormente dava erro se o circuito contivesse uma instrução Reset instruçã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ço RuntimeWarning se encontrar um circuito que contenha um dos dois. Corrigido #10354

  • Foi corrigido um problema com a classe CommutationChecker em que ocorria um erro se o atributo name de 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() e Pauli.apply_layout() quando uma matriz inválida com índices duplicados ou negativos era passada para o argumento layout . 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 erro QiskitError se índices duplicados ou índices negativos forem fornecidos como parte de um layout.

  • Foi corrigido um problema de desempenho no BackendSamplerV2 e BackendEstimatorV2. 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 atributo BackendConfiguration.supported_instructions , que é o local típico em que as instruções de fluxo de controle são especificadas em um objeto BackendConfiguration objeto. Corrigido #11872.

  • Foi corrigido um problema com o circuit_drawer() ou QuantumCircuit.draw() ao usar a opção de saída mpl , em que o programa travava se o circuito que estava sendo desenhado tivesse uma operação ControlFlow e a opção fold estivesse 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.qobj legado. 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 para Waveform como deveria. Corrigido #11828.

  • Foi corrigido um bug em transpile() foi corrigido quando as restrições personalizadas instruction_durations, dt e backend_properties eram ignoradas quando fornecidas ao mesmo tempo que um backend do tipo BackendV2. O comportamento após a correção agora é independente do fato de o backend fornecido ser do tipo BackendV1 ou do tipo BackendV2. Da mesma forma, o timing_constraints personalizado agora é substituído pelas entradas do target , mas tem precedência sobre o BackendV1 e BackendV2 entradas.

  • 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 como BasisTranslator ainda usariam as regras antigas. Corrigido #11958.

  • O EvolvedOperatorAnsatz agora lida corretamente com o caso em que o argumento do operador é uma lista vazia. Anteriormente, isso resultava em um erro.

  • De agora em diante, EvolvedOperatorAnsatz não terá nenhuma qregs quando houver zero qubits, em vez de ter uma instância QuantumRegister com zero qubits. Esse comportamento se alinha de forma mais consistente com sua superclasse QuantumCircuit.

  • O método Instruction.repeat() agora move um conjunto condition para o retorno externo Instruction e deixa os portões internos de sua definição incondicionais. Anteriormente, o método deixava as instâncias ClassicalRegister dentro 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 InverseCancellation em 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 MCXGate e MCPhaseGate sem usar qubits de ancilla, de modo que o número de CXGate cresç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 em QubitProperties são preenchidos com None.

  • BasePassManager.run() não vazará mais o PropertySet anterior em novos fluxos de trabalho quando chamado mais de uma vez. Anteriormente, o mesmo PropertySet como 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ão frame='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_alignment do build(). As entradas do tipo AlignmentKind agora 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 QDrift em 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 para dt em 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 Commuting2qGateRouter onde 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 propriedade layout do 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 init não estava gerando corretamente uma mensagem TranspilerError quando 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 um Operator invá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 o PassManager (que é um requisito para a execução paralela) quando receber várias entradas, se for processar as entradas apenas em série.

  • Parameter foi atualizado para que as instâncias que se comparam iguais sempre tenham o mesmo hash. Anteriormente, apenas o Parameter.uuid era comparado, portanto Parameter com nomes diferentes poderiam ser comparadas igualmente se tivessem sido construídas usando um valor comum para o parâmetro uuid (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() e qasm2.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 2π2\pi.

  • Parameter as instâncias usadas como substitutos para as variáveis de input nos 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() com copy=True (seu padrão) agora copiará corretamente as instruções parametrizadas por ParameterExpression e não apenas por instâncias Parameter instâncias.

  • O manuseio interno de calibrações de circuitos personalizados e InstructionDurations foi transferido da função transpile() 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 argumento num_processes só seria usado se dt ou instruction_durations fossem fornecidos.

Outras observações


1.0.0rc1

Notas de atualização dos fornecedores

  • O módulo qiskit.providers.fake_provider foi migrado para o pacote qiskit-ibm-runtime Python. Por esse motivo, os seguintes elementos na seção qiskit.providers.fake_provider foram removidos após sua descontinuação no Qiskit 0.46:

    • qiskit.providers.fake_provider.FakeProvider
    • qiskit.providers.fake_provider.FakeProviderForBackendV2
    • qiskit.providers.fake_provider.FakeProviderFactory
    • qiskit.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.FakeQasmSimulator
    • qiskit.providers.fake_provider.FakeJob
    • qiskit.providers.fake_provider.FakeQobj

    Para usar o novo módulo de provedor falso, você pode executar pip install qiskit-ibm-runtime e 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 GenericBackendV2 e 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.FakeBackendV2LegacyQubitProps
    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2
    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple

    Exemplo de migração para a nova GenericBackendV2 classe:

    # 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
Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.