Skip to main content
IBM Quantum Platform

Notas de versão do Qiskit 0.39


0.39.5

Terra 0.22.4

Prelúdio

O Qiskit Terra 0.22.4 é uma versão com pequenas correções de bugs, corrigindo alguns bugs identificados na série 0.22.

Correções de bugs

  • Corrigido um bug no BackendSampler que gerava um erro se seu método run() fosse chamado duas vezes sequencialmente.

  • Corrigidos dois erros no ComposedOp em que o método ComposedOp.to_matrix() não fornecia os resultados corretos para composições com StateFn e para composições com um coeficiente global. Corrigido #9283.

  • Corrigido o problema em que os primitivos, Sampler e Estimatornão funcionavam quando era passado um circuito com numpy.ndarray como parâmetro.

  • Corrigido um erro no SamplingVQE em que o argumento aggregation não tinha efeito. Agora, a função de agregação e, com ela, o valor de expectativa CVaR podem ser especificados corretamente.

  • Corrigido um erro de desempenho em que o SamplingVQE avaliava as energias dos estados próprios de forma lenta.

  • Corrigida a avaliação automática dos parâmetros beta em VQDadicionou suporte para entradas SparsePauliOp e corrigiu a função de avaliação de energia para aproveitar a execução assíncrona de primitivos, recuperando os resultados do trabalho somente depois que ambos os trabalhos tiverem sido enviados.

  • Foi corrigido um problema com o Statevector.probabilities_dict() e DensityMatrix.probabilities_dict() em que eles retornavam resultados incorretos para sistemas não-qubit quando o argumento qargs era especificado. Corrigido #9210

  • Correção do tratamento de alguns classmethods por wrap_method() em Python 3.11. Anteriormente, em Python 3.11, wrap_method envolvia a função não vinculada associada a classmethod e, em seguida, falhava quando invocada porque o objeto de classe normalmente vinculado a classmethod não era passado para a função. A partir de Python 3.11.1, esse problema afetou QiskitTestCase, impedindo que ele fosse importado por outro código de teste. Corrigido #9291.

Aer 0.11.2

Nenhuma mudança

IBM 0.19.2

Nenhuma mudança


0.39.4

Terra 0.22.3

Nenhuma mudança

Aer 0.11.2

Novos Recurso

  • Foi adicionado suporte à execução do Qiskit Aer com suporte a Python 3.11.

Problemas Conhecidos

  • Correção de dois erros em AerStatevector. AerStatevector usa instruções mc*, que não estão habilitadas no método matrix_product_state. Esse commit altera o site AerStatevector para não usar MC* e usar H, X, Y, Z, U e CX. AerStatevector também falhou se uma instrução for decomposta em QuantumCircuit vazio. Esse commit permite essa instrução.

Correções de bugs

  • Corrigido o suporte no método AerSimulator.from_backend() para instanciar uma instância de AerSimulator a partir de um objeto a BackendV2 objeto. Anteriormente, a tentativa de usar AerSimulator.from_backend() com um objeto BackendV2 teria gerado um AerError dizendo que isso não era suportado.

  • Corrige um bug em que NoiseModel.from_backend() com um objeto BackendV2 pode gerar um modelo de ruído com QuantumError s excessivos em instruções não-Gate, enquanto, por exemplo, apenas ReadoutError s deve ser suficiente para medidas. Esse commit atualiza o NoiseModel.from_backend() com um objeto BackendV2 para que ele retorne o mesmo modelo de ruído que o chamado com o objeto BackendV1 correspondente. Ou seja, o modelo de ruído resultante não contém nenhum QuantumError s nas medidas e pode conter apenas erros de relaxamento térmico em outras instruções que não sejam de porta, como reinicializações. Observe que ele ainda contém ReadoutError s nas medidas.

  • Foi corrigido um bug no site NoiseModel.from_backend() em que o uso do temperature kwarg com um valor não padrão calculava incorretamente a população de estados excitados para a temperatura especificada. Anteriormente, havia um fator adicional de 2 no cálculo da distribuição de Boltzman, o que levava a um valor menor incorreto para a população do estado excitado.

  • Correção da lógica incorreta no compilador de fluxo de controle que poderia permitir que instruções não relacionadas aparecessem "dentro" de corpos de fluxo de controle durante a execução, causando resultados incorretos. Por exemplo, anteriormente:

    from qiskit import QuantumCircuit
    from qiskit_aer import AerSimulator
    
    backend = AerSimulator(method="statevector")
    
    circuit = QuantumCircuit(3, 3)
    circuit.measure(0, 0)
    circuit.measure(1, 1)
    
    with circuit.if_test((0, True)):
        with circuit.if_test((1, False)):
            circuit.x(2)
    
    with circuit.if_test((0, False)):
        with circuit.if_test((1, True)):
            circuit.x(2)
    
    circuit.measure(range(3), range(3))
    print(backend.run(circuit, method=method, shots=100).result())

    imprimiria {'010': 100} , pois as operações de fluxo de controle aninhadas saltariam acidentalmente sobre a primeira porta X no qubit 2, que deveria ter sido executada.

  • Corrige um bug em que o site NoiseModel.from_backend() imprime avisos detalhados ao fornecer um backend que informa parâmetros de dispositivos não físicos, como T2 > 2 * T1, devido a erros estatísticos em sua estimativa. Esse commit remove esses avisos porque eles não são acionáveis para os usuários, no sentido de que não há outros meios além de truncá-los para os limites teóricos, conforme feito no módulo noise.device . Consulte a edição 1631 para obter detalhes sobre o bug corrigido.

  • Esta é uma correção para o simulador de vetor de estado da GPU. A distribuição de pedaços tentou alocar toda a memória livre na GPU, mas isso causou um erro de alocação de memória. Portanto, essa correção aloca 80% da memória livre. Isso também corrige o tamanho do buffer de matriz quando a amostragem de ruído é aplicada.

  • Esta é uma correção do site AerState em execução com bloqueio de cache. AerState transpilador de Aer configurado incorretamente para bloqueio de cache e, em seguida, seu algoritmo para trocar qubits funcionou incorretamente. Essa correção corrige o site AerState para usar esse transpilador. Mais especificamente, após a transpilação, um mapa de qubit trocado é recuperado para o mapa original ao usar AerState. Essa correção é necessária para que o site AerStatevector use várias GPUs.

  • Esta é a correção para AerStatevector. Não foi possível criar uma instância do AerStatevector diretamente do Statevector do Terra. Essa correção permite um Statevector como entrada AerStatevector’s.

  • SamplerResult.quasi_dists contêm os dados sobre o número de qubits. QuasiDistribution.binary_probabilities() retorna bitstrings com o comprimento correto.

  • Anteriormente, a semente não era inicializada em AerStatevector e, portanto, os resultados da amostragem eram sempre os mesmos. Com esse commit, uma semente é inicializada para cada amostragem e os resultados da amostragem podem ser variados.

IBM 0.19.2

Nenhuma mudança


0.39.3

Terra 0.22.3

Prelúdio

O Qiskit Terra 0.22.3 é uma versão menor de correção de bugs, que corrige alguns bugs adicionais na série 0.22.

Correções de bugs

  • AdaptVQE agora indica corretamente que é compatível com operadores auxiliares.

  • As gavetas do circuito (QuantumCircuit.draw() e circuit_drawer()) não emitirão mais um aviso sobre o parâmetro cregbundle ao usar os argumentos padrão, se o conteúdo do circuito exigir que todos os bits sejam desenhados individualmente. Era mais provável que isso ocorresse ao tentar desenhar circuitos com operações de fluxo de controle de novo estilo.

  • Foi corrigido um bug que fazia com que o QNSPSA falhar quando max_evals_grouped era definido com um valor maior que 1.

  • Foi corrigido um problema com a passagem SabreSwap que fazia com que a saída de várias execuções da passagem sem o argumento seed especificado reutilizasse a mesma semente de gerador de números aleatórios entre as execuções, em vez de usar sementes diferentes. Isso anteriormente fazia com que resultados idênticos fossem retornados entre as execuções, mesmo quando nenhum seed era especificado.

  • Corrigido um problema com as classes primitivas, BackendSampler e BackendEstimatorem que as instâncias não podiam ser serializadas com pickle. Em geral, não é garantido que essas classes sejam serializáveis como BackendV2 e as instâncias BackendV1 não precisam ser serializáveis (e geralmente não são), mas as definições de classe de BackendSampler e BackendEstimator não impedem mais o uso de pickle.

  • O método pulse.Instruction.draw() agora será bem-sucedido, como antes. Esse método está obsoleto e não há previsão de substituição, mas ele ainda deve funcionar durante o período de obsoletismo.

Aer 0.11.1

Nenhuma mudança

IBM 0.19.2

Nenhuma mudança


0.39.2

Terra 0.22.2

Prelúdio

O Qiskit Terra 0.22.2 é uma versão com pequenas correções de bugs e marca o primeiro suporte oficial para Python 3.11.

Correções de bugs

  • Correção de um problema com as classes primitivas de backend BackendSampler e BackendEstimator que impedia a execução com uma instância BackendV1 que não tivesse um campo max_experiments definido em sua instância BackendConfiguration.

  • Foi corrigido um bug na passagem VF2PostLayout ao transpilar para backends com um Targetdefinido, em que o gráfico de interação era criado incorretamente. Isso pode resultar em tempos de execução excessivos devido ao fato de o gráfico ser muito mais complexo do que o necessário.

  • O analisador de expressões do Pulse não deve mais travar periodicamente quando chamado a partir de notebooks Jupyter. Isso é feito evitando um deepycopy interno de um objeto recursivo que parece ser particularmente difícil para a memoização avaliar.

Aer 0.11.1

Nenhuma mudança

IBM 0.19.2

Nenhuma mudança


0.39.1

Terra 0.22.1

Prelúdio

O Qiskit Terra 0.22.1 é uma versão de correção de bugs, que aborda alguns problemas menores identificados desde a versão 0.22.0.

Notas de descontinuação

  • O kwarg pauli_list de pauli_basis() foi descontinuado, pois pauli_basis() agora sempre retorna um PauliList. Esse argumento foi removido prematuramente do Qiskit Terra 0.22.0, o que quebrou a compatibilidade dos usuários que estavam aproveitando o pauli_list``argument. Now, the argument has been restored but will emit a ``DeprecationWarning quando usado. Se for usado, não terá efeito, pois como o Qiskit Terra 0.22.0 a PauliList é sempre retornado.

Correções de bugs

  • Corrigido o BarrierBeforeFinalMeasurements passagem do transpilador quando há condições em camadas soltas Clbits soltas imediatamente antes da camada de medição final. Anteriormente, isso falhava, alegando que o bit não estava presente em um circuito interno temporário. Corrigido #8923

  • Os verificadores de igualdade para QuantumCircuit e DAGCircuit (com objetos do mesmo tipo) agora manipularão corretamente as condições em bits únicos. Anteriormente, isso produzia falsos negativos para a igualdade, pois os bits usavam verificações de igualdade "exatas" em vez das verificações "semânticas" que o restante das propriedades das instruções do circuito recebe.

  • Tratamento fixo de bits clássicos em StochasticSwap com o fluxo de controle. Anteriormente, as operações de fluxo de controle eram expandidas para conter todos os bits clássicos no circuito externo e não eram contraídas novamente, o que levava a uma incompatibilidade entre o número de clbits que a instrução informava precisar e o número real fornecido a ela. Corrigido #8903

  • Corrigido o tratamento de instruções definidas globalmente para a classe Target classe. Anteriormente, dois métodos, operations_for_qargs() e operation_names_for_qargs() ignoravam/tratavam incorretamente quaisquer operações ideais definidas globalmente presentes no destino. Por exemplo:

    from qiskit.transpiler import Target
    from qiskit.circuit.library import CXGate
    
    target = Target(num_qubits=5)
    target.add_instruction(CXGate())
    names = target.operation_names_for_qargs((1, 2))
    ops = target.operations_for_qargs((1, 2))

    agora retornará {"cx"} para names e [CXGate()] para ops em vez de gerar um KeyError ou um retorno vazio.

  • Foi corrigido um problema no método Target.add_instruction() em que ele aceitava um argumento com um número inválido de qubits como parte do argumento properties . Por exemplo:

    from qiskit.transpiler import Target
    from qiskit.circuit.library import CXGate
    
    target = Target()
    target.add_instruction(CXGate(), {(0, 1, 2): None})

    Agora, isso gerará corretamente um TranspilerError em vez de causar problemas de tempo de execução ao interagir com o alvo. Corrigido #8914

  • Foi corrigido um problema com a função de visualização plot_state_hinton() que resultava em um eixo mal posicionado que era deslocado do gráfico real. Corrigido #8446 <https://github.com/Qiskit/qiskit/issues/8446>

  • Corrigimos a saída da função plot_state_hinton() para que os rótulos de estado sejam ordenados corretamente e a imagem corresponda à ordenação natural da matriz. Corrigido #8324

  • Corrigido um problema com as classes primitivas, BackendSampler e BackendEstimator ao executar em backends que têm um número limitado de circuitos em cada trabalho. Nem todos os back-ends suportam um tamanho de lote ilimitado (a maioria dos back-ends de hardware não o faz) e, anteriormente, as classes primitivas de back-end poderiam ter enviado incorretamente mais circuitos do que o back-end suportava. Isso foi corrigido para que BackendSampler e BackendEstimator dividirá os circuitos em vários trabalhos se o backend tiver um número limitado de circuitos por trabalho.

  • Foi corrigido um problema com a classe BackendEstimator em que a configuração anterior de uma opção de execução chamada monitor para um valor avaliado como True acionava incorretamente um monitor de trabalho que só funcionava em back-ends do pacote qiskit-ibmq-provider . Isso foi removido para que você possa usar uma opção de execução monitor , se necessário, sem causar problemas.

  • Foi corrigido um problema com o método Target.build_coupling_map() em que ele retornava incorretamente None para um objeto Target com uma mistura de instruções ideais disponíveis globalmente e instruções que têm restrições de qubit. Agora, nesses casos, o Target.build_coupling_map() retornará um mapa de acoplamento para a instrução restrita (a menos que seja uma operação de 2 qubits, que retornará None porque globalmente não há restrição de conectividade). Corrigido #8971

  • Foi corrigido um problema com o atributo Target.qargs em que ele retornava incorretamente None para um objeto Target que contivesse qualquer instrução ideal disponível globalmente.

  • Foi corrigida a remoção prematura do argumento da palavra-chave pauli_list da função pauli_basis() que quebrou o código existente usando o caminho de compatibilidade futura pauli_list=True na atualização para o Qiskit Terra 0.22.0. Esse argumento de palavra-chave foi adicionado novamente à função e agora está obsoleto e será removido em uma versão futura.

  • Foi corrigido um problema na serialização do QPY (dump()) quando uma subclasse ControlledGate que sobrecarregou o método _define() para fornecer uma definição personalizada para a operação. Anteriormente, esse caso de operação não era serializado corretamente porque não estava sendo considerado o uso do método potencialmente _define() para fornecer uma definição. Correções #8794

  • A desserialização do QPY não adicionará mais instâncias Clbit ao circuito se houver instâncias soltas de Clbits soltas no circuito e mais Qubits do que Clbits.

  • A desserialização do QPY não adicionará mais os registros denominados q e c se o circuito de entrada contiver apenas bits soltos.

  • Corrigido o método SparsePauliOp.dot() quando executado em dois operadores com coeficientes reais. Para corrigir isso, o dtype que SparsePauliOp pode assumir é restrito a np.complex128 e object. Corrigido #8992

  • Foi corrigido um problema na função circuit_drawer() e no método QuantumCircuit.draw() em que o único estilo incorporado para a saída mpl que era utilizável era default. Se outro estilo incorporado, como iqx, fosse usado, seria emitido um aviso de que o estilo não foi encontrado e a gaveta voltaria a usar o estilo default . Corrigido #8991

  • Foi corrigido um problema com o transpile() em que ele falhava anteriormente com um TypeError se um objeto Target personalizado fosse passado por meio do argumento target e uma lista de vários circuitos fosse especificada para o argumento circuits .

  • Foi corrigido um problema com transpile() ao direcionar um Target (seja diretamente por meio do argumento target ou por meio de uma instância BackendV2 do argumento backend ) que continha uma instrução Measure ideal (uma instrução que não tem nenhuma propriedade definida). Anteriormente, isso gerava uma exceção ao tentar analisar o destino. Corrigido #8969

  • Foi corrigido um problema com a passagem VF2Layout em que ele dava erro ao ser executado com um Target que tinha instruções que não tinham taxas de erro. Isso foi corrigido, de modo que, nesses casos, a falta de uma taxa de erro será tratada como uma implementação ideal e, se nenhuma taxa de erro estiver presente, ele selecionará apenas o primeiro layout correspondente. Corrigido #8970

  • Foi corrigido um problema com a passagem VF2PostLayout em que ele dava erro ao ser executado com um Target que tinha instruções que estavam faltando. Nesses casos, a ausência de uma taxa de erro será tratada como uma implementação ideal da operação.

  • Foi corrigido um problema com a classe VQD se mais de k=2 autovalores fossem computados. Anteriormente, isso falhava devido a uma incompatibilidade de tipo interno, mas agora funciona como esperado. Corrigido #8982

  • Foi corrigido um bug de desempenho em que os novos algoritmos variacionais baseados em primitivas minimum_eigensolvers.VQE, eigensolvers.VQD e SamplingVQE não faziam avaliações de energia em lote por padrão, o que resultava em uma desaceleração significativa se um backend de hardware fosse usado.

  • As portas e instruções de operando zero agora funcionarão com circuit_to_gate(), QuantumCircuit.to_gate(), Gate.control()e a construção de um Operator a partir de um QuantumCircuit contendo instruções de operando-zero. Esse caso extremo é ocasionalmente útil na criação de portas de fase global como parte de instruções compostas maiores, embora para muitos usos, QuantumCircuit.global_phase pode ser mais apropriado.

  • Corrige o problema em que Statevector.evolve() e DensityMatrix.evolve() gerava uma exceção para a evolução de subsistemas aninhados para subsistemas não-qubit. Corrige o problema #8897

  • Corrige o erro em Statevector.evolve() em que a evolução do subsistema retornará o valor incorreto em determinados casos em que houver 2 ou mais subsistemas não evoluídos com diferentes dimensões de subsistema. Corrige o problema nº 8899

Aer 0.11.1

Correções de bugs

  • Foi corrigido um possível erro de compilação ao tentar usar o CMake 3.18 ou mais recente e compilar o qiskit-aer com suporte a GPU ativado. Desde o CMake 3.18 ou posterior, ao criar com CUDA, o CMAKE_CUDA_ARCHITECTURES precisava ser definido com o valor da arquitetura para a GPU de destino. Isso foi corrigido para que a configuração AER_CUDA_ARCH seja usada se não tiver sido definida.

  • Corrige um bug no tratamento de instruções com clbits em LocalNoisePass. Anteriormente, ele apagava acidentalmente os clbits das instruções (por exemplo, medidas) às quais o ruído é aplicado no caso do method="append".

  • Foi corrigida a sobrecarga de desempenho da classe Sampler ao ser executada com circuitos idênticos em várias execuções. Isso foi feito pulando/armazenando em cache a transpilação desses circuitos idênticos em execuções subsequentes.

  • Corrigida a compatibilidade das classes primitivas Sampler e Estimator classes primitivas com a versão qiskit-terra 0.22.0. No qiskit-terra 0.22.0 foram feitas alterações significativas na API da interface abstrata, o que quebrou a compatibilidade com essas classes Sampler e Estimator agora podem ser usadas com o qiskit-terra >= 0.22.0.

IBM 0.19.2

Nenhuma mudança


0.39.0

Essa versão também descontinua oficialmente o projeto Qiskit Aer como parte do metapacote Qiskit. Isso significa que, em uma versão futura, o pip install qiskit não incluirá mais o qiskit-aer. Se você estiver instalando ou listando qiskit como uma dependência para obter o Aer, deverá atualizá-lo para listar explicitamente qiskit-aer também.

O projeto qiskit-aer ainda está ativo e é mantido, mas, para o metapacote Qiskit (ou seja, o que é instalado via pip install qiskit), o projeto está se movendo em direção a um modelo em que o pacote Qiskit contém apenas a funcionalidade central comum para criar e compilar circuitos, programas e aplicativos quânticos, e os pacotes que se baseiam nele ou vinculam o Qiskit a hardware ou simuladores são pacotes separados.

Terra 0.22.0

Prelúdio

A versão do Qiskit Terra 0.22.0 é uma versão de recursos importantes que inclui uma infinidade de novos recursos e correções de bugs. Os destaques desse lançamento são:

  • Adição de suporte inicial ao transpilador para transpilar QuantumCircuit que contêm instruções de fluxo de controle, como ForLoopOp e WhileLoopOp.
  • Dimensionamento e desempenho muito melhores para a função transpile() com grandes números de qubits, especialmente quando optimization_level=3 é usado.
  • Interface de plug-in externo para transpile() que permite que pacotes externos implementem estágios para os gerenciadores de passes padrão. Mais detalhes sobre isso podem ser encontrados em qiskit.transpiler.preset_passmanagers.plugin. Além disso, BackendV2 agora podem, opcionalmente, definir plug-ins padrão personalizados a serem usados nos estágios de agendamento e tradução.
  • Implementações atualizadas de algoritmos em qiskit.algorithms que aproveitam as classes primitives que implementam as classes BaseSampler e BaseEstimator.

Novos Recurso

  • Adicione suporte para representar uma operação que tenha uma largura variável para a classe Target classe. Anteriormente, um objeto Target precisava ter uma instância de Operation definida para cada operação suportada no destino. Isso foi usado para validação de argumentos e parâmetros da operação. Entretanto, para operações que têm uma largura variável, isso não foi possível porque cada instância de uma classe Operation só pode ter um número fixo de qubits. Nos casos em que um backend oferece suporte a operações de largura variável, a instrução pode ser adicionada com a classe da operação em vez de uma instância. Nesses casos, a operação será tratada como globalmente suportada em todos os qubits. Por exemplo, se estiver construindo um alvo como:

    from qiskit.circuit import Parameter, Measure, IfElseOp, ForLoopOp, WhileLoopOp
    from qiskit.circuit.library import IGate, RZGate, SXGate, XGate, CXGate
    from qiskit.transpiler import Target, InstructionProperties
    
    theta = Parameter("theta")
    
    ibm_target = Target()
    i_props = {
        (0,): InstructionProperties(duration=35.5e-9, error=0.000413),
        (1,): InstructionProperties(duration=35.5e-9, error=0.000502),
        (2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
        (3,): InstructionProperties(duration=35.5e-9, error=0.000614),
        (4,): InstructionProperties(duration=35.5e-9, error=0.006149),
    }
    ibm_target.add_instruction(IGate(), i_props)
    rz_props = {
        (0,): InstructionProperties(duration=0, error=0),
        (1,): InstructionProperties(duration=0, error=0),
        (2,): InstructionProperties(duration=0, error=0),
        (3,): InstructionProperties(duration=0, error=0),
        (4,): InstructionProperties(duration=0, error=0),
    }
    ibm_target.add_instruction(RZGate(theta), rz_props)
    sx_props = {
        (0,): InstructionProperties(duration=35.5e-9, error=0.000413),
        (1,): InstructionProperties(duration=35.5e-9, error=0.000502),
        (2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
        (3,): InstructionProperties(duration=35.5e-9, error=0.000614),
        (4,): InstructionProperties(duration=35.5e-9, error=0.006149),
    }
    ibm_target.add_instruction(SXGate(), sx_props)
    x_props = {
        (0,): InstructionProperties(duration=35.5e-9, error=0.000413),
        (1,): InstructionProperties(duration=35.5e-9, error=0.000502),
        (2,): InstructionProperties(duration=35.5e-9, error=0.0004003),
        (3,): InstructionProperties(duration=35.5e-9, error=0.000614),
        (4,): InstructionProperties(duration=35.5e-9, error=0.006149),
    }
    ibm_target.add_instruction(XGate(), x_props)
    cx_props = {
        (3, 4): InstructionProperties(duration=270.22e-9, error=0.00713),
        (4, 3): InstructionProperties(duration=305.77e-9, error=0.00713),
        (3, 1): InstructionProperties(duration=462.22e-9, error=0.00929),
        (1, 3): InstructionProperties(duration=497.77e-9, error=0.00929),
        (1, 2): InstructionProperties(duration=227.55e-9, error=0.00659),
        (2, 1): InstructionProperties(duration=263.11e-9, error=0.00659),
        (0, 1): InstructionProperties(duration=519.11e-9, error=0.01201),
        (1, 0): InstructionProperties(duration=554.66e-9, error=0.01201),
    }
    ibm_target.add_instruction(CXGate(), cx_props)
    measure_props = {
        (0,): InstructionProperties(duration=5.813e-6, error=0.0751),
        (1,): InstructionProperties(duration=5.813e-6, error=0.0225),
        (2,): InstructionProperties(duration=5.813e-6, error=0.0146),
        (3,): InstructionProperties(duration=5.813e-6, error=0.0215),
        (4,): InstructionProperties(duration=5.813e-6, error=0.0333),
    }
    ibm_target.add_instruction(Measure(), measure_props)
    ibm_target.add_instruction(IfElseOp, name="if_else")
    ibm_target.add_instruction(ForLoopOp, name="for_loop")
    ibm_target.add_instruction(WhileLoopOp, name="while_loop")

    O IfElseOp, ForLoopOp, e WhileLoopOp são suportadas globalmente para qualquer número de qubits. Isso é então refletido por outras chamadas na Target API, como instruction_supported():

    ibm_target.instruction_supported(operation_class=WhileLoopOp, qargs=(0, 2, 3, 4))
    ibm_target.instruction_supported('if_else', qargs=(0, 1))

    ambos retornam True.

  • Adicionadas novas implementações primitivas, BackendSampler e BackendEstimatorpara qiskit.primitives. Essa nova implementação de classe primitiva envolve um BackendV1 ou BackendV2 como uma instância de BaseSampler ou BaseEstimator respectivamente. O caso de uso pretendido para essas implementações primitivas é preencher a lacuna entre os provedores que não têm implementações primitivas nativas e usar o back-end desse provedor com APIs que funcionam com primitivas. Por exemplo, a classe SamplingVQE requer uma instância BaseSampler para funcionar. Se você quiser executar essa classe com um backend de um provedor sem uma implementação primitiva nativa, poderá construir um BackendSampler para fazer isso:

    from qiskit.algorithms.minimum_eigensolvers import SamplingVQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import BackendSampler
    from qiskit.providers.fake_provider import FakeHanoi
    from qiskit.opflow import PauliSumOp
    from qiskit.quantum_info import SparsePauliOp
    
    backend = FakeHanoi()
    sampler = BackendSampler(backend=backend)
    
    operator = PauliSumOp(SparsePauliOp(["ZZ", "IZ", "II"], coeffs=[1, -0.5, 0.12]))
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    sampling_vqe = SamplingVQE(sampler, ansatz, optimizer)
    result = sampling_vqe.compute_minimum_eigenvalue(operator)
    eigenvalue = result.eigenvalue

    Se você estiver usando um provedor que tenha implementações primitivas nativas (como qiskit-ibm-runtime ou qiskit-aer), é sempre melhor usar essa implementação primitiva nativa em vez de BackendEstimator ou BackendSampler pois as implementações nativas serão muito mais eficientes e/ou farão pré e pós-processamento adicional. BackendEstimator e BackendSampler são projetados para serem genéricos, podendo funcionar com qualquer backend que retorne Counts em seu site Results , o que impossibilita otimizações adicionais.

  • Adição de uma nova classe de algoritmo, AdaptVQE a qiskit.algorithms Esse algoritmo usa um qiskit.algorithms.minimum_eigensolvers.VQE em combinação com um conjunto de operadores a partir do qual se constrói um sistema de qiskit.circuit.library.EvolvedOperatorAnsatz de forma adaptativa. Por exemplo:

    from qiskit.algorithms.minimum_eigensolvers import AdaptVQE, VQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.primitives import Estimator
    from qiskit.circuit.library import EvolvedOperatorAnsatz
    
    # get your Hamiltonian
    hamiltonian = ...
    
    # construct your ansatz
    ansatz = EvolvedOperatorAnsatz(...)
    
    vqe = VQE(Estimator(), ansatz, SLSQP())
    
    adapt_vqe = AdaptVQE(vqe)
    
    result = adapt_vqe.compute_minimum_eigenvalue(hamiltonian)
  • A classe BackendV2 agora tem suporte para dois novos pontos de conexão opcionais que permitem que os backends injetem etapas de compilação personalizadas como parte de transpile() e generate_preset_pass_manager(). Se uma BackendV2 incluir os métodos get_scheduling_stage_plugin() ou get_translation_stage_plugin() , o transpilador usará a string retornada como o valor padrão para os argumentos scheduling_method e translation_method . Isso permite que os back-ends executem passagens adicionais personalizadas do transpilador ao direcionar esse back-end, aproveitando a interface do estágio do transpilador plugin interface. Para obter mais detalhes sobre como usar isso, consulte: Custom Transpiler Passes.

  • Foi adicionado um novo argumento de palavra-chave, ignore_backend_supplied_default_methods, à função transpile() que pode ser usado para desativar a seleção personalizada de um backend de um método padrão se o backend de destino tiver get_scheduling_stage_plugin() ou get_translation_stage_plugin() definido.

  • Adicionado um parâmetro label ao construtor da classe Barrier da classe e ao método barrier() que permite que um usuário atribua um rótulo a uma instância da diretiva Barrier diretiva. Para visualizações geradas com circuit_drawer() ou QuantumCircuit.draw() esse rótulo será impresso na parte superior do site barrier.

    from qiskit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.h(1)
    circuit.barrier(label="After H")
    circuit.draw('mpl')
  • Adicionar novos portões CCZGate, CSGate, e CSdgGate às portas padrão na Biblioteca de circuitos (qiskit.circuit.library).

  • Adicionado o pacote qiskit.algorithms.eigensolvers para incluir interfaces para algoritmos habilitados para primitivas. Esse novo módulo acabará substituindo o anterior qiskit.algorithms.eigen_solvers. Esse novo módulo contém uma implementação alternativa do módulo VQD que, em vez de usar um backend ou QuantumInstance recebe uma instância de BaseEstimator, incluindo Estimator, BackendEstimator, ou qualquer implementação de provedor, como as presentes em qiskit-ibm-runtime e qiskit-aer.

    Por exemplo, para usar a nova implementação com uma instância de Estimator classe:

    from qiskit.algorithms.eigensolvers import VQD
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import Sampler, Estimator
    from qiskit.algorithms.state_fidelities import ComputeUncompute
    from qiskit.opflow import PauliSumOp
    from qiskit.quantum_info import SparsePauliOp
    
    h2_op = PauliSumOp(SparsePauliOp(
        ["II", "IZ", "ZI", "ZZ", "XX"],
        coeffs=[
            -1.052373245772859,
            0.39793742484318045,
            -0.39793742484318045,
            -0.01128010425623538,
            0.18093119978423156,
        ],
    ))
    
    estimator = Estimator()
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    fidelity = ComputeUncompute(Sampler())
    
    vqd = VQD(estimator, fidelity, ansatz, optimizer, k=2)
    result = vqd.compute_eigenvalues(h2_op)
    eigenvalues = result.eigenvalues

    Observe que os operadores auxiliares avaliados são agora obtidos por meio do campo aux_operators_evaluated nos resultados. Isso consistirá em uma lista ou ditado de tuplas contendo os valores de expectativa para esses operadores, bem como os metadados da execução primitiva. aux_operator_eigenvalues não é mais um campo válido.

  • Adicionados novos algoritmos para calcular fidelidades/sobreposições de estado para pares de circuitos quânticos (que podem ser parametrizados). Além da classe base (BaseStateFidelity) que define a interface, há uma implementação do método compute-uncompute que aproveita as instâncias da classe BaseSampler primitivo: qiskit.algorithms.state_fidelities.ComputeUncompute.

    Por exemplo:

    import numpy as np
    from qiskit.primitives import Sampler
    from qiskit.algorithms.state_fidelities import ComputeUncompute
    from qiskit.circuit.library import RealAmplitudes
    
    sampler = Sampler(...)
    fidelity = ComputeUncompute(sampler)
    circuit = RealAmplitudes(2)
    values = np.random.random(circuit.num_parameters)
    shift = np.ones_like(values) * 0.01
    
    job = fidelity.run([circuit], [circuit], [values], [values+shift])
    fidelities = job.result().fidelities
  • Adicionado um novo módulo qiskit.algorithms.gradients que contém classes que são usadas para calcular gradientes usando as interfaces primitivas definidas em qiskit.primitives. Há quatro tipos de classes de gradiente: Diferença finita, Mudança de parâmetro, Combinação linear de unitário e SPSA com implementações que usam uma instância da BaseEstimator interface:

    ou uma instância da BaseSampler interface:

    Os gradientes baseados em estimador calculam o gradiente dos valores de expectativa, enquanto os gradientes baseados em amostrador retornam gradientes dos resultados de medição (também chamados de "gradientes de probabilidade").

    Por exemplo:

    estimator = Estimator(...)
    gradient = ParamShiftEstimatorGradient(estimator)
    job = gradient.run(circuits, observables, parameters)
    gradients = job.result().gradients
  • A classe Grover tem um novo argumento de palavra-chave, sampler , que é usado para executar o algoritmo usando uma instância da interface BaseSampler para calcular os resultados. Esse novo argumento substitui o argumento quantum_instance e, portanto, quantum_instance está pendente de descontinuação e será descontinuado e, posteriormente, removido em versões futuras.

    Exemplo:

    from qiskit import QuantumCircuit
    from qiskit.primitives import Sampler
    from qiskit.algorithms import Grover, AmplificationProblem
    
    sampler = Sampler()
    oracle = QuantumCircuit(2)
    oracle.cz(0, 1)
    problem = AmplificationProblem(oracle, is_good_state=["11"])
    grover = Grover(sampler=sampler)
    result = grover.amplify(problem)
  • Uma nova opção, "formatter.control.fill_waveform" , foi adicionada às folhas de estilo da gaveta de pulsos (pulse_v2.draw() e Schedule.draw()). Essa opção pode ser usada para remover a cor da face dos pulsos na visualização de saída, o que permite desenhar pulsos apenas com linhas.

    Por exemplo:

    from qiskit.visualization.pulse_v2 import IQXStandard
    
    my_style = IQXStandard(
        **{"formatter.control.fill_waveform": False, "formatter.line_width.fill_waveform": 2}
    )
    
    my_sched.draw(style=my_style)
  • Adicionada uma nova passagem de transpilador, ResetAfterMeasureSimplificationque é usada para substituir uma operação Reset após uma operação Measure por uma condicional XGate. Essa passagem pode ser usada em backends em que uma Reset é realizada por meio de uma medição e, em seguida, uma porta X condicional, de modo que isso removerá a duplicação implícita Measure duplicado da Reset operação. Por exemplo:

    from qiskit import QuantumCircuit
    from qiskit.transpiler.passes import ResetAfterMeasureSimplification
    
    qc = QuantumCircuit(1)
    qc.measure_all()
    qc.reset(0)
    qc.draw('mpl')
    result = ResetAfterMeasureSimplification()(qc)
    result.draw('mpl')
  • Adição de um novo valor suportado, "reverse_linear" , para o argumento da palavra-chave entanglement no construtor da classe NLocal classe de circuito. Para TwoLocal circuitos (que são subclasses de NLocal), se entanglement_blocks="cx" , o uso de entanglement="reverse_linear" fornece um circuito n-qubit equivalente a entanglement="full" , mas com apenas n1n-1 CXGate gates, em vez de n(n1)2\frac{n(n-1)}{2}.

  • ScheduleBlock foi atualizado para que possa gerenciar sub-rotinas não atribuídas, em outras palavras, para permitir a chamada preguiçosa de outros programas. Por exemplo, isso permite o seguinte fluxo de trabalho:

    from qiskit import pulse
    
    with pulse.build() as prog:
      pulse.reference("x", "q0")
    
    with pulse.build() as xq0:
      pulse.play(Gaussian(160, 0.1, 40), pulse.DriveChannel(0))
    
    prog.assign_references({("x", "q0"): xq0})

    Agora, um usuário pode criar o site prog sem conhecer a implementação real da referência ("x", "q0") e atribuí-la posteriormente para execução. Isso melhora a modularidade dos programas de pulso e, portanto, é possível escrever facilmente um programa de pulso modelo com base em outras calibrações.

    Para realizar esse recurso, a nova instrução de pulso (diretiva do compilador) Reference foi adicionada. Essa instrução é injetada no escopo do construtor atual quando o comando reference() é usado. Todas as referências definidas no programa de pulso atual podem ser listadas com a propriedade references .

    Além disso, cada referência é gerenciada com um escopo para facilitar o gerenciamento de parâmetros. scoped_parameters() e search_parameters() foram adicionados a ScheduleBlock. Consulte a documentação da API para obter mais detalhes.

  • Adicionado um novo método SparsePauliOp.argsort()que retorna a composição de permutações na ordem de classificação por coeficiente e classificação por Pauli. Usando o argumento da palavra-chave weight para o método, a saída pode ser classificada adicionalmente pelo número de termos não idênticos no Pauli, em que o conjunto de todos os Paulis de um determinado peso ainda é ordenado lexicograficamente.

  • Adicionado um novo método SparsePauliOp.sort()que primeiro classifica os coeficientes usando o argsort() do numpy e, em seguida, classifica por Pauli, onde a classificação Pauli tem precedência. Se a classificação de Pauli for a mesma, ela será classificada por coeficiente. Usando o argumento da palavra-chave weight , a saída pode ser classificada adicionalmente pelo número de termos não idênticos no Pauli, em que o conjunto de todos os Paulis de um determinado peso ainda é ordenado lexicograficamente.

  • Adicionado um novo argumento de palavra-chave, wire_order, à função circuit_drawer() função e QuantumCircuit.draw() que permite reordenar arbitrariamente os bits quânticos e clássicos na visualização de saída. Por exemplo:

    from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qr = QuantumRegister(4, "q")
    cr = ClassicalRegister(4, "c")
    cr2 = ClassicalRegister(2, "ca")
    circuit = QuantumCircuit(qr, cr, cr2)
    circuit.h(0)
    circuit.h(3)
    circuit.x(1)
    circuit.x(3).c_if(cr, 10)
    circuit.draw('mpl', cregbundle=False, wire_order=[2, 1, 3, 0, 6, 8, 9, 5, 4, 7])
  • Foi adicionado suporte para o CSGate, CSdgGate e CCZGate ao construtor da classe de operador CNOTDihedral. Os circuitos de entrada ao criar um operador CNOTDihedral agora serão compatíveis com circuitos que usam essas portas. Por exemplo:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import CNOTDihedral
    
    qc = QuantumCircuit(2)
    qc.t(0)
    qc.cs(0, 1)
    qc.tdg(0)
    operator = CNOTDihedral(qc)
  • As classes do algoritmo de estimativa de amplitude:

    Agora têm um novo argumento de palavra-chave, sampler , em seu construtor que recebe uma instância de um objeto que implementa a BaseSampler incluindo BackendSamplerSampler, ou qualquer implementação de provedor, como as presentes no qiskit-ibm-runtime e no qiskit-aer. Isso oferece uma alternativa ao uso do argumento quantum_instance para definir o alvo Backend ou QuantumInstance para executar o algoritmo. O uso de um QuantumInstance está pendente de descontinuação e será descontinuado em uma versão futura.

  • Adicionada uma nova classe, BackendV2Converterque é usada para envolver uma instância BackendV1 em uma BackendV2 interface. Ele permite que você tenha uma instância BackendV2 instância de qualquer BackendV1. Isso permite padronizar os padrões de acesso na interface mais recente BackendV2 mais recente, mesmo que você ainda ofereça suporte a BackendV1.

  • Adicionada uma nova função convert_to_target() que é usada para receber um BackendConfiguratione, opcionalmente, um BackendProperties e PulseDefaults e criar um objeto Target equivalente ao conteúdo desses objetos.

  • qiskit.quantum_info.BaseOperator subclasses (como ScalarOp, SparsePauliOp e PauliList) agora podem ser usadas com a função incorporada Python sum() .

  • Um novo transpiler pass, ConvertConditionsToIfOps foi adicionada, que pode ser usada para converter instruções condicionadas de estilo antigo Instruction.c_if()-instruções condicionadas em IfElseOp objetos. Isso ajuda a facilitar a transição do tipo antigo para o novo tipo de back-end. Para a maioria dos usuários, não há necessidade de adicionar esse recurso aos gerenciadores de passes, e ele não está incluído em nenhum gerenciador de passes predefinido.

  • Análise de comutatividade de porta refatorada em uma classe CommutationChecker. Essa classe permite que você verifique (com base na multiplicação de matrizes) se duas portas são ou não comutáveis e armazene em cache os resultados (para que uma verificação semelhante no futuro não exija mais a multiplicação de matrizes).

    Por exemplo, agora podemos fazer:

    from qiskit.circuit import QuantumRegister, CommutationChecker
    
    comm_checker = CommutationChecker()
    qr = QuantumRegister(4)
    
    res = comm_checker.commute(CXGate(), [qr[1], qr[0]], [], CXGate(), [qr[1], qr[2]], [])

    Como as duas portas CX são comutadas (a primeira porta CX está sobre os qubits qr[1] e qr[0], e a segunda porta CX está sobre os qubits qr[1] e qr[2]), teremos que res é True.

    Essa verificação de comutatividade é excessivamente conservadora para portas condicionais e parametrizadas, e pode retornar False mesmo quando essas portas são comutativas.

  • Adicionada uma nova passagem de transpilador CommutativeInverseCancellation que cancela pares de portas inversas explorando relações de comutação entre portas. Essa passagem é uma generalização da passagem do transpilador InverseCancellation pois detecta um conjunto maior de portas inversas e leva em conta a comutatividade. A passagem também evita alguns problemas associados à passagem do transpilador CommutativeCancellation.

    Por exemplo:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import CommutativeInverseCancellation
    
    circuit = QuantumCircuit(2)
    circuit.z(0)
    circuit.x(1)
    circuit.cx(0, 1)
    circuit.z(0)
    circuit.x(1)
    
    passmanager = PassManager(CommutativeInverseCancellation())
    new_circuit = passmanager.run(circuit)

    cancela o par de portas Z auto-inversas e o par de portas X auto-inversas (já que as portas relevantes comutam com a porta CX), produzindo um circuito que consiste em uma única porta CX.

    A verificação inversa é excessivamente conservadora para portas condicionais e parametrizadas, e pode não cancelar algumas dessas portas.

  • QuantumCircuit.compose() agora aceitará um operando com bits clássicos se o circuito base não tiver nenhum. O padrão de composição de um circuito com medições em um circuito somente quântico agora é válido. Por exemplo:

    from qiskit import QuantumCircuit
    
    base = QuantumCircuit(3)
    terminus = QuantumCircuit(3, 3)
    terminus.measure_all()
    
    # This will now succeed, though it was previously a CircuitError.
    base.compose(terminus)
  • Os DAGCircuit métodos depth() e size() têm um novo argumento de palavra-chave recurse para uso com circuitos que contêm operações de fluxo de controle (como IfElseOp, WhileLoopOp,, e ForLoopOp). Por padrão, é False e gerará um erro se as operações de fluxo de controle estiverem presentes, para evitar resultados mal definidos. Se definido como True, é retornado um valor de proxy que tenta pesar de forma justa cada bloco de fluxo de controle em relação à sua condição, mesmo que a profundidade ou o tamanho de uma corrida de concreto seja geralmente desconhecido. Consulte a documentação de cada método para saber como cada operação de fluxo de controle afeta a saída.

  • DAGCircuit.count_ops() ganhou um argumento de palavra-chave recurse para recursar em blocos de fluxo de controle. Por padrão, é True, e todas as operações em todos os blocos serão retornadas, bem como as próprias operações de fluxo de controle.

  • Foi adicionado um argumento create_preds_and_succs às funções circuit_to_dagdependency() e dag_to_dagdependency() que convertem de QuantumCircuit e DAGCircuitrespectivamente, para DAGDependency. Quando o valor de create_preds_and_succs é False, os predecessores e sucessores transitivos dos nós em DAGDependency não são construídos, o que torna as conversões mais rápidas e consomem muito menos memória. Os predecessores e sucessores diretos dos nós em DAGDependency são construídos como de costume.

    Por exemplo:

    from qiskit.converters import circuit_to_dagdependency
    from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
    
    circuit_in = QuantumCircuit(2)
    circuit_in.h(qr[0])
    circuit_in.h(qr[1])
    
    dag_dependency = circuit_to_dagdependency(circuit_in, create_preds_and_succs=False)
  • Novos atributos adicionados Clifford.symplectic_matrix, Clifford.tableau, Clifford.z, Clifford.x, Clifford.phase, Clifford.stab, Clifford.stab_z, Clifford.stab_x, Clifford.stab_phase, Clifford.destab, Clifford.destab_z, Clifford.destab_x, Clifford.destab_phase para a Clifford classe. Eles podem ser usados em vez de Clifford.table, que será descontinuado no futuro. StabilizerTable e PauliTable estão pendentes de descontinuação e serão descontinuados na versão futura e, posteriormente, removidos.

  • O construtor Commuting2qGateRouter agora tem um novo argumento de palavra-chave, edge_coloring. Esse argumento é usado para fornecer uma coloração de borda do mapa de acoplamento para determinar a ordem em que as portas de comutação são aplicadas.

  • Foi adicionada uma nova interface de algoritmos para a criação de algoritmos de evolução temporal usando as primitivas BaseSampler e BaseEstimator. Essa nova interface consiste em:

    Essa nova interface é uma alternativa à interface de algoritmos de evolução do tempo existente anteriormente, disponível definida com EvolutionProblem, EvolutionResult, RealEvolver, e ImaginaryEvolver que funcionava com um objeto QuantumInstance em vez de primitivos. Essa nova interface substitui a interface anterior, que será descontinuada e, posteriormente, removida em versões futuras.

  • Adicionadas novas classes de back-end para qiskit.providers.fake_provider:

    Essas novas classes implementam a interface BackendV2 e são criadas usando instantâneos armazenados das informações de backend dos sistemas IBM Quantum ibm_auckland, ibm_oslo, ibm_geneva e ibm_perth , respectivamente.

  • A classe Z2Symmetries tem dois novos métodos, convert_clifford() e taper_clifford(). Esses dois métodos são as duas operações necessárias para afunilar um operador com base nas Z2 simetrias do objeto e eram anteriormente executadas internamente por meio do método taper() método. No entanto, esses métodos agora são métodos públicos da classe que podem ser chamados individualmente, se necessário.

  • O desempenho do tempo de execução para a conjugação de um objeto longo PauliList por um objeto Clifford usando o PauliList.evolve() melhorou significativamente. Agora, ele será executado significativamente mais rápido do que antes.

  • Adicionada uma nova classe abstrata ClassicalIOChannel ao módulo qiskit.pulse.channels módulo. Essa classe é usada para representar canais de E/S clássicos e diferenciar esses canais de outras subclasses de Channel. Essa nova classe é a classe base para a classe MemorySlot, RegisterSlot, e SnapshotChannel classes. Dessa forma, a pad() transformação de pulso de canonização em qiskit.pulse.transforms não introduzirá atrasos em nenhuma instância de ClassicalIOChannel

  • A passagem SabreSwap transpiler pass tem um novo argumento de palavra-chave em seu construtor, trials. O argumento trials é usado para especificar o número de tentativas de tentativas de sementes aleatórias. O resultado do algoritmo SABRE pode ser muito diferente com base na semente usada para o número aleatório. SabreSwap agora executará o algoritmo com trials número de sementes aleatórias e escolherá a melhor (com o menor número de trocas inseridas). Se trials não for especificado, a passagem usará por padrão o número de CPUs físicas no sistema local.

  • A passagem SabreLayout transpiler pass tem um novo argumento de palavra-chave em seu construtor, swap_trials. O argumento swap_trials é usado para especificar quantas tentativas de sementes aleatórias devem ser executadas na SabreSwap passar internamente. Corresponde ao argumento trials no SabreSwap passe. Quando definido, cada iteração de SabreSwap será executada internamente swap_trials vezes. Se swap_trials não for especificado, o padrão será usar o número de CPUs físicas no sistema local.

  • Adicionada uma nova função, estimate_observables() que usa uma implementação da interface BaseEstimator interface (por exemplo Estimator, BackendEstimatorou qualquer implementação de provedor, como as presentes em qiskit-ibm-runtime e qiskit-aer) para calcular os valores de expectativa, suas médias e desvios padrão de uma lista ou dicionário de observáveis. Isso serve a um propósito semelhante ao da função pré-existente eval_observables() que realizava o cálculo usando um objeto QuantumInstance e foi substituída (e será descontinuada e subsequentemente removida em versões futuras) por essa nova função.

  • Adicionada uma nova Operation que fornece uma interface abstrata leve para objetos que podem ser colocados no QuantumCircuit. Isso permite armazenar objetos de "nível superior" diretamente em um circuito (por exemplo, Clifford objetos), combinar diretamente esses objetos (por exemplo, compor vários objetos consecutivos Clifford objetos consecutivos sobre os mesmos qubits) e sintetizar esses objetos em tempo de execução (por exemplo, sintetizar Clifford de uma forma que otimize a profundidade e/ou explore a conectividade do dispositivo). Anteriormente, somente as subclasses de qiskit.circuit.Instruction podiam ser colocadas em QuantumCircuitmas essa interface se tornou pesada e inclui muitos métodos e atributos para objetos de uso geral.

    A nova interface Operation inclui name, num_qubits e num_clbits (no futuro, isso pode ser ligeiramente ajustado), mas não inclui definition (e, portanto, não vincula a síntese ao objeto), não inclui condition (isso deve fazer parte do fluxo de controle clássico separado) e não inclui duration e unit (pois essas são propriedades da saída do transpilador).

    A partir de agora, Operation inclui Gate, Reset, Barrier, Measuree objetos de "nível superior", como Clifford. Essa lista de objetos de "nível superior" crescerá no futuro.

  • A Clifford é agora adicionado a um circuito quântico como um Operationsem primeiro sintetizar um subcircuito que implemente esse Clifford. A síntese real é adiada para uma HighLevelSynthesis passagem de transpilação posterior.

    Por exemplo, o código a seguir:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import random_clifford
    
    qc = QuantumCircuit(3)
    cliff = random_clifford(2)
    qc.append(cliff, [0, 1])

    não converte mais cliff em qiskit.circuit.Instructiono que inclui sintetizar o clifford em um circuito, quando ele é anexado a qc.

  • Adicionada uma nova passagem de transpilador OptimizeCliffords que coleta blocos de objetos Clifford consecutivos em um circuito e substitui cada bloco por um único objeto Clifford.

    Por exemplo, o código a seguir:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import random_clifford
    from qiskit.transpiler.passes import OptimizeCliffords
    from qiskit.transpiler import PassManager
    
    qc = QuantumCircuit(3)
    cliff1 = random_clifford(2)
    cliff2 = random_clifford(2)
    qc.append(cliff1, [2, 1])
    qc.append(cliff2, [2, 1])
    qc_optimized = PassManager(OptimizeCliffords()).run(qc)

    primeiro armazena os dois Cliffords cliff1 e cliff2 em qc como objetos de "nível superior" e, em seguida, a passagem do transpilador OptimizeCliffords otimiza o circuito compondo esses dois Cliffords em um único Clifford. Observe que o Clifford resultante ainda está armazenado em qc como um objeto de nível superior. Esse passe ainda não está incluído em nenhum dos gerenciadores de passes predefinidos.

  • Adicionada uma nova passagem de transpilador HighLevelSynthesis que sintetiza objetos de nível superior (por exemplo, Clifford objetos).

    Por exemplo, o código a seguir:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import random_clifford
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import HighLevelSynthesis
    
    qc = QuantumCircuit(3)
    qc.h(0)
    cliff = random_clifford(2)
    qc.append(cliff, [0, 1])
    
    qc_synthesized = PassManager(HighLevelSynthesis()).run(qc)

    sintetizará o Clifford de nível superior armazenado em qc usando a função padrão decompose_clifford() .

    Esse novo passe de transpilador HighLevelSynthesis é integrada aos gerenciadores de passagem predefinidos, sendo executada logo após a UnitarySynthesis passe. Portanto, transpile() sintetizará todos os Cliffords de nível superior presentes no circuito.

    É importante observar que o trabalho feito para armazenar Clifford como objetos de "nível superior" e para transpilar esses objetos usando HighLevelSynthesis deve ser completamente transparente, e nenhuma alteração de código é necessária.

  • SparsePauliOps agora podem ser construídos com matrizes de coeficientes que são objetos Python gerais. Isso se destina ao uso com objetos ParameterExpression outros objetos podem funcionar, mas não têm suporte de primeira classe. Alguns métodos SparsePauliOp (como a conversão para outras representações de classe) podem não funcionar ao usar object arrays, se o destino desejado não puder representar esses arrays gerais.

    Por exemplo, um ParameterExpression SparsePauliOp poderia ser construído por:

    import numpy as np
    from qiskit.circuit import Parameter
    from qiskit.quantum_info import SparsePauliOp
    
    print(SparsePauliOp(["II", "XZ"], np.array([Parameter("a"), Parameter("b")])))

    o que dá

    SparsePauliOp(['II', 'XZ'],
          coeffs=[ParameterExpression(1.0*a), ParameterExpression(1.0*b)])
  • Adicionada uma nova função plot_distribution() para plotar distribuições sobre quase-probabilidades. Isso é adequado para Counts, QuasiDistribution e ProbDistribution. O ditado bruto também pode ser passado. Por exemplo:

    from qiskit.visualization import plot_distribution
    
    quasi_dist = {'0': .98, '1': -.01}
    plot_distribution(quasi_dist)
  • Introduziu uma nova interface de plug-in de síntese de alto nível que é usada para permitir o uso de técnicas de síntese alternativas incluídas em pacotes externos sem problemas com a passagem do HighLevelSynthesis passagem do transpilador. Essas técnicas alternativas de síntese podem ser especificadas para qualquer objeto de "nível superior" do tipo Operationcomo, por exemplo, para Clifford e LinearFunction objetos. Essa interface de plug-in é semelhante à da síntese unitária. No último caso, os detalhes sobre como escrever um novo plug-in aparecem na qiskit.transpiler.passes.synthesis.plugin documentação do módulo.

  • Introduziu uma nova classe HLSConfig que pode ser usada para especificar algoritmos de síntese alternativos para objetos de "nível superior" do tipo Operation. Para cada objeto de interesse de nível superior, um objeto HLSConfig especifica uma lista de métodos de síntese e seus argumentos. Esse objeto pode ser passado para o HighLevelSynthesis transpiler pass ou especificado como um parâmetro hls_config em transpile().

    Como exemplo, vamos supor que op_a e op_b são nomes de dois objetos de nível superior, que op_a-objetos têm dois métodos de síntese default que não requerem nenhum parâmetro adicional e other com dois parâmetros inteiros opcionais option_1 e option_2, que op_b-objetos têm um único método de síntese default, e qc é um circuito quântico que contém os objetos op_a e op_b . O trecho de código a seguir:

    hls_config = HLSConfig(op_b=[("other", {"option_1": 7, "option_2": 4})])
    pm = PassManager([HighLevelSynthesis(hls_config=hls_config)])
    transpiled_qc = pm.run(qc)

    mostra como executar o método de síntese alternativo other para os objetos op_b, enquanto usa os métodos default para todos os outros objetos de alto nível, inclusive os objetos op_a.

  • Adição de novos métodos para execução de primitivos: BaseSampler.run() e BaseEstimator.run(). Esses métodos são executados de forma assíncrona e retornam objetos JobV1 que fornecem um identificador para as execuções. Esses novos métodos de execução podem ser passados para QuantumCircuit (e observáveis para BaseEstimator) que não estão registrados no construtor. Por exemplo:

    estimator = Estimator()
    result = estimator.run(circuits, observables, parameter_values).result()

    Isso fornece uma alternativa para o modelo de execução anterior (que agora está obsoleto) para os objetos BaseSampler e BaseEstimator que receberiam todas as entradas por meio do construtor e chamariam o objeto primitivo com a combinação desses parâmetros de entrada a serem usados na execução.

  • Adicionada a opção shots para implementações de referência de primitivos. Os números aleatórios podem ser corrigidos fornecendo seed_primitive. Por exemplo:

    from qiskit.primitives import Sampler
    from qiskit import QuantumCircuit
    
    bell = QuantumCircuit(2)
    bell.h(0)
    bell.cx(0, 1)
    bell.measure_all()
    
    with Sampler(circuits=[bell]) as sampler:
        result = sampler(circuits=[0], shots=1024, seed_primitive=15)
        print([q.binary_probabilities() for q in result.quasi_dists])
  • Os construtores para os arquivos BaseSampler e BaseEstimator têm um novo argumento de palavra-chave opcional, options , que é usado para definir os valores padrão para as opções expostas por meio do atributo options atributo.

  • Adicionada a classe PVQD à estrutura de evolução temporal em qiskit.algorithms. Essa classe implementa o algoritmo de dinâmica quântica variacional projetada (p-VQD) de Barison et al.

    Em cada intervalo de tempo, esse algoritmo calcula o próximo estado com uma fórmula de Trotter e o projeta em uma forma variacional. A projeção é determinada pela maximização da fidelidade do estado evoluído de Trotter e do ansatz, usando uma rotina de otimização clássica.

    import numpy as np
    
    from qiskit.algorithms.state_fidelities import ComputeUncompute
    from qiskit.algorithms.evolvers import EvolutionProblem
    from qiskit.algorithms.time_evolvers.pvqd import PVQD
    from qiskit.primitives import Estimator, Sampler
    from qiskit import BasicAer
    from qiskit.circuit.library import EfficientSU2
    from qiskit.quantum_info import Pauli, SparsePauliOp
    from qiskit.algorithms.optimizers import L_BFGS_B
    
    sampler = Sampler()
    fidelity = ComputeUncompute(sampler)
    estimator = Estimator()
    hamiltonian = 0.1 * SparsePauliOp([Pauli("ZZ"), Pauli("IX"), Pauli("XI")])
    observable = Pauli("ZZ")
    ansatz = EfficientSU2(2, reps=1)
    initial_parameters = np.zeros(ansatz.num_parameters)
    
    time = 1
    optimizer = L_BFGS_B()
    
    # setup the algorithm
    pvqd = PVQD(
        fidelity,
        ansatz,
        initial_parameters,
        estimator,
        num_timesteps=100,
        optimizer=optimizer,
    )
    
    # specify the evolution problem
    problem = EvolutionProblem(
        hamiltonian, time, aux_operators=[hamiltonian, observable]
    )
    
    # and evolve!
    result = pvqd.evolve(problem)
  • O método QNSPSA.get_fidelity() agora suporta um argumento opcional sampler que é usado para fornecer uma implementação da BaseSampler interface (como Sampler, BackendSamplerou quaisquer implementações de provedor, como as presentes em qiskit-ibm-runtime e qiskit-aer) para calcular a fidelidade de um QuantumCircuit. Por exemplo:

    from qiskit.primitives import Sampler
    from qiskit.algorithms.optimizers import QNSPSA
    
    fidelity = QNSPSA.get_fidelity(my_circuit, Sampler())
  • Adição de um novo argumento de palavra-chave sampler aos construtores das classes de estimativa de fase:

    Esse argumento é usado para fornecer uma implementação da interface BaseSampler interface, como Sampler, BackendSamplerou qualquer implementação de provedor, como as presentes em qiskit-ibm-runtime e qiskit-aer.

    Por exemplo:

    from qiskit.primitives import Sampler
    from qiskit.algorithms.phase_estimators import HamiltonianPhaseEstimation
    from qiskit.synthesis import MatrixExponential
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.opflow import PauliSumOp
    
    
    sampler = Sampler()
    num_evaluation_qubits = 6
    phase_est = HamiltonianPhaseEstimation(
        num_evaluation_qubits=num_evaluation_qubits, sampler=sampler
    )
    
    hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Y", 0.6), ("I", 0.7)]))
    result = phase_est.estimate(
        hamiltonian=hamiltonian,
        state_preparation=None,
        evolution=MatrixExponential(),
        bound=1.05,
    )
  • A passagem do SabreSwap melhorou significativamente o desempenho do tempo de execução devido a uma reescrita do algoritmo em Rust.

  • Subclasses de pulso simbólico Gaussian, GaussianSquare, Drag e Constant foram atualizadas para instanciar SymbolicPulse em vez da própria subclasse. Todos os objetos de pulso paramétrico em programas de pulso devem ser instâncias de pulso simbólico, pois a subclasse não é mais necessária. Observe que o site SymbolicPulse pode identificar exclusivamente um envelope específico com o objeto de expressão simbólica definido em SymbolicPulse.envelope.

  • Adicionada uma nova função, sampled_expectation_value()que permite calcular valores de expectativa para operadores diagonais de distribuições como Counts e QuasiDistribution. Os operadores válidos para uso com essa função são: str, Pauli, PauliOp, PauliSumOp, e SparsePauliOp.

  • A SamplingVQE que é otimizada para hamiltonianos diagonais e aproveita a primitiva sampler . A QAOA também foi adicionada uma classe que é subclasse de SamplingVQE.

    Para usar o novo SamplingVQE com um primitivo de referência, é possível fazer isso, por exemplo:

    from qiskit.algorithms.minimum_eigensolvers import SamplingVQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import Sampler
    from qiskit.opflow import PauliSumOp
    from qiskit.quantum_info import SparsePauliOp
    
    operator = PauliSumOp(SparsePauliOp(["ZZ", "IZ", "II"], coeffs=[1, -0.5, 0.12]))
    
    sampler = Sampler()
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    
    sampling_vqe = SamplingVQE(sampler, ansatz, optimizer)
    result = sampling_vqe.compute_minimum_eigenvalue(operator)
    eigenvalue = result.eigenvalue

    Observe que os operadores auxiliares avaliados são agora obtidos por meio do campo aux_operators_evaluated nos resultados. Isso consistirá em uma lista ou ditado de tuplas contendo os valores de expectativa para esses operadores, bem como os metadados da execução primitiva. aux_operator_eigenvalues não é mais um campo válido.

  • Foi adicionado um novo argumento de palavra-chave atol ao método SparsePauliOp.equiv() para ajustar a tolerância da verificação de equivalência,

  • Introduziu uma nova interface de plug-in para estágios do transpilador que é usada para habilitar objetos alternativos PassManager de um pacote externo em um estágio específico como parte do transpile() ou a StagedPassManager saída de generate_preset_pass_manager(), level_0_pass_manager(), level_1_pass_manager(), level_2_pass_manager(), e level_3_pass_manager(). Os usuários podem selecionar um plug-in a ser usado para um estágio de transpilador com os argumentos de palavra-chave init_method, layout_method, routing_method, translation_method, optimization_method e scheduling_method em transpile() e generate_preset_pass_manager(). Uma lista completa dos nomes dos plug-ins atualmente instalados pode ser encontrada com a função list_stage_plugins() função. Para criar plug-ins, consulte a documentação do módulo qiskit.transpiler.preset_passmanagers.plugin que inclui um guia para a criação de plug-ins de estágio.

  • O transpile() tem dois novos argumentos de palavra-chave, init_method e optimization_method , que são usados para especificar plug-ins alternativos a serem usados nos estágios init e optimization , respectivamente.

  • A classe PassManagerConfig tem dois novos atributos, init_method e optimization_method , além de argumentos de palavras-chave correspondentes nos métodos do construtor. Eles representam os plug-ins init e optimization especificados pelo usuário para serem usados na compilação.

  • A classe SteppableOptimizer é adicionada. Ele permite realizar otimizações clássicas passo a passo usando o método step() método. Esses otimizadores implementam a interface "ask and tell" que (opcionalmente) permite calcular manualmente a função ou as avaliações de gradiente necessárias e conectá-las novamente ao otimizador. Para obter mais informações sobre essa interface, consulte: interface ask and tell. Um caso de uso muito simples em que o usuário pode querer fazer a otimização passo a passo é para leitura:

    import random
    import numpy as np
    from qiskit.algorithms.optimizers import GradientDescent
    
    def objective(x):
          return (np.linalg.norm(x) - 1) ** 2
    
    def grad(x):
          return 2 * (np.linalg.norm(x) - 1) * x / np.linalg.norm(x)
    
    
    initial_point = np.random.normal(0, 1, size=(100,))
    
    optimizer = GradientDescent(maxiter=20)
    optimizer.start(x0=initial_point, fun=objective, jac=grad)
    
    for _ in range(maxiter):
        state = optimizer.state
        # Here you can manually read out anything from the optimizer state.
        optimizer.step()
    
    result = optimizer.create_result()

    Um caso mais complexo seria o tratamento de erros. Imagine que a função que você está avaliando tem uma chance aleatória de falhar. Nesse caso, você pode detectar o erro e executar a função novamente até que ela produza o resultado desejado antes de continuar o processo de otimização. Nesse caso, seria usada a interface ask and tell.

    import random
    import numpy as np
    from qiskit.algorithms.optimizers import GradientDescent
    
    def objective(x):
        if random.choice([True, False]):
            return None
        else:
            return (np.linalg.norm(x) - 1) ** 2
    
    def grad(x):
        if random.choice([True, False]):
            return None
        else:
            return 2 * (np.linalg.norm(x) - 1) * x / np.linalg.norm(x)
    
    
    initial_point = np.random.normal(0, 1, size=(100,))
    
    optimizer = GradientDescent(maxiter=20)
    optimizer.start(x0=initial_point, fun=objective, jac=grad)
    
    while optimizer.continue_condition():
        ask_data = optimizer.ask()
        evaluated_gradient = None
    
        while evaluated_gradient is None:
            evaluated_gradient = grad(ask_data.x_center)
            optimizer.state.njev += 1
    
        optmizer.state.nit += 1
    
        cf  = TellData(eval_jac=evaluated_gradient)
        optimizer.tell(ask_data=ask_data, tell_data=tell_data)
    
    result = optimizer.create_result()

    Transição de GradientDescent para ser uma subclasse de SteppableOptimizer.

  • O método subset_fitter é adicionado à classe TensoredMeasFitter classe. A implementação é restrita a padrões de atenuação nos quais cada qubit é atenuado individualmente, por exemplo, [[0], [1], [2]]. No entanto, esse é o caso mais amplamente utilizado. Ele permite que o TensoredMeasFitter seja usado nos casos em que a ordem numérica dos qubits físicos não corresponda ao índice do bit clássico.

  • As operações de fluxo de controle agora são compatíveis com o transpilador nos níveis de otimização 0 e 1 (por exemplo, chamar transpile() ou generate_preset_pass_manager() com argumento de palavra-chave optimization_level=1). Agora é possível construir um circuito como

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(2, 1)
    qc.h(0)
    qc.measure(0, 0)
    with qc.if_test((0, True)) as else_:
      qc.x(1)
    with else_:
      qc.y(1)

    e transpilar isso com sucesso, como por exemplo, por:

    from qiskit import transpile
    from qiskit_aer import AerSimulator
    
    backend = AerSimulator(method="statevector")
    transpiled = transpile(qc, backend)

    Os valores disponíveis para o argumento da palavra-chave layout_method são "trivial" e "dense". Para routing_method, estão disponíveis "stochastic" e "none". A tradução (translation_method) pode ser feita usando "translator" ou "unroller". Os níveis de otimização 2 e 3 ainda não são compatíveis com o fluxo de controle, nem o agendamento de circuitos (ou seja, fornecer um valor para scheduling_method), embora tenhamos a intenção de expandir o suporte para esses e outros métodos de layout, roteamento e tradução em versões posteriores do Qiskit Terra.

    Para que a transpilação com operações de fluxo de controle seja bem-sucedida com um backend, o backend deve ter as operações de fluxo de controle necessárias em sua base declarada. O Qiskit Aer, por exemplo, faz isso. Se você quiser apenas experimentar essas transpilações, considere substituir o argumento basis_gates por transpile().

  • As seguintes passagens do transpilador foram ensinadas a entender as construções de fluxo de controle na forma de ControlFlowOp instruções em um circuito:


    Relacionado ao layout


    Relacionado com o roteamento


    Relacionado com tradução


    Relacionado à otimização

    Esses passes são mais comumente usados por meio dos gerenciadores de passes predefinidos (aqueles usados internamente pelo transpile() e generate_preset_pass_manager()), mas também estão disponíveis para outros usos. Essas passagens agora recorrem a operações de fluxo de controle, quando apropriado, atualizando ou analisando os blocos internos.

  • Adicionada uma nova classe TrotterQRTE que implementa a interface RealTimeEvolver que usa um qiskit.primitives.BaseEstimator para realizar o cálculo. Essa nova classe substitui a classe qiskit.algorithms.TrotterQRTE anteriormente disponível (que será descontinuada e posteriormente removida em versões futuras) que usava um Backend ou QuantumInstance para realizar o cálculo.

  • DAGCircuit.substitute_node_with_dag() agora aceita propagate_condition como um argumento de palavra-chave. O padrão é True, que era o comportamento anterior, e copia qualquer condição do nó a ser substituído para cada nó de operação na substituição. Se definido como False, a condição não será copiada, o que permite a substituição de um nó condicional por um subDAG que já implementa fielmente a condição.

  • DAGCircuit.substitute_node_with_dag() agora pode receber um mapeamento para seu parâmetro wires , bem como uma sequência. O mapeamento deve mapear os bits no DAG de substituição para os bits no DAG em que ele está sendo inserido. Isso permite um estilo de construção mais fácil para os chamadores quando o nó de entrada tem bits clássicos e uma condição, e o DAG de substituição pode usá-los fora de ordem.

  • Adicionado o pacote qiskit.algorithms.minimum_eigensolvers para incluir interfaces para algoritmos habilitados para primitivas. VQE foi refatorado nesta implementação para aproveitar as primitivas.

    Para usar a nova implementação com uma referência primitiva, é possível fazer, por exemplo:

    from qiskit.algorithms.minimum_eigensolvers import VQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import TwoLocal
    from qiskit.primitives import Estimator
    from qiskit.quantum_info import SparsePauliOp
    
    h2_op = SparsePauliOp(
        ["II", "IZ", "ZI", "ZZ", "XX"],
        coeffs=[
            -1.052373245772859,
            0.39793742484318045,
            -0.39793742484318045,
            -0.01128010425623538,
            0.18093119978423156,
        ],
    )
    
    estimator = Estimator()
    ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
    optimizer = SLSQP()
    
    vqe = VQE(estimator, ansatz, optimizer)
    result = vqe.compute_minimum_eigenvalue(h2_op)
    eigenvalue = result.eigenvalue

    Observe que os operadores auxiliares avaliados são agora obtidos por meio do campo aux_operators_evaluated nos resultados. Isso consistirá em uma lista ou ditado de tuplas contendo os valores de expectativa para esses operadores, bem como os metadados da execução primitiva. aux_operator_eigenvalues não é mais um campo válido.

Notas da Atualização

  • Para Target que contenham apenas operações de 2 qubits definidas globalmente, sem quaisquer restrições de conectividade, o retorno do método Target.build_coupling_map() agora retornará None em vez de um objeto CouplingMap que contém num_qubits nós e nenhuma borda. Essa alteração foi feita para refletir melhor as restrições reais de conectividade do backend Target porque, nesse caso, não há restrições de conectividade no backend que está sendo modelado pelo Targete não uma falta de conectividade. Se, por algum motivo, você desejar o comportamento anterior, poderá reproduzi-lo verificando um retorno None e criando manualmente um mapa de acoplamento, por exemplo:

    from qiskit.transpiler import Target, CouplingMap
    from qiskit.circuit.library import CXGate
    
    target = Target(num_qubits=3)
    target.add_instruction(CXGate())
    cmap = target.build_coupling_map()
    if cmap is None:
        cmap = CouplingMap()
        for i in range(target.num_qubits):
            cmap.add_physical_qubit(i)
  • O valor padrão para o argumento da palavra-chave entanglement no construtor para os objetos RealAmplitudes e EfficientSU2 foi alterado de "full" para "reverse_linear". Essa alteração foi feita porque o circuito de saída é equivalente, mas usa apenas n1n-1 em vez de n(n1)2\frac{n(n-1)}{2} CXGate gates. Se você desejar o padrão anterior, poderá definir explicitamente entanglement="full" ao chamar um dos construtores.

  • Adicionada uma verificação de validação ao BaseSampler.run(). Ele gera um erro se não houver um bit clássico.

  • O comportamento da função call() a função de criação de pulsos foi atualizada. Quando uma instância ScheduleBlock é chamada por esse método, ele cria internamente uma instância Reference no contexto atual e atribui imediatamente o programa chamado à referência. Assim, a instrução Call não é mais gerada. Junto com essa alteração, é proibido chamar blocos diferentes com o mesmo argumento name . Essa operação resultará em um erro.

  • Para a maioria das arquiteturas, a partir da próxima versão do Qiskit Terra, 0.23, o pacote tweedledum se tornará uma dependência opcional, em vez de um requisito. Isso é usado atualmente por algumas funções clássicas de oráculo de fase. Se o seu aplicativo ou biblioteca precisar dessa funcionalidade, talvez você queira se preparar adicionando imediatamente o endereço tweedledum às dependências do seu pacote.

    tweedledum não é mais um requisito em macOS arm64 ( M1 ) com efeito imediato no Qiskit Terra 0.22. Isso ocorre porque as rodas fornecidas para essa plataforma estão quebradas e a criação a partir do sdist não é confiável para a maioria das pessoas. Se você instalar manualmente uma versão funcional do tweedledum, todas as funcionalidades dependentes continuarão a funcionar.

  • O atributo ._layout do objeto QuantumCircuit foi alterado do armazenamento de um objeto Layout para armazenar uma classe de dados com 2 atributos, initial_layout que contém um objeto Layout para o layout inicial definido durante a compilação e input_qubit_mapping que contém um dicionário que mapeia os qubits para posicionar os índices no circuito original. Essa alteração foi necessária para fornecer todas as informações para que um circuito pós-transpilado pudesse reverter totalmente a permutação causada pelo layout inicial em todas as situações. Embora esse atributo seja privado e não deva ser usado externamente, é a única maneira de rastrear o layout inicial por meio do transpile() portanto, a alteração está sendo documentada, caso você dependa dela. Se você tiver um caso de uso para o atributo _layout que não esteja sendo abordado pela API do Qiskit, abra um problema para que possamos resolver essa lacuna de recurso.

  • Os construtores para o SetPhase, ShiftPhase, SetFrequency, e ShiftFrequency agora gerarão um erro PulseError se o valor passado pelo argumento channel não for uma instância de PulseChannel. Essa alteração foi feita para validar a entrada dos construtores, pois as instruções são válidas apenas para canais de pulso e não para outros tipos de canais.

  • A função plot_histogram() foi modificada para retornar um histograma real de valores discretos em compartimentos. O comportamento anterior da função era, apesar do nome, gerar de fato uma visualização da distribuição da entrada. Devido a essa disparidade entre o nome da função e o comportamento, o comportamento da função foi alterado, de modo que agora ela está realmente gerando um histograma adequado de dados discretos. Se você quiser preservar o comportamento anterior de plotar uma distribuição de probabilidade dos dados de contagem, poderá usar a função plot_distribution() para gerar um gráfico equivalente. Por exemplo, o comportamento anterior de plot_histogram({'00': 512, '11': 500}) pode ser recriado com:

    from qiskit.visualization import plot_distribution
    import matplotlib.pyplot as plt
    
    ax = plt.subplot()
    plot_distribution({'00': 512, '11': 500}, ax=ax)
    ax.set_ylabel('Probabilities')
  • Os contextos qiskit.pulse.builder inline e pad foram removidos. Eles foram descontinuados pela primeira vez no Terra 0.18.0 (julho de 2021). Não há como substituir o site inline; basta escrever os pulsos no escopo que o contém. O gerenciador de contexto pad não teve efeito desde que foi descontinuado.

  • A saída da passagem do SabreSwap (inclusive quando optimization_level=3 ou routing_method ou layout_method são definidos como 'sabre' ao chamar transpile()) com um valor de semente fixo pode mudar em relação às versões anteriores. Isso é causado por um novo gerador de números aleatórios que está sendo usado como parte da reescrita da passagem SabreSwap em Rust, o que melhorou significativamente o desempenho. Se você depende de uma saída consistente, pode executar a passagem em uma versão anterior do Qiskit e usar o qiskit.qpy para salvar o circuito e depois carregá-lo usando a versão atual.

  • O comportamento Layout.add() quando não se especifica um physical_bit foi alterado em relação às versões anteriores. Nas versões anteriores, um novo bit físico era adicionado com base no comprimento do Layout objeto. Por exemplo, se você tiver um Layout com os bits físicos 1 e 3, chamadas sucessivas para add() adicionariam os bits físicos 2, 4, 5, 6, etc. Se os bits físicos fossem 2 e 3, as chamadas sucessivas adicionariam 4, 5, 6, 7 etc. Isso foi alterado para que, em vez disso Layout.add() adicionará primeiro todos os bits físicos ausentes entre 0 e o bit físico máximo contido no Layout. Portanto, para o exemplo 1 e 3, ele agora adiciona 0, 2, 4, 5 e, para o exemplo 2 e 3, ele adiciona 0, 1, 4, 5 ao Layout. Essa alteração foi feita para aumentar a previsibilidade do resultado e também para corrigir uma classe de erros causados pelo comportamento inesperado. Como os bits físicos em um backend são sempre sequências contíguas de 0 a nn, adicionar novos bits quando ainda há bits físicos não utilizados pode fazer com que o layout use mais bits do que os disponíveis no backend. Se desejar o comportamento anterior, você poderá especificar manualmente o bit físico desejado ao chamar Layout.add().

  • O método obsoleto do atributo SparsePauliOp.table foi removido. Ele foi originalmente descontinuado no Qiskit Terra 0.19. Em vez disso, deve ser usado o método paulis() .

  • O suporte para retornar um PauliTable da função pauli_basis() foi removido. Da mesma forma, o argumento pauli_list na função pauli_basis() que foi usado para mudar para um PauliList (agora o único tipo de retorno) foi removido. Essa funcionalidade foi descontinuada na versão do Qiskit Terra 0.19.

  • Os objetos de backend falsos FakeJohannesburg, FakeJohannesburgV2, FakeAlmaden, FakeAlmadenV2, FakeSingapore, e FakeSingaporeV2 não contêm mais os payloads padrão de pulso. Isso significa que, para as BackendV1 o método BackendV1.defaults() e a simulação de pulso via BackendV1.run() não estão mais disponíveis. Para BackendV2 a propriedade calibration para instruções na seção Target não é mais preenchida. Essa alteração foi feita porque esses sistemas tinham cargas úteis de padrões de pulso extremamente grandes (no total ~50MB ) devido ao uso de formas de onda amostradas em vez de definições de pulso paramétrico. Esses três arquivos de carga útil ocuparam mais de 50% do espaço em disco necessário para instalar o qiskit-terra. Quando comparado com o valor potencial de poder compilar com reconhecimento de pulso ou simular pulso nesses dispositivos aposentados, o tamanho do arquivo não vale o custo. Se você precisar aproveitar essas propriedades, poderá usar uma versão mais antiga do Qiskit e usar o qpy para transferir circuitos de versões mais antigas do qiskit para a versão atual.

  • isinstance verifique com as classes de pulso Gaussian, GaussianSquare, Drag e Constant será invalidada porque essas subclasses de pulso não são mais instanciadas. Eles ainda funcionarão no Terra 0.22, mas você deve iniciar a transição imediatamente. Em vez de usar informações de tipo, o site SymbolicPulse.pulse_type deve ser usado. Presume-se que esse seja um identificador de string exclusivo para envelopes de pulso, e podemos usar a igualdade de string para investigar os tipos de pulso. Por exemplo,

    from qiskit.pulse.library import Gaussian
    
    pulse = Gaussian(160, 0.1, 40)
    
    if isinstance(pulse, Gaussian):
      print("This is Gaussian pulse.")

    Esse código deve ser atualizado para

    from qiskit.pulse.library import Gaussian
    
    pulse = Gaussian(160, 0.1, 40)
    
    if pulse.pulse_type == "Gaussian":
      print("This is Gaussian pulse.")

    Pelo mesmo motivo, os atributos de classe, como pulse.__class__.__name__ , não devem ser acessados para obter informações sobre o tipo de pulso.

  • A exceção qiskit.exceptions.QiskitIndexError foi removida e não existe mais, de acordo com o aviso de depreciação do qiskit-terra 0.18.0 (lançado em 12 de julho de 2021).

  • Os argumentos obsoletos epsilon e factr para o construtor da classe L_BFGS_B foram removidos. Esses argumentos foram originalmente descontinuados como parte da versão 0.18.0 (lançada em 12 de julho de 2021). Em vez disso, deve ser usado o argumento ftol . Consulte a documentação do scipy sobre o otimizador para obter mais detalhes sobre a relação entre esses argumentos.

  • Os gerenciadores de passagem predefinidos para os níveis 1 e 2, que serão usados quando optimization_level=1 ou optimization_level=2 com transpile() ou generate_preset_pass_manager() e a saída de level_1_pass_manager() e level_2_pass_manager()agora usarão SabreLayout e SabreSwap por padrão, em vez dos padrões anteriores DenseLayout e StochasticSwap. Essa alteração foi feita para melhorar a qualidade de saída do transpilador, a combinação de SabreLayout e SabreSwap normalmente resultam em menos SwapGate objetos sendo inseridos no circuito de saída. Se você quiser usar as passagens padrão anteriores, poderá definir layout_method='dense' e routing_method='stochastic' em transpile() ou generate_preset_pass_manager() para aproveitar DenseLayout e StochasticSwap respectivamente.

  • O uso implícito de approximation_degree!=1.0 por padrão na função transpile() quando optimization_level=3 é definido foi desativado. O transpilador deve, por padrão, preservar a unitariedade da entrada até as transformações conhecidas, como permutações unilaterais e transformações de similaridade. Isso foi interrompido pelo uso anterior do site approximation_degree=None , que levou a resultados incorretos em casos como a evolução Trotterizada com muitas etapas de tempo em que os unitários estavam sendo excessivamente aproximados, levando a resultados incorretos. Foi decidido que as transformações que quebram a equivalência unitária devem ser ativadas explicitamente pelo usuário. Se você desejar o comportamento padrão anterior em que as instruções sintetizadas do UnitaryGate são aproximadas até as taxas de erro das instruções nativas do backend de destino, poderá definir explicitamente approximation_degree=None ao chamar transpile() com optimization_level=3, por exemplo:

    transpile(circuit, backend, approximation_degree=None, optimization_level=3)
  • Altere o padrão do número máximo de avaliações de função permitidas (maxfun) em L_BFGS_B de 1000 para 15000 para corresponder ao padrão SciPy. Esse número também corresponde ao número padrão de iterações (maxiter).

  • Atualizada ProbDistribution e QuasiDistribution para armazenar a informação do número de bits se forem fornecidas cadeias de bits sem o prefixo “0b”. ProbDistribution.binary_probabilities() e QuasiDistribution.binary_probabilities() usar o número de bits armazenado como o valor padrão do número de bits.

  • RZXCalibrationBuilder e RZXCalibrationBuilderNoEcho foram atualizados para ignorar as portas CX de alongamento implementadas pela sequência de ressonância cruzada não ecoada (ECR) para evitar o término da passagem com erros inesperados. Essas passagens recebem um novo argumento verbose que controla se as passagens avisam quando isso ocorre. Se verbose=True estiver definido, o pass emitirá um aviso ao usuário quando encontrar uma sequência não ECR.

  • O módulo de visualização qiskit.visualization passou por uma reorganização interna. Isso não deve ter afetado a interface pública, mas se você estava acessando qualquer parte interna das gavetas de circuito, elas agora podem estar em lugares diferentes. As únicas partes do módulo de visualização que são consideradas públicas são os componentes que estão documentados nesta documentação on-line.

Notas de descontinuação

  • A importação dos nomes Int1, Int2, classical_function e BooleanExpression diretamente de qiskit.circuit está obsoleto. Isso faz parte da mudança para tornar o tweedledum uma dependência opcional em vez de um requisito completo. Em vez disso, você deve importar esses nomes de qiskit.circuit.classicalfunction.

  • Os módulos qiskit.algorithms.factorizers e qiskit.algorithms.linear_solvers estão obsoletos e serão removidos em uma versão futura. Eles são substituídos por tutoriais no Qiskit Textbook: Shor HHL

  • O random_stabilizer_table() foi preterido e será removido em uma versão futura. Em vez disso, a função random_pauli_list() deve ser usada.

  • A função do módulo de pulso qiskit.pulse.utils.deprecated_functionality está obsoleta e será removida em uma versão futura. Essa era uma função essencialmente interna. A mesma funcionalidade é fornecida pelo site qiskit.utils.deprecate_function, que deve ser usado em seu lugar.

  • O método de execução de primitivos foi alterado. Os métodos BaseSampler.__call__() e BaseEstimator.__call__() foram preteridos. Por exemplo:

    estimator = Estimator(...)
    result = estimator(circuits, observables, parameters)
    
    sampler = Sampler(...)
    result = sampler(circuits, observables, parameters)

    deve ser reescrito como

    estimator = Estimator()
    result = estimator.run(circuits, observables, parameter_values).result()
    
    sampler = Sampler()
    result = sampler.run(circuits, parameter_values).result()

    O uso de primitivos como gerenciadores de contexto está obsoleto. Nem todas as primitivas têm um gerenciador de contexto disponível. Quando disponível (por exemplo, em qiskit-ibm-runtime), o gerenciador de contexto da sessão fornece funcionalidade equivalente.

    circuits, observables e parameters no construtor foi preterido. circuits e observables podem ser transmitidos pelos métodos run . run os métodos não são compatíveis com parameters. Os usuários precisam recorrer aos valores dos parâmetros por conta própria.

  • O argumento não utilizado qubit_channel_mapping no RZXCalibrationBuilder e RZXCalibrationBuilderNoEcho foram preteridos e serão removidos em uma versão futura. Esse argumento não é mais usado e não tem efeito sobre a operação das passagens.

Correções de bugs

  • Foi corrigido um problema em que Pauli.evolve() e PauliList.evolve() gerava um erro de tipo ao evoluir por certas portas de Clifford que modificavam a fase de Pauli. Corrigido #8438

  • Corrigido um erro no QuantumCircuit.initialize() e QuantumCircuit.prepare_state() que fazia com que eles não aceitassem um único Qubit como argumento para inicialização.

  • O método QuantumCircuit.while_loop() agora resolverá as referências de bits clássicos em sua condição da mesma forma que QuantumCircuit.if_test() e InstructionSet.c_if() fazem.

  • Os DAGCircuit métodos depth(), size() e DAGCircuit.count_ops() anteriormente retornavam silenciosamente resultados que tinham pouco ou nenhum significado se o fluxo de controle estivesse presente no circuito. O depth() e size() agora lançam corretamente um erro nesses casos, mas têm um novo argumento de palavra-chave recurse para permitir o cálculo de um valor de proxy, enquanto count_ops() por padrão, recursará os blocos e contará as operações dentro deles.

  • Foi corrigido um problema na passagem do DenseLayout passagem do transpilador em que qualquer objeto Qubit (ou seja, não faziam parte de um objeto QuantumRegister) que faziam parte de um QuantumCircuit não seriam incluídos na saída Layout que era gerado pela passagem.

  • O método do construtor Operator.from_circuit() foi atualizado para que ele possa lidar com a saída de layout do transpile() e reverter corretamente a permutação de qubit causada pelo layout em todos os casos. Anteriormente, se seu circuito transpilado usasse Qubit objetos, vários QuantumRegister ou um único objeto QuantumRegister com um nome diferente de "q" , o construtor teria falhado ao criar um Operator do circuito. Corrigido #8800.

  • Foi corrigido um bug em que a decomposição de uma instrução com um qubit e um bit clássico contendo uma única porta quântica falhava. Agora, o seguinte se decompõe como esperado:

    block = QuantumCircuit(1, 1)
    block.h(0)
    
    circuit = QuantumCircuit(1, 1)
    circuit.append(block, [0], [0])
    
    decomposed = circuit.decompose()
  • Corrigida a inicialização da matriz simétrica vazia em from_symplectic() na classe PauliList classe Por exemplo:

    from qiskit.quantum_info.operators import PauliList
    
    x = np.array([], dtype=bool).reshape((1,0))
    z = np.array([], dtype=bool).reshape((1,0))
    pauli_list = PauliList.from_symplectic(x, z)
  • Corrigir um problema na passagem do GateDirection passagem do transpilador para o arquivo CZGate. A porta CZ é simétrica, portanto, a inversão dos argumentos do qubit é permitida para corresponder ao mapa de acoplamento direcionado.

  • Correção de problemas com o método DerivativeBase.gradient_wrapper() ao reutilizar um amostrador de circuito entre as chamadas e vincular parâmetros aninhados.

  • Foi corrigido um problema nas gavetas de circuito mpl e latex , quando a configuração da opção idle_wires como False (Falso) quando havia um barrier no circuito fazia com que as gavetas falhassem. Corrigido #8313

  • Foi corrigido um problema no circuit_drawer() e QuantumCircuit.draw() com o método latex , no qual um OSError seria gerado em sistemas cujos diretórios temporários (por exemplo, /tmp) estão em um sistema de arquivos diferente do diretório de trabalho. Correções #8542

  • Aninhando um FlowController dentro de outro em um PassManager poderia anteriormente fazer com que algumas passagens do transpilador fossem "esquecidas" durante a transpilação, se as passagens retornassem um novo DAGCircuit em vez de alterar sua entrada. Os FlowControllers aninhados agora afetarão a transpilação corretamente.

  • Comparando QuantumCircuit e DAGCircuits para igualdade era anteriormente não determinística se os circuitos contivessem mais de um registro do mesmo tipo (por exemplo, dois ou mais QuantumRegisters), às vezes retornando False mesmo que os registros fossem idênticos. Agora, ele comparará corretamente os circuitos com vários registros.

  • O exportador do OpenQASM 2 (QuantumCircuit.qasm()) agora definirá corretamente os parâmetros do qubit para operações UnitaryGate que não afetam todos os qubits sobre os quais são definidos. Corrigido #8224.

  • Havia dois bugs na gaveta de circuitos do site text que foram corrigidos. Eles apareceram quando vertical_compression foi definido como medium, que é o padrão. O primeiro, às vezes, fazia com que o texto sobrescrevesse outro texto ou portões, e o segundo, às vezes, fazia com que as conexões entre um portão e seus controles fossem interrompidas. Consulte #8588.

  • Foi corrigido um problema com o UnitarySynthesis em que um circuito com portas de 1 qubit e uma entrada Target às vezes falhava em vez de processar o circuito como esperado.

  • A passagem do GateDirection agora respeitará os valores disponíveis para os parâmetros de porta ao lidar com portas parametrizadas com um Target.

  • Foi corrigido um problema na classe SNOBFIT quando um erro interno era gerado durante a execução do método minimize() se nenhum limite de entrada fosse especificado. Agora, isso é verificado no momento da chamada para gerar rapidamente um ValueError se os limites necessários estiverem faltando na minimize() chamada. Correções #8580

  • Foi corrigido um problema no callable de saída do método get_energy_evaluation() do método VQD agora chamará corretamente o callback especificado quando for executado. Anteriormente, o retorno de chamada não era usado incorretamente nesse caso. Corrigido #8575

  • Foi corrigido um problema quando circuit_drawer() era usado com reverse_bits=True em um circuito sem bits clássicos, o que causava a emissão de um aviso potencialmente confuso sobre cregbundle . Corrigido #8690

  • O exportador do OpenQASM 3 (qiskit.qasm3) agora tratará corretamente os built-ins do OpenQASM (como reset e measure) que têm uma condição clássica aplicada por c_if(). Anteriormente, a condição teria sido ignorada.

  • Foi corrigido um problema com a classe SPSA em que internamente ele tentava agrupar os trabalhos em lotes de tamanho uniforme, o que gerava uma exceção se não fosse possível criar lotes uniformes. Isso foi corrigido para que os trabalhos em lote sejam sempre bem-sucedidos, mesmo que não tenham o mesmo tamanho.

  • Corrigido o comportamento do Layout.add() que estava potencialmente causando a saída de transpile() fosse inválida e contivesse mais Qubits do que o que estava disponível no backend de destino. Corrigido: #8667

  • Foi corrigido um problema com a função state_to_latex() : passar uma string de látex para o argumento opcional prefix da função gerava um erro. Corrigido #8460

  • A função state_to_latex() produziu LaTeX não válido na presença de valores próximos de zero, resultando em erros quando state_drawer() é chamado. Corrigido #8169.

  • GradientDescent agora contará corretamente o número de iterações, avaliações de função e avaliações de gradiente. Além disso, a documentação agora afirma corretamente que o gradiente é aproximado por um método de diferença finita avançada.

  • Correção de avisos de depreciação em NaturalGradientque agora usa o StandardScaler para dimensionar os dados antes de ajustar o modelo se o parâmetro normalize estiver definido como True.

Aer 0.11.0

Nenhuma mudança

IBM 0.19.2

Nenhuma mudança

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