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
BackendSamplerque gerava um erro se seu métodorun()fosse chamado duas vezes sequencialmente. -
Corrigidos dois erros no
ComposedOpem que o métodoComposedOp.to_matrix()não fornecia os resultados corretos para composições comStateFne para composições com um coeficiente global. Corrigido #9283. -
Corrigido o problema em que os primitivos,
SamplereEstimatornão funcionavam quando era passado um circuito comnumpy.ndarraycomo parâmetro. -
Corrigido um erro no
SamplingVQEem que o argumentoaggregationnã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
SamplingVQEavaliava as energias dos estados próprios de forma lenta. -
Corrigida a avaliação automática dos parâmetros beta em
VQDadicionou suporte para entradasSparsePauliOpe 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()eDensityMatrix.probabilities_dict()em que eles retornavam resultados incorretos para sistemas não-qubit quando o argumentoqargsera especificado. Corrigido #9210 -
Correção do tratamento de alguns
classmethods porwrap_method()em Python 3.11. Anteriormente, em Python 3.11,wrap_methodenvolvia a função não vinculada associada aclassmethode, em seguida, falhava quando invocada porque o objeto de classe normalmente vinculado aclassmethodnão era passado para a função. A partir de Python 3.11.1, esse problema afetouQiskitTestCase, 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 deAerSimulatora partir de um objeto aBackendV2objeto. Anteriormente, a tentativa de usarAerSimulator.from_backend()com um objetoBackendV2teria gerado umAerErrordizendo que isso não era suportado. -
Corrige um bug em que
NoiseModel.from_backend()com um objetoBackendV2pode gerar um modelo de ruído comQuantumErrors excessivos em instruções não-Gate, enquanto, por exemplo, apenasReadoutErrors deve ser suficiente para medidas. Esse commit atualiza oNoiseModel.from_backend()com um objetoBackendV2para que ele retorne o mesmo modelo de ruído que o chamado com o objetoBackendV1correspondente. Ou seja, o modelo de ruído resultante não contém nenhumQuantumErrors 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émReadoutErrors nas medidas. -
Foi corrigido um bug no site
NoiseModel.from_backend()em que o uso dotemperaturekwarg 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ódulonoise.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_distscontê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
-
AdaptVQEagora indica corretamente que é compatível com operadores auxiliares. -
As gavetas do circuito (
QuantumCircuit.draw()ecircuit_drawer()) não emitirão mais um aviso sobre o parâmetrocregbundleao 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
QNSPSAfalhar quandomax_evals_groupedera definido com um valor maior que 1. -
Foi corrigido um problema com a passagem
SabreSwapque fazia com que a saída de várias execuções da passagem sem o argumentoseedespecificado 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 nenhumseedera especificado. -
Corrigido um problema com as classes primitivas,
BackendSamplereBackendEstimatorem que as instâncias não podiam ser serializadas compickle. Em geral, não é garantido que essas classes sejam serializáveis comoBackendV2e as instânciasBackendV1não precisam ser serializáveis (e geralmente não são), mas as definições de classe deBackendSamplereBackendEstimatornão impedem mais o uso depickle. -
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
BackendSamplereBackendEstimatorque impedia a execução com uma instânciaBackendV1que não tivesse um campomax_experimentsdefinido em sua instânciaBackendConfiguration. -
Foi corrigido um bug na passagem
VF2PostLayoutao transpilar para backends com umTargetdefinido, 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
deepycopyinterno 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_listdepauli_basis()foi descontinuado, poispauli_basis()agora sempre retorna umPauliList. Esse argumento foi removido prematuramente do Qiskit Terra 0.22.0, o que quebrou a compatibilidade dos usuários que estavam aproveitando opauli_list``argument. Now, the argument has been restored but will emit a ``DeprecationWarningquando usado. Se for usado, não terá efeito, pois como o Qiskit Terra 0.22.0 aPauliListé sempre retornado.
Correções de bugs
-
Corrigido o
BarrierBeforeFinalMeasurementspassagem do transpilador quando há condições em camadas soltasClbits 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
QuantumCircuiteDAGCircuit(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
StochasticSwapcom 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
Targetclasse. Anteriormente, dois métodos,operations_for_qargs()eoperation_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"}paranamese[CXGate()]paraopsem vez de gerar umKeyErrorou 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 argumentoproperties. 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
TranspilerErrorem 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,
BackendSamplereBackendEstimatorao 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 queBackendSamplereBackendEstimatordividirá 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
BackendEstimatorem que a configuração anterior de uma opção de execução chamadamonitorpara um valor avaliado comoTrueacionava incorretamente um monitor de trabalho que só funcionava em back-ends do pacoteqiskit-ibmq-provider. Isso foi removido para que você possa usar uma opção de execuçãomonitor, se necessário, sem causar problemas. -
Foi corrigido um problema com o método
Target.build_coupling_map()em que ele retornava incorretamenteNonepara um objetoTargetcom uma mistura de instruções ideais disponíveis globalmente e instruções que têm restrições de qubit. Agora, nesses casos, oTarget.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áNoneporque globalmente não há restrição de conectividade). Corrigido #8971 -
Foi corrigido um problema com o atributo
Target.qargsem que ele retornava incorretamenteNonepara um objetoTargetque contivesse qualquer instrução ideal disponível globalmente. -
Foi corrigida a remoção prematura do argumento da palavra-chave
pauli_listda funçãopauli_basis()que quebrou o código existente usando o caminho de compatibilidade futurapauli_list=Truena 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 subclasseControlledGateque 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
Clbitao circuito se houver instâncias soltas deClbits soltas no circuito e maisQubits do queClbits. -
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 queSparsePauliOppode assumir é restrito anp.complex128eobject. Corrigido #8992 -
Foi corrigido um problema na função
circuit_drawer()e no métodoQuantumCircuit.draw()em que o único estilo incorporado para a saídamplque era utilizável eradefault. Se outro estilo incorporado, comoiqx, fosse usado, seria emitido um aviso de que o estilo não foi encontrado e a gaveta voltaria a usar o estilodefault. Corrigido #8991 -
Foi corrigido um problema com o
transpile()em que ele falhava anteriormente com umTypeErrorse um objetoTargetpersonalizado fosse passado por meio do argumentotargete uma lista de vários circuitos fosse especificada para o argumentocircuits. -
Foi corrigido um problema com
transpile()ao direcionar umTarget(seja diretamente por meio do argumentotargetou por meio de uma instânciaBackendV2do argumentobackend) que continha uma instruçãoMeasureideal (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
VF2Layoutem que ele dava erro ao ser executado com umTargetque 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
VF2PostLayoutem que ele dava erro ao ser executado com umTargetque 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
VQDse mais dek=2autovalores 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.VQDeSamplingVQEnã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 umOperatora partir de umQuantumCircuitcontendo 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_phasepode ser mais apropriado. -
Corrige o problema em que
Statevector.evolve()eDensityMatrix.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_ARCHITECTURESprecisava ser definido com o valor da arquitetura para a GPU de destino. Isso foi corrigido para que a configuraçãoAER_CUDA_ARCHseja 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 domethod="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
SamplereEstimatorclasses 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 classesSamplereEstimatoragora 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
QuantumCircuitque contêm instruções de fluxo de controle, comoForLoopOpeWhileLoopOp.- Dimensionamento e desempenho muito melhores para a função
transpile()com grandes números de qubits, especialmente quandooptimization_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 emqiskit.transpiler.preset_passmanagers.plugin. Além disso,BackendV2agora 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.algorithmsque aproveitam as classesprimitivesque implementam as classesBaseSamplereBaseEstimator.
Novos Recurso
-
Adicione suporte para representar uma operação que tenha uma largura variável para a classe
Targetclasse. Anteriormente, um objetoTargetprecisava ter uma instância deOperationdefinida 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 classeOperationsó 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, eWhileLoopOpsão suportadas globalmente para qualquer número de qubits. Isso é então refletido por outras chamadas naTargetAPI, comoinstruction_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,
BackendSamplereBackendEstimatorparaqiskit.primitives. Essa nova implementação de classe primitiva envolve umBackendV1ouBackendV2como uma instância deBaseSamplerouBaseEstimatorrespectivamente. 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 classeSamplingVQErequer uma instânciaBaseSamplerpara funcionar. Se você quiser executar essa classe com um backend de um provedor sem uma implementação primitiva nativa, poderá construir umBackendSamplerpara 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.eigenvalueSe você estiver usando um provedor que tenha implementações primitivas nativas (como
qiskit-ibm-runtimeouqiskit-aer), é sempre melhor usar essa implementação primitiva nativa em vez deBackendEstimatorouBackendSamplerpois as implementações nativas serão muito mais eficientes e/ou farão pré e pós-processamento adicional.BackendEstimatoreBackendSamplersão projetados para serem genéricos, podendo funcionar com qualquer backend que retorneCountsem seu siteResults, o que impossibilita otimizações adicionais. -
Adição de uma nova classe de algoritmo,
AdaptVQEaqiskit.algorithmsEsse algoritmo usa umqiskit.algorithms.minimum_eigensolvers.VQEem combinação com um conjunto de operadores a partir do qual se constrói um sistema deqiskit.circuit.library.EvolvedOperatorAnsatzde 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
BackendV2agora tem suporte para dois novos pontos de conexão opcionais que permitem que os backends injetem etapas de compilação personalizadas como parte detranspile()egenerate_preset_pass_manager(). Se umaBackendV2incluir os métodosget_scheduling_stage_plugin()ouget_translation_stage_plugin(), o transpilador usará a string retornada como o valor padrão para os argumentosscheduling_methodetranslation_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 transpiladorplugininterface. 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çãotranspile()que pode ser usado para desativar a seleção personalizada de um backend de um método padrão se o backend de destino tiverget_scheduling_stage_plugin()ouget_translation_stage_plugin()definido. -
Adicionado um parâmetro
labelao construtor da classeBarrierda classe e ao métodobarrier()que permite que um usuário atribua um rótulo a uma instância da diretivaBarrierdiretiva. Para visualizações geradas comcircuit_drawer()ouQuantumCircuit.draw()esse rótulo será impresso na parte superior do sitebarrier.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, eCSdgGateàs portas padrão na Biblioteca de circuitos (qiskit.circuit.library). -
Adicionado o pacote
qiskit.algorithms.eigensolverspara incluir interfaces para algoritmos habilitados para primitivas. Esse novo módulo acabará substituindo o anteriorqiskit.algorithms.eigen_solvers. Esse novo módulo contém uma implementação alternativa do móduloVQDque, em vez de usar um backend ouQuantumInstancerecebe uma instância deBaseEstimator, incluindoEstimator,BackendEstimator, ou qualquer implementação de provedor, como as presentes emqiskit-ibm-runtimeeqiskit-aer.Por exemplo, para usar a nova implementação com uma instância de
Estimatorclasse: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.eigenvaluesObserve que os operadores auxiliares avaliados são agora obtidos por meio do campo
aux_operators_evaluatednos 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_eigenvaluesnã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 classeBaseSamplerprimitivo: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.gradientsque contém classes que são usadas para calcular gradientes usando as interfaces primitivas definidas emqiskit.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 daBaseEstimatorinterface:ou uma instância da
BaseSamplerinterface: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
Grovertem um novo argumento de palavra-chave,sampler, que é usado para executar o algoritmo usando uma instância da interfaceBaseSamplerpara calcular os resultados. Esse novo argumento substitui o argumentoquantum_instancee, portanto,quantum_instanceestá 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()eSchedule.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çãoResetapós uma operaçãoMeasurepor uma condicionalXGate. Essa passagem pode ser usada em backends em que umaReseté realizada por meio de uma medição e, em seguida, uma porta X condicional, de modo que isso removerá a duplicação implícitaMeasureduplicado daResetoperaçã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-chaveentanglementno construtor da classeNLocalclasse de circuito. ParaTwoLocalcircuitos (que são subclasses deNLocal), seentanglement_blocks="cx", o uso deentanglement="reverse_linear"fornece um circuito n-qubit equivalente aentanglement="full", mas com apenasCXGategates, em vez de . -
ScheduleBlockfoi 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
progsem 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)
Referencefoi adicionada. Essa instrução é injetada no escopo do construtor atual quando o comandoreference()é usado. Todas as referências definidas no programa de pulso atual podem ser listadas com a propriedadereferences.Além disso, cada referência é gerenciada com um escopo para facilitar o gerenciamento de parâmetros.
scoped_parameters()esearch_parameters()foram adicionados aScheduleBlock. 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-chaveweightpara 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 oargsort()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-chaveweight, 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çãocircuit_drawer()função eQuantumCircuit.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,CSdgGateeCCZGateao construtor da classe de operadorCNOTDihedral. Os circuitos de entrada ao criar um operadorCNOTDihedralagora 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 aBaseSamplerincluindoBackendSamplerSampler, ou qualquer implementação de provedor, como as presentes no qiskit-ibm-runtime e no qiskit-aer. Isso oferece uma alternativa ao uso do argumentoquantum_instancepara definir o alvoBackendouQuantumInstancepara executar o algoritmo. O uso de umQuantumInstanceestá pendente de descontinuação e será descontinuado em uma versão futura. -
Adicionada uma nova classe,
BackendV2Converterque é usada para envolver uma instânciaBackendV1em umaBackendV2interface. Ele permite que você tenha uma instânciaBackendV2instância de qualquerBackendV1. Isso permite padronizar os padrões de acesso na interface mais recenteBackendV2mais recente, mesmo que você ainda ofereça suporte aBackendV1. -
Adicionada uma nova função
convert_to_target()que é usada para receber umBackendConfiguratione, opcionalmente, umBackendPropertiesePulseDefaultse criar um objetoTargetequivalente ao conteúdo desses objetos. -
qiskit.quantum_info.BaseOperatorsubclasses (comoScalarOp,SparsePauliOpePauliList) agora podem ser usadas com a função incorporada Pythonsum(). -
Um novo transpiler pass,
ConvertConditionsToIfOpsfoi adicionada, que pode ser usada para converter instruções condicionadas de estilo antigoInstruction.c_if()-instruções condicionadas emIfElseOpobjetos. 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]eqr[0], e a segunda porta CX está sobre os qubitsqr[1]eqr[2]), teremos quereséTrue.Essa verificação de comutatividade é excessivamente conservadora para portas condicionais e parametrizadas, e pode retornar
Falsemesmo quando essas portas são comutativas. -
Adicionada uma nova passagem de transpilador
CommutativeInverseCancellationque cancela pares de portas inversas explorando relações de comutação entre portas. Essa passagem é uma generalização da passagem do transpiladorInverseCancellationpois detecta um conjunto maior de portas inversas e leva em conta a comutatividade. A passagem também evita alguns problemas associados à passagem do transpiladorCommutativeCancellation.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
DAGCircuitmétodosdepth()esize()têm um novo argumento de palavra-chaverecursepara uso com circuitos que contêm operações de fluxo de controle (comoIfElseOp,WhileLoopOp,, eForLoopOp). Por padrão, éFalsee gerará um erro se as operações de fluxo de controle estiverem presentes, para evitar resultados mal definidos. Se definido comoTrue, é 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-chaverecursepara 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çõescircuit_to_dagdependency()edag_to_dagdependency()que convertem deQuantumCircuiteDAGCircuitrespectivamente, paraDAGDependency. Quando o valor decreate_preds_and_succsé False, os predecessores e sucessores transitivos dos nós emDAGDependencynã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 emDAGDependencysã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_phasepara aCliffordclasse. Eles podem ser usados em vez deClifford.table, que será descontinuado no futuro.StabilizerTableePauliTableestão pendentes de descontinuação e serão descontinuados na versão futura e, posteriormente, removidos. -
O construtor
Commuting2qGateRouteragora 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
BaseSamplereBaseEstimator. 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, eImaginaryEvolverque funcionava com um objetoQuantumInstanceem 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
BackendV2e são criadas usando instantâneos armazenados das informações de backend dos sistemas IBM Quantumibm_auckland,ibm_oslo,ibm_genevaeibm_perth, respectivamente. -
A classe
Z2Symmetriestem dois novos métodos,convert_clifford()etaper_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étodotaper()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
PauliListpor um objetoCliffordusando oPauliList.evolve()melhorou significativamente. Agora, ele será executado significativamente mais rápido do que antes. -
Adicionada uma nova classe abstrata
ClassicalIOChannelao móduloqiskit.pulse.channelsmódulo. Essa classe é usada para representar canais de E/S clássicos e diferenciar esses canais de outras subclasses deChannel. Essa nova classe é a classe base para a classeMemorySlot,RegisterSlot, eSnapshotChannelclasses. Dessa forma, apad()transformação de pulso de canonização emqiskit.pulse.transformsnão introduzirá atrasos em nenhuma instância deClassicalIOChannel -
A passagem
SabreSwaptranspiler pass tem um novo argumento de palavra-chave em seu construtor,trials. O argumentotrialsé 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.SabreSwapagora executará o algoritmo comtrialsnúmero de sementes aleatórias e escolherá a melhor (com o menor número de trocas inseridas). Setrialsnão for especificado, a passagem usará por padrão o número de CPUs físicas no sistema local. -
A passagem
SabreLayouttranspiler pass tem um novo argumento de palavra-chave em seu construtor,swap_trials. O argumentoswap_trialsé usado para especificar quantas tentativas de sementes aleatórias devem ser executadas naSabreSwappassar internamente. Corresponde ao argumentotrialsnoSabreSwappasse. Quando definido, cada iteração deSabreSwapserá executada internamenteswap_trialsvezes. Seswap_trialsnã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 interfaceBaseEstimatorinterface (por exemploEstimator,BackendEstimatorou qualquer implementação de provedor, como as presentes emqiskit-ibm-runtimeeqiskit-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é-existenteeval_observables()que realizava o cálculo usando um objetoQuantumInstancee foi substituída (e será descontinuada e subsequentemente removida em versões futuras) por essa nova função. -
Adicionada uma nova
Operationque fornece uma interface abstrata leve para objetos que podem ser colocados noQuantumCircuit. Isso permite armazenar objetos de "nível superior" diretamente em um circuito (por exemplo,Cliffordobjetos), combinar diretamente esses objetos (por exemplo, compor vários objetos consecutivosCliffordobjetos consecutivos sobre os mesmos qubits) e sintetizar esses objetos em tempo de execução (por exemplo, sintetizarCliffordde uma forma que otimize a profundidade e/ou explore a conectividade do dispositivo). Anteriormente, somente as subclasses deqiskit.circuit.Instructionpodiam ser colocadas emQuantumCircuitmas essa interface se tornou pesada e inclui muitos métodos e atributos para objetos de uso geral.A nova interface
Operationincluiname,num_qubitsenum_clbits(no futuro, isso pode ser ligeiramente ajustado), mas não incluidefinition(e, portanto, não vincula a síntese ao objeto), não incluicondition(isso deve fazer parte do fluxo de controle clássico separado) e não incluidurationeunit(pois essas são propriedades da saída do transpilador).A partir de agora,
OperationincluiGate,Reset,Barrier,Measuree objetos de "nível superior", comoClifford. Essa lista de objetos de "nível superior" crescerá no futuro. -
A
Cliffordé agora adicionado a um circuito quântico como umOperationsem primeiro sintetizar um subcircuito que implemente esse Clifford. A síntese real é adiada para umaHighLevelSynthesispassagem 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
cliffemqiskit.circuit.Instructiono que inclui sintetizar o clifford em um circuito, quando ele é anexado aqc. -
Adicionada uma nova passagem de transpilador
OptimizeCliffordsque coleta blocos de objetosCliffordconsecutivos em um circuito e substitui cada bloco por um único objetoClifford.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
cliff1ecliff2emqccomo objetos de "nível superior" e, em seguida, a passagem do transpiladorOptimizeCliffordsotimiza o circuito compondo esses dois Cliffords em um único Clifford. Observe que o Clifford resultante ainda está armazenado emqccomo 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
HighLevelSynthesisque sintetiza objetos de nível superior (por exemplo,Cliffordobjetos).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
qcusando a função padrãodecompose_clifford().Esse novo passe de transpilador
HighLevelSynthesisé integrada aos gerenciadores de passagem predefinidos, sendo executada logo após aUnitarySynthesispasse. Portanto,transpile()sintetizará todos os Cliffords de nível superior presentes no circuito.É importante observar que o trabalho feito para armazenar
Cliffordcomo objetos de "nível superior" e para transpilar esses objetos usandoHighLevelSynthesisdeve 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 objetosParameterExpressionoutros objetos podem funcionar, mas não têm suporte de primeira classe. Alguns métodosSparsePauliOp(como a conversão para outras representações de classe) podem não funcionar ao usarobjectarrays, se o destino desejado não puder representar esses arrays gerais.Por exemplo, um
ParameterExpressionSparsePauliOppoderia 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 paraCounts,QuasiDistributioneProbDistribution. 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
HighLevelSynthesispassagem do transpilador. Essas técnicas alternativas de síntese podem ser especificadas para qualquer objeto de "nível superior" do tipoOperationcomo, por exemplo, paraCliffordeLinearFunctionobjetos. Essa interface de plug-in é semelhante à da síntese unitária. No último caso, os detalhes sobre como escrever um novo plug-in aparecem naqiskit.transpiler.passes.synthesis.plugindocumentação do módulo. -
Introduziu uma nova classe
HLSConfigque pode ser usada para especificar algoritmos de síntese alternativos para objetos de "nível superior" do tipoOperation. Para cada objeto de interesse de nível superior, um objetoHLSConfigespecifica uma lista de métodos de síntese e seus argumentos. Esse objeto pode ser passado para oHighLevelSynthesistranspiler pass ou especificado como um parâmetrohls_configemtranspile().Como exemplo, vamos supor que
op_aeop_bsão nomes de dois objetos de nível superior, queop_a-objetos têm dois métodos de síntesedefaultque não requerem nenhum parâmetro adicional eothercom dois parâmetros inteiros opcionaisoption_1eoption_2, queop_b-objetos têm um único método de síntesedefault, eqcé um circuito quântico que contém os objetosop_aeop_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
otherpara os objetosop_b, enquanto usa os métodosdefaultpara todos os outros objetos de alto nível, inclusive os objetosop_a. -
Adição de novos métodos para execução de primitivos:
BaseSampler.run()eBaseEstimator.run(). Esses métodos são executados de forma assíncrona e retornam objetosJobV1que fornecem um identificador para as execuções. Esses novos métodos de execução podem ser passados paraQuantumCircuit(e observáveis paraBaseEstimator) 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
BaseSamplereBaseEstimatorque 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
shotspara implementações de referência de primitivos. Os números aleatórios podem ser corrigidos fornecendoseed_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
BaseSamplereBaseEstimatortê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 atributooptionsatributo. -
Adicionada a classe
PVQDà estrutura de evolução temporal emqiskit.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 opcionalsamplerque é usado para fornecer uma implementação daBaseSamplerinterface (comoSampler,BackendSamplerou quaisquer implementações de provedor, como as presentes emqiskit-ibm-runtimeeqiskit-aer) para calcular a fidelidade de umQuantumCircuit. 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
sampleraos construtores das classes de estimativa de fase:Esse argumento é usado para fornecer uma implementação da interface
BaseSamplerinterface, comoSampler,BackendSamplerou qualquer implementação de provedor, como as presentes emqiskit-ibm-runtimeeqiskit-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
SabreSwapmelhorou significativamente o desempenho do tempo de execução devido a uma reescrita do algoritmo em Rust. -
Subclasses de pulso simbólico
Gaussian,GaussianSquare,DrageConstantforam atualizadas para instanciarSymbolicPulseem 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 siteSymbolicPulsepode identificar exclusivamente um envelope específico com o objeto de expressão simbólica definido emSymbolicPulse.envelope. -
Adicionada uma nova função,
sampled_expectation_value()que permite calcular valores de expectativa para operadores diagonais de distribuições comoCountseQuasiDistribution. Os operadores válidos para uso com essa função são:str,Pauli,PauliOp,PauliSumOp, eSparsePauliOp. -
A
SamplingVQEque é otimizada para hamiltonianos diagonais e aproveita a primitivasampler. AQAOAtambém foi adicionada uma classe que é subclasse deSamplingVQE.Para usar o novo
SamplingVQEcom 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.eigenvalueObserve que os operadores auxiliares avaliados são agora obtidos por meio do campo
aux_operators_evaluatednos 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_eigenvaluesnão é mais um campo válido. -
Foi adicionado um novo argumento de palavra-chave
atolao métodoSparsePauliOp.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
PassManagerde um pacote externo em um estágio específico como parte dotranspile()ou aStagedPassManagersaída degenerate_preset_pass_manager(),level_0_pass_manager(),level_1_pass_manager(),level_2_pass_manager(), elevel_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-chaveinit_method,layout_method,routing_method,translation_method,optimization_methodescheduling_methodemtranspile()egenerate_preset_pass_manager(). Uma lista completa dos nomes dos plug-ins atualmente instalados pode ser encontrada com a funçãolist_stage_plugins()função. Para criar plug-ins, consulte a documentação do móduloqiskit.transpiler.preset_passmanagers.pluginque inclui um guia para a criação de plug-ins de estágio. -
O
transpile()tem dois novos argumentos de palavra-chave,init_methodeoptimization_method, que são usados para especificar plug-ins alternativos a serem usados nos estágiosiniteoptimization, respectivamente. -
A classe
PassManagerConfigtem dois novos atributos,init_methodeoptimization_method, além de argumentos de palavras-chave correspondentes nos métodos do construtor. Eles representam os plug-insiniteoptimizationespecificados 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étodostep()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
GradientDescentpara ser uma subclasse deSteppableOptimizer. -
O método
subset_fitteré adicionado à classeTensoredMeasFitterclasse. 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 oTensoredMeasFitterseja 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()ougenerate_preset_pass_manager()com argumento de palavra-chaveoptimization_level=1). Agora é possível construir um circuito comofrom 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_methodsão "trivial" e "dense". Pararouting_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 parascheduling_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_gatesportranspile(). -
As seguintes passagens do transpilador foram ensinadas a entender as construções de fluxo de controle na forma de
ControlFlowOpinstruções em um circuito:Relacionado ao layout
ApplyLayoutDenseLayoutEnlargeWithAncillaFullAncillaAllocationSetLayoutTrivialLayoutVF2LayoutVF2PostLayout
Relacionado com o roteamento
Relacionado com tradução
BasisTranslatorContainsInstructionGatesInBasisUnitarySynthesisUnroll3qOrMoreUnrollCustomDefinitionsUnroller
Relacionado à otimização
BarrierBeforeFinalMeasurementsDepthFixedPointSizeOptimize1qGatesDecompositionCXCancellationRemoveResetInZeroState
Esses passes são mais comumente usados por meio dos gerenciadores de passes predefinidos (aqueles usados internamente pelo
transpile()egenerate_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
TrotterQRTEque implementa a interfaceRealTimeEvolverque usa umqiskit.primitives.BaseEstimatorpara realizar o cálculo. Essa nova classe substitui a classeqiskit.algorithms.TrotterQRTEanteriormente disponível (que será descontinuada e posteriormente removida em versões futuras) que usava umBackendouQuantumInstancepara realizar o cálculo. -
DAGCircuit.substitute_node_with_dag()agora aceitapropagate_conditioncomo 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 comoFalse, 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âmetrowires, 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_eigensolverspara incluir interfaces para algoritmos habilitados para primitivas.VQEfoi 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.eigenvalueObserve que os operadores auxiliares avaliados são agora obtidos por meio do campo
aux_operators_evaluatednos 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_eigenvaluesnão é mais um campo válido.
Notas da Atualização
-
Para
Targetque contenham apenas operações de 2 qubits definidas globalmente, sem quaisquer restrições de conectividade, o retorno do métodoTarget.build_coupling_map()agora retornaráNoneem vez de um objetoCouplingMapque contémnum_qubitsnós e nenhuma borda. Essa alteração foi feita para refletir melhor as restrições reais de conectividade do backendTargetporque, nesse caso, não há restrições de conectividade no backend que está sendo modelado peloTargete não uma falta de conectividade. Se, por algum motivo, você desejar o comportamento anterior, poderá reproduzi-lo verificando um retornoNonee 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
entanglementno construtor para os objetosRealAmplitudeseEfficientSU2foi alterado de"full"para"reverse_linear". Essa alteração foi feita porque o circuito de saída é equivalente, mas usa apenas em vez deCXGategates. Se você desejar o padrão anterior, poderá definir explicitamenteentanglement="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ânciaScheduleBlocké chamada por esse método, ele cria internamente uma instânciaReferenceno contexto atual e atribui imediatamente o programa chamado à referência. Assim, a instruçãoCallnão é mais gerada. Junto com essa alteração, é proibido chamar blocos diferentes com o mesmo argumentoname. 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
tweedledumse 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çotweedledumàs dependências do seu pacote.tweedledumnã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 dotweedledum, todas as funcionalidades dependentes continuarão a funcionar. -
O atributo
._layoutdo objetoQuantumCircuitfoi alterado do armazenamento de um objetoLayoutpara armazenar uma classe de dados com 2 atributos,initial_layoutque contém um objetoLayoutpara o layout inicial definido durante a compilação einput_qubit_mappingque 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 dotranspile()portanto, a alteração está sendo documentada, caso você dependa dela. Se você tiver um caso de uso para o atributo_layoutque 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, eShiftFrequencyagora gerarão um erroPulseErrorse o valor passado pelo argumentochannelnão for uma instância dePulseChannel. 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çãoplot_distribution()para gerar um gráfico equivalente. Por exemplo, o comportamento anterior deplot_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.builderinlineepadforam removidos. Eles foram descontinuados pela primeira vez no Terra 0.18.0 (julho de 2021). Não há como substituir o siteinline; basta escrever os pulsos no escopo que o contém. O gerenciador de contextopadnão teve efeito desde que foi descontinuado. -
A saída da passagem do
SabreSwap(inclusive quandooptimization_level=3ourouting_methodoulayout_methodsão definidos como'sabre'ao chamartranspile()) 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 passagemSabreSwapem 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 oqiskit.qpypara salvar o circuito e depois carregá-lo usando a versão atual. -
O comportamento
Layout.add()quando não se especifica umphysical_bitfoi alterado em relação às versões anteriores. Nas versões anteriores, um novo bit físico era adicionado com base no comprimento doLayoutobjeto. Por exemplo, se você tiver umLayoutcom os bits físicos 1 e 3, chamadas sucessivas paraadd()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 dissoLayout.add()adicionará primeiro todos os bits físicos ausentes entre 0 e o bit físico máximo contido noLayout. 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 aoLayout. 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 , 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 chamarLayout.add(). -
O método obsoleto do atributo
SparsePauliOp.tablefoi removido. Ele foi originalmente descontinuado no Qiskit Terra 0.19. Em vez disso, deve ser usado o métodopaulis(). -
O suporte para retornar um
PauliTableda funçãopauli_basis()foi removido. Da mesma forma, o argumentopauli_listna funçãopauli_basis()que foi usado para mudar para umPauliList(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, eFakeSingaporeV2não contêm mais os payloads padrão de pulso. Isso significa que, para asBackendV1o métodoBackendV1.defaults()e a simulação de pulso viaBackendV1.run()não estão mais disponíveis. ParaBackendV2a propriedadecalibrationpara instruções na seçãoTargetnã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 oqpypara transferir circuitos de versões mais antigas do qiskit para a versão atual. -
isinstanceverifique com as classes de pulsoGaussian,GaussianSquare,DrageConstantserá 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 siteSymbolicPulse.pulse_typedeve 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.QiskitIndexErrorfoi 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
epsilonefactrpara o construtor da classeL_BFGS_Bforam 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 argumentoftol. 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=1ouoptimization_level=2comtranspile()ougenerate_preset_pass_manager()e a saída delevel_1_pass_manager()elevel_2_pass_manager()agora usarãoSabreLayouteSabreSwappor padrão, em vez dos padrões anterioresDenseLayouteStochasticSwap. Essa alteração foi feita para melhorar a qualidade de saída do transpilador, a combinação deSabreLayouteSabreSwapnormalmente resultam em menosSwapGateobjetos sendo inseridos no circuito de saída. Se você quiser usar as passagens padrão anteriores, poderá definirlayout_method='dense'erouting_method='stochastic'emtranspile()ougenerate_preset_pass_manager()para aproveitarDenseLayouteStochasticSwaprespectivamente. -
O uso implícito de
approximation_degree!=1.0por padrão na funçãotranspile()quandooptimization_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 siteapproximation_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 doUnitaryGatesão aproximadas até as taxas de erro das instruções nativas do backend de destino, poderá definir explicitamenteapproximation_degree=Noneao chamartranspile()comoptimization_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) emL_BFGS_Bde 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
ProbDistributioneQuasiDistributionpara armazenar a informação do número de bits se forem fornecidas cadeias de bits sem o prefixo “0b”.ProbDistribution.binary_probabilities()eQuasiDistribution.binary_probabilities()usar o número de bits armazenado como o valor padrão do número de bits. -
RZXCalibrationBuildereRZXCalibrationBuilderNoEchoforam 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 argumentoverboseque controla se as passagens avisam quando isso ocorre. Severbose=Trueestiver definido, o pass emitirá um aviso ao usuário quando encontrar uma sequência não ECR. -
O módulo de visualização
qiskit.visualizationpassou 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_functioneBooleanExpressiondiretamente deqiskit.circuitestá obsoleto. Isso faz parte da mudança para tornar otweedledumuma dependência opcional em vez de um requisito completo. Em vez disso, você deve importar esses nomes deqiskit.circuit.classicalfunction. -
Os módulos
qiskit.algorithms.factorizerseqiskit.algorithms.linear_solversestã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çãorandom_pauli_list()deve ser usada. -
A função do módulo de pulso
qiskit.pulse.utils.deprecated_functionalityestá obsoleta e será removida em uma versão futura. Essa era uma função essencialmente interna. A mesma funcionalidade é fornecida pelo siteqiskit.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__()eBaseEstimator.__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,observableseparametersno construtor foi preterido.circuitseobservablespodem ser transmitidos pelos métodosrun.runos métodos não são compatíveis comparameters. Os usuários precisam recorrer aos valores dos parâmetros por conta própria. -
O argumento não utilizado
qubit_channel_mappingnoRZXCalibrationBuildereRZXCalibrationBuilderNoEchoforam 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()ePauliList.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()eQuantumCircuit.prepare_state()que fazia com que eles não aceitassem um únicoQubitcomo 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 queQuantumCircuit.if_test()eInstructionSet.c_if()fazem. -
Os
DAGCircuitmétodosdepth(),size()eDAGCircuit.count_ops()anteriormente retornavam silenciosamente resultados que tinham pouco ou nenhum significado se o fluxo de controle estivesse presente no circuito. Odepth()esize()agora lançam corretamente um erro nesses casos, mas têm um novo argumento de palavra-chaverecursepara permitir o cálculo de um valor de proxy, enquantocount_ops()por padrão, recursará os blocos e contará as operações dentro deles. -
Foi corrigido um problema na passagem do
DenseLayoutpassagem do transpilador em que qualquer objetoQubit(ou seja, não faziam parte de um objetoQuantumRegister) que faziam parte de umQuantumCircuitnão seriam incluídos na saídaLayoutque 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 dotranspile()e reverter corretamente a permutação de qubit causada pelo layout em todos os casos. Anteriormente, se seu circuito transpilado usasseQubitobjetos, váriosQuantumRegisterou um único objetoQuantumRegistercom um nome diferente de"q", o construtor teria falhado ao criar umOperatordo 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 classePauliListclasse 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
GateDirectionpassagem do transpilador para o arquivoCZGate. 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
mplelatex, quando a configuração da opçãoidle_wirescomo False (Falso) quando havia umbarrierno circuito fazia com que as gavetas falhassem. Corrigido #8313 -
Foi corrigido um problema no
circuit_drawer()eQuantumCircuit.draw()com o métodolatex, no qual umOSErrorseria 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
FlowControllerdentro de outro em umPassManagerpoderia anteriormente fazer com que algumas passagens do transpilador fossem "esquecidas" durante a transpilação, se as passagens retornassem um novoDAGCircuitem vez de alterar sua entrada. OsFlowControllers aninhados agora afetarão a transpilação corretamente. -
Comparando
QuantumCircuiteDAGCircuits para igualdade era anteriormente não determinística se os circuitos contivessem mais de um registro do mesmo tipo (por exemplo, dois ou maisQuantumRegisters), às vezes retornandoFalsemesmo 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çõesUnitaryGateque não afetam todos os qubits sobre os quais são definidos. Corrigido #8224. -
Havia dois bugs na gaveta de circuitos do site
textque foram corrigidos. Eles apareceram quandovertical_compressionfoi definido comomedium, 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
UnitarySynthesisem que um circuito com portas de 1 qubit e uma entradaTargetàs vezes falhava em vez de processar o circuito como esperado. -
A passagem do
GateDirectionagora respeitará os valores disponíveis para os parâmetros de porta ao lidar com portas parametrizadas com umTarget. -
Foi corrigido um problema na classe
SNOBFITquando um erro interno era gerado durante a execução do métodominimize()se nenhum limite de entrada fosse especificado. Agora, isso é verificado no momento da chamada para gerar rapidamente umValueErrorse os limites necessários estiverem faltando naminimize()chamada. Correções #8580 -
Foi corrigido um problema no callable de saída do método
get_energy_evaluation()do métodoVQDagora chamará corretamente ocallbackespecificado 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 comreverse_bits=Trueem um circuito sem bits clássicos, o que causava a emissão de um aviso potencialmente confuso sobrecregbundle. Corrigido #8690 -
O exportador do OpenQASM 3 (
qiskit.qasm3) agora tratará corretamente os built-ins do OpenQASM (comoresetemeasure) que têm uma condição clássica aplicada porc_if(). Anteriormente, a condição teria sido ignorada. -
Foi corrigido um problema com a classe
SPSAem 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 detranspile()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 opcionalprefixda 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 quandostate_drawer()é chamado. Corrigido #8169. -
GradientDescentagora 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 oStandardScalerpara dimensionar os dados antes de ajustar o modelo se o parâmetronormalizeestiver definido comoTrue.
Aer 0.11.0
Nenhuma mudança
IBM 0.19.2
Nenhuma mudança