Skip to main content
IBM Quantum Platform

Notas de versão do Qiskit 1.0


1.0.2

Prelúdio

O Qiskit 1.0.2 é uma versão menor de correção de bugs para a série 1.0.

Correções de bugs

  • Foi corrigido um problema com o 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.

  • 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 operators é uma lista vazia. Anteriormente, isso resultava em um erro.

  • Corrigido um problema de consistência com instâncias EvolvedOperatorAnsatz instâncias com zero qubits. Anteriormente, essas instâncias continham um único QuantumRegister in qregs com zero qubits, mas agora nenhum registro é criado. Esse comportamento se alinha de forma mais consistente com sua superclasse QuantumCircuit.

  • Corrigida uma falha no convert_to_target() que ocorria quando as propriedades do qubit ( T1, T2 ou frequência) estavam ausentes. Os valores de propriedade ausentes em QubitProperties estão agora preenchidos com None.

  • 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 em que EstimatorPub.coerce() e SamplerPub.coerce() tratavam de forma inadequada um parâmetro do tipo BindingsArray. Anteriormente, uma exceção ValueError era falsamente levantada.

  • Os gerenciadores de passagem predefinidos usados por transpile() não falharão mais em circuitos com fluxo de controle quando 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.

  • Corrigido o site coerce() para que ele retorne uma matriz 0-d quando a entrada for um único observável não aninhado. Anteriormente, ele foi erroneamente atualizado para uma única dimensão, com a forma (1,).

  • Parameter foi atualizado de modo que as instâncias que se comparam iguais sempre têm 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 o bug no QuantumCircuit.draw() que fazia com que os dicionários de estilo personalizados da gaveta Matplotlib fossem modificados durante a execução.


1.0.1

Prelúdio

O Qiskit 1.0.1 é uma versão de correção que corrige um pequeno número de erros identificados na versão do Qiskit 1.0.0.

Correções de bugs

  • 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 em um pulse.Waveform como deveria. Corrigido #11828.

  • 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.

  • 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.

  • Foi corrigido um erro no site convert_durations_to_dt() em que a função presumia que suas entradas eram todas em segundos, em vez de ler a unidade real. Isso pode levar a ordens de magnitude erradas nas durações de circuito relatadas.


1.0.0

Prelúdio

É com grande satisfação que lançamos o Qiskit 1.0.0. Esta versão é o ponto culminante de 7 anos de desenvolvimento para amadurecer o Qiskit em um SDK estável e de alto desempenho para computação quântica e é o início de uma nova era para o projeto e a comunidade Qiskit. Além das melhorias gerais de desempenho e estabilidade, as mudanças mais significativas na versão 1.0.0 estão relacionadas à política de estabilidade, aos ciclos de lançamento e ao controle de versão. O Qiskit agora está usando formalmente o controle de versão semântico, o que significa que, durante todo o ciclo de vida da série de versões 1.x, o projeto está comprometido em manter a compatibilidade com versões anteriores em suas APIs públicas documentadas. Também estamos começando a oferecer suporte à correção de bugs para versões principais, para que você continue a ter uma ramificação com suporte por 6 meses após o lançamento da próxima versão principal. Isso começa agora com as séries principais 1.x e 0.x : a versão 0.46.x continuará a receber suporte, com lançamentos periódicos de patches que contêm correções de bugs, por 6 meses após o lançamento de 1.0. Ou seja, o site 0.46.x terá suporte até 2024-08. Você pode ver os detalhes completos da nova política aqui:

start/install#qiskit-versioning

A mudança na embalagem também é de grande importância nesta versão. Desde o lançamento do Qiskit 0.7 em 2018-12, quando o Qiskit introduziu seu modelo de elementos, o pacote qiskit que você instalaria seria um meta-pacote (ou pacote de pacotes) que instala os elementos combinados que compõem o Qiskit. Conforme anunciado em versões anteriores (para mais detalhes, consulte as notas de versão 0.44.0, 0.45.3 e 0.46.0, juntamente com esta postagem do blog ), com a versão 1.0, estamos concluindo uma transição para ter um único qiskit pacote expondo apenas o SDK principal (o que era anteriormente qiskit-terra ). Isso significa que, para versões >= 1.0.0, paramos de usar o pacote qiskit-terra e publicaremos apenas qiskit. Como essa mudança na estrutura do pacote não é totalmente compatível com o instalador do pacote Python pip, não é possível usar apenas o pip install -U qiskit para atualizar do qiskit 0.46.0 para o 1.0.0. É altamente recomendável que, para atualizar para o Qiskit 1.0.0, você crie um ambiente virtual separado para isolar a instalação. Há um guia de migração detalhado que explica as alterações no pacote e como instalar o Qiskit 1.0.0 em diferentes cenários, que pode ser encontrado aqui:

https://qisk.it/1-0-packaging-migration

Como acontece com todas as nossas principais versões, o Qiskit 1.0.0 também tem uma infinidade de novos recursos, sendo que os destaques dessa versão são:

  • A QuantumCircuit estrutura interna da classe data da classe foi reescrita em Rust para melhorar muito a eficiência da memória dos objetos QuantumCircuit ao armazenar em cache os argumentos das instruções.
  • Uma nova versão da definição da interface de primitivos em qiskit.primitives com as tags BaseSamplerV2 e BaseEstimatorV2 classes abstratas. Essa nova versão da interface adiciona suporte à execução de chamadas vetorizadas para a primitiva, de modo que as varreduras sobre conjuntos de valores de parâmetros e observáveis possam ser especificadas com eficiência.
  • Um novo analisador nativo experimental OpenQASM 3 qiskit.qasm3.loads_experimental() e qiskit.qasm3.load_experimental(). Esse novo analisador ainda está em desenvolvimento, tem várias limitações e ainda é experimental. No entanto, nos casos em que pode ser usado, o novo analisador é significativamente mais rápido e tem uma mensagem de erro de diagnóstico melhor, que permite depurar onde um programa OpenQASM 3 é inválido. Esse novo analisador é escrito em Rust e baseado em uma biblioteca Rust recém-desenvolvida para analisar OpenQASM3, que pode ser encontrada aqui: https://github.com/Qiskit/openqasm3_parser

Por fim, a versão do Qiskit 1.0.0 foi uma oportunidade de limpar alguns débitos técnicos acumulados nos últimos 7 anos de desenvolvimento. Você notará que a versão do Qiskit 1.0.0 está praticamente livre da emissão de DeprecationWarnings e, ao mesmo tempo, a seção de atualização das notas de versão do 1.0.0 é mais longa do que o normal. Essas são consequências diretas da limpeza da dívida técnica. Para ajudar na migração de 0.46.x para 1.0.0, além das notas de versão, também publicamos um guia de migração dedicado que pode ser encontrado aqui:

Qiskit 1.0 alterações de recursos

Este guia tem o objetivo de complementar as notas de versão e oferecer uma orientação específica sobre como migrar as alterações de API após a remoção da funcionalidade obsoleta da versão 0.46.0.

Recursos dos circuitos

  • Foi adicionado um novo argumento, annotated, aos métodos QuantumCircuit.inverse(), circuit.Instruction.inverse() e .inverse() métodos de Instruction subclasses (como SwapGate ou SGate) para retornar opcionalmente um AnnotatedOperation. O valor padrão de annotated é False e corresponde ao comportamento pré-existente do método. Além disso, para portas padrão com um método inverse explicitamente definido, o argumento annotated não tem efeito, por exemplo, ambos:

    SwapGate().inverse(annotated=False)
    SwapGate().inverse(annotated=True)

    return a SwapGatee ambos:

    SGate().inverse(annotated=False)
    SGate().inverse(annotated=True)

    retornar um SdgGate. A diferença se manifesta nas instruções personalizadas sem um inverso explicitamente definido. Com annotated=False, o método retorna uma nova instrução com a definição recursivamente invertida, exatamente como antes. Enquanto annotated=True retorna um AnnotatedOperation que representa a instrução modificada com o comando InverseModifier.

  • Adicionada uma biblioteca de comutação ao CommutationChecker. Essa biblioteca armazena todas as relações de comutação de portas padrão não parametrizáveis em um dicionário que permite uma pesquisa eficiente em tempo de execução. Isso acelera a execução da classe CommutationChecker e, por extensão, a passagem do CommutationAnalysis pois, em vez de computar se duas portas padrão não parametrizáveis são comuns, basta procurar na biblioteca.

    Além disso, o CommutationChecker foi refatorado e agora tem um limite superior definido para o número de relações de comutação em cache que não estão na biblioteca de comutação. Isso abordou: #8020 e #7101

  • QuantumCircuit.assign_parameters() agora aceita chaves de cadeia de caracteres no formulário de mapeamento de entrada. Esses nomes são usados para procurar a instância Parameter correspondente usando get_parameter(). Isso permite que você faça:

    from qiskit.circuit import QuantumCircuit, Parameter
    
    a = Parameter("a")
    qc = QuantumCircuit(1)
    qc.rx(a, 0)
    
    qc.assign_parameters({"a": 1}) == qc.assign_parameters({a: 1})
  • QuantumCircuit tem dois novos métodos, get_parameter() e has_parameter()que, respectivamente, recuperam uma instância Parameter usada no circuito por nome e retornam um booleano que indica se um parâmetro com um nome correspondente (ou a instância exata fornecida) é usado no circuito.

  • A uuid foi adicionada à classe qiskit.circuit.Parameter classe. Em casos de uso avançado, essa propriedade pode ser usada para criar qiskit.circuit.Parameter instâncias que se comparam umas com as outras.

  • Foi adicionado um novo método, ParameterExpression.numeric()que converte uma expressão de parâmetro totalmente vinculada no tipo numérico incorporado mais restritivo Python que descreve com precisão o resultado da avaliação simbólica. Por exemplo, um número inteiro simbólico se tornará um intenquanto um número real simbólico se tornará um float e um número complexo se tornará um complex. Esse método inclui várias soluções alternativas para as peculiaridades dos contextos de avaliação de symengine, que às vezes podem levar a resultados espúrios ao chamar complex ou float em uma expressão diretamente.

Recursos primitivos

  • A versão 2 das primitivas é introduzida por meio de uma nova classe base para o amostrador e o estimador, juntamente com novos tipos para suas entradas e saídas. A ênfase dessa nova versão está na execução de chamadas vetorizadas para os métodos primitivos do run() , de modo que as varreduras sobre conjuntos de valores de parâmetros e observáveis possam ser especificadas com eficiência. Veja StatevectorSampler e StatevectorEstimator para obter referências de implementações das primitivas do site V2.

    Além disso, o estimador ganhou um argumento precision no método run() que especifica a precisão desejada das estimativas do valor da expectativa. De forma análoga, o sampler moveu shots para fora das opções e para os argumentos do método run() método. O sampler também foi alterado para retornar as saídas (por exemplo, cadeias de bits) de cada disparo, em vez de fornecer um retorno do tipo Counts-e também para armazenar os dados de ClassicalRegisters. Isso permite que as classes derivadas implementem o suporte ao sampler para circuitos com fluxo de controle clássico.

    As classes básicas primitivas do V2 são:

    Os novos tipos usados para entradas e saídas são:

    • SamplerPubLikebloco unificado primitivo ( PUB ) de entradas do amostrador; um tipo de união de entradas permitidas para um amostrador
    • EstimatorPubLike: Bloco unificado primitivo ( PUB ) de entradas do estimador; um tipo de união de entradas permitidas para um estimador
    • PubResult: os dados e metadados resultantes de uma única execução do PUB
    • DataBin: Um espaço de nome para armazenar dados de uma única execução do site PUB
    • BitArray: um conjunto de valores de bits em um formato denso
    • PrimitiveResult: um iterável de PubResults junto com metadados
  • A implementação de referência StatevectorEstimator do BaseEstimatorV2 foi adicionada. Como visto no exemplo abaixo, esse estimador (e todos os estimadores do site V2 ) suporta o fornecimento de matrizes de observáveis e/ou matrizes de conjuntos de valores de parâmetros que são anexados a circuitos específicos.

    Cada tupla de (circuit, observables, <optional> parameter values, <optional> precision), chamada de bloco unificado primitivo do estimador ( PUB ), produz seu próprio resultado baseado em matriz. O método run() pode ser usado em vários bares ao mesmo tempo.

    from qiskit.circuit import Parameter, QuantumCircuit
    from qiskit.primitives import StatevectorEstimator
    from qiskit.quantum_info import Pauli, SparsePauliOp
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Define a circuit with two parameters.
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.ry(Parameter("a"), 0)
    circuit.rz(Parameter("b"), 0)
    circuit.cx(0, 1)
    circuit.h(0)
    
    # Define a sweep over parameter values, where the second axis is over
    # the two parameters in the circuit.
    params = np.vstack([
        np.linspace(-np.pi, np.pi, 100),
        np.linspace(-4 * np.pi, 4 * np.pi, 100)
    ]).T
    
    # Define three observables. Many formats are supported here including
    # classes such as qiskit.quantum_info.SparsePauliOp. The inner length-1
    # lists cause this array of observables to have shape (3, 1), rather
    # than shape (3,) if they were omitted.
    observables = [
        [SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
        [Pauli("XX")],
        [Pauli("IY")]
    ]
    
    # Instantiate a new statevector simulation based estimator object.
    estimator = StatevectorEstimator()
    
    # Estimate the expectation value for all 300 combinations of
    # observables and parameter values, where the pub result will have
    # shape (3, 100). This shape is due to our array of parameter
    # bindings having shape (100,), combined with our array of observables
    # having shape (3, 1)
    pub = (circuit, observables, params)
    job = estimator.run([pub])
    
    # Extract the result for the 0th pub (this example only has one pub).
    result = job.result()[0]
    
    # Error-bar information is also available, but the error is 0
    # for this StatevectorEstimator.
    result.data.stds
    
    # Pull out the array-based expectation value estimate data from the
    # result and plot a trace for each observable.
    for idx, pauli in enumerate(observables):
        plt.plot(result.data.evs[idx], label=pauli)
    plt.legend()
  • A implementação de referência StatevectorSampler do BaseSamplerV2 foi adicionada. Como visto no exemplo abaixo, esse amostrador (e todos os amostradores do site V2 ) suporta o fornecimento de matrizes de conjuntos de valores de parâmetros para associar a um único circuito.

    Cada tupla de (circuit, <optional> parameter values, <optional> shots), chamada de bloco unificado primitivo do amostrador ( PUB ), produz seu próprio resultado baseado em matriz. O método run() pode ser usado em vários bares ao mesmo tempo.

    from qiskit.circuit import (
        Parameter, QuantumCircuit, ClassicalRegister, QuantumRegister
    )
    from qiskit.primitives import StatevectorSampler
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Define our circuit registers, including classical registers
    # called 'alpha' and 'beta'.
    qreg = QuantumRegister(3)
    alpha = ClassicalRegister(2, "alpha")
    beta = ClassicalRegister(1, "beta")
    
    # Define a quantum circuit with two parameters.
    circuit = QuantumCircuit(qreg, alpha, beta)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.cx(1, 2)
    circuit.ry(Parameter("a"), 0)
    circuit.rz(Parameter("b"), 0)
    circuit.cx(1, 2)
    circuit.cx(0, 1)
    circuit.h(0)
    circuit.measure([0, 1], alpha)
    circuit.measure([2], beta)
    
    # Define a sweep over parameter values, where the second axis is over.
    # the two parameters in the circuit.
    params = np.vstack([
        np.linspace(-np.pi, np.pi, 100),
        np.linspace(-4 * np.pi, 4 * np.pi, 100)
    ]).T
    
    # Instantiate a new statevector simulation based sampler object.
    sampler = StatevectorSampler()
    
    # Start a job that will return shots for all 100 parameter value sets.
    pub = (circuit, params)
    job = sampler.run([pub], shots=256)
    
    # Extract the result for the 0th pub (this example only has one pub).
    result = job.result()[0]
    
    # There is one BitArray object for each ClassicalRegister in the
    # circuit. Here, we can see that the BitArray for alpha contains data
    # for all 100 sweep points, and that it is indeed storing data for 2
    # bits over 256 shots.
    assert result.data.alpha.shape == (100,)
    assert result.data.alpha.num_bits == 2
    assert result.data.alpha.num_shots == 256
    
    # We can work directly with a binary array in performant applications.
    raw = result.data.alpha.array
    
    # For small registers where it is anticipated to have many counts
    # associated with the same bitstrings, we can turn the data from,
    # for example, the 22nd sweep index into a dictionary of counts.
    counts = result.data.alpha.get_counts(22)
    
    # Or, convert into a list of bitstrings that preserve shot order.
    bitstrings = result.data.alpha.get_bitstrings(22)
    print(bitstrings)

Recursos dos provedores

  • Adicionada uma nova classe, GenericBackendV2ao módulo qiskit.providers.fake_provider módulo. Essa classe é configurável e cria uma instância de BackendV2 que pode ser executada localmente (no espírito dos backends falsos). Os usuários podem configurar o número de qubits, portas de base, mapa de acoplamento, capacidade de executar circuitos dinâmicos (instruções de fluxo de controle), calibrações de instruções e intervalo de tempo de medição do backend sem precisar lidar com a construção manual de alvos. As propriedades do Qubit e da porta (duração, erro) são geradas por amostragem aleatória a partir de intervalos padrão. A semente para essa geração aleatória pode ser fixada para garantir a reprodutibilidade da saída do backend. É importante observar que esse backend só oferece suporte a gates na biblioteca padrão. Se você precisar de um backend mais flexível, há sempre a opção de instanciar diretamente um objeto Target para usar na transpilação.

    Exemplo de uso 1:

    from qiskit import QuantumCircuit, transpile
    from qiskit.providers.fake_provider import GenericBackendV2
    
    # Create a simple circuit
    circuit = QuantumCircuit(3)
    circuit.h(0)
    circuit.cx(0,1)
    circuit.cx(0,2)
    circuit.measure_all()
    circuit.draw('mpl')
    
    # Define backend with 3 qubits
    backend = GenericBackendV2(num_qubits=3)
    
    # Transpile and run
    transpiled_circuit = transpile(circuit, backend)
    result = backend.run(transpiled_circuit).result()

    Exemplo de uso 2:

    from qiskit import QuantumCircuit, ClassicalRegister, transpile
    from qiskit.providers.fake_provider import GenericBackendV2
    
    # Create a circuit with classical control
    creg = ClassicalRegister(19)
    qc = QuantumCircuit(25)
    qc.add_register(creg)
    qc.h(0)
    for i in range(18):
        qc.cx(0, i + 1)
    for i in range(18):
        qc.measure(i, creg[i])
    with qc.if_test((creg, 0)):
        qc.ecr(20, 21)
    
    # Define backend with custom basis gates and control flow instructions
    backend = GenericBackendV2(
        num_qubits=25,
        basis_gates=["ecr", "id", "rz", "sx", "x"],
        control_flow=True,
      )
    
    #Transpile
    transpiled_qc = transpile(qc, backend)
    Nota

    As propriedades de ruído geradas por essa classe não imitam nenhum dispositivo quântico concreto e não devem ser usadas para medir nenhum comportamento concreto. Eles são "padrões razoáveis" que podem ser usados para testar a funcionalidade de interface de back-end não vinculada a valores de ruído específicos de sistemas quânticos reais. Para uma simulação mais precisa dos dispositivos existentes, você pode criar manualmente um modelo de ruído a partir do backend real usando a funcionalidade oferecida no qiskit_aer.

  • O módulo qiskit.providers.fake_provider agora inclui uma série de backends genéricos falsos seguindo a interface BackendV1 interface. Eles foram introduzidos como uma alternativa aos back-ends falsos baseados em snapshot expostos no obsoleto FakeProvider (FakeVigo, FakeTokyo, etc.). A lista de novos back-ends falsos inclui:

    Eles podem ser importados seguindo o padrão: from qiskit.providers.fake_provider import Fake5QV1. Mais detalhes sobre as propriedades do backend podem ser encontrados na documentação da API de cada backend.

OpenQASM Características

  • O pacote qiskit.qasm3 agora contém um analisador embutido, baseado em Rust, para ler programas OpenQASM 3 no QuantumCircuits, encontrado em qiskit.qasm3.load_experimental() e loads_experimental(). Normalmente, eles são várias vezes mais rápidos do que os existentes, puros Python load() e loads() que, além disso, exigem a instalação do qiskit-qasm3-import .

    Por exemplo, podemos criar um emaranhado de 20.000 instruções QuantumCircuit:

    import numpy as np
    import qiskit.qasm3
    from qiskit.circuit.library import RealAmplitudes
    
    qc = RealAmplitudes(100, reps=100, flatten=True)
    qc = qc.assign_parameters(np.random.rand(qc.num_parameters))
    oq3 = qiskit.qasm3.dumps(qc)

    O antigo qasm3.loads() demorou cerca de 7.3s para carregar o programa OpenQASM 3 resultante, enquanto o qasm3.loads_experimental() levou menos de 300ms em um Macbook Pro de consumo ( i7, 2020) - um aumento de velocidade de 25x!

    O conjunto de recursos suportados do analisador experimental é muito limitado nesta versão de visualização, mas será ampliado à medida que o lado do Qiskit e o analisador nativo baseado em Rust forem aprimorados.

    Um de nossos principais objetivos com esse novo analisador, além das enormes melhorias de velocidade, é fornecer diagnósticos de erros de alta qualidade. Assim como em outras partes do analisador, essas são um trabalho em andamento, mas você começará a ver mensagens de erro de qualidade muito maior exibidas ao analisar programas OpenQASM 3 inválidos com o analisador experimental.

  • O exportador OpenQASM 3 (consulte dump() e dumps() em qiskit.qasm3) agora é compatível com a sintaxe estabilizada da instrução switch em OpenQASM 3 por padrão. A sintaxe de pré-certificação da declaração switch ainda está disponível usando o sinalizador ExperimentalFeatures.SWITCH_CASE_V1 no argumento experimental do exportador. Não é necessário nenhum sinalizador de recurso para a sintaxe estabilizada, mas se você estiver fazendo interface com outras ferramentas que ainda não foram atualizadas, talvez seja necessário passar o sinalizador experimental.

    A sintaxe da forma estabilizada é ligeiramente diferente no que diz respeito ao término das instruções break (não mais necessárias nem permitidas), e vários casos agora são combinados em uma única linha case , em vez de usar o fall-through no estilo C. Para obter mais detalhes, consulte a documentação do OpenQASM 3 sobre a construção do switch-case.

Recursos do QPY

  • Adicionada uma nova classe de aviso, QPYLoadingDeprecatedFeatureWarningao módulo QPY. Essa classe permite que os avisos de descontinuidade apareçam mesmo que o recurso descontinuado seja acessado em um ponto variável na pilha de chamadas, como é o caso de muitas funções de carregamento do QPY que são chamadas recursivamente.

  • Adicionado um novo sinalizador, version, à função qpy.dump() função. Isso permite que qpy.dump() opcionalmente, receba um valor inteiro para a versão do formato QPY a ser emitida. Isso é útil se você precisar gerar um arquivo QPY que será carregado por uma versão mais antiga do Qiskit. No entanto, as versões compatíveis a serem emitidas são limitadas, somente as versões entre a versão mais recente do QPY (que é a padrão) e a versão de compatibilidade do QPY, que é a Versão 10 (que foi introduzida no Qiskit 0.45.0 ), podem ser usadas. A versão de compatibilidade permanecerá fixa durante toda a série de lançamentos da versão principal do 1.x.y. Isso não altera as garantias de compatibilidade com versões anteriores do formato QPY ao chamar qpy.load()ele apenas permite que os usuários emitam uma versão mais antiga do QPY para manter a compatibilidade e a interoperabilidade entre as séries de versões 0.x e 1.x.

Recursos de informação quântica

  • Adicionado um método qiskit.quantum_info.StabilizerState.from_stabilizer_list() que gera um estado de estabilizador a partir de uma lista de estabilizadores:

    from qiskit.quantum_info import StabilizerState
    
    stabilizer_list = ["ZXX", "-XYX", "+ZYY"]
    stab = StabilizerState.from_stabilizer_list(stabilizer_list)
  • SparsePauliOp.from_operator() agora usa uma implementação do "algoritmo de decomposição tensorizada de Pauli" apresentado em Hatznko, Binkowski e Gupta (2023). O método agora é várias ordens de magnitude mais rápido; por exemplo, é possível decompor um operador aleatório de 10 qubits em cerca de 250ms em um Macbook Pro (Intel i7, 2020).

Recursos de síntese

  • Adicionada uma função qiskit.synthesis.synth_circuit_from_stabilizers() que retorna um circuito que produz o estado estabilizado por uma série de estabilizadores fornecidos.

  • O método de plug-in de síntese unitária AQC agora usa uma avaliação de função objetiva mais rápida por padrão, o que resulta em uma melhoria substancial no tempo de síntese.

  • Adicione um novo método de síntese synth_qft_line() de um circuito QFT para conectividade linear do vizinho mais próximo, que reduz significativamente o número de SWAPs para um grande número de qubits em comparação com o SABRE.

  • A classe TwoQubitWeylDecomposition foi adicionada à API pública em qiskit.synthesis. Essa classe permite aplicar a decomposição de Weyl de unitários de dois qubits. Se você estava importando isso anteriormente enquanto era uma classe não pública no módulo qiskit.quantum_info.synthesis , agora removido, deverá atualizar seus caminhos de importação.

Recursos do Transpiler

  • Adicionada uma nova classe de exceção: InvalidLayoutError. Esta é uma subclasse TranspilerError que é acionado quando um layout fornecido pelo usuário é inválido (tamanho incompatível, qubits duplicados, etc.).

  • Foi adicionado um novo argumento de palavra-chave, num_processes, a transpile() e o método PassManager.run() método. Isso permite substituir QISKIT_NUM_PROCS e o campo num_processes nos arquivos de configuração do usuário por arquivo. Por exemplo:

    from qiskit import transpile, QuantumCircuit
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    transpile([qc]*10, basis_gates=['u', 'cz'], num_processes=2)

    executará o transpile nos 10 circuitos de entrada usando apenas 2 processos e substituirá o padrão do sistema, a variável de ambiente ou o arquivo de configuração do usuário para essa transpile() chamada.

  • Adicionada uma nova passagem de transpilador, OptimizeAnnotatedque otimiza as operações anotadas em um circuito quântico.

    Considere o exemplo a seguir:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.annotated_operation import (
        AnnotatedOperation,
        InverseModifier,
        ControlModifier,
    )
    from qiskit.circuit.library import CXGate, SwapGate
    from qiskit.transpiler.passes import OptimizeAnnotated
    
    # Create a quantum circuit with multiple annotated gates
    gate1 = AnnotatedOperation(
        SwapGate(),
        [InverseModifier(), ControlModifier(2), InverseModifier(), ControlModifier(1)],
    )
    gate2 = AnnotatedOperation(
        SwapGate(),
        [InverseModifier(), InverseModifier()]
    )
    gate3 = AnnotatedOperation(
        AnnotatedOperation(CXGate(), ControlModifier(2)),
        ControlModifier(1)
    )
    qc = QuantumCircuit(6)
    qc.append(gate1, [3, 2, 4, 0, 5])
    qc.append(gate2, [1, 5])
    qc.append(gate3, [5, 4, 3, 2, 1])
    
    # Optimize the circuit using OptimizeAnnotated transpiler pass
    qc_optimized = OptimizeAnnotated()(qc)
    
    # This is how the optimized circuit should look like
    gate1_expected = AnnotatedOperation(SwapGate(), ControlModifier(3))
    gate2_expected = SwapGate()
    gate3_expected = AnnotatedOperation(CXGate(), ControlModifier(3))
    qc_expected = QuantumCircuit(6)
    qc_expected.append(gate1_expected, [3, 2, 4, 0, 5])
    qc_expected.append(gate2_expected, [1, 5])
    qc_expected.append(gate3_expected, [5, 4, 3, 2, 1])
    
    assert qc_optimized == qc_expected

    No caso de gate1, os modificadores da porta de troca anotada são trazidos para a forma canônica: os dois InverseModifiers se cancelam, e os dois ControlModifiers são combinados. No caso de gate2, todos os modificadores são removidos e a operação anotada é substituída por sua operação básica. No caso do gate3, várias camadas de anotações são combinadas em uma só.

    O construtor do OptimizeAnnotated pass aceita argumentos opcionais target, equivalence_library, basis_gates e recurse. Quando recurse é True (o valor padrão) e quando target ou basis_gates são especificados, a passagem recursivamente desce para os circuitos definition da porta, com exceção das portas que já são compatíveis com o destino ou que pertencem à biblioteca de equivalência. Por outro lado, quando nem target nem basis_gates são especificados, ou quando recurse é definido como False, a passagem sintetiza apenas as operações anotadas de "nível superior", ou seja, não desce recursivamente para os circuitos definition . Esse comportamento é consistente com o da passagem HighLevelSynthesis que precisa ser chamada para "desenrolar" as operações anotadas em portas de 1 qubit e 2 qubits.

  • Adicionado um novo HighLevelSynthesisPlugin para PermutationGate baseado no algoritmo de troca de tokens do Qiskit. Para usar esse plug-in, especifique token_swapper ao definir a configuração de síntese de alto nível.

    Esse plug-in de síntese pode ser executado antes ou depois da definição do layout. Quando a síntese é bem-sucedida, o plug-in gera um circuito quântico que consiste apenas em portas de troca. Quando a síntese não é bem-sucedida, o plug-in gera None.

    O código a seguir ilustra como o novo plug-in pode ser executado:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PermutationGate
    from qiskit.transpiler import PassManager, CouplingMap
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import HighLevelSynthesis, HLSConfig
    
    # This creates a circuit with a permutation gate.
    qc = QuantumCircuit(8)
    perm_gate = PermutationGate([0, 1, 4, 3, 2])
    qc.append(perm_gate, [3, 4, 5, 6, 7])
    
    # This defines the coupling map.
    coupling_map = CouplingMap.from_ring(8)
    
    # This high-level-synthesis config specifies that we want to use
    # the "token_swapper" plugin for synthesizing permutation gates,
    # with the option to use 10 trials.
    synthesis_config = HLSConfig(permutation=[("token_swapper", {"trials": 10})])
    
    # This creates the pass manager that runs high-level-synthesis on our circuit.
    # The option use_qubit_indices=True indicates that synthesis is run after the layout is set,
    # and hence should preserve the specified coupling map.
    pm = PassManager(
        HighLevelSynthesis(
            synthesis_config, coupling_map=coupling_map, target=None, use_qubit_indices=True
        )
    )
    
    qc_transpiled = pm.run(qc)
  • Foram adicionados dois novos argumentos, matrix_based e max_qubits, ao construtor da CommutativeInverseCancellation passagem do transpilador. Quando matrix_based é True, a passagem usa representações de matriz para verificar se duas operações são o inverso uma da outra. Isso torna as verificações mais eficientes e, além disso, permite o cancelamento de pares de operações que são inversas até uma fase, enquanto atualiza a fase global do circuito de acordo. Em geral, isso resulta em mais reduções à custa do aumento do tempo de execução. O argumento max_qubits limita o número de qubits em verificações de comutatividade e inversas baseadas em matrizes. Por exemplo:

    import numpy as np
    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import CommutativeInverseCancellation
    
    circuit = QuantumCircuit(1)
    circuit.rz(np.pi / 4, 0)
    circuit.p(-np.pi / 4, 0)
    
    passmanager = PassManager(CommutativeInverseCancellation(matrix_based=True))
    new_circuit = passmanager.run(circuit)

    A passagem é capaz de cancelar as portas RZ e P , enquanto ajusta a fase global do circuito para 15π8\frac{15 \pi}{8}.

  • Adicionada uma nova função, high_level_synthesis_plugin_names()que pode ser usada para obter a lista de plug-ins de síntese de alto nível instalados para um determinado nome de operação.

Recursos de visualização

  • As saídas text e mpl para o QuantumCircuit.draw() e circuit_drawer() agora exibirão informações detalhadas sobre as operações de AnnotatedOperation. Se o site AnnotatedOperation.modifiers contiver um ControlModifiera operação será exibida da mesma forma que as portas controladas. Se o InverseModifier ou PowerModifier for usado, eles serão indicados com o nome da operação básica. Por exemplo:

    from qiskit.circuit import (
        AnnotatedOperation,
        ControlModifier,
        PowerModifier,
        InverseModifier,
        QuantumCircuit
    )
    from qiskit.circuit.library import SGate
    
    annotated_op = AnnotatedOperation(SGate(), [PowerModifier(3.4), ControlModifier(3), InverseModifier()])
    qc = QuantumCircuit(4)
    qc.append(annotated_op, range(4))
    qc.draw("mpl")
    _images/release_notes-1.png

Páginas Recursos

  • Adicionada uma nova classe base de aviso, QiskitWarning. Embora o Qiskit continue a usar os avisos incorporados do Python (como DeprecationWarning) quando estes forem mais apropriados, para casos mais específicos do Qiskit, os avisos serão subclasses de QiskitWarning.

  • Os testadores de funcionalidade opcional (qiskit.utils.optionals) agora distinguirão uma dependência opcional que não foi encontrada (uma situação normal) de uma que foi encontrada, mas gerou erros durante sua importação. Nesse último caso, eles agora emitirão uma mensagem OptionalDependencyImportWarning informando o que aconteceu, pois isso pode indicar uma falha na instalação ou uma versão incompatível.

Notas da Atualização

  • O Qiskit 1.0 agora requer a versão 0.14.0 de rustworkx. O requisito de versão mínima foi aumentado para oferecer suporte ao novo plug-in de síntese token_swapper PermutationGate plug-in de síntese para o HighLevelSynthesisPlugin.

  • A versão mínima suportada do Rust para a criação do Qiskit a partir do código-fonte agora é 1.70. Isso foi aumentado em relação à versão mínima compatível anterior do Rust do 1.64 na série de versões do Qiskit 0.45.x e 0.46.0.

  • A dependência do psutil foi removida. A biblioteca psutil era usada anteriormente apenas para detectar o número de CPUs físicas e a memória total do sistema; no entanto, essas informações fornecidas não agregam valor suficiente para justificar as dependências e a sobrecarga adicionais, por isso foram removidas. Isso significa que o número padrão de processos usados por parallel_map() e funções que internamente podem usar parallel_map() como transpile() e PassManager.run() podem usar mais ou menos processos paralelos do que nas versões anteriores. Se quiser ajustar o número de processos usados, você pode usar o novo argumento num_processes para essas funções, ou a variável de ambiente QISKIT_NUM_PROCS ou o campo num_processes em um arquivo de configuração do usuário (consulte o guia de configuração local para obter mais detalhes) se precisar ajustar o número de processos que o Qiskit potencialmente usa.

  • Os métodos scoped_parameters e search_parameters foram removidos da classe ScheduleBlock classe. Esses métodos retornaram Parameter que estavam parcialmente vinculados aos parâmetros na instância ScheduleBlock mas a atribuição de valores usando esses objetos não funcionou corretamente. Os usuários devem usar ScheduleBlock.parameters em vez disso e iterar através de ScheduleBlock.references e comparar com os atributos Schedule.parameters das sub-referências quando for necessário distinguir em qual sub-rotina um parâmetro é usado. Consulte #11654 para obter mais informações.

  • Removida a lógica de injeção de QuantumCircuit e Gate no contexto do pulso (como em pulse.builder.call()), que era um comportamento legado obsoleto no Qiskit 0.46. As programações de pulso devem ser construídas como um contexto de programação completo; os circuitos e as portas são um nível mais alto de abstração.

    Isso inclui a remoção das funções relacionadas:

    • pulse.builder.call_gate
    • pulse.builder.cx
    • pulse.builder.u1
    • pulse.builder.u2
    • pulse.builder.u3
    • pulse.builder.x
    • pulse.builder.active_transpiler_settings
    • pulse.builder.active_circuit_scheduler_settings
    • pulse.builder.transpiler_settings
    • pulse.builder.circuit_scheduler_settings

    Os argumentos default_transpiler_settings e default_circuit_scheduler_settings para pulse.builder.build() são removidos da mesma forma.

    from qiskit import transpile, schedule, QuantumCircuit, pulse
    from qiskit.providers.fake_provider import Fake7QPulseV1
    
    backend = Fake7QPulseV1()
    
    # Create a schedule from a hardware-based circuit.
    qc = QuantumCircuit(2)
    qc.cx(0, 1)
    qc = transpile(qc, backend)
    sched = schedule(qc, backend)
    
    # These pulse schedules can still be called in builder contexts.
    with pulse.build(backend) as qc_sched:
      pulse.call(sched)
    
    # Schedules for certain operations can also be directly retrieved
    # from BackendV1 instances:
    sched = backend.defaults().instruction_schedule_map.get('x', (0,))
    
    # ... and from BackendV2 instances:
    sched = backend.target['x'][(0,)].calibration
  • A versão mínima exigida para o symengine foi aumentada para >= 0.11.

Notas sobre atualização de circuitos

  • Removido o método Instruction.qasm , que foi preterido no Qiskit 0.45.0. Use qiskit.qasm2.dump() com um QuantumCircuit em vez disso.

  • As propriedades Bit.register e Bit.index são removidas. Eles foram descontinuados no Qiskit 0.25 (lançado em 2021-04). Os qubits e bits agora vivem apenas no contexto de um QuantumCircuit. A alternativa às propriedades é usar QuantumCircuit.find_bit() para encontrar todos os registros contidos em um circuito e o índice do bit no circuito.

  • O método QuantumCircuit.bind_parameters foi removido, após sua descontinuação no Qiskit 0.45. Você pode usar o QuantumCircuit.assign_parameters() como um substituto imediato, com todos os seus padrões, e também expõe recursos adicionais em relação ao método antigo.

  • A importação de Int1, Int2, BooleanFunction, classical_function() de qiskit.circuit agora está desativado. Em vez disso, importe os objetos do submódulo qiskit.circuit.classicalfunction que requer o pacote tweedledum .

  • Os atributos header e extension_lib somente de dados de QuantumCircuit foram removidos após sua descontinuação no Qiskit 0.45. Esses eram detalhes internos do exportador OpenQASM 2 que não são mais usados.

  • Removido o módulo qiskit.extensions , que estava pendente de descontinuação desde a versão 0.45 e foi totalmente descontinuado na versão 0.46. As seguintes operações desse módulo estão disponíveis em qiskit.circuit.library:

    Os seguintes objetos foram removidos:

    • SingleQubitUnitary (em vez disso, use library.UnitaryGate),
    • Snapshot (substituído pelas instruções de salvamento da Aer),
    • ExtensionError,

    juntamente com os seguintes métodos de circuito:

    • QuantumCircuit.snapshot,
    • QuantumCircuit.squ,
    • QuantumCircuit.diagonal,
    • QuantumCircuit.hamiltonian,
    • QuantumCircuit.isometry e QuantumCircuit.iso,
    • QuantumCircuit.uc,
    • QuantumCircuit.ucrx,
    • QuantumCircuit.ucry,
    • QuantumCircuit.ucrz.

    Essas operações ainda podem ser realizadas anexando a instrução apropriada a um circuito quântico.

  • Remoção de métodos obsoletos e duplicados QuantumCircuit métodos. Dentre eles:

  • Você não pode mais definir QuantumCircuit.metadata para ser None, após a depreciação no Qiskit 0.43.0. Seu tipo é dictportanto, para limpá-lo, defina-o como {}.

  • O atributo .Register.name_format foi removido após sua descontinuidade no Qiskit 0.40.0. Não há mais restrições para nomes de registros, e a expressão regular era simplesmente [a-z][a-zA-Z0-9_]*.

Notas sobre a atualização dos primitivos

Notas de atualização dos fornecedores

  • Alterado o valor padrão de dois argumentos (add_delay e filter_faulty) na função convert_to_target() função. Essa função de conversão agora adiciona instruções de atraso e remove instruções defeituosas por padrão.

  • O BackendProperties e PulseDefaults usados pelo aplicativo FakeOpenPulse2Q foram atualizados para serem internamente consistentes e para adicionar instruções ausentes. Se você estava contando com os objetos do modelo anterior como alvo de compilação, poderá usar o backend com o Qiskit 0.46 e exportar um QuantumCircuit gerado com transpile() e serializá-lo usando qpy.dump para acessá-lo nesta versão.

  • O módulo qiskit.providers.basicaer , exposto como qiskit.BasicAer, foi removido após sua descontinuidade na versão 0.46. Sua funcionalidade foi substituída pelo módulo qiskit.quantum_info e pelo novo módulo qiskit.providers.basic_provider módulo.

    A migração do uso do site qiskit.providers.basicaer (qiskit.BasicAer) para qiskit.providers.basic_provider pode ser realizada da seguinte forma:

    Migrar de
    Substituir por
    qiskit.BasicAerO novo provedor não tem uma instância global, as importações devem ser de qiskit.providers.basic_provider
    qiskit.providers.basicaerbasic_provider
    BasicAerProviderBasicProvider
    BasicAerJobBasicProviderJob
    QasmSimulatorPyBasicSimulator
    UnitarySimulatorPyuso Operator
    StatevectorSimulatorPyuso Statevector

    Uma diferença notável é que o novo provedor não é mais exposto por meio de uma instância global (como BasicAer), portanto, não será válido fazer from qiskit import BasicProvider. Em vez disso, a classe do provedor deve ser importada de seu submódulo e instanciada manualmente:

    from qiskit.providers.basic_provider import BasicProvider
    
    provider = BasicProvider()
    backend = provider.get_backend("basic_simulator")

    Os exemplos a seguir mostram os caminhos de migração dos três simuladores em BasicAer.

    1. Simulador de vetor de estado:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("statevector_simulator")
      statevector = backend.run(qc).result().get_statevector()
      
      # New path
      from qiskit.quantum_info import Statevector
      statevector = Statevector(qc)
    2. Simulador unitário:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("unitary_simulator")
      result = backend.run(qc).result()
      
      # New path
      from qiskit.quantum_info import Operator
      result = Operator(qc).data
    3. Simulador de Qasm:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      qc.measure_all()
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("qasm_simulator")
      result = backend.run(qc).result()
      
      # New path
      from qiskit.providers.basic_provider import BasicProvider
      backend = BasicProvider().get_backend("basic_simulator")
      result = backend.run(qc).result()
      # or, directly
      from qiskit.providers.basic_provider import BasicSimulator
      backend = BasicSimulator()
      result = backend.run(qc).result()
  • Removida a classe ConfigurableFakeBackend , obsoleta no Qiskit 0.46.0. Em vez disso, um FakeBackend adequado pode ser usado.

  • 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

Notas sobre a atualização do Pulse

  • Removida a classe obsoleta qiskit.pulse.instructions.Call Nenhuma instrução de pulso alternativa é fornecida.

  • Remoção de métodos obsoletos em InstructionToQobjConverter e QobjToInstructionConverter. Isso inclui

    • InstructionToQobjConverter.convert_acquire()
    • InstructionToQobjConverter.convert_bundled_acquires()
    • InstructionToQobjConverter.convert_set_frequency()
    • InstructionToQobjConverter.convert_shift_frequency()
    • InstructionToQobjConverter.convert_set_phase()
    • InstructionToQobjConverter.convert_shift_phase()
    • InstructionToQobjConverter.convert_delay()
    • InstructionToQobjConverter.convert_play()
    • InstructionToQobjConverter.convert_snapshot()
    • QobjToInstructionConverter.convert_acquire()
    • QobjToInstructionConverter.convert_set_phase()
    • QobjToInstructionConverter.convert_shift_phase()
    • QobjToInstructionConverter.convert_set_frequency()
    • QobjToInstructionConverter.convert_shift_frequency()
    • QobjToInstructionConverter.convert_delay()
    • QobjToInstructionConverter.bind_pulse()
    • QobjToInstructionConverter.convert_parametric()
    • QobjToInstructionConverter.convert_snapshot()

    Esses métodos públicos são todos substituídos por métodos protegidos que são chamados implicitamente a partir do ponto de entrada único, ou seja, chamando a classe como se fosse uma função.

  • A classe qiskit.pulse.library.ParametricPulse e todas as subclasses são removidas. Eles foram descontinuados desde o Qiskit 0.39 (com qiskit-terra 0.22 ), lançado em 2022-10. Em vez disso, use SymbolicPulse e verifique sua documentação para obter detalhes.

OpenQASM Notas sobre a atualização

  • Os métodos qasm() das classes QuantumRegister e ClassicalRegister foram removidos. Não há necessidade de substituição; esses eram detalhes internos de uma implementação herdada do exportador OpenQASM 2. Para exportar um programa para OpenQASM 2, use qasm2.dump() ou qasm2.dumps().

Notas de atualização do QPY

  • A versão de formato mais recente do QPY agora é a Versão 11 e é isso que é emitido por padrão ao executar qpy.dump().

  • O caminho do módulo qiskit.circuit.qpy_serialization foi removido, após sua descontinuação no Qiskit 0.40.0. Para a serialização QPY, use qiskit.qpyque é o novo local.

Notas sobre a atualização das informações quânticas

  • Removidos os métodos mágicos obsoletos __getitem__/__setitem__ de Clifford. Os métodos foram descontinuados desde o Qiskit 0.44, lançado em 2023-07. Em vez disso, indexe ou itere pelo atributo Clifford.tableau .

  • Removido o módulo qiskit.quantum_info.synthesis , que está obsoleto desde a versão 0.46. Os seguintes objetos foram movidos para qiskit.synthesis:

    Essa função foi removida, pois já foi descontinuada na versão 0.46 : * cnot_rxx_decompose

    Essas funções foram removidas, pois já haviam sido descontinuadas em uma versão anterior: * decompose_clifford (use synth_clifford_full() em vez disso) * decompose_cnotdihedral (use synth_cnotdihedral_full() em seu lugar)

  • As funções process_fidelity(), average_gate_fidelity(), gate_error() e diamond_norm() não tentarão mais coagir entradas arbitrárias para seus tipos esperados marcados, seguindo a depreciação no Qiskit 0.25.0. Passe entradas dos tipos marcados para cada argumento diretamente.

Notas sobre a atualização da síntese

Notas sobre a atualização do Transpiler

  • O método obsoleto Target.aquire_alignment foi removido. Ele foi marcado como obsoleto no Qiskit 0.43 (lançado em 2023-05). Em vez disso, deve ser usado o método Target.acquire_alignment() .

  • Removida a função obsoleta qiskit.transpiler.preset_passmanagers.common.get_vf2_call_limit. Em vez disso, use o get_vf2_limits().

  • O uso implícito de approximation_degree!=1.0 por padrão na função generate_preset_pass_manager() foi desativado. O padrão anterior poderia causar aproximações indevidas e inesperadas, especialmente em cargas de trabalho que envolvem Trotterização ou execuções similares de operações que são próximas, mas decididamente não iguais, à identidade.

    Essa alteração alinha os padrões internos de geração do gerenciador de passes com transpile()que sempre foi a intenção. Consulte o número 8595 para obter mais detalhes.

  • Removida a classe Unroller obsoleta em qiskit.transpiler.passes.basis. Essa classe foi descontinuada no Qiskit 0.45 e seu uso pode ser substituído pelo uso combinado de BasisTranslator e UnrollCustomDefinitions.

    Observe que BasisTranslator e UnrollCustomDefinitions recebem argumentos diferentes de Unroller, pois exigem que um objeto EquivalenceLibrary seja passado.

    Onde antes era possível usar Unroller(basis_gates) , agora é possível usar:

    from qiskit.circuit.library.standard_gates.equivalence_library import (
        StandardEquivalenceLibrary as std_eqlib,
    )
    pm = PassManager([
        UnrollCustomDefinitions(std_eqlib, basis_gates)
        BasisTranslator(std_eqlib, basis_gates),
    ])
    translated = pm.run(circuit)
  • A passagem obsoleta do transpilador NoiseAdaptiveLayout foi removida. Ele foi marcado como obsoleto no Qiskit 0.46.0. Esse passe foi amplamente substituído pelo VF2Layout e VF2PostLayout que definirá um layout com base nas características de ruído relatadas de um backend. Junto com o passe, o plug-in layout_method "noise_adaptive" foi removido.

  • A passagem obsoleta do transpilador CrosstalkAdaptiveSchedule foi removida. Ele foi marcado como obsoleto no Qiskit 0.46.0. Essa passagem não era mais utilizável porque sua operação interna dependia da definição de propriedades personalizadas na BackendProperties carga útil de uma BackendV1 instância. Como nenhum backend está definindo esses campos, a passagem foi removida. Se você depender do passe para um fluxo de trabalho personalizado, poderá usar a versão no Qiskit 0.46.x.

  • Removido o módulo qiskit.transpiler.synthesis , que está obsoleto desde a versão 0.46. Os seguintes objetos foram movidos:

  • O alias da palavra-chave target ao chamar instâncias TwoQubitBasisDecomposer como funções foi removida após sua descontinuação no Qiskit 0.40.0. Você deve passar o argumento de forma posicional como o primeiro argumento ou usar o novo nome unitary.

  • A passagem especializada do transpilador LinearFunctionsSynthesis foi removida após sua descontinuidade no Qiskit 0.40.0. Desde sua descontinuação, ele tem sido apenas um invólucro muito fino em torno do HighLevelSynthesisque você deve usar em seu lugar.

  • O caminho de importação qiskit.transpiler.passes.scheduling.calibration_creators foi removido. O transpilador passa por ele, RZXCalibrationBuilder e RZXCalibrationBuilderNoEcho pode ser importado diretamente do qiskit.transpiler.passes.

  • O caminho de importação qiskit.transpiler.passes.scheduling.rzx_templates foi removido. Você deve importar rzx_templates() de qiskit.transpiler.passes diretamente.

  • Um padrão para a construção da linha de passagem foi atualizado. O açúcar sintático mostrado abaixo para a instanciação do controlador de fluxo foi removido.

    from qiskit.transpiler import PassManager
    
    pm = PassManager()
    pm.append(my_pass, condition=condition_callable, do_while=do_while_callable)

    Em vez de usar esse padrão de argumento de palavra-chave, você deve instanciar explicitamente o controlador de fluxo.

    from qiskit.passmanager import ConditionalController, DoWhileController
    from qiskit.transpiler import PassManager
    
    pm = PassManager()
    pm.append(
      ConditionalController(
        DoWhileController(my_pass, do_while=do_while_callable),
        condition=condition_callable,
      )
    )

    Observe que você pode gerenciar a ordem de classificação dos controladores quando quiser aninhá-los, o que não era possível com argumentos de palavras-chave. Você também pode criar o pipeline com o construtor do gerenciador de passes, como abaixo, porque não há motivo para chamar o método append agora.

    pm = PassManager(
      ConditionalController(
        DoWhileController(my_pass, do_while=do_while_callable),
        condition=condition_callable,
      )
    )
  • O método append dos controladores de fluxo incorporados foi removido. Isso inclui

    • ConditionalController.append
    • DoWhileController.append
    • FlowControllerLinear.append

    O pipeline de tarefas em um controlador de fluxo é congelado e deve ser passado quando a instância do controlador é criada.

  • Removidos os métodos passess de PassManager e StagedPassManager que retornavam uma representação dos passes incluídos na forma de uma lista de dicionários. Entretanto, esse formato não representa eficientemente um pipeline de passagem mais complicado, que pode incluir ramificação condicional e condições aninhadas. Em vez de usar essa representação, use o seguinte padrão

    pm = PassManager(...)
    pm.to_flow_controller().tasks

    Retorna diretamente uma instância de tarefa básica linearizada no formato de tupla.

  • O argumento max_iteration foi removido de PassManager.append() e PassManager.replace().

  • As seguintes classes legadas foram removidas dos módulos do gerenciador de passes e do transpilador após sua descontinuação no Qiskit 0.46:

    • qiskit.passmanager.flow_controllers.FlowController
    • qiskit.transpiler.fencedobjs.FencedObject
    • qiskit.transpiler.fencedobjs.FencedPropertySet
    • qiskit.transpiler.fencedobjs.FencedDAGCircuit
    • qiskit.transpiler.runningpassmanager.RunningPassManager

Notas sobre a atualização da visualização

  • O estilo padrão para a visualização do circuito usando Matplotlib foi alterado para "iqp", correspondendo à Plataforma Quantum IBM.

  • O módulo obsoleto qiskit.visualization.qcstyle foi removido. Esse módulo foi marcado como obsoleto desde o Qiskit 0.39.0. Em vez disso, você deve usar o endereço qiskit.visualization.circuit.qcstyle.

  • O suporte obsoleto para passar um QuasiDistribution, ProbDistributionou um dicionário de distribuição para o argumento data da plot_histogram() foi removido. Essa funcionalidade foi marcada como obsoleta na versão do Qiskit 0.39.0 (2022-10). Em vez disso, se você quiser traçar um histograma de um QuasiDistribution, ProbDistributionou de um dicionário de distribuição, deverá usar a função plot_distribution() em vez disso.

  • A chave link_interval_dt de QiskitTimelineStyle foi removida. Você deve usar o novo nome link_interval_percent.

Páginas Notas da Atualização

  • O objeto qiskit.Aer foi removido após sua descontinuação no Qiskit 0.46. Em vez disso, você pode usar o site qiskit_aer.Aer, que é um substituto imediato.

  • A importação a partir de qiskit.providers.aer não funcionará mais, após sua descontinuação no Qiskit 0.46. Em vez disso, você deve importar do site qiskit_aer, que é um substituto imediato.

  • Os trabalhos de pulso não são mais compatíveis com back-ends falsos, após a depreciação e a remoção da funcionalidade de simulação subjacente no Aer. Para simulação em nível de pulso, fora do contexto de objetos de circuito, considere o uso de uma biblioteca para fins especiais, como a Qiskit Dynamics.

  • A função execute() do Qiskit foi removida. Essa função serviu como um invólucro de alto nível para transpilar um circuito com algumas opções de transpile e executá-lo em um backend com algumas opções de execução. Para fazer a mesma coisa, você pode usar explicitamente a função transpile() (com as opções de transpile apropriadas) seguida por backend.run() (com as opções de execução apropriadas).

    Por exemplo, em vez de executar:

    from qiskit import execute
    job = execute(circuit, backend)

    você pode correr:

    from qiskit import transpile
    new_circuit = transpile(circuit, backend)
    job = backend.run(new_circuit)

    Como alternativa, a primitiva Sampler é semanticamente equivalente à função obsoleta execute() . A classe BackendSampler é um invólucro genérico para backends que não oferecem suporte a primitivos:

    from qiskit.primitives import BackendSampler
    sampler = BackendSampler(backend)
    job = sampler.run(circuit)
  • O objeto obsoleto qiskit.IBMQ foi removido. Esse objeto de alias foi marcado como obsoleto na versão do Qiskit 0.40.0. Esse objeto de alias redirecionou preguiçosamente o acesso ao atributo para qiskit.providers.ibmq.IBMQ. Como o pacote qiskit-ibmq-provider já foi retirado e substituído pelo pacote qiskit-ibm-provider , que mantém seu próprio namespace, a manutenção desse alias não é mais relevante. Se você estava usando o alias qiskit.IBMQ , deve migrar seu uso para o pacote qiskit-ibm-provider . Consulte o guia de migração para obter mais detalhes.

  • Removido o módulo obsoleto qiskit.tools.jupyter , que anteriormente incluía Jupyter magics e widgets para visualizar interativamente alguns dados do Qiskit. Esse módulo foi descontinuado no Qiskit 0.46.0. A maior parte dessa funcionalidade estava diretamente vinculada ao pacote legado qiskit-ibmq-provider e não era mais válida, portanto, o módulo foi removido. Funcionalidade semelhante está disponível no módulo qiskit_ibm_provider.jupyter do pacote qiskit-ibm-provider.

  • Removido o módulo obsoleto qiskit.tools.monitor , que anteriormente incluía ferramentas para rastrear instâncias de trabalho JobV1 instâncias de trabalho, principalmente do pacote legado qiskit-ibm-provider . Esse módulo foi marcado como obsoleto no Qiskit 0.46.0. Ele está sendo removido porque estava diretamente vinculado ao pacote legado qiskit-ibm-provider .

  • Removido o caminho de importação obsoleto qiskit.test.mock , que anteriormente era usado para redirecionar as importações dos back-ends simulados para seu novo local no arquivo qiskit.providers.fake_provider. Esse módulo foi marcado como obsoleto no Qiskit 0.37.0. Se você estiver usando esse módulo, deverá atualizar suas importações de qiskit.test.mock para qiskit.providers.fake_provider em vez disso.

  • O módulo qiskit.test não é mais um módulo público. Nunca foi planejado para ser público nem usado fora do próprio conjunto de testes do Qiskit. Toda a funcionalidade era específica do Qiskit e nenhuma alternativa é fornecida; se você precisar de uma funcionalidade semelhante, deverá incluí-la em seus próprios chicotes de teste.

  • O módulo obsoleto qiskit.tools.visualization foi removido. Esse módulo foi descontinuado na versão do Qiskit 0.46.0. Esse módulo era um redirecionamento herdado do local original do módulo de visualização do Qiskit e foi movido para qiskit.visualization no Qiskit 0.8.0. Se você ainda estiver usando esse caminho, basta atualizar suas importações de qiskit.tools.visualization para qiskit.visualization.

  • O módulo qiskit.tools.events obsoleto e o utilitário qiskit.tools.progressbar correspondente que ele expunha foram removidos. Ele foi descontinuado na versão do Qiskit 0.46.0. A funcionalidade desse módulo não era muito usada e era melhor coberta por pacotes dedicados, como o tqdm.

  • O módulo qiskit.tools foi removido. Esse módulo foi descontinuado no Qiskit 0.46.0. Todo o conteúdo desse módulo foi removido, exceto a função qiskit.tools.parallel_map , que agora pode ser usada em qiskit.utils.parallel_map() em seu lugar.

Descontinuidade de primitivas

  • Os métodos PrimitiveJob.submit() e PrimitiveJob.wait_for_final_state() foram removidos após sua descontinuidade no Qiskit 0.46. Esses métodos não deveriam ser públicos, mas eram um legado de uma estrutura de herança incorreta.

Correções de bugs

  • Corrigido o retorno de programações de medição impróprias quando apenas um subconjunto de qubits era solicitado. Anteriormente, era retornado um cronograma de medição para todos os qubits.

  • Foi corrigido um problema na gaveta do circuito text ao exibir operações que não eram de circuit.instruction.Instruction classe. Essas operações causariam a falha da gaveta. Os exemplos são Clifford e AnnotatedOperation.

  • Foi corrigido um problema com a passagem do SetLayout em que uma entrada de lista de números inteiros inválida que continha entradas duplicadas resultava em um Layout inválido sendo gerado, e as passagens subsequentes do transpilador falhavam com um erro enigmático. Isso agora é detectado quando SetLayout.run() é chamado, um erro InvalidLayoutError será gerado um erro indicando que há entradas duplicadas na lista de inteiros.

  • QPY (usando qpy.dump() e qpy.load()) agora serializará e deserializará corretamente os circuitos quânticos com operações anotadas (AnnotatedOperation).

  • Chamada copy() ou copy_empty_like() em um BlueprintCircuit agora propagará corretamente o global_phase para a cópia. Anteriormente, a fase global seria sempre zero após a cópia.

  • QuantumCircuit.compose() agora exibirá corretamente um CircuitError quando houver duplicatas nos argumentos qubits ou clbits .

  • QPY (usando qpy.dump() e qpy.load()) agora irá serializar e desserializar corretamente os circuitos quânticos com operadores Clifford (Clifford).

  • Foi corrigido um problema na gaveta de circuito mpl em que o texto era impresso além do final da caixa para um SwitchCaseOp se a caixa padrão estivesse vazia.

  • A transmissão do argumento qubit de QuantumCircuit.delay() agora produz corretamente instruções Delay individuais para cada qubit, conforme pretendido. Anteriormente, ao receber determinados iteráveis (como sets), ele produzia silenciosamente um circuito inválido que poderia falhar em locais incomuns.

  • Foi corrigido um problema ao usar transpile() ou executando um gerenciador de passagens predefinido (como o gerado por generate_preset_pass_manager()) ao direcionar um backend que tem conectividade disjunta, adicionando barreiras extras à saída QuantumCircuit. Em alguns casos, várias diretivas de qubit único Barrier seriam incluídas no circuito de saída logo antes de qualquer medição final no circuito. Esse era um estado interno gerado pelo processamento interno para conectividade disjunta que estava sendo adicionada incorretamente ao circuito de saída. Corrigido #11649

  • Foi corrigido um erro quando um usuário tentava carregar os dados de calibração de uma porta de um sistema de controle de acesso Target em uma situação específica. Isso ocorre quando o backend informa apenas dados de calibração parciais, por exemplo, referenciando um pulso de forma de onda em uma definição de comando, mas não incluindo esse pulso de forma de onda na biblioteca de pulsos. Nessa situação, o objeto de pulso do Qiskit não pôde ser criado, resultando em uma falha na criação da programação de pulso para a calibração. Agora, quando os dados de calibração estão incompletos, o Target trata isso como equivalente a nenhuma calibração sendo relatada e não gera uma exceção.

  • O método Operator.power() agora funciona com expoentes de ponto flutuante, de acordo com a descrição documentada.

  • Foi corrigido um problema com a passagem OptimizeSwapBeforeMeasure em que ela otimizava incorretamente os circuitos que envolviam instruções de troca e medição. Por exemplo:

    from qiskit import QuantumCircuit
    from qiskit.transpiler.passes import OptimizeSwapBeforeMeasure
    pass_ = OptimizeSwapBeforeMeasure()
    qc = QuantumCircuit(2, 1)
    qc.swap(0, 1)
    qc.measure(0, 0)
    qc.measure(0, 0)
    print(qc.draw())
    print(pass_(qc).draw())

    seria impresso anteriormente:

            ┌─┐┌─┐
    q_0: ─X─┤M├┤M├
          │ └╥┘└╥┘
    q_1: ─X──╫──╫─
             ║  ║
    c: 1/════╩══╩═
             0  0
         ┌─┐
    q_0: ┤M├───
         └╥┘┌─┐
    q_1: ─╫─┤M├
          ║ └╥┘
    c: 1/═╩══╩═
          0  0

    e agora o segundo circuito está otimizado corretamente para:

    q_0: ──────
         ┌─┐┌─┐
    q_1: ┤M├┤M├
         └╥┘└╥┘
    c: 1/═╩══╩═
          0  0
  • Foi corrigido um problema com a serialização do QPY quando um QuantumCircuit continha várias instâncias de instruções personalizadas que tinham o mesmo name atributo. Nas versões do formato QPY anteriores à Versão 11, a carga útil do QPY não diferenciava essas instâncias e apenas serializava as propriedades da primeira instância em um circuito. Isso poderia causar uma desserialização incorreta se as outras propriedades da instrução personalizada fossem diferentes, mas os nomes fossem os mesmos. Isso foi corrigido na versão 11 do QPY, de modo que cada instância de uma instrução personalizada é serializada individualmente e não haverá mais um possível conflito com nomes sobrepostos. Correções #8941.

  • 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.

  • Corrigir um erro na representação de StabilizerState representação de string.

  • Um bug onde convert_to_target() e BackendV2Converter gerava um erro inesperado foi resolvido. O erro ocorria quando o backend a ser convertido incluía calibrações para uma porta que não tinha uma definição nas propriedades do backend. Essa porta agora é transmitida a todos os qubits como uma instrução ideal sem erros, mesmo quando são relatadas calibrações para um conjunto finito de qubits.

  • 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.

  • InstructionDurations.from_backend() agora retorna uma instância de qualquer subclasse de InstructionDurations em vez da classe base.

  • A passagem do UnitarySynthesis agora gerará um erro na inicialização quando um plug-in de síntese inexistente for especificado, em vez de esperar até o tempo de execução para gerar o erro. Corrigido #11355.

  • Os exportadores do OpenQASM 3 qasm3.dump() e dumps() agora produzirão corretamente arquivos que afirmam ser da versão 3.0 em vez da não qualificada 3, já que o projeto OpenQASM 3 agora padronizou o controle de versão.

  • A forma paramétrica de XXPlusYYGate e XXMinusYYGate retornada de get_standard_gate_name_mapping() agora inclui corretamente o parâmetro β\beta, bem como a rotação inicial de θ\theta.

  • A passagem TemplateOptimization agora retornará expressões paramétricas usando o formato nativo de expressão simbólica do ParameterExpressionem vez de usar sempre o Sympy. Para a maioria das plataformas compatíveis, isso significa que as expressões serão objetos Symengine. Anteriormente, a passagem poderia retornar objetos incompatíveis, o que poderia levar a falhas posteriores no código de manipulação de parâmetros.

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.