Skip to main content
IBM Quantum Platform

Qiskit SDK 2.2 notas de versão


2.2.3

Prelúdio

O Qiskit 2.2.3 corrige um bug que foi introduzido pelo Qiskit 2.2.2 ao usar o run() método em um PassManager para mais de um circuito.

Notas da Atualização

  • ConsolidateBlocks agora lê uma PropertySet chave ConsolidateBlocks_qubit_map na entrada. Esta chave e seu valor não são públicos e não devem ser lidos ou gravados por outros passes.

Correções de bugs

  • Reutilização fixa da mesma ConsolidateBlocks instância em vários circuitos, incluindo chamadas para mais de um transpile() circuito e sem paralelização baseada em processos. Um bug introduzido no Qiskit 2.2.2 fazia com que o passe entrasse em pânico ou produzisse resultados inválidos se a mesma instância fosse reutilizada em circuitos diferentes.

2.2.2

Prelúdio

O Qiskit 2.2.2 é uma versão de correção de bugs para a série de versões secundárias v2.2.

Correções de bugs

  • Corrigida a implementação do __deepcopy__() em QuantumCircuit que não copiava profundamente os parâmetros do circuito. Como consequência, a mutação de um BoxOp em um circuito copiado não afeta mais o circuito original.

  • Corrigido um problema na passagem Optimize1qGatesDecomposition quando a passagem é inicializada com uma Target contendo portas de 1 qubit com parâmetros de ângulo fixos. Anteriormente, a passagem poderia gerar portas não incluídas no destino, pois não verificava se as portas no destino suportavam valores de parâmetros arbitrários. Corrigido #14743.

  • Corrigido comportamento incorreto na BasisTranslator passagem em que um portão multi-qubit dentro de um ControlFlowOp bloco rastreava usando seus índices de qubit locais em vez de usar os índices absolutos do circuito de origem.

  • A passagem do ConsolidateBlocks transpiler agora avaliará corretamente se um determinado gate é compatível com o hardware enquanto recursiona em operações de fluxo de controle.

  • qpy.dump() agora pode lidar com a gravação em .gz arquivos abertos usando o módulo da gzip biblioteca padrão com versões QPY 16 ou superiores. Consulte o número 15157 para obter mais detalhes.

  • Corrigido o método MCPhaseGate.inverse() para preservar os estados de controle dos portões controlados abertos ao calcular seus inversos.

  • ConsolidateBlocks agora retornará uma exceção de espaço Python em vez de entrar em pânico quando detectar uma análise inválida ou desatualizada nas chaves block_listPropertySet legadas run_list ou. Corrigido #14646.

  • Optimize1qGatesDecomposition agora irá gerar um TranspilerError em vez de um panic do Rust-space ao tentar executar em um circuito que é muito grande para o Target. Corrigido #15116.

  • Os passes de programação, ALAPScheduleAnalysis e ASAPScheduleAnalysis, agora lidarão corretamente com circuitos sem operações. Anteriormente, eles levantaram uma alegação TranspilerError falsa de que “não foram fornecidas durações”. Corrigido #15145.

  • Corrigida uma falha na caixa de texto do circuito, que podia ocorrer quando blocos de circuito dentro de operações de fluxo de controle eram definidos em registros diferentes dos do circuito externo. Essa situação pode ocorrer, por exemplo, ao anexar ControlFlowOp operações diretamente ou para circuitos após a transpilagem.


2.2.1

Prelúdio

O Qiskit 2.2.1 é uma pequena versão de correção que corrige vários erros identificados na versão 2.2.0.

Notas sobre a atualização do Transpiler

  • Os limites máximos de chamadas e testes para a execução de correspondência exata de VF2PostLayout em optimization_level=3 foram reduzidos para evitar tempos de execução excessivos para circuitos de teste altamente simétricos mapeados para grandes mapas de acoplamento.

Correções de bugs

  • DAGCircuit.apply_operation_back(), apply_operation_back() e agora circuit_to_dag() adicionará novas arestas em uma ordem determinística. O comportamento anterior poderia fazer com que certas passagens do transpiler (como SabreSwap) percorressem o DAG em ordens não determinísticas.

  • DAGCircuit.apply_operation_front() não é mais possível inserir loops próprios inválidos ao lidar com nós que incluem condições clássicas.

  • Corrigido um problema com pickle o suporte para o SabreSwap qual uma SabreSwap instância apresentava erro ao ser pickled após a execução do SabreSwap.run() método. Corrigido #15071.

  • Corrigido um problema em que is_unitary() não respeitava adequadamente os valores de tolerância de entrada ao verificar se um operador era unitário. O método agora usa corretamente os parâmetros rtol fornecidos atol e ao simplificar o operador e verificar se ele é igual à identidade. Isso corrige o problema #14107.


2.2.0

Prelúdio

O Qiskit v2.2 acrescenta vários aprimoramentos à API C e ao transpilador, além de muitos outros aprimoramentos e correções de bugs. Os principais recursos dessa nova versão são:

  • Função de transpilagem da API C: A API C agora inclui uma função para transpilagem de um circuito quântico: qk_transpile(). Esta função é equivalente à Python função transpile() para um contexto C independente.
  • Passagem de transformação Litinski: Uma nova passagem de LitinskiTransformation transformação que implementa a transformação descrita arXiv:1808.02892. Essa passagem é normalmente usada na compilação para arquiteturas tolerantes a falhas.
  • Suporte a limites angulares para alvos: A Target classe agora suporta a especificação de limites para os valores permitidos para operações parametrizadas adicionadas ao alvo. Quando uma instrução é adicionada ao Target você pode adicionar o argumento opcional ângulo_limites para especificar os limites superior e inferior para portas de rotação parametrizadas. Uma nova passagem do WrapAngles transpiler foi adicionada para aplicar as restrições de ângulo como parte de um pipeline de transpilagem.

A série de versões v2.2 é a última série de versões secundárias com suporte Python 3.9. A versão mínima compatível do Rust usada para criar o Qiskit a partir da fonte agora é o Rust v1.85, aumentado de 1.79 em 2.1.0. Para obter mais informações sobre as alterações acima e outras alterações feitas, consulte as notas de versão abaixo e examine a documentação atualizada.

Recursos da API C

Recursos dos circuitos

  • Um novo método é fornecido para garantir que um circuito seja definido sobre qubits físicos, QuantumCircuit.ensure_physical() com os índices de qubits referindo-se a qubits físicos. Consulte a nova discussão sobre representações abstratas e de circuitos físicos na documentação para obter mais detalhes sobre os conceitos de metadados. Os conceitos de circuitos “abstratos” e “físicos” não são novidade para o Qiskit, apenas a documentação explícita.

  • A classe Duration ganhou uma nova variante ps , que pode ser usada para representar uma duração em picossegundos.

  • Melhorado PauliEvolutionGate.control(), PauliEvolutionGate.power() e PauliEvolutionGate.inverse() para retornar representações mais eficientes em termos de a PauliEvolutionGate. Para calcular as versões controladas e exponencializadas do portão de evolução, essa mudança leva a circuitos significativamente mais rasos e contagens de portões mais baixas em comparação com os mecanismos genéricos usados anteriormente. A decomposição inversa não muda, mas agora é gerada de forma mais eficiente e permite melhores otimizações do compilador.

  • Um novo método de ParameterExpression.bind_all() caminho rápido foi adicionado para dar suporte ao caso de uso de vinculação de muitas instâncias ParameterExpression diferentes a valores numéricos usando o mesmo dicionário de mapeamentos. O método bind() existente tem uma grande quantidade de sobrecarga e alocações desnecessárias, uma vez que sempre retorna um ParameterExpression para consistência de digitação.

OpenQASM Características

  • Adicionado suporte parcial para defcal símbolos no exportador OpenQASM3. Isso permite que pacotes downstream exportem instruções personalizadas que operam tanto em bits quânticos quanto clássicos usando qiskit.qasm3.dumps(). Os usuários agora podem definir instruções personalizadas (por exemplo, uma CustomMeasure que atua em um qubit e retorna um bit clássico) e especificar seu comportamento usando DefcalInstruction. Esses defcals são passados para o exportador por meio do implicit_defcals argumento em qiskit.qasm3.dumps().

    Por exemplo:

    from qiskit.circuit import Instruction, QuantumCircuit
    from qiskit.qasm3 import dumps
    from qiskit.qasm3.exporter import DefcalInstruction, types
    
    custom_measure = Instruction("measure_2", 1, 1, [])
    qc = QuantumCircuit(1, 1)
    qc.h(0)
    qc.append(custom_measure, [0], [0])
    qc.measure(0, 0)
    
    defcals = {
        "measure_2": DefcalInstruction("measure_2", 0, 1, types.Bool()),
    }
    
    out_qasm = dumps(qc, implicit_defcals=defcals)
    print(out_qasm)

    O resultado seria a seguinte cadeia de caracteres válida OpenQASM3 :

    OPENQASM 3.0;
    bit[1] c;
    qubit[1] q;
    h q[0];
    c[0] = measure_2 q[0];
    c[0] = measure q[0];

    Essa abordagem pressupõe que a definição da gramática para o defcal seja fornecida externamente (por exemplo, em um arquivo de cabeçalho), embora esse arquivo não seja estritamente necessário para que o exportador funcione.

  • As funções qasm3.loads() e qasm3.load() agora têm um argumento extra chamado num_qubits. Se fornecidas, as funções retornarão circuitos que terão qubits iguais a num_qubits. Se não for fornecido, o circuito retornado terá qubits iguais ao índice máximo observado no circuito serializado. Consulte o número 14435 para obter mais detalhes

Recursos do QPY

  • Adicionada uma configuração chamada min_qpy_version no arquivo de configuração do usuário. Quando definido, define a versão mínima permitida do QPY para qpy.load(). Se a versão do formato de um arquivo QPY for inferior à configuração minimum_qpy_version``minimum_qpy_version , será gerada uma exceção.

  • Introduziu o formato QPY versão 16. Essa nova versão introduz uma nova tabela de início de circuito no cabeçalho do arquivo, que contém os deslocamentos de bytes do início de cada circuito em um arquivo QPY. Isso permite um carregamento potencialmente mais eficiente de circuitos a partir de arquivos QPY e uma implementação do Rust potencialmente multi-threaded no futuro. Além disso, a nova versão do formato adiciona suporte para a nova variante DURATION de picossegundos.

Recursos de informação quântica

Recursos de síntese

  • Adicionado novo algoritmo de síntese para ModularAdderGate que não requer qubits auxiliares e tem melhor contagem CX em comparação com adder_qft_d00():

  • Adicionado um novo algoritmo de síntese, synth_mcx_noaux_hp24(), para MCXGate que não requer quaisquer qubits auxiliares. Este método produz um número linear, em vez de quadrático, de portas CX, em comparação com o algoritmo synth_mcx_noaux_v24() existente. Em particular, o novo método é melhor quando o número de qubits de controle é superior a cinco. O algoritmo baseia-se no artigo “Compiling Conditional Quantum Gates without Using Helper Qubits” (Compilando portas quânticas condicionais sem usar qubits auxiliares), de Huang e Palsberg ( https://dl.acm.org/doi/10.1145/3656436 ).

  • Melhorou a qs_decomposition() função que era originalmente baseada em Shende et. al. (https://arxiv.org/abs/quant-ph/0406176). O novo método de síntese baseia-se em Krol e Al-Ars ( https://arxiv.org/abs/2403.13692 ) e reduz o número total de CXGates de um unitário n-qubit geral por um 4n213\frac{4^{n − 2} − 1}{3} e CXGates. Com a decomposição aprimorada, uma unidade geral de 3 qubits pode ser decomposta usando 19 CXGates (em vez de 20).

  • Adicionado synth_mcmt_xgate() para sintetizar o gate multicontrolo e multialvo quando o gate base é XGate. Possui uma decomposição em número linear de portas CX e 0 qubits auxiliares, juntamente com o plug-in de síntese de MCMTSynthesisXGate alto nível.

Recursos do Transpiler

  • Adicionado novo plugin de síntese de alto nível para sintetizar um ModularAdderGate:

    O também ModularAdderSynthesisDefault foi atualizado para seguir a seguinte sequência de sintetizadores somadores modulares: "ModularAdder.qft_d00" quando o número de qubits é 4\leq 4, "ModularAdder.modular_v17" em todos os outros casos.

  • Adicionada uma nova passagem do LitinskiTransformation transpiler que implementa a transformação descrita em arXiv:1808.02892.

    A entrada para a passagem é um circuito com portas Clifford e portas de rotação RZ de qubit único, e a saída é um circuito com rotações Pauli de múltiplos qubits (implementadas como PauliEvolutionGate portas) seguidas por portas Clifford. A passagem gera uma TranspilerError exceção se o circuito contiver portas não suportadas.

    A passagem suporta todos os portões Clifford na lista retornada por get_clifford_gate_names(), ou seja, ["id", "x", "y", "z", "h", "s", "sdg", "sx", "sxdg", "cx", "cz", "cy", "swap", "iswap", "ecr", "dcx"]. A lista de rotações RZ suportadas é ["t", "tdg", "rz"] (convertemos automaticamente portas T e Tdg em rotações RZ).

    Além disso, o LitinskiTransformation construtor aceita um argumento fix_clifford. Quando False (não padrão), o circuito retornado contém apenas PauliEvolutionGate portas, com as portas Clifford finais omitidas. Observe que, neste caso, os operadores dos circuitos original e sintetizado geralmente não serão equivalentes.

    Por exemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import LitinskiTransformation
    from qiskit.quantum_info import Operator
    
    # The following quantum circuit consists of 5 Clifford gates
    # and two single-qubits RZ-rotation gates (note that Tdg is
    # an RZ-rotation).
    qc = QuantumCircuit(2)
    qc.cx(0, 1)
    qc.rz(0.1, 0)
    qc.cz(0, 1)
    qc.tdg(1)
    qc.h(1)
    qc.s(1)
    qc.cz(1, 0)
    
    # The transformed circuit consists of two PauliEvolution gates
    # and the same Clifford gates as in the original circuit.
    qct = LitinskiTransformation()(qc)
    
    # The circuits before and after the transformation are equivalent
    assert Operator(qc) == Operator(qct)
  • Adicionado um novo plug-in de síntese de MCXSynthesisNoAuxHP24 alto nível para MCXGate objetos. Além disso, o plug-in de síntese MCXSynthesisDefault padrão para MCXGate objetos foi atualizado para sempre escolher o melhor método de síntese, dependendo do número disponível de qubits auxiliares.

  • Adicionado suporte para especificar limites de Target ângulo nas instruções. Antes desta versão, Target era possível especificar que uma operação que recebia um parâmetro permitiria qualquer valor válido ou um valor específico. Por exemplo, se RZGate(Parameter("theta")) fosse adicionado ao alvo, isso indicaria que RZGate qualquer valor para theta seria permitido. Se RZGate(math.pi) fosse adicionado ao alvo, isso indicaria RZGate que apenas π\pi é o único valor permitido no alvo. Esse novo recurso permite restringir os ângulos permitidos a qualquer float valor entre um limite inclusivo. Por exemplo, você pode adicionar RZGate(math.pi) a um Target e restringir o valor do ângulo entre os valores 0 e 2π2\pi.

    Existem vários métodos disponíveis para trabalhar com os limites de ângulo no alvo. O primeiro é Target.add_instruction() que possui um novo argumento angle_bounds de palavra-chave usado para adicionar um limite angular a uma instrução no Target. Para trabalhar com limites angulares, você também precisará registrar uma função de retorno de chamada no registro WRAP_ANGLE_REGISTRY global que informará ao transpilador e WrapAngles passará como ajustar os portões para limites angulares. A função de retorno receberá uma lista de valores float arbitrários representando os ângulos do portão do circuito, bem como os índices de qubit no circuito em que o portão estava operando, e retornará um DAGCircuit que representa um circuito equivalente para o portão com esse ângulo, mas respeitando os limites de ângulo e outras Target restrições. Por exemplo:

    import math
    
    from qiskit.dagcircuit import DAGCircuit
    from qiskit.transpiler import Target
    from qiskit.transpiler.passes.utils.wrap_angles import WRAP_ANGLE_REGISTRY
    
    target = Target(num_qubits=1)
    target.add_instruction(RZGate(Parameter("theta")), angle_bounds=[(-math.pi, math.pi)])
    
    def callback(angles: List[float], qubits: List[int]) -> DAGCircuit:
        """Callback function to wrap RZ gate angles
    
        Args:
            angles: The list of floating point parameter values for the instance of RZGate in
                the circuit
            qubits: The physical qubit indices that this gate is operating on
    
        Returns:
            The DAGCircuit of the equivalent circuit"""
    
        angle = angles[0]
        dag = DAGCircuit()
        dag.add_qubits([Qubit()])
        if angle > 0:
            divisor = math.pi
        else:
            divisor = -math.pi
        gate_counts = int(angles[0] // divisor)
        rem = angles[0] % divisor
        for _ in range(gate_counts):
            dag.apply_operation_back(RZGate(math.pi), [dag.qubits[0]], check=True)
        dag.apply_operation_back(rem, [dag.qubits[0]], check=True)
    
    WRAP_ANGLE_REGISTRY.add_wrapper("rz", callback)

    Target.has_angle_bounds() pode ser usado para verificar se há limites de ângulo definidos no alvo e Target.gate_has_angle_bounds().

    Se você deseja aplicar os limites de ângulo de um alvo a quaisquer portas em um circuito, a passagem WrapAngles do transpiler deve ser usada para fazer isso.

  • Adicionado um novo kwarg check_angle_bounds ao método Target.instruction_supported() . Quando definido como True (padrão), o método verificará se o especificado parameters também está em conformidade com quaisquer limites de ângulo que possam existir para a instrução que está sendo consultada.

  • Adicionada uma nova passagem do WrapAngles transpiler, que é usada para aplicar restrições de ângulo em portas no Target. Se um Target tiver limites de ângulo definidos, esta passagem analisará todos os parâmetros para as portas no circuito e verificará isso em relação aos limites especificados no alvo. Por exemplo, se um alvo contiver um gate personalizado com limites de ângulo, a passagem decomporá esse gate em um gate que esteja em conformidade com os limites:

    from qiskit.circuit import Gate, Parameter, QuantumCircuit, Qubit
    from qiskit.dagcircuit import DAGCircuit
    from qiskit.transpiler import Target, WrapAngleRegistry
    from qiskit.transpiler.passes import WrapAngles
    
    class MyCustomGate(Gate):
    
        def __init__(self, angle):
            super().__init__("my_custom", 1, [angle])
    
    param = Parameter("a")
    circuit = QuantumCircuit(1)
    circuit.append(MyCustomGate(6.0), [0])
    target = Target(num_qubits=1)
    target.add_instruction(MyCustomGate(param), angle_bounds=[(0, 0.5)])
    
    def callback(angles, _qubits):
        angle = angles[0]
        if angle > 0:
            number_of_gates = angle / 0.5
        else:
            number_of_gates = (6.28 - angle) / 0.5
        dag = DAGCircuit()
        dag.add_qubits([Qubit()])
        for _ in range(int(number_of_gates)):
            dag.apply_operation_back(MyCustomGate(0.5), [dag.qubits[0]])
        return dag
    
    registry = WrapAngleRegistry()
    registry.add_wrapper("my_custom", callback)
    wrap_pass = WrapAngles(target, registry)
    res = wrap_pass(circuit)
    res.draw('mpl')
    _images/release_notes-1.png
  • DAGCircuit agora possui uma implementação manual de __deepcopy__(). Isso é muito mais rápido do que a implementação implícita anterior do protocolo pickle, especialmente para circuitos grandes. Isso também beneficia diretamente o desempenho da compilação ao executar transpile() ou executar os gerenciadores de passagem predefinidos retornados por generate_preset_pass_manager() , optimization_level=3 pois o nível de otimização 3 copia internamente o DAGCircuit para cada iteração do loop de otimização na optimization etapa.

  • É fornecido um novo método, DAGCircuit.make_physical(), que substitui eficientemente os qubits no DAGCircuit pelo registro canônico de qubits físicos, incluindo potencialmente a expansão. Um método semelhante também está disponível QuantumCircuit.ensure_physical() .

  • Um novo método, DAGCircuit.structurally_equal(), pode ser usado se duas DAGCircuit instâncias tiverem sido criadas e modificadas exatamente na mesma ordem. Este é um teste muito mais rigoroso do que a verificação padrão de equivalência semântica da == sobrecarga e pode ser usado pelos autores do transpiler-pass para verificar se suas ordens de modificação são determinísticas.

  • Subclasses personalizadas de agora BasePassManager podem modificar seu property_set atributo durante seu _passmanager_frontend() método, para inicializar propriedades iniciais. Isso proporciona simetria, já que anteriormente só era possível ler as propriedades finais durante _passmanager_backend().

  • Adicionada uma nova classe OptimizationMetric que especifica o critério de otimização na HighLevelSynthesis passagem. Atualmente, as duas métricas suportadas são:

    • COUNT_2Qotimiza o número de portas de dois qubits.
    • COUNT_Totimiza o número de portas T ao fazer a transposição para um conjunto de bases Clifford+T.

    O transpiler seleciona automaticamente a métrica de destino com base no conjunto de portas básicas, por exemplo, ele usará COUNT_T se um conjunto básico Clifford+T for detectado. No entanto, essa classe não pode ser definida manualmente no momento da execução transpile() ou da execução de um gerenciador de passagem predefinido gerado por generate_preset_pass_manager().

  • Adicionado um novo argumento optimization_metric ao construtor para a HighLevelSynthesis passagem do transpiler que recebe um OptimizationMetric objeto. Quando definido como COUNT_T, a passagem escolhe decomposições que são mais adequadas para o conjunto de portas Clifford+T.

  • Os plug-ins padrão de síntese de alto nível para ModularAdderGate e MultiplierGate produzem melhores contagens T ao transpilá-los para o conjunto de bases Clifford+T.

  • O plug-in de síntese de alto nível padrão para MCXGate produz melhores contagens T ao transpilando para o conjunto de bases Clifford+T, desde que pelo menos 1 qubit auxiliar esteja disponível.

  • Adicionado um conjunto padrão de portas inversas para a passagem do InverseCancellation transpiler. Anteriormente, uma lista explícita de portas ou pares de portas a serem canceladas era um argumento obrigatório para o construtor do objeto pass. Agora, essa lista é opcional e, se nenhuma lista for fornecida, os portões inversos próprios são:

    e os pares inversos:

    será cancelado pelo passe.

  • Adicionado um novo argumento ao InverseCancellation construtor, que, quando definido como True , executará a nova lista run_default padrão de portas de cancelamento inverso, além de quaisquer portas personalizadas fornecidas. Isto destina-se a casos de uso em que você deseja executar um conjunto personalizado de cancelamentos inversos, além dos gates padrão.

  • TranspileLayout possui dois novos métodos: from_property_set() e write_into_property_set(), que formalizam a estrutura ad hoc atual das propriedades de transpilagem e como elas são convertidas em um TranspileLayout. Isso permite que as passagens durante um pipeline de transpiler acessem o que TranspileLayout será, modifiquem-no na forma totalmente estruturada e, em seguida, o gravem novamente na forma canônica.

    Espera-se que, na versão futura 3.0 do Qiskit, o TranspileLayout (ou algo semelhante a ele) seja um atributo direto da representação intermediária do DAGCircuit transpiler e exigido pelas passagens para manter a sincronia com o restante do DAGCircuit.

  • Reativou a execução da VF2PostLayout passagem do transpiler na optimization etapa para optimization_level=3 com a transpile() função e os objetos gerenciadores de passagem gerados retornados pela generate_preset_pass_manager() função. A passagem é executada strict_direction=True após todas as otimizações físicas realizadas na etapa para tentar melhorar o layout uma última vez com o circuito de saída exato. Isso foi habilitado anteriormente no Qiskit v2.1.0, mas foi revertido em 2.1.2 devido a problemas com a implementação inicial. Esses problemas foram corrigidos e o layout será aplicado corretamente se for encontrado um melhor.

Recursos de visualização

  • Uma nova opção, measure_arrows, foi adicionada aos backends mpl``text e para o desenhista de circuitos qiskit.visualization.circuit_drawer() e qiskit.circuit.QuantumCircuit.draw(). Quando esta opção estiver definida como True, a gaveta desenhará uma seta da measure caixa para os bits clássicos abaixo. Esse era o comportamento anterior nas gavetas. Se estiver definido como False, nenhuma seta será desenhada e, em vez disso, o registro clássico e o bit usado pelo measure serão indicados dentro da measure caixa. Isso permite que measure as caixas sejam empilhadas em uma camada vertical.

    Se nenhuma opção for definida, o padrão será True. O usuário pode alterar o padrão no arquivo de configuração do usuário, por padrão no diretório ~/.qiskit , no arquivo settings.conf. No cabeçalho [Default] , um usuário pode inserir circuit_measure_arrows = False para alterar o padrão.

Notas da Atualização

  • A versão mínima de suporte do Rust para a criação do Qiskit a partir do código-fonte (incluindo a criação da API C em modo autônomo) foi aumentada de Rust 1.79 para Rust 1.85. Essa alteração foi necessária para permitir o uso de uma versão mais recente da biblioteca de álgebra linear Rust faer, que é usada no Qiskit. Foram identificados problemas ao executar o Qiskit no Windows com a versão anterior do faer. Esses problemas foram corrigidos na versão mais recente, mas é necessária uma versão mais recente do compilador Rust para criar a versão mais recente do faer.

Notas sobre atualização de circuitos

Notas sobre a atualização da API C

Notas de atualização do QPY

  • A versão padrão do QPY emitida pelo agora qpy.dump() é a versão 16 do formato QPY. Se você precisar de uma versão de formato diferente, pode usar o version argumento para especificar uma versão de formato anterior.

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

Notas sobre a atualização da síntese

  • Os valores padrão dos argumentos opt_a1 e opt_a2 agora qs_decomposition() são opt_a1 = None e opt_a2 = None. Os novos padrões escolherão o valor ideal com base no fato de a unidade de entrada para o mat argumento ser controlada ou não, para resultar na contagem CXGate mínima por padrão. Se você precisar do comportamento anterior, pode chamar opt_a1 = True explicitamente e opt_a2 = True para manter o mesmo comportamento das versões anteriores.

Notas sobre a atualização do Transpiler

  • O circuito PassManager agora define sempre as propriedades original_circuit_indices e num_input_qubits antes do início da execução em passagens individuais. Essas são propriedades do circuito de entrada, que anteriormente dependiam de passagens individuais para serem definidas, muitas vezes como um efeito colateral de seu objetivo principal.

Circuitos obsoletos

Correções de bugs

  • ApplyLayout agora tratará corretamente o caso da aplicação de um qubit zero Layout. Anteriormente, ele alegaria que nenhum layout havia sido definido, mesmo que o "layout" campo do PropertySet fosse igual a Layout().

  • Corrigidos problemas de vazamento de memória durante a criação de uma QkOpCounts instância e durante quaisquer chamadas sempre qk_opcounts_clear() que uma instância vazia é passada.

  • Anteriormente, era possível definir um inválido PauliEvolutionGate a partir de uma lista de operadores, em que os operadores não estavam todos definidos no mesmo número de qubits. Isso já foi corrigido e agora geramos um erro quando o gate é definido:

    from qiskit.quantum_info import Pauli, SparsePauliOp
    from qiskit.circuit.library import PauliEvolutionGate
    
    pauli = Pauli("XYZ")  # 3 qubits
    op = SparsePauliOp(["XYIZ"], [1])  # 4 qubits
    evo = PauliEvolutionGate([pauli, op], time=1)
  • Corrigimos um problema na passagem VF2Layout do transpiler em que, mesmo com um conjunto de sementes fixo, a saída da passagem era potencialmente não determinística; especificamente, se o circuito de entrada tivesse quaisquer qubits ativos que contivessem apenas operações de qubit único. Corrigido #14729

  • Corrigido um bug em PassManager.run() que a callback função não era invocada ao executar com múltiplos circuitos. A chamada de retorno agora é acionada corretamente para cada passagem em cada circuito, inclusive na execução paralela.

  • Corrigimos vários problemas na passagem do CommutativeInverseCancellation transpiler. A passagem agora funciona corretamente em circuitos que contêm Clifford operações, operações de fluxo de controle e operações não invertíveis, como Initialize.

    Além disso, a passagem agora sempre executa uma verificação sintática (não baseada em matriz) primeiro, ao identificar pares de portas inversas. Se as portas não forem sintaticamente iguais, o argumento matrix_based for definido como True e a operação não atuar em mais de max_qubits qubits, também será realizada uma verificação baseada em matriz. Isso melhora um pouco o potencial de redução do passe.

    Correção dos números 14407, 14635 e 14645.

  • Corrigimos vários problemas na passagem CommutativeCancellation do transpiler (e, consequentemente, em transpile()), onde a fase global do circuito não era atualizada corretamente. Em particular, a fusão de um X-gate e um RX-gate introduziu uma incompatibilidade de fase, enquanto a remoção de um gate de rotação de Pauli com ângulo da forma (2+4k)π(2 + 4k)\pi, kZk \in \mathbb Z produziu incorretamente uma mudança de fase de 1-1.

  • Corrigido um problema em CommutationCheckerque portas controladas padrão não eram tratadas corretamente se fossem controladas em algo diferente do estado “todos uns”. Corrigido #14974

  • Corrigido um problema de indeterminismo em CommutativeCancellation. Isso não afetou a ordem retornada por DAGCircuit.topological_nodes() ou topological_op_nodes(), que normalmente devem ser usados quando o determinismo da ordem dos nós é importante, devido à sua função de classificação canônica integrada. No entanto, se inspecionar os nós por ordem arbitrária (DAGCircuit.op_nodes()) ou a estrutura de arestas (DAGCircuit.edges()), a ordem de iteração seria não determinística após uma chamada para CommutativeCancellation.

  • Corrigido um bug em MCXGate.control()que adicionar mais controles a um controle aberto MCXGate não levava em consideração o controle ctrl_state do gate MCX, levando a um controle incorreto ctrl_state do gate MCX estendido. Observe que as classes MCX CXGateexplícitas, CCXGate, C3XGate e já C4XGate foram tratadas corretamente.

  • Foi corrigido o aviso de descontinuidade do site Python 3.9 para que ele seja corretamente identificado como sendo causado pelo código do usuário ao importar o Qiskit. Anteriormente, ele não era identificado como sendo causado pelo código do usuário e isso significava que os filtros de aviso padrão do Python não exibiam o aviso ao usuário.

  • Corrigido um erro em PhaseOracle, PhaseOracleGate e BitFlipOracleGate onde a tentativa de carregar a partir do arquivo dimacs gerava um TypeError.

  • Corrigido um bug na passagem ElidePermutations do transpiler, onde o mapeamento do qubit não era atualizado corretamente na presença de PermutationGates, levando a circuitos incorretos e atualizações no conjunto de propriedades do gerenciador de passagens.

  • O transpiler integrado que define a final_layout propriedade agora tratará corretamente a atualização desse campo, caso ele já tenha sido definido. Isso pode ser observado como o método TranspileLayout.routing_permutation agora retornando uma permutação correta após executar mais de uma passagem que define final_layout.

    Isso não afetou nenhuma chamada normal para transpile() ou generate_preset_pass_manager() usando os plug-ins integrados do Qiskit; nenhum pipeline construído dessa forma tentaria definir final_layout mais de uma vez.

  • Corrigido um bug na HighLevelSynthesis passagem em que, se o circuito contivesse objetos de alto nível com registros clássicos, estes seriam mapeados para o índice relativo no objeto, em vez do índice correspondente no circuito externo. Os registros clássicos agora estão mapeados corretamente para o índice do circuito externo.

  • Corrigido um bug em Target.instruction_supported() que a verificação da ordem dos qubits da instrução era ignorada quando o método era chamado com operation_name``parameters argumentos que correspondiam a uma instrução existente.

  • Corrigido o comportamento do max_trials argumento para VF2Layout quando definido como None ou um número negativo. A passagem foi documentada como limitando a pesquisa com base no tamanho do circuito ou alvo, se a opção estivesse definida como, None e como aceitando valores negativos para especificar uma pesquisa ilimitada. No entanto, no 2.1.0, esse comportamento foi alterado incorretamente, de modo que None executava uma pesquisa ilimitada e tentar usar um número negativo gerava um erro. Essas omissões foram corrigidas para que o passe funcione conforme documentado e seja consistente com as versões anteriores.

  • Corrigido um problema nos plug-ins de síntese de MCXSynthesis1DirtyKG24 alto nível e MCXSynthesis2DirtyKG24 para MCXGate, em que os plug-ins não consideravam os qubits auxiliares limpos disponíveis como qubits auxiliares sujos disponíveis. Em particular, o plug-in MCXSynthesis2DirtyKG24 não se aplicava quando um qubit auxiliar limpo e um sujo estavam disponíveis.

  • O PauliEvolutionGate.to_matrix() método agora retorna a exponencial exata da matriz exp(itH)\exp(-it H), onde HH é o operator e tt é o time passado para o gate. Isso corrige um comportamento inesperado, uma vez que o PauliEvolutionGate está documentado para representar a evolução temporal exata, mas anteriormente a matriz dependia de como o compilador aproximava a evolução temporal. O to_matrix método agora está consistente com a documentação.

  • Corrigida uma regressão de desempenho ao compilar incrementalmente ParameterExpression a partir da combinação de um grande número de subexpressões. Corrigido #14653

  • Foi corrigido um erro de correção ao exportar circuitos com instruções de atraso usando unidades 'ps' para QASM3.

  • Corrigido um caso extremo na exibição do QFT circuito. Anteriormente, quando QFT.inverse() era chamado e, em seguida, os atributos do circuito QFT eram modificados, o QFT era exibido como "IQFT_dg". Isso estava incorreto e agora é exibido corretamente "IQFT". Corrigido #14758.

  • Corrigido um bug no PauliEvolutionSynthesisRustiq plugin que produzia circuitos incorretos no caso em que o operador de um PauliEvolutionGate contém objetos do tipo SparseObservable.

    Por exemplo:

    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.quantum_info import SparseObservable, Operator
    from qiskit.transpiler.passes.synthesis.hls_plugins import PauliEvolutionSynthesisRustiq
    
    obs = SparseObservable.from_sparse_list([("1+XY", (0, 1, 2, 3), 1.5)], num_qubits=4)
    evo = PauliEvolutionGate(obs, 1)
    qct = PauliEvolutionSynthesisRustiq().run(evo)
    assert Operator(qct) == Operator(evo)
  • Corrigido um problema com a generate_preset_pass_manager() função, que ignorava incorretamente os dados de restrições de tempo contidos em um Target objeto fornecido quando o backend argumento não estava definido. Corrigido #14329

  • Foi corrigido um bug no site ObservablesArray.coerce_observable() em que uma exceção de que um observável não era hermitiano era acionada em excesso. Observáveis iguais a zero não são permitidos e agora invocam uma falha graciosa.

  • qiskit.circuit.library.quantum_volume() foi atualizado para lidar com um numpy.random.Generator como entrada para seu seed argumento. Anteriormente, tal argumento gerador resultaria em um TypeError.

  • QuantumCircuit.compose() agora remapará corretamente as variáveis e trechos usados nas Delay instruções quando o var_remap argumento for especificado.

  • SabreLayout usa um layout de “subconjunto denso” como uma de suas tentativas, seguindo o mesmo algoritmo que DenseLayout. Anteriormente, porém, a versão usada pela Sabre atribuía todos os qubits virtuais, incluindo ancillas fictícias, a um qubit físico, comprometendo a eficácia do algoritmo, mas não sua correção. A Sabre agora utilizará apenas os qubits virtuais definidos pelo usuário para este teste inicial, o que pode resultar em pequenas melhorias na seleção do layout quando calculada a média em grandes classes de circuitos.

  • Corrigido um erro em SparsePauliOp.simplify() que o método removia os termos de Pauli com base nas magnitudes de seus coeficientes antes de combinar duplicatas. Isso causou um comportamento incorreto em dois casos extremos importantes:

    1. Quando vários termos de Pauli idênticos tinham coeficientes pequenos que estavam individualmente abaixo do limite de simplificação, mas cuja soma excedia o limite, esses termos eram removidos incorretamente.
    2. Quando vários termos de Pauli idênticos tinham coeficientes acima do limite, mas somados a quase zero, eles eram mantidos incorretamente.

    Consulte #14194 para obter mais detalhes.

  • TranspileLayout.initial_index_layout() agora tratará corretamente o filter_ancillas=True argumento se os qubits virtuais no não initial_layout foram especificados pelo construtor em ordem de índice.

  • VF2Layout e agora VF2PostLayout incluirá corretamente atribuições de layout (arbitrárias) para qubits completamente ociosos. Anteriormente, isso poderia ter sido observado por chamadas que TranspileLayout.initial_index_layout() falhavam após uma compilação.

  • Corrigido um problema na passagem do VF2PostLayout transpiler. Em determinadas situações, quando a passagem é executada com o argumento, strict_direction=True havia um potencial problema de dimensionamento de tempo de execução quando o gráfico de interação do circuito continha quaisquer qubits que tivessem apenas operações de 1 qubit. Esses problemas de mapeamento resultam em uma complexidade combinatória para a pontuação que levaria a passe quase sempre atingindo o tempo limite de pontuação e, normalmente, não melhorando o layout. No strict_direction=False modo existe uma implementação de pesquisa otimizada para esses problemas, mas as restrições adicionais para strict_direction=True não tornam essa abordagem viável. Em vez disso, nesses casos, a pesquisa VF2PostLayout será ignorada, uma vez que o problema de layout não é viável para a passagem.

Outras observações

  • A implementação do roteamento Sabre usado por SabreLayout e SabreSwap agora comprime sequências de nós que se tornarão automaticamente elegíveis para roteamento ao mesmo tempo dentro de sua representação de interação virtual interna. Isso melhora a eficiência do roteamento, reduz o uso de memória intermediária e evita que portas e 2q es influenciem os componentes lookahead heurísticos.

2.1.0rc1

Notas de descontinuação

  • O suporte para a execução do Qiskit com Python 3.9 foi descontinuado e será removido na versão do Qiskit 2.3.0. O 2.3.0 é a primeira versão após o Python 3.9 entrar em fim de vida útil e não ter mais suporte. [1] Isso significa que, a partir da versão 2.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/

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