Skip to main content
IBM Quantum Platform

Notas de versão do Qiskit 0.45

Esta página contém as notas de versão do Qiskit 0.45, a primeira versão após a remoção completa da estrutura legada de "elementos". Para ver todas as notas de versão, inclusive as que se estendem até a antiga estrutura de "meta-pacote" do Qiskit, consulte Notas de versão. Para obter uma tabela de versões do meta-pacote, consulte as notas de versão do Qiskit 0.44.


0.45.3

Prelúdio

O Qiskit 0.45.3 é uma versão pontual sem nenhuma alteração de código além de gerar uma mensagem de erro ImportError se ele detectar que foi instalado em um ambiente inválido com o Qiskit >= 1.0.

Leia nosso guia de migração sobre o novo pacote para obter ajuda sobre erros, preparação para o Qiskit 1.0 e informações mais detalhadas.

Nota

O lançamento do Qiskit 1.0 está previsto para aproximadamente duas semanas após o lançamento do Qiskit 0.45.3, em 15 de fevereiro de 2024, e talvez ainda não esteja disponível quando você ler esta mensagem. Essa alteração está sendo feita de forma proativa.

A estrutura de empacotamento do Qiskit está mudando no Qiskit 1.0 e, infelizmente, os requisitos alterados não podem ser totalmente comunicados ao pip, especialmente se os comandos do pip install --upgrade forem executados depois que o ambiente tiver sido configurado inicialmente. Todas as versões do Qiskit anteriores a 1.0 (incluindo esta) têm um conflito de instalação com o Qiskit 1.0 que o pip não resolverá.

Se o site import qiskit gerar uma mensagem de erro ImportError para você, seu ambiente está em um estado inválido e as versões do Qiskit 0.45/0.46 e 1.0 podem ser acessadas, o que resultará em um código sutilmente quebrado. Você precisará criar um novo ambiente virtual e garantir que apenas uma das duas versões esteja instalada. Em particular, se você pretende instalar o Qiskit 1.0, não deve ter nenhum pacote que dependa do qiskit-terra instalado; esses pacotes são incompatíveis com o Qiskit 1.0 e devem ser atualizados. Se estiver pretendendo instalar o Qiskit 0.45 ou 0.46, você deve se certificar de que não há nada tentando instalar o qiskit>=1.0.

Se você desenvolver uma biblioteca baseada no Qiskit e ainda tiver uma dependência de qiskit-terra, deverá lançar urgentemente um novo pacote que dependa apenas de qiskit. Desde a versão 0.44, o pacote qiskit contém apenas o núcleo do compilador qiskit-terra (o componente que agora é chamado simplesmente de "Qiskit"), portanto, se a sua versão mínima for 0.44, você poderá mudar com segurança uma dependência de qiskit-terra>=0.44 para qiskit>=0.44 sem nenhuma alteração no que será instalado. Para obter mais detalhes e recomendações sobre testes e preparação, consulte a seção para desenvolvedores do guia de migração.


0.45.2

Prelúdio

O Qiskit 0.45.2 é uma pequena versão de correção que corrige vários erros encontrados na série de versões 0.45.

Correções de bugs

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

  • 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 bug que resultava em um erro quando um usuário tentava carregar dados de calibração de uma porta em 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 pode 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.

  • Foi corrigido um problema com a passagem do Optimize1qGatesDecomposition onde ele potencialmente ressintetizaria uma única porta ideal (o que significa que a taxa de erro é 0.0), que estava presente no arquivo Target. Isso agora foi corrigido para que a aprovação Optimize1qGatesDecomposition será adiado para a porta do circuito se a taxa de erro (que inclui o número de portas) for a mesma. Corrigido #10568

  • Foi corrigido um problema com a passagem OptimizeSwapBeforeMeasure em que ela otimizava incorretamente os circuitos que envolviam instruções de troca e medição. Este commit corrige o bug alterando DAGCircuit.successors() para DAGCircuit.descendants(). Além disso, adicionei alguns testes extras para garantir que o bug seja corrigido. 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
  • Corrigir um erro na representação de StabilizerState representação de string.


0.45.1

Prelúdio

O Qiskit Terra 0.45.1 é um pequeno patch de lançamento que corrige vários erros encontrados na série de lançamentos 0.45. É também a primeira versão a ter suporte oficial para Python 3.12. A versão 0.45.1 é compatível com Python, 3.8, 3.9, 3.10, 3.11 e 3.12.

Novos Recurso

  • Foi adicionado suporte para o uso do Qiskit com Python 3.12. A partir desta versão, o Qiskit suporta a execução das versões Python, 3.8, 3.9, 3.10, 3.11 e 3.12.

Correções de bugs

  • QuantumCircuit.barrier() agora gerará a saída correta quando receber um set como uma de suas entradas. Anteriormente, ele acrescentava uma operação inválida ao circuito, embora na prática isso normalmente não causasse problemas observáveis. Corrigido #11208

  • A propriedade Instruction.condition_bits agora tratará corretamente as expressões clássicas em tempo de execução (qiskit.circuit.classical).

  • Corrigido o erro de hash() dos objetos do Qiskit Pulse Channel (como DriveChannel) nos casos em que o canal era transferido de um processo Python para outro que usava uma semente de hash diferente.

  • Agora, os portões personalizados condicionados importados do site OpenQASM 2 manterão corretamente suas condições quando forem selecionados e copiados. Anteriormente, qualquer porta personalizada condicional (definida por uma instrução gate em um arquivo OpenQASM 2) perdia sua condição quando copiada ou selecionada.

  • Corrigida a desserialização do QPY dos arquivos StatePreparation e Initialize com parâmetros de cadeia de caracteres e inteiros (em vez de um vetor de estado explícito, que já estava funcionando). Corrigido #11158.

  • Foi corrigido um erro no SabreLayout onde não era possível adicionar as informações de registro ao objeto Layout usado para o objeto TranspileLayout.initial_layout. Isso afetou a visualização do circuito com QuantumCircuit.draw() e circuit_drawer() após a transpilação, que mostraria um rótulo de qubit virtual da forma Qubit[QuantumRegister(6, 'q', 0)] em vez do rótulo de qubit virtual esperado usando o nome do registro (por exemplo, q0). Corrigido #11038

  • Foi corrigido um problema com qpy.dump() que fazia com que a função potencialmente ignorasse o valor de use_symengine ao serializar um objeto ScheduleBlock objeto. Isso resultaria na geração de uma carga útil QPY inválida, pois ela informaria que estava usando o symengine para expressões simbólicas, mas na verdade conteria dados serializados sympy.

  • Foi corrigido um bug que fazia com que o UnitaryOverlap desse erro na inicialização se fosse fornecido um circuito de entrada contendo uma barreira.


0.45.0

Prelúdio

O Qiskit 0.45.0 é a última versão de recursos antes de 1.0. Ele prepara o terreno para as alterações na API que estamos planejando para o lançamento da nossa primeira versão principal, incluindo muitas remoções de funcionalidades anteriormente obsoletas, bem como uma série de novas obsoletas.

Nota

Se o seu projeto depender do Qiskit, ele poderá contar com uma funcionalidade que não será mais compatível com o Qiskit 1.0. Por esse motivo, recomendamos que você proativamente limite sua versão compatível para <1.0.

Alguns destaques de recursos do Qiskit 0.45.0 são:

  • A partir desta versão, todas as portas não parametrizadas na biblioteca de circuitos padrão do Qiskit agora são singletons. Por padrão, essas portas compartilham uma única instância na memória, portanto, quando uma porta de um tipo específico, digamos XGateé instanciada, todas as instâncias subsequentes de XGate serão uma referência à primeira. Isso resulta em uma redução do uso da memória e da sobrecarga de construção ao usar várias portas do mesmo tipo em um circuito. Para realizar esse recurso, foram introduzidas novas classes básicas: SingletonInstruction e SingletonGate. Consulte as notas do recurso para obter mais detalhes.
  • Adicionamos uma nova interface genérica de gerenciador de passes que pode ser encontrada no novo módulo qiskit.passmanager módulo. Trata-se de uma generalização do gerenciador de passes que foi usado para criar o transpilador Qiskit e introduz uma estrutura genérica para permitir que os usuários criem novos gerenciadores de passes que usem diferentes representações intermediárias (IRs). O módulo inclui uma classe básica genérica de gerenciador de passes, controladores de fluxo e a infraestrutura necessária para gerenciar a execução das tarefas do gerenciador de passes. A nova interface foi usada para reconstruir o gerenciador de passes existente no módulo qiskit.transpiler limpando a dívida técnica no código e melhorando a usabilidade e o desempenho. Consulte as notas sobre recursos e atualizações para obter mais detalhes.
  • 0.45.0 permite que os usuários interajam melhor com as permutações de layout realizadas pelo transpilador. Os dados contidos na classe TranspileLayout agora estão mais acessíveis por meio de uma série de novos métodos e atributos. E um novo método SparsePauliOp.apply_layout() método permite aplicar uma permutação de layout específica a um SparsePauliOp observável que foi criado para um circuito de entrada para o transpilador. Consulte as notas do recurso para obter mais detalhes.
  • Por fim, introduzimos operações anotadas com a nova classe AnnotatedOperation que permite formular instruções de circuitos complexos como uma instrução básica com um conjunto de modificadores. Por exemplo, em vez de um tipo de operação específico que implementa o inverso controlado de um RXGatepodemos agora usar uma operação anotada RXGate com atributos de controle e inverso. Consulte as notas do recurso para obter mais detalhes.

Recursos dos circuitos

  • Adicionada uma nova classe AnnotatedOperation que é uma subclasse de Operation e representa alguma "operação básica" modificada por uma lista de "modificadores". A operação básica é do tipo Operation e os modificadores atualmente suportados são dos tipos InverseModifier, ControlModifier e PowerModifier. Os modificadores são aplicados na ordem em que aparecem na lista.

    Como um exemplo:

    gate = AnnotatedOperation(
      base_op=SGate(),
      modifiers=[
          InverseModifier(),
          ControlModifier(1),
          InverseModifier(),
          PowerModifier(2),
      ],
    )

    é logicamente equivalente a gate = SGate().inverse().control(1).inverse().power(2), ou a:

    gate = AnnotatedOperation(
      AnnotatedOperation(SGate(), [InverseModifier(), ControlModifier(1)]),
      [InverseModifier(), PowerModifier(2)],
    )

    Entretanto, essa equivalência é apenas lógica, pois as representações internas são muito diferentes.

    Por conveniência, um único modificador também pode ser passado diretamente, portanto, AnnotatedGate(SGate(), [ControlModifier(1)]) é equivalente a AnnotatedGate(SGate(), ControlModifier(1)).

    Uma característica distintiva de uma operação anotada é que a definição do circuito não é construída quando a operação é declarada e, em vez disso, ocorre somente durante a transpilação, especificamente durante a HighLevelSynthesis passagem do transpilador.

    Uma operação anotada também pode ser vista como um objeto de "nível superior" ou "mais abstrato" que pode ser adicionado a um circuito quântico. Isso permite escrever passes de otimização do transpilador que fazem uso dessa representação de nível superior, por exemplo, removendo uma porta que é imediatamente seguida por sua inversa (observe que essa redução pode não ser possível se a porta e sua inversa forem sintetizadas primeiro em portas mais simples).

    De certa forma, uma operação anotada pode ser vista como uma extensão de ControlledGateque também permite adicionar controle à operação de base. No futuro, estamos planejando substituir ControlledGate por AnnotatedOperation. Semelhante aos portões controlados, o transpilador sintetiza operações anotadas antes da execução do layout/roteamento.

    Até o momento, as operações anotadas podem aparecer somente no nível superior de um circuito quântico, ou seja, não podem aparecer dentro do circuito definition definido recursivamente. Estamos planejando remover essa limitação posteriormente.

  • Adicionada uma nova opção max_num_qubits ao qiskit.circuit.CommutationChecker.commute() que especifica o número máximo de qubits a ser considerado para a verificação de comutatividade baseada em multiplicação de matriz mais cara. Isso evita a tentativa de alocar internamente matrizes de tamanho 2N×2N2^N \times 2^N. Versões mais simples da verificação de comutatividade (por exemplo, duas operações quânticas são comutadas quando estão sobre conjuntos de qubits disjuntos) continuam a funcionar sem esse limite.

  • Adicionado um novo argumento, check_input, ao construtor da classe UnitaryGate classe. Esse sinalizador é usado para desativar as verificações de inicialização padrão de que o objeto de entrada representa uma matriz unitária. Isso pode ser usado para acelerar a criação de objetos UnitaryGate se você souber que a entrada já é uma matriz unitária. Essa nova opção só deve ser usada nesses casos porque, se for definida como False e a entrada não for unitária, isso resultará em um objeto UnitaryGate inválido.

  • Um novo método Parameter.assign() foi adicionado. Esse método serve principalmente como um caminho rápido para melhorar o desempenho do QuantumCircuit.assign_parameters() para o caso comum de circuitos que contêm predominantemente "expressões" que, na verdade, são apenas parâmetros únicos a serem atribuídos posteriormente.

  • O desempenho do QuantumCircuit.assign_parameters() ao atribuir um único parâmetro de um circuito que envolve muitos parâmetros foi aprimorado.

  • Introduziu duas novas classes, SingletonInstruction e SingletonGateque são subclasses de Instruction e Gate respectivamente, que usam uma única instância para todos os objetos desse tipo. A intenção por trás dessa classe é minimizar a memória e a sobrecarga de construção do uso de várias portas em um circuito com a desvantagem de ter um estado global compartilhado. Por esse motivo, essa classe só se aplica a portas que não têm nenhum estado exclusivo e/ou mutável armazenado em uma instância. Por exemplo, o melhor exemplo disso é XGate não contém nenhum estado e poderia usar o SingletonGate (e o faz a partir desta versão), enquanto o RXGate armazena um parâmetro de ângulo em uma instância e, portanto, não pode usar SingletonGate porque uma única instância global compartilhada não pode representar os valores dos parâmetros.

    O outro possível problema a ser considerado ao usar classes singleton é que o modelo de dados Instruction suporta algum estado mutável. Especificamente, o label, duration, unit, e condition são todos acessíveis e mutáveis na classe Instruction e em suas subclasses diretas. No entanto, isso é incompatível com a existência de um objeto compartilhado via SingletonInstruction. Para instâncias de SingletonInstructiona definição direta desses atributos não é permitida e gerará uma exceção. Se eles forem necessários para uma instância específica, você deverá garantir que tenha uma instância mutável usando Instruction.to_mutable() (ou usar Instruction.c_if() for condition). label, duration e unit também podem ser fornecidos como argumentos de palavras-chave durante a construção da classe.

  • As seguintes portas da biblioteca padrão agora são instâncias de SingletonGate:

    Isso significa que, se essas classes forem instanciadas como (por exemplo) XGate() usando todos os padrões do construtor, todos eles compartilharão uma única instância global. Isso resulta em uma grande redução na sobrecarga de memória para > 1 objeto desses tipos e em um tempo de construção de objetos significativamente mais rápido.

  • Introduzimos uma nova classe SingletonControlledGate que é uma subclasse de ControlledGate que usa uma única instância para todos os objetos desse tipo. A intenção por trás dessa classe é minimizar a memória e a sobrecarga de construção do uso de várias portas em um circuito, com a desvantagem de ter um estado global compartilhado. Por esse motivo, essa classe só se aplica a portas que não têm nenhum estado exclusivo e/ou mutável armazenado em uma instância. Por exemplo, um CXGate não contém nenhum estado e, portanto, pode aproveitar o SingletonControlledGate (e o faz a partir desta versão). Por outro lado, CRXGate armazena um parâmetro de ângulo como parte de seus dados de instância e, portanto, não pode usar SingletonControlledGate.

    O outro possível problema que deve ser observado ao usar o SingletonControlledGate é que o modelo de dados original de ControlledGate suporta mutação. Especificamente, o label, duration, unit, condition, e ctrl_state são todos acessíveis e mutáveis no arquivo ControlledGatemas a mutação desses atributos em subclasses SingletonControlledGate não é permitida e gerará uma exceção. Esses atributos podem ser personalizados, mas somente no momento da criação (ou seja, por meio do construtor). Nesse caso, o portão recém-construído será uma instância separada com o estado personalizado em vez da instância compartilhada globalmente. Você também pode usar o método SingletonControlledGate.to_mutable() para obter uma cópia mutável de um objeto gate e, em seguida, alterar os atributos como faria em qualquer outro objeto Instruction objeto.

  • As seguintes portas da biblioteca padrão agora são instâncias de SingletonControlledGate:

    Isso significa que, a menos que label, condition, duration, unit ou ctrl_state sejam definidos na instância no momento da criação, todos eles compartilharão uma única instância global sempre que um novo objeto de portão for criado. Isso resulta em uma grande redução na sobrecarga de memória para > 1 objeto desses tipos.

  • Adicionado um novo método Instruction.to_mutable() e atributo Instruction.mutable que é usado para obter uma cópia mutável e verificar se um objeto Instruction objeto é mutável. Com a introdução do SingletonGate esses métodos podem ser usados para ter uma interface unificada para lidar com a mutabilidade dos objetos de instrução.

  • Adicionado um atributo Instruction.base_classque obtém o tipo "base" de uma instrução. Muitas instruções atenderão a type(obj) == obj.base_class, mas as instâncias únicas de SingletonInstruction e SingletonGate são subclasses de seu tipo básico. Você pode usar o atributo new base_class para encontrar a classe base deles. Consulte a documentação do atributo para obter considerações sobre quando outras subclasses podem modificar seus atributos base_classe o que isso significa para a execução.

  • Adicionado o circuito UnitaryOverlap à biblioteca de circuitos do Qiskit. Ele pode ser usado para calcular a fidelidade dos estados gerados por unitários, observando a probabilidade da distribuição de saída no estado de todos os zeros ou, de forma equivalente, calculando o valor da expectativa do projetor no estado de todos os zeros. Isso é útil em aplicações como aprendizado de máquina e computação de estados excitados em química quântica, para citar alguns exemplos.

Recursos do Pulse

  • Programação de circuito-para-pulso ativada usando BackendV2.

    # import a fake backend which is a sub-class of BackendV2
    from qiskit.providers.fake_provider import FakePerth
    from qiskit.compiler.scheduler import schedule
    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.measure(0,0)
    sched = schedule(circuits=qc, backend=FakePerth())

    Como BackendV2 não era compatível com a função schedule() isso fazia com que o método schedule() apresentasse erro quando o argumento backend era fornecido com uma instância de BackendV2. Consulte o número 10837 para obter mais informações.

OpenQASM Características

  • O módulo OpenQASM 2 qiskit.qasm2 ganhou as funções de exportação dump() e dumps(). Elas são usadas de maneira muito semelhante às anteriores QuantumCircuit.qasm():

    from qiskit import qasm2, QuantumCircuit
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure([0, 1], [0, 1])
    print(qasm2.dumps(qc))

    As novas funções têm origem no mesmo código do QuantumCircuit.qasm()que será lentamente eliminado e substituído pelos novos caminhos, para fornecer uma interface mais coerente em comparação com o OpenQASM 3 (qiskit.qasm3) e QPY (qiskit.qpy). Isso é particularmente importante, pois o nome do método qasm() não deu nenhuma indicação da versão OpenQASM e, desde que foi originalmente adicionado, o Qiskit ganhou vários módulos de serialização que poderiam ser facilmente confundidos.

Recursos do QPY

  • O QPY agora é compatível com o uso de serialização e desserialização nativas do symengine para objetos do tipo ParameterExpression , bem como expressões simbólicas em blocos de programação do Pulse. Essa é uma alternativa de serialização mais rápida, mas não é compatível com todas as plataformas. Verifique se sua plataforma de destino é compatível com a biblioteca symengine antes de definir essa opção, pois ela será exigida pelo qpy para desserializar a carga útil.

    O recurso pode ser ativado por meio do parâmetro use_symengine em qpy.dump():

    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit import qpy
    
    theta = Parameter("theta")
    phi = Parameter("phi")
    sum_param = theta + phi
    
    qc = QuantumCircuit(1)
    qc.rz(sum_param, 0)
    qc.measure_all()
    
    with open('bell.qpy', 'wb') as fd:
        qpy.dump(qc, fd, use_symengine=True)
    
    with open('bell.qpy', 'rb') as fd:
        new_qc = qpy.load(fd)[0]

Recursos de informação quântica

  • Adicionado Clifford.from_linear_function() e Clifford.from_permutation() que criam um objeto Clifford objeto de LinearFunction e de PermutationGate respectivamente. Como consequência, um Clifford pode agora ser construído diretamente a partir de a LinearFunction, a PermutationGateou de um circuito quântico que contenha essas portas.

  • A classe Operator agora tem um método draw() que permite que ela seja exibida como uma matriz de texto, objeto IPython LaTeX ou fonte LaTeX. O tipo de sorteio padrão ainda é o ASCII __repr__ do operador.

  • Adicionado um novo método, apply_layout()à classe SparsePauliOp classe. Esse método é usado para aplicar um layout TranspileLayout layout do transpilador a um SparsePauliOp observável que foi criado para um circuito de entrada para o transpilador. Isso permite trabalhar com BaseEstimator implementações e a transpilação local com mais facilidade. Por exemplo:

    from qiskit.circuit.library import RealAmplitudes
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.primitives import BackendEstimator
    from qiskit.compiler import transpile
    from qiskit.providers.fake_provider import FakeNairobiV2
    
    psi = RealAmplitudes(num_qubits=2, reps=2)
    H1 = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
    backend = FakeNairobiV2()
    estimator = BackendEstimator(backend=backend, skip_transpilation=True)
    
    thetas = [0, 1, 1, 2, 3, 5]
    transpiled_psi = transpile(psi, backend, optimization_level=3)
    permuted_op = H1.apply_layout(transpiled_psi.layout)
    res = estimator.run(transpiled_psi, permuted_op, thetas)

    onde um circuito de entrada é transpilado localmente antes de ser passado para run. A transpilação expande o circuito original de 2 para 7 qubits (o tamanho de backend) e altera seu layout, que é então aplicado a H1 usando apply_layout() para refletir as transformações realizadas por transpile().

Recursos do Transpiler

  • A classe HighLevelSynthesis é estendida para sintetizar circuitos com objetos do tipo AnnotatedOperation.

  • Um novo módulo qiskit.passmanager foi adicionado à biblioteca do Qiskit. Esse módulo implementa um gerenciador de passagens genérico e controladores de fluxo, além de fornecer infraestrutura para gerenciar a execução das tarefas do gerenciador de passagens. O módulo fornece classes básicas para passes (GenericPass) e controladores de fluxo (BaseController), bem como uma nova classe de interface, passmanager.Task, para gerenciar a execução do gerenciador de passes (consulte o método Task.execute() ). Essas novas classes seguem o padrão composto, pois os controladores de fluxo são coleções de passes, e um controlador pode ser aninhado recursivamente no pipeline de tarefas. Também é preciso observar que as classes básicas não estão cientes dos tipos de objetos de entrada e saída e devem ser subclassificadas para otimizar um tipo de programa específico. Esse design unificado reduz a complexidade do gerenciador de passagens convencional e não exige mais o uso de classes como RunningPassManager para lidar com o envio da lógica de execução e a renormalização da estrutura da tarefa. O módulo qiskit.transpiler foi reorganizado para reconstruir os gerenciadores de passes existentes com base no gerenciador de passes genérico. Consulte as notas de upgrade para obter mais detalhes.

  • Adicionada uma nova análise SabrePreLayout que cria um layout inicial para SabreLayoutgravando o layout no valor do conjunto de propriedades sabre_starting_layouts.

    A passagem funciona aumentando o mapa de acoplamento com mais e mais bordas "extras" até que VF2Layout consiga encontrar um isomorfismo de gráfico perfeito. Mais precisamente, o mapa de acoplamento aumentado contém bordas entre nós que estão dentro de uma determinada distância d no mapa de acoplamento original, e o valor de d é aumentado até que um isomorfismo seja encontrado. Opcionalmente, a passagem também minimiza o número de bordas extras envolvidas no layout até que um mínimo local seja encontrado. Isso envolve a remoção de bordas extras e a chamada de VF2Layout para verificar se ainda existe um isomorfismo.

    Aqui está um exemplo de como chamar a função SabrePreLayout antes SabreLayout:

    import math
    from qiskit.transpiler import CouplingMap, PassManager
    from qiskit.circuit.library import EfficientSU2
    from qiskit.transpiler.passes import SabrePreLayout, SabreLayout
    
    qc = EfficientSU2(16, entanglement='circular', reps=6, flatten=True)
    qc.assign_parameters([math.pi / 2] * len(qc.parameters), inplace=True)
    qc.measure_all()
    
    coupling_map = CouplingMap.from_heavy_hex(7)
    
    pm = PassManager(
        [
            SabrePreLayout(coupling_map=coupling_map),
            SabreLayout(coupling_map),
        ]
    )
    
    pm.run(qc)
  • Foram adicionados os argumentos coupling_map, target e use_qubit_indices à HighLevelSynthesis passagem do transpilador. O argumento target especifica o backend de destino, permitindo que os plug-ins de síntese chamados dentro da passagem acessem todas as informações específicas do destino, como o mapa de acoplamento e o conjunto de portas suportado. O argumento coupling_map especifica apenas o mapa de acoplamento e só é usado quando target não é especificado. O argumento use_qubit_indices indica se a passagem de síntese de alto nível está sendo executada antes ou depois da definição do layout, ou seja, se os índices de qubit dos objetos de nível superior correspondem aos índices de qubit no backend de destino.

  • Foram adicionados os argumentos coupling_map, target e qubits a HighLevelSynthesisPlugin. O argumento posicional target especifica o backend de destino, permitindo que o plug-in acesse todas as informações específicas do destino, como o mapa de acoplamento, o conjunto de portas suportado e assim por diante. O argumento posicional coupling_map especifica apenas o mapa de acoplamento e só é usado quando target não é especificado. O argumento posicional qubits especifica a lista de qubits sobre a qual o objeto de nível superior é definido, caso a síntese seja feita no circuito físico. O valor de None indica que o layout ainda não foi escolhido.

    Isso permite uma separação mais limpa das opções de plug-ins de síntese em opções gerais de interface para plug-ins (ou seja, coupling_map, target e qubits) e em opções específicas de plug-ins (um dicionário de configuração de forma livre especificado em options). Vale a pena observar que essa alteração é compatível com as versões anteriores; se as opções coupling_map, etc. não forem explicitamente adicionadas ao método run() do plug-in, elas aparecerão como parte de options.

  • Os DAGCircuit métodos apply_operation_back() e apply_operation_front() ganharam um argumento de palavra-chave check que pode ser definido como False para ignorar a validação de que as entradas atendem às DAGCircuit invariantes da estrutura de dados. Isso é útil como uma otimização de desempenho quando o DAG está sendo criado a partir de dados conhecidos como bons, como durante as passagens do transpilador.

  • O método CouplingMap.reduce() agora aceita um argumento adicional check_if_connected, cujo padrão é True. Isso corresponde ao comportamento anterior, verificando se o mapa de acoplamento reduzido permanece conectado e gerando um CouplingError caso contrário. Quando definido como False, a verificação é ignorada, permitindo mapas de acoplamento reduzido desconectados.

  • O construtor do HighLevelSynthesis transpiler pass agora aceita argumentos adicionais equivalence_library, basis_gates, e min_qubits. A passagem agora pode desenrolar definições personalizadas de forma semelhante a UnrollCustomDefinitionse, como tal, substitui completamente a funcionalidade da última passagem. Em particular, HighLevelSynthesis agora é recursivo, corrigindo um descuido na implementação inicial. Portanto, quando target ou basis_gates são especificados, HighLevelSynthesis sintetiza recursivamente todos os objetos de alto nível, operações anotadas e portas personalizadas no circuito, deixando apenas as portas que são compatíveis com o destino ou que pertencem à biblioteca de equivalência. Isso permite o uso HighLevelSynthesis como um substituto para UnrollCustomDefinitions. Por outro lado, quando nem target nem basis_gates são especificados, a passagem sintetiza apenas os objetos de alto nível "top-level" e as operações anotadas, ou seja, não desce recursivamente para o campo definition dos portões personalizados. Isso é compatível com as versões anteriores do UnrollCustomDefinitions (que não faria nada) e com o comportamento mais antigo da passagem de síntese de alto nível, que permite usá-lo como uma transformação intermediária, sintetizando apenas objetos de alto nível, conforme especificado por HLSConfig.

  • Melhorou significativamente o desempenho da passagem do MergeAdjacentBarriers passagem do transpilador, que costumava reconstruir o DAG completo para mesclar as barreiras.

  • Foi adicionado um novo argumento de palavra-chave, min_qubits, ao construtor da passagem BasisTranslator passagem do transpilador. Quando definido como um valor diferente de zero, é usado para definir um número mínimo de qubits para filtrar as operações a serem traduzidas no circuito. Por exemplo, se min_qubits=3 for definido, a instância BasisTranslator somente traduzirá as portas no circuito que operam em 3 ou mais qubits.

  • Foi adicionado um novo argumento de palavra-chave, min_qubits, ao construtor da passagem UnrollCustomDefinitions passagem do transpilador. Quando definido como um valor diferente de zero, é usado para definir um número mínimo de qubits para filtrar as operações a serem traduzidas no circuito. Por exemplo, se min_qubits=3 for definido, a instância UnrollCustomDefinitions somente traduzirá as portas no circuito que operam em 3 ou mais qubits.

  • Foi adicionado suporte à função SabreLayout para adicionar tentativas com layouts iniciais especificados. A SabreLayout transpiler normalmente executa várias tentativas de layout que começam com layouts totalmente aleatórios e, em seguida, usa uma passagem de roteamento para permutar esse layout em vez de inserir trocas para encontrar um layout que resulte em menos portas de troca. Esse novo recurso permite executar um AnalysisPass antes de SabreLayout que define o campo "sabre_starting_layout" no conjunto de propriedades para fornecer ao SabreLayout com layouts iniciais adicionais para usar em seus testes internos. Por exemplo, se você quiser executar DenseLayout como ponto de partida para uma tentativa em SabreLayout você faria algo como:

    from qiskit.providers.fake_provider import FakeSherbrooke
    from qiskit.transpiler import AnalysisPass, PassManager
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.transpiler.passes import DenseLayout
    
    class SabreDenseLayoutTrial(AnalysisPass):
    
      def __init__(self, target):
          self.dense_pass = DenseLayout(target=target)
          super().__init__()
    
      def run(self, dag):
          self.dense_pass.run(dag)
          self.property_set["sabre_starting_layouts"] = [self.dense_pass.property_set["layout"]]
    
    backend = FakeSherbrooke()
    opt_level_1 = generate_preset_pass_manager(1, backend)
    pre_layout = PassManager([SabreDenseLayoutTrial(backend.target)])
    opt_level_1.pre_layout = pre_layout

    Então, quando o opt_level_1 StagedPassManager for executado com um circuito, a saída do DenseLayout será usada para uma das SabreLayout tentativas, além das 5 tentativas totalmente aleatórias que são executadas por padrão no nível de otimização 1.

  • Duas novas passagens de transpilador foram adicionadas para gerar calibrações de porta RX de pulso único em tempo real. Essas calibrações de RX de pulso único reduzirão o tempo de porta pela metade, conforme descrito em P.Gokhale et al, Optimized Quantum Compilation for Near-Term Algorithms with OpenPulse (2020), arXiv:2004.11205.

    Para reduzir a quantidade de dados de calibração de RX que precisam ser gerados, NormalizeRXAngle executa três otimizações: agrupando os RXGate ângulos de rotação para [0, pi], substituindo RX(pi/2) e RX(pi) por SXGate e XGatee quantizando os ângulos de rotação. Essa passagem deve ser executada antes do RXCalibrationBuilderque gera calibrações de RX em tempo real.

    As otimizações realizadas pelo NormalizeRXAngle reduzem a quantidade de dados de calibração e nos permitem aproveitar os pulsos mais precisos e calibrados por hardware. As calibrações geradas por RXCalibrationBuilder são inicializadas a partir da calibração SXGate que já deve estar presente no alvo. A amplitude é escalonada linearmente para atingir o ângulo de rotação arbitrário desejado.

    Essas calibrações de pulso único reduzem o RXGate tempo pela metade, em comparação com a sequência convencional que consiste em dois SXGate pulsos. Pode haver um aprimoramento na fidelidade devido a essa redução no tempo de acesso.

  • Foram adicionados novos métodos para TranspileLayout, initial_index_layout() e routing_permutation()que são usados para gerar uma exibição de lista do TranspileLayout.initial_layout e TranspileLayout.final_layout respectivamente. Por exemplo, se o atributo final_layout fosse:

    Layout({
      qr[0]: 2,
      qr[1]: 3,
      qr[2]: 0,
      qr[3]: 1,
    })

    então routing_permutation() retornará:

    [2, 3, 0, 1]
  • Adicionado um novo método para TranspileLayout, initial_virtual_layout()que é equivalente ao atributo TranspileLayout.initial_layout mas oferece a opção de filtrar os qubits de ancilla que foram adicionados ao circuito. Por padrão, o TranspileLayout.initial_layout normalmente incluirá todos os ancillas adicionados pelo transpilador.

  • Adicionado um novo método, final_index_layout() e final_virtual_layout() à classe TranspileLayout classe. Esses métodos são usados para retornar um layout final (o mapeamento dos qubits do circuito de entrada para a posição final na saída). Isso é diferente do atributo final_layout que é a permutação causada pelo roteamento como um objeto Layout objeto. O método final_index_layout() retorna uma lista para mostrar a posição de saída de cada qubit no circuito de entrada para o transpilador. Por exemplo, com um circuito original:

    qc = QuantumCircuit(3)
    qc.h(0)
    qc.cx(0, 1)
    qc.cx(0, 2)

    e a saída do transpilador foi:

    tqc = QuantumCircuit(3)
    tqc.h(2)
    tqc.cx(2, 1)
    tqc.swap(0, 1)
    tqc.cx(2, 1)

    então a saída de final_index_layout() retornaria uma lista de:

    [2, 0, 1]

    O final_virtual_layout() retorna isso como um objeto Layout portanto, o retorno do exemplo acima seria:

    Layout({
      qc.qubits[0]: 2,
      qc.qubits[1]: 0,
      qc.qubits[2]: 1,
    })

Recursos de visualização

  • Foi adicionada a capacidade de exibir condições como expressões de Expr no método QuantumCircuit.draw() e na função circuit_drawer() função ao visualizar circuitos que têm ControlFlowOp instruções.

  • Foram adicionados os estilos de cores "iqp" e "iqp-dark" para a gaveta de circuitos matplotlib , que são baseados no esquema de cores IBM Quantum Platform.

  • Em TextDrawer, as operações criadas a partir de ControlFlowOpincluindo if, else, while, for e switch/case, sejam elas diretamente instanciadas ou criadas usando métodos em QuantumCircuitagora exibirão totalmente os circuitos definidos em ControlFlowOps com colchetes para delinear os circuitos.

  • Ao definir uma folha de estilo personalizada para a gaveta da linha do tempo de pulso qiskit.visualization.timeline_drawer()as funções de "gerador" que têm o atributo de objeto accepts_program definido como True receberão um argumento de palavra-chave extra program contendo a programação completa QuantumCircuit que está sendo desenhado.

  • As visualizações do plot_gate_map(), plot_coupling_map(). plot_error_map(), e plot_circuit_layout() foram significativamente aprimoradas para renderizar layouts de backends com grande número de qubits. Isso foi feito aproveitando o graphviz por meio da função graphviz_draw() do rustworkx para executar um layout de gráfico algorítmico mais sofisticado que é dimensionado para um grande número de qubits.

    _images/release_notes-1.png

Páginas Recursos

  • Foi adicionado suporte para expressar o sinal de um ParameterExpression. Em vez de atribuir um valor concreto e usar numpy.sign ou outras funções de biblioteca, o usuário pode usar a instância da classe ParameterExpression para calcular o sinal e pode trabalhar com o sinal antes que a expressão seja totalmente atribuída.

    Ele pode ser usado da seguinte forma:

    from qiskit.circuit import Parameter
    
    b = Parameter("phi")
    sign_value = b.sign()
    print("sign of an unassigned Parameter is: ", sign_value)
    print("Sign of a Parameter assigned to -3 is: ", sign_value.assign(b,-3))

    Consulte a seção 10360 para obter mais detalhes.

  • Parameter agora tem um argumento de palavra-chave de uso avançado uuid em seu construtor, que pode ser usado para tornar o Parameter se compare a outro com o mesmo nome. Normalmente, não deve ser usado pelos usuários e é mais útil para serialização e desserialização personalizadas.

Notas sobre atualização de circuitos

  • O ControlledGate.definition da saída do método Gate.control() pode ser diferente em comparação com as versões anteriores. A geração interna do método Gate.control() não está mais usando o agora obsoleto Unroller para gerar sua definição, e isso pode fazer com que uma definição diferente seja gerada. A definição do objeto ControlledGate será unitariamente equivalente ao que foi gerado anteriormente. Mas se você precisar da definição exata da chamada Gate.control() poderá usar uma versão anterior e salvar o circuito com qpy.dump() e depois carregá-lo com uma versão mais recente.

  • A propriedade num_ancilla_qubits da classe PolynomialPauliRotations foi removida, pois foi descontinuada no Qiskit 0.23.0. Em vez disso, use a propriedade PolynomialPauliRotations.num_ancillas.

  • As seguintes portas da biblioteca padrão:

    não são mais capazes de definir label, condition, duration, ou unit (e ctrl_state para ControlledGate subclasses) depois de instanciar um objeto. Você ainda pode definir condition através do uso c_if(). Você pode usar to_mutable() para obter uma cópia mutável da instrução e, em seguida, usar o setter nessa cópia em vez do objeto original. label, duration e unit podem ser fornecidos como argumentos de palavra-chave para essas portas no momento da construção, e uma instância mutável será retornada automaticamente. Essa alteração foi necessária como parte da conversão dessas classes para serem SingletonGate e SingletonControlledGate o que reduz bastante o espaço de memória de instâncias repetidas dessas portas.

  • Para qualquer coisa que interaja com Gate, Operation, ou Instruction ou trabalha com eles como parte de um objeto QuantumCircuit ou DAGCircuit é importante observar que o uso de referências compartilhadas para instâncias é muito mais comum atualmente. Anteriormente, era possível reutilizar e compartilhar uma instância de uma operação de circuito, mas isso não era muito usado e uma cópia geraria uma instância exclusiva. Isso foi alterado a partir desta versão devido a SingletonInstruction e SingletonGate que estão sendo disponibilizados (e um grande número de portas de biblioteca padrão agora construídas com base neles). Se o seu uso desses objetos estiver assumindo instâncias exclusivas para cada operação de circuito, isso se tornará um problema em potencial, pois agora um estado compartilhado será reutilizado entre operações do mesmo tipo (que persistirá por meio de cópias e cópias profundas). Você pode contar com o atributo Instruction.mutable para verificar a mutabilidade de um objeto ou usar o atributo Instruction.to_mutable() para obter uma cópia mutável de qualquer instrução.

  • Mais Instruction instâncias (aquelas que retornam singletons) não satisfazem mais estritamente (por exemplo):

    type(XGate()) is XGate

    No entanto, o objeto retornado ainda será uma subclasse padrão, portanto isinstance() (a maneira correta de fazer a verificação de tipo) continuará a funcionar corretamente. Várias instruções já tinham essa propriedade (por exemplo MCXGate), mas agora é mais comum, pois muitos outros portões padrão fazem isso.

    Se, por algum motivo, você precisar do tipo "base" de uma porta, omitindo as subclasses sintéticas de singleton, que não podem ser instanciadas, consulte Instruction.base_class.

  • A definição de UnitaryGate para unitários de um único qubit está agora em termos de UGate em vez da antiga classe U3Gate classe.

Notas de atualização dos fornecedores

  • O QasmSimulatorPy baseado em python incluído em qiskit.providers.basicaer agora inclui 'h' (HGate), 'p' (PhaseGate) e 'u' (UGate) em seu conjunto de portas de base.

  • O argumento channel no método PulseBackendConfiguration.control() é removido. Ele foi descontinuado no Qiskit 0.33 (com o Terra 0.19 ), lançado em dezembro de 2021. Em vez disso, use o argumento qubits .

  • Substituiu o argumento qobj[Qobj] em QasmSimulatorPy.run() por run_input[QuantumCircuit or list]

    Aqui está um exemplo para migrar seu código:

    # Importing necessary Qiskit libraries
    from qiskit import transpile, QuantumCircuit
    from qiskit.aer import QasmSimulator
    
    # Defining the Quantum Circuit
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    # Transpile the circuit to optimize for the target simulator
    simulator = QasmSimulator()
    transpiled_circuit = transpile(qc, simulator)
    # Run the simulation
    job = simulator.run(transpiled_circuit, shots=1024)
    # Get the simulation result
    result = job.result()

    Todos eles foram descontinuados desde 0.22 (lançado em 13 de outubro de 2022) e agora foram removidos.

Notas sobre a atualização do Pulse

  • As funções qiskit.scheduler.utils.format_meas_map(), qiskit.scheduler.utils.measure() e qiskit.scheduler.utils.measure_all() foram movidas para qiskit.pulse.utils.format_meas_map(), qiskit.pulse.macros.measure() e qiskit.pulse.macros.measure_all() , respectivamente. O local anterior foi descontinuado no Qiskit 0.20.0 (Terra 0.15.0, lançado em 2020-08-10) e não é mais compatível.

  • Os métodos to_dict nas classes pulse.transforms.AlignmentKind, pulse.transforms.AlignEquispaced, e pulse.transforms.AlignFunc são removidos. Eles foram descontinuados no Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022.

Notas de atualização do QPY

  • O uso da palavra-chave circuits para o primeiro argumento posicional na função qiskit.qpy.dump() foi removido, pois seu uso foi descontinuado no Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022. Em vez disso, use a palavra-chave programs (ou simplesmente passe o argumento na posição), que tem comportamento idêntico.

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

  • O método qiskit.quantum_info.pauli_basis() não aceita mais o argumento pauli_list . Ele foi descontinuado no Qiskit 0.39 (com o Terra 0.22 ), lançado em outubro de 2022.

  • A função random_stabilizer_table no módulo qiskit.quantum_info.random foi removida. Ele foi descontinuado no Qiskit 0.39 (com o Terra 0.22 ), lançado em outubro de 2022. Em vez disso, use qiskit.quantum_info.random.random_pauli_list().

  • As classes qiskit.quantum_info.PauliTable e qiskit.quantum_info.StabilizerTable foram removidas. A função random_pauli_table() também foi removida. Eles foram descontinuados no Qiskit 0.43 (com o Terra 0.24 ), lançado em maio de 2023. Em vez disso, você deve usar PauliList e random_pauli_list().

  • Os argumentos z e x para o inicializador de to Pauli foram removidos, pois foram descontinuados no Qiskit Terra 0.17 (lançado em abril de 2021). Em vez disso, um par de x e z deve ser passado posicionalmente como uma única tupla (Pauli((z, x))).

  • O argumento label para o inicializador de Pauli foi removido, pois foi descontinuado no Qiskit Terra 0.17 (lançado em abril de 2021). Em vez disso, passe o rótulo de forma posicional, como em Pauli("XYZ").

  • A importação de qiskit.quantum_info.operators.pauli não é mais permitida, pois foi descontinuada no Qiskit Terra 0.21 (lançado em junho de 2022). Em vez disso, importe diretamente de qiskit.quantum_info .

Notas sobre a atualização da síntese

  • O parâmetro order no construtor synthesis.SuzukiTrotter do construtor gera uma exceção em vez de um aviso de depreciação quando definido em um número ímpar. As fórmulas do produto Suzuki são simétricas e, portanto, definidas apenas para ordens pares.

Notas sobre a atualização do Transpiler

  • Como consequência dos esforços de refatoração do gerenciador de passes, os controladores de fluxo existentes: FlowControllerLinear, ConditionalController, e DoWhileController agora são subclasses do controle de fluxo BaseController. Observe que esses controladores abandonaram a implementação do método __iter__() método. Agora, eles só podem ser iterados no contexto de uma execução de controlador de fluxo, que encadeia o estado de compilação após a execução de cada tarefa interna.

  • A funcionalidade da classe RunningPassManager foi substituída pela nova estrutura do gerenciador de passes (BasePassManager e BaseController). O gerenciador de passagens em execução agora é um controlador de fluxo sem estado (essencialmente, um alias de FlowControllerLinear), pois o gerenciador de passagens é responsável pela construção do pipeline de tarefas, enquanto o controlador é responsável pela execução das tarefas associadas. A subclasse RunningPassManager não é mais recomendada, e essa classe será completamente substituída pelo controlador de fluxo em versões futuras.

  • Uma nova classe, WorkflowStatusfoi introduzida para rastrear o status do fluxo de trabalho do gerenciador de passes. Esse objeto portátil é criado quando o gerenciador de passes é executado e entregue às tarefas subjacentes. Esse status era gerenciado anteriormente pelo site RunningPassManager com variáveis de instância.

  • O transpilador específico transpiler.PassManager (usado em transpile()) é agora uma subclasse de passmanager.BasePassManager. No entanto, essa alteração na hierarquia de classes não introduz nenhuma mudança significativa na API voltada para o público.

  • As exceções geradas durante a execução do gerenciador de passagens agora herdam do recém-introduzido PassManagerError. Uma falha genérica do mecanismo do gerenciador de passes gerará PassManagerError para gerenciadores de passagens em geral, mas o transpile.PassManager específico do transpilador atualmente envolverá isso em seu TranspilerError específico para compatibilidade com versões anteriores. Esse invólucro será removido no futuro.

  • O uso do FencedObject na estrutura do gerenciador de passes foi removido. Essa classe de proteção não pode proteger atributos de objetos mutáveis contra modificações, e isso não deve ser um problema para o código implementado corretamente. As passagens de análise não devem modificar um IR de entrada, os controladores não devem atualizar o conjunto de propriedades e assim por diante. É responsabilidade do desenvolvedor do gerenciador de passes garantir que o passe não esteja modificando os atributos do objeto,

  • O nome do plug-in default é reservado para os estágios do plug-in init, layout, optimization e scheduling. Anteriormente, esses estágios não reservavam esse nome de plug-in, mas o nome default agora é usado para representar o método padrão incorporado do Qiskit para esses estágios. Se você estava usando esses nomes para plug-ins nesses estágios, eles entrarão em conflito com o uso do Qiskit e você deverá renomear seu plug-in.

  • Desativou o uso da classe RemoveResetInZeroState nos gerenciadores de passagens predefinidos. Anteriormente, quando transpile() ou generate_preset_pass_manager() era executado com optimization_level nos níveis 1, 2 ou 3, ele executava RemoveResetInZeroState. Entretanto, essa passagem proibiu a noção de estados iniciais arbitrários, a menos que explicitamente definidos como zeros com redefinições. Se você precisar executar a passagem como parte do pipeline de compilação, poderá executar algo como:

    pm = generate_preset_pass_manager(1, backend)
    pm.init.append(RemoveResetInZeroState())
    pm.run(circuit)

    para manter essa funcionalidade em sua compilação de circuitos.

  • O passe de roteamento do transpilador obsoleto, BIPMapping , foi removido. Ele foi marcado como obsoleto na versão do Qiskit 0.43.0. Ele foi substituído por um pacote de plug-in externo: qiskit-bip-mapper. Os detalhes desse novo pacote podem ser encontrados no repositório github do pacote:

    https://github.com/qiskit-community/qiskit-bip-mapper

    A passagem foi transformada em um pacote de plug-in separado por dois motivos: primeiro, a dependência do CPLEX dificulta o uso e, segundo, o pacote de plug-in se integra de forma mais limpa ao transpile(). O extra opcional bip-mapper para instalar cplex e docplex para dar suporte a essa passagem foi removido, pois nada no Qiskit exige mais isso como opcional.

  • O argumento qubits no método InstructionDurations.get()não aceita mais Qubit (ou uma lista deles). Essa funcionalidade foi descontinuada no Qiskit 0.33 (com o Terra 0.19 ), lançado em dezembro de 2021. Em vez disso, use um número inteiro para os índices de qubit.

  • Removido o argumento qubit_channel_mapping em RZXCalibrationBuilderque foi descontinuado no Qiskit 0.39 (lançado em outubro de 2022, com o qiskit-terra 0.22 )

  • No transpiler.CouplingMap o método subgraph é removido como obsoleto em 0.20. reduce() pode ser usado no lugar do método subgraph.

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

  • Foi removido o suporte ao uso da palavra-chave rho para o primeiro argumento posicional em plot_state_hinton(), plot_bloch_multivector(), plot_state_city(), plot_state_paulivec(), e plot_state_qsphere(). O uso de rho foi substituído por state, que pode ser usado em seu lugar. Removido qiskit.scheduler.utils , pois todas as funções contidas foram movidas para qiskit.pulse.macros e qiskit.pulse.utils. Todos eles foram descontinuados desde 0.15 (lançado em 06 de agosto de 2020) e agora foram removidos.

  • Os argumentos do construtor de classe qregs, cregs, layout e global_phase para visualization.QCircuitImage foram removidos, pois foram descontinuados em 0.20.

  • As funções de visualização: plot_gate_map(), plot_coupling_map(). plot_error_map(), e plot_circuit_layout() agora dependem da instalação do graphviz para funcionar. Essa alteração foi necessária para permitir a visualização de backends com um número maior de qubits. Esse requisito externo adicional se soma às dependências opcionais existentes que essas funções exigiam anteriormente. Você encontra detalhes sobre como instalar o graphviz aqui: https://graphviz.org/download/

Páginas Notas da Atualização

  • Os valores QuasiDistribution podem incluir erros de ponto flutuante. QuasiDistribution.__repr__ rodadas usando numpy.round() e o parâmetro ndigits pode ser manipulado com o atributo de classe __ndigits__. O padrão é 15.

  • A classe qiskit.qobj.Qobj é removida. Ele foi descontinuado no Qiskit 0.33 (com o Terra 0.19 ), lançado em dezembro de 2021. Em vez disso, use qiskit.qobj.QasmQobj ou qiskit.qobj.PulseQobj.

  • O decorador qiskit.utils.deprecation.deprecate_function() está obsoleto desde o Qiskit 0.39.0 (lançado em outubro de 2022, com o qiskit-terra 0.22.0 ) e agora foi removido. Use qiskit.utils.deprecate_func() em vez disso.

  • A função execute() não aceita mais os argumentos qobj_id e qobj_header . Seu uso foi descontinuado no Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022.

  • A passagem de transpilação qiskit.transpiler.passes.CXDirection é removida. Seu uso foi descontinuado no Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022. Em vez disso, use a opção mais genérica GateDirection pass.

  • A passagem de transpilação qiskit.transpiler.passes.CheckCXDirection é removida. Seu uso foi descontinuado no Qiskit 0.37 (com o Terra 0.21 ), lançado em junho de 2022. Em vez disso, use a opção mais genérica CheckGateDirection pass.

  • A compilação do Qiskit a partir da fonte agora requer um compilador Rust compatível com a versão da linguagem 1.64. Isso foi aumentado em relação à versão mínima compatível anterior do Rust do 1.61 para a criação de versões anteriores do Qiskit.

Algoritmos obsoletos

  • Os utilitários de algoritmo em qiskit.utils.validation e qiskit.utils.algorithm_globals agora estão obsoletos e serão removidos em pelo menos três meses a partir da data de lançamento. Esses utilitários foram introduzidos com o módulo qiskit.algorithms para dar suporte a fluxos de trabalho de algoritmos antigos e baseados em primitivas. Agora que o qiskit.algorithms está obsoleto e a base de código dos algoritmos baseados em primitivas foi migrada para uma biblioteca autônoma, esses utilitários não são mais usados no contexto do Qiskit. Se o seu aplicativo permitir, recomendamos que você migre seu código para usar o qiskit_algorithms, onde você poderá importar os utilitários relevantes em algorithm_globals e validation de qiskit_algorithms.utils. Observe que a funcionalidade herdada não foi migrada para o novo pacote.

Descontinuidade de circuitos

Depreciações do Transpiler

  • O método de fábrica do controlador de fluxo FlowController.controller_factory() foi descontinuado junto com FlowController.add_flow_controller() e FlowController.remove_flow_controller(). No futuro, a construção de tarefas com argumentos de palavras-chave no método BasePassManager.append() também será preterida. Os controladores devem ser explicitamente instanciados e anexados ao gerenciador de passes. Por exemplo, a sintaxe convencional usada anteriormente

    pm.append([task1, task2], condition=lambda x: x["value1"] > 10)

    deve ser substituído por

    controller = ConditionalController([task1, task2], condition=lambda x: x["value1"] > 10)
    pm.append(controller)

    O último permite um controle mais preciso da ordem dos controladores, especialmente quando vários argumentos de palavras-chave são especificados juntos, e permite a construção de controladores de fluxo gerais que podem ter mais de um pipeline ou que não usam uma única função condicional simples em seus construtores.

  • O FlowControllerLinear.append(), DoWhileController.append(), e ConditionalController.append() são todos imediatamente obsoletos. A construção do pipeline de tarefas do gerenciador de passes agora é função do BasePassManagere os controladores de fluxo individuais não precisam usar esse método. Para um controlador de fluxo, todas as passagens devem ser especificadas de uma só vez diretamente no construtor.

  • O atributo geral e o nome da variável passes são substituídos por tasks em todo o qiskit.passmanager módulo. Observe que uma tarefa deve indicar uma união de pass e controller, e a forma singular pass entra em conflito com a palavra-chave Python. Nesse sentido, o uso de tarefas é muito preferível.

  • A passagem Unroller foi preterido e será removido em uma versão futura. O Unroller foi substituído pelo BasisTranslator que oferece um conjunto semelhante de funcionalidades, mas de forma mais geral, para que você possa traduzir um circuito para qualquer conjunto de base universal. A classe Unroller só funciona em situações em que as definições das portas do circuito são definidas recursivamente em termos da base de destino; para as portas da biblioteca padrão do Qiskit, isso significa UGate e CXGate. Se você estiver usando o passe Unroller ele poderá ser substituído pelo uso de um gerenciador de passes personalizado do formulário:

    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import UnrollCustomDefinitions, BasisTranslator
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    
    pm = PassManager(
        [
            UnrollCustomDefinitions(sel, basis_gates=basis_gates),
            BasisTranslator(sel, target_basis=basis_gates),
        ]
    )
    pm.run(circuit)
  • O uso do valor "unroller" para o argumento da palavra-chave translation_method no transpile() e generate_preset_pass_manager() foi descontinuado. Esse plug-in de estágio de tradução será removido do Qiskit em uma versão futura, pois foi substituído pelo método padrão "translator" , que funcionará de forma semelhante ao plug-in "unroller" , mas suportará um conjunto mais amplo de back-ends de destino.

Descontinuidade da visualização

  • A configuração padrão da gaveta matplotlib agora emite um FutureWarning, pois o estilo padrão está mudando para o estilo "iqp" (anteriormente conhecido como "iqx"). O padrão antigo está disponível como o estilo "clifford" . Para silenciar o aviso, você pode definir explicitamente o estilo desejado, por exemplo. g.:

    from qiskit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.x(0)
    circuit.h(0)
    circuit.cp(0.5, 0, 1)
    
    circuit.draw("mpl", style="clifford")  # or style="iqp"
  • Passar um circuito para qiskit.visualization.timeline_drawer() que não tenha informações de horário de início do nó agendado está obsoleto. Somente os circuitos que passaram por uma das etapas da análise de programação (por exemplo ALAPScheduleAnalysis ou ASAPScheduleAnalysis) podem ser visualizados. Se você tiver usado um dos passes de agendamento de estilo antigo (por exemplo ALAPSchedule ou ASAPSchedule), você poderá propagar as informações de agendamento executando:

    from qiskit import transpile
    from qiskit.transpiler import InstructionDurations
    
    scheduled = transpile(
      my_old_style_circuit,
      optimization_level=0,
      scheduling_method="alap",
      instruction_durations=InstructionDurations(),
    )

    Esse comportamento foi previamente planejado para ser descontinuado no Qiskit 0.37, mas devido a um erro no aviso, ele não foi exibido aos usuários até agora. O comportamento será removido no Qiskit 1.0.

Correções de bugs

  • O número máximo de qubits a ser considerado para a verificação de comutatividade baseada em multiplicação de matriz em CommutationChecker agora está limitado a 3 por padrão. Corrigido #10488

  • A passagem do GateDirection agora usará traduções de base discreta em vez de depender de uma tradução contínua de RYGateo que deve ajudar a tornar alguns alvos de conjunto de base discreta um pouco mais confiáveis. Em geral, transpile() tem suporte apenas parcial para conjuntos de bases que não contêm uma operação continuamente parametrizada e, portanto, nem sempre é bem-sucedido nessas situações e quase certamente não produzirá resultados ideais.

  • Fixo CommutationAnalysis para agrupar as portas em um fio em conjuntos, sendo que cada conjunto contém apenas portas que se combinam em pares. Isso evita que o site CommutationCancellation realize otimizações não confiáveis. Veja #8020

  • CUGate agora se comportará corretamente durante as chamadas para QuantumCircuit.assign_parameters(). Anteriormente, isso causava vários erros estranhos, geralmente algum tempo após a atribuição inicial do circuito. Consulte #7326, #7410, #9627, #10002 e #10131.

  • A interface do construtor de fluxo de controle (as formas de gerenciador de contexto de QuantumCircuit.if_test(), while_loop(), for_loop() e switch()) agora acompanhará corretamente um avanço de fase global separado dentro desse bloco. Você pode adicionar um avanço de fase global a um bloco interno atribuindo a QuantumCircuit.global_phase dentro de um escopo do construtor:

    from math import pi
    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(3, 3)
    qc.global_phase = pi / 2  # Set the outer circuit's global phase.
    
    with qc.if_test((qc.clbits[0], False)) as else_:
      # The global phase advancement in a control-flow block begins at 0,
      # because it represents how much the phase will be advanced by an
      # execution of the block.  The defined phase of the outer scope is not
      # affected by this set.
      qc.global_phase = pi
    with else_:
      # Similarly, the `else` block may induce a different global-phase
      # advancement to the `if`, so it can also be set separately.
      qc.global_phase = 1.5 * pi
    
    # The phase advancement caused directly by the outer scope is independent
    # of the phase advancement conditionally caused by each control-flow path.
    assert qc.global_phase == pi / 2

    O significado de QuantumCircuit.global_phase é considerado o avanço da fase global que é inerente a uma única execução do bloco. Ainda é um avanço de fase global, no sentido de que, se o bloco for inserido, a fase de todos os qubits em todo o programa será avançada.

  • Corrigir a coloração dos esquemas de cores "iqx" e "iqx-dark" do matplotlib, que anteriormente desenhavam o RZGate, RZZGate, (multi-)controlados PhaseGates e iSwapGate na cor errada.

  • O hash de um Parameter agora é igual aos hashes de qualquer ParameterExpression com os quais ele se compara. Anteriormente, os hashes eram diferentes, o que causava entradas adicionais espúrias nos hashmaps quando Parameter e ParameterExpression eram misturados no mesmo mapa, pois isso violava o modelo de dados do Python.

  • Foi corrigido um bug na serialização do QPY (qiskit.qpy) em que as portas unitárias controladas em um circuito poderiam resultar em falha na desserialização. Corrigido #10802.

  • Corrige a implementação do random_statevector() para que ele colete amostras da distribuição uniforme.

  • O passe NoiseAdaptiveLayout agora recebe CouplingMap como um argumento opcional. Isso é usado pelo plug-in para controlar a inconsistência entre configuration() e properties()como no caso de FakeMelbourne. Corrigido #7677.

  • Os métodos QuantumCircuit.copy() e copy_empty_like() agora gerarão um erro se o argumento name for digitado incorretamente, em vez de gerar um circuito inválido.

  • A heurística "decay" de SabreSwap e SabreLayout agora rastreia a profundidade corretamente nos qubits físicos, em vez de rastrear erroneamente a "profundidade" das trocas nos qubits virtuais.

  • Foi corrigido um descuido na seção ECRGate que impedia a definição de um atributo ECRGate.label no momento da construção do objeto. Todas as outras Gate permitem definir um argumento da palavra-chave label no construtor.

  • Foi corrigido um descuido no construtor Gate (e nas subclasses da biblioteca padrão), em que os valores duration e unit não podiam ser definidos como argumentos de palavra-chave durante a construção. A classe principal Instruction suportava essa configuração, mas Gate anteriormente não estava expondo essa interface corretamente.

  • Foi adicionado suporte para permitir a inicialização padrão do SparsePauliOp passando um iterável vazio para os métodos estáticos from_list() e from_sparse_list(). Corrigido #10159.

  • O uso da classe (obsoleta) Optimizer em AQC não tinha um caminho alternativo não obsoleto, que deveria ter sido introduzido no Qiskit 0.44. Ele agora aceita um callable que implementa o protocolo Minimizer conforme explicitamente declarado no aviso de depreciação. O chamável pode se parecer com o exemplo a seguir:

    from scipy.optimize import minimize
    from qiskit.transpiler.synthesis.aqc.aqc import AQC
    
    optimizer = partial(minimize, args=(), method="L-BFGS-B", options={"maxiter": 200})
    aqc = AQC(optimizer=optimizer)
  • Foi corrigido um problema com a classe Barrier classe. Ao adicionar uma instância Barrier a uma instância QuantumCircuit com o método QuantumCircuit.append() anteriormente, não havia validação de que o tamanho da barreira correspondia aos qargs especificados.

  • A passagem do transpilador BlockCollapser agora trata corretamente os circuitos que contêm mais de uma condição no mesmo registro clássico.

  • BlueprintCircuit agora se comportarão corretamente quando o método semipúblico QuantumCircuit._append() for usado com o blueprint em um estado não construído, ou seja, o circuito será construído antes da tentativa de anexação.

  • Zoom, tamanho da fonte e margens ajustados em plot_state_city() para ajustar melhor o gráfico para mais tamanhos de figuras. Correção do comportamento de ordenação Z das barras e do plano de amplitude zero, e correção da exibição de barras de valor real negativo.

Outras observações

  • Essa versão do Qiskit é explicitamente fixada na série Numpy 1.x, pois inclui extensões compiladas que ainda não foram compiladas na série Numpy 2.x, ainda não lançada. Lançaremos uma nova versão do Qiskit com suporte ao Numpy 2.x assim que for possível.

    Não podemos evitar que o seu gerenciador de pacotes resolva para versões mais antigas do Qiskit (que não têm o mesmo pino, mas que provavelmente ainda serão incompatíveis) se você tentar instalar o Qiskit à força junto com o Numpy 2, antes de lançarmos uma versão compatível.

  • Modificou o comportamento dos botões VF2Layout e VF2PostLayout que anteriormente executavam sua pontuação interna usando multithreading se os circuitos de entrada fossem suficientemente grandes. O uso de multithreading foi removido dos passes, pois foi demonstrado que ele causava uma regressão no desempenho em vez de uma melhoria, como pretendido originalmente.

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