Qiskit SDK 2.2 notas de versão
2.2.3
Prelúdio
O Qiskit 2.2.3 corrige um bug que foi introduzido pelo Qiskit 2.2.2 ao usar o run() método em um PassManager para mais de um circuito.
Notas da Atualização
ConsolidateBlocksagora lê umaPropertySetchaveConsolidateBlocks_qubit_mapna entrada. Esta chave e seu valor não são públicos e não devem ser lidos ou gravados por outros passes.
Correções de bugs
- Reutilização fixa da mesma
ConsolidateBlocksinstância em vários circuitos, incluindo chamadas para mais de umtranspile()circuito e sem paralelização baseada em processos. Um bug introduzido no Qiskit 2.2.2 fazia com que o passe entrasse em pânico ou produzisse resultados inválidos se a mesma instância fosse reutilizada em circuitos diferentes.
2.2.2
Prelúdio
O Qiskit 2.2.2 é uma versão de correção de bugs para a série de versões secundárias v2.2.
Correções de bugs
-
Corrigida a implementação do
__deepcopy__()emQuantumCircuitque não copiava profundamente os parâmetros do circuito. Como consequência, a mutação de umBoxOpem um circuito copiado não afeta mais o circuito original. -
Corrigido um problema na passagem
Optimize1qGatesDecompositionquando a passagem é inicializada com umaTargetcontendo portas de 1 qubit com parâmetros de ângulo fixos. Anteriormente, a passagem poderia gerar portas não incluídas no destino, pois não verificava se as portas no destino suportavam valores de parâmetros arbitrários. Corrigido #14743. -
Corrigido comportamento incorreto na
BasisTranslatorpassagem em que um portão multi-qubit dentro de umControlFlowOpbloco rastreava usando seus índices de qubit locais em vez de usar os índices absolutos do circuito de origem. -
A passagem do
ConsolidateBlockstranspiler agora avaliará corretamente se um determinado gate é compatível com o hardware enquanto recursiona em operações de fluxo de controle. -
qpy.dump()agora pode lidar com a gravação em.gzarquivos abertos usando o módulo dagzipbiblioteca padrão com versões QPY 16 ou superiores. Consulte o número 15157 para obter mais detalhes. -
Corrigido o método
MCPhaseGate.inverse()para preservar os estados de controle dos portões controlados abertos ao calcular seus inversos. -
ConsolidateBlocksagora retornará uma exceção de espaço Python em vez de entrar em pânico quando detectar uma análise inválida ou desatualizada nas chavesblock_listPropertySetlegadasrun_listou. Corrigido #14646. -
Optimize1qGatesDecompositionagora irá gerar umTranspilerErrorem vez de um panic do Rust-space ao tentar executar em um circuito que é muito grande para oTarget. Corrigido #15116. -
Os passes de programação,
ALAPScheduleAnalysiseASAPScheduleAnalysis, agora lidarão corretamente com circuitos sem operações. Anteriormente, eles levantaram uma alegaçãoTranspilerErrorfalsa de que “não foram fornecidas durações”. Corrigido #15145. -
Corrigida uma falha na caixa de texto do circuito, que podia ocorrer quando blocos de circuito dentro de operações de fluxo de controle eram definidos em registros diferentes dos do circuito externo. Essa situação pode ocorrer, por exemplo, ao anexar
ControlFlowOpoperações diretamente ou para circuitos após a transpilagem.
2.2.1
Prelúdio
O Qiskit 2.2.1 é uma pequena versão de correção que corrige vários erros identificados na versão 2.2.0.
Notas sobre a atualização do Transpiler
- Os limites máximos de chamadas e testes para a execução de correspondência exata de
VF2PostLayoutemoptimization_level=3foram reduzidos para evitar tempos de execução excessivos para circuitos de teste altamente simétricos mapeados para grandes mapas de acoplamento.
Correções de bugs
-
DAGCircuit.apply_operation_back(),apply_operation_back()e agoracircuit_to_dag()adicionará novas arestas em uma ordem determinística. O comportamento anterior poderia fazer com que certas passagens do transpiler (comoSabreSwap) percorressem o DAG em ordens não determinísticas. -
DAGCircuit.apply_operation_front()não é mais possível inserir loops próprios inválidos ao lidar com nós que incluem condições clássicas. -
Corrigido um problema com
pickleo suporte para oSabreSwapqual umaSabreSwapinstância apresentava erro ao ser pickled após a execução doSabreSwap.run()método. Corrigido #15071. -
Corrigido um problema em que
is_unitary()não respeitava adequadamente os valores de tolerância de entrada ao verificar se um operador era unitário. O método agora usa corretamente os parâmetrosrtolfornecidosatole ao simplificar o operador e verificar se ele é igual à identidade. Isso corrige o problema #14107.
2.2.0
Prelúdio
O Qiskit v2.2 acrescenta vários aprimoramentos à API C e ao transpilador, além de muitos outros aprimoramentos e correções de bugs. Os principais recursos dessa nova versão são:
- Função de transpilagem da API C: A API C agora inclui uma função para transpilagem de um circuito quântico:
qk_transpile(). Esta função é equivalente à Python funçãotranspile()para um contexto C independente.- Passagem de transformação Litinski: Uma nova passagem de
LitinskiTransformationtransformação que implementa a transformação descrita arXiv:1808.02892. Essa passagem é normalmente usada na compilação para arquiteturas tolerantes a falhas.- Suporte a limites angulares para alvos: A
Targetclasse agora suporta a especificação de limites para os valores permitidos para operações parametrizadas adicionadas ao alvo. Quando uma instrução é adicionada aoTargetvocê pode adicionar o argumento opcional ângulo_limites para especificar os limites superior e inferior para portas de rotação parametrizadas. Uma nova passagem doWrapAnglestranspiler foi adicionada para aplicar as restrições de ângulo como parte de um pipeline de transpilagem.
A série de versões v2.2 é a última série de versões secundárias com suporte Python 3.9. A versão mínima compatível do Rust usada para criar o Qiskit a partir da fonte agora é o Rust v1.85, aumentado de 1.79 em 2.1.0. Para obter mais informações sobre as alterações acima e outras alterações feitas, consulte as notas de versão abaixo e examine a documentação atualizada.
Recursos da API C
-
Adição de novas funções de passagem de transpilador autônomo à API C. Essas funções recebem um
QkCircuitpara executar a passagem e são equivalentes a chamar uma passagem instanciada. -
O
QkTargettipo agora pode representar alvos que suportam tiposQkGateparametrizados que aceitam qualquer valor de parâmetro. Anteriormente, esses portões só podiam ser adicionados ao alvo com um valor de ângulo fixo suportado pelo uso deqk_target_entry_new_fixed()para criar oQkTargetEntry. Agora, aqk_target_entry_new()função pode ser usada com portas parametrizadas. Quando usada com portas parametrizadas, esta função indica que a porta no destino suporta qualquer valor para todos os parâmetros da porta. Por exemplo:#include <qiskit.h> QkTarget *target = qk_target_new(5); QkTargetEntry *rz_entry = qk_target_entry_new(QkGate_RZ); for (uint32_t i = 0; i < 5; i++) { uint32_t qargs[1] = {i}; qk_target_entry_add_property(rz_entry, qargs, 1, 1.2e-6, 1.3e-9); } qk_target_add_instruction(target, rz_entry); // Clean up after using target qk_target_free(target);Isso cria um alvo de 5 qubits que aceitará uma porta RZ em qualquer qubit com qualquer valor de parâmetro suportado por essa porta.
-
Adicionado
qk_obs_apply_layout()para aplicar novos layouts de qubits a umQkObsobservável. Esta função recebe o observável, os novos índices de qubits e um número de qubits de saída. É importante ressaltar que essa função permite aplicar layouts de transpile, geralmente fornecidos como umaQkTranspileLayoutpassagem de transpiler, a um observável. Por exemplo:// get the number of output qubits -- transpile_layout is a QkTranspileLayout* uint32_t num_output_qubits = qk_transpile_layout_num_output_qubits(transpile_layout); // get the layout including the ancillas (hence the ``false`` in the function call) uint32_t *layout = malloc(sizeof(uint32_t) * num_output_qubits); qk_transpile_layout_final_layout(transpile_layout, false, layout); // apply the layout -- obs is a QkObs* int exit = qk_obs_apply_layout(obs, layout, num_output_qubits); // free the layout array free(layout); -
Adicionada uma nova função
qk_transpile()à API C do Qiskit. Esta função é usada para transpilar circuitos quânticos em um contexto C independente, sem usar Python. Este é o último componente importante necessário na API C para fluxos de trabalho típicos de execução de hardware usando o Qiskit.Essa função espelha os gerenciadores de passagem predefinidos que são usados para o transpilador Python, exceto por algumas passagens e a funcionalidade é ignorada se não for relevante para circuitos construídos usando a API C. Isso torna a função adequada apenas para contextos C autônomos.
-
Adição de um novo tipo
QkTranspileLayoutà API do C. Esse tipo é usado para raciocinar sobre as permutações causadas pelo transpilador.
Recursos dos circuitos
-
Um novo método é fornecido para garantir que um circuito seja definido sobre qubits físicos,
QuantumCircuit.ensure_physical()com os índices de qubits referindo-se a qubits físicos. Consulte a nova discussão sobre representações abstratas e de circuitos físicos na documentação para obter mais detalhes sobre os conceitos de metadados. Os conceitos de circuitos “abstratos” e “físicos” não são novidade para o Qiskit, apenas a documentação explícita. -
A classe
Durationganhou uma nova varianteps, que pode ser usada para representar uma duração em picossegundos. -
Melhorado
PauliEvolutionGate.control(),PauliEvolutionGate.power()ePauliEvolutionGate.inverse()para retornar representações mais eficientes em termos de aPauliEvolutionGate. Para calcular as versões controladas e exponencializadas do portão de evolução, essa mudança leva a circuitos significativamente mais rasos e contagens de portões mais baixas em comparação com os mecanismos genéricos usados anteriormente. A decomposição inversa não muda, mas agora é gerada de forma mais eficiente e permite melhores otimizações do compilador. -
Um novo método de
ParameterExpression.bind_all()caminho rápido foi adicionado para dar suporte ao caso de uso de vinculação de muitas instânciasParameterExpressiondiferentes a valores numéricos usando o mesmo dicionário de mapeamentos. O métodobind()existente tem uma grande quantidade de sobrecarga e alocações desnecessárias, uma vez que sempre retorna umParameterExpressionpara consistência de digitação.
OpenQASM Características
-
Adicionado suporte parcial para
defcalsímbolos no exportador OpenQASM3. Isso permite que pacotes downstream exportem instruções personalizadas que operam tanto em bits quânticos quanto clássicos usandoqiskit.qasm3.dumps(). Os usuários agora podem definir instruções personalizadas (por exemplo, umaCustomMeasureque atua em um qubit e retorna um bit clássico) e especificar seu comportamento usandoDefcalInstruction. Esses defcals são passados para o exportador por meio doimplicit_defcalsargumento emqiskit.qasm3.dumps().Por exemplo:
from qiskit.circuit import Instruction, QuantumCircuit from qiskit.qasm3 import dumps from qiskit.qasm3.exporter import DefcalInstruction, types custom_measure = Instruction("measure_2", 1, 1, []) qc = QuantumCircuit(1, 1) qc.h(0) qc.append(custom_measure, [0], [0]) qc.measure(0, 0) defcals = { "measure_2": DefcalInstruction("measure_2", 0, 1, types.Bool()), } out_qasm = dumps(qc, implicit_defcals=defcals) print(out_qasm)O resultado seria a seguinte cadeia de caracteres válida OpenQASM3 :
OPENQASM 3.0; bit[1] c; qubit[1] q; h q[0]; c[0] = measure_2 q[0]; c[0] = measure q[0];Essa abordagem pressupõe que a definição da gramática para o defcal seja fornecida externamente (por exemplo, em um arquivo de cabeçalho), embora esse arquivo não seja estritamente necessário para que o exportador funcione.
-
As funções
qasm3.loads()eqasm3.load()agora têm um argumento extra chamadonum_qubits. Se fornecidas, as funções retornarão circuitos que terão qubits iguais anum_qubits. Se não for fornecido, o circuito retornado terá qubits iguais ao índice máximo observado no circuito serializado. Consulte o número 14435 para obter mais detalhes
Recursos do QPY
-
Adicionada uma configuração chamada
min_qpy_versionno arquivo de configuração do usuário. Quando definido, define a versão mínima permitida do QPY paraqpy.load(). Se a versão do formato de um arquivo QPY for inferior à configuraçãominimum_qpy_version``minimum_qpy_version, será gerada uma exceção. -
Introduziu o formato QPY versão 16. Essa nova versão introduz uma nova tabela de início de circuito no cabeçalho do arquivo, que contém os deslocamentos de bytes do início de cada circuito em um arquivo QPY. Isso permite um carregamento potencialmente mais eficiente de circuitos a partir de arquivos QPY e uma implementação do Rust potencialmente multi-threaded no futuro. Além disso, a nova versão do formato adiciona suporte para a nova variante
DURATIONde picossegundos.
Recursos de informação quântica
-
Adicionados os
PauliLindbladMap.drop_qubits()métodosPauliLindbladMap.keep_qubits()e para rastrear subsistemas fora dos mapas de Pauli Lindblad. -
Adicionados os métodos
QubitSparsePauli.to_pauli()eQubitSparsePauliList.to_pauli_list(), que convertem os objetos esparsos nas versões densas correspondentes,PauliePauliList, respectivamente. -
Adicionadas as
PhasedQubitSparsePauliclassesPhasedQubitSparsePauliListe. Essas classes representam um único operador de Pauli e uma lista de operadores de Pauli, respectivamente armazenados em formato qubit-esparso. Essas classes são muito semelhantes aQubitSparsePaulieQubitSparsePauliList, exceto que contêm informações adicionais sobre a fase. -
Adicionado o método
QubitSparsePauliList.to_dense_array(). Isso retorna a lista como uma matriz de inteiros com os valores dePauli.
Recursos de síntese
-
Adicionado novo algoritmo de síntese para
ModularAdderGateque não requer qubits auxiliares e tem melhor contagem CX em comparação comadder_qft_d00(): -
Adicionado um novo algoritmo de síntese,
synth_mcx_noaux_hp24(), paraMCXGateque não requer quaisquer qubits auxiliares. Este método produz um número linear, em vez de quadrático, de portas CX, em comparação com o algoritmosynth_mcx_noaux_v24()existente. Em particular, o novo método é melhor quando o número de qubits de controle é superior a cinco. O algoritmo baseia-se no artigo “Compiling Conditional Quantum Gates without Using Helper Qubits” (Compilando portas quânticas condicionais sem usar qubits auxiliares), de Huang e Palsberg ( https://dl.acm.org/doi/10.1145/3656436 ). -
Melhorou a
qs_decomposition()função que era originalmente baseada em Shende et. al. (https://arxiv.org/abs/quant-ph/0406176). O novo método de síntese baseia-se em Krol e Al-Ars ( https://arxiv.org/abs/2403.13692 ) e reduz o número total deCXGates de um unitário n-qubit geral por um eCXGates. Com a decomposição aprimorada, uma unidade geral de 3 qubits pode ser decomposta usando 19CXGates (em vez de 20). -
Adicionado
synth_mcmt_xgate()para sintetizar o gate multicontrolo e multialvo quando o gate base éXGate. Possui uma decomposição em número linear de portas CX e 0 qubits auxiliares, juntamente com o plug-in de síntese deMCMTSynthesisXGatealto nível.
Recursos do Transpiler
-
Adicionado novo plugin de síntese de alto nível para sintetizar um
ModularAdderGate:ModularAdderSynthesisV17, com base emadder_modular_v17().
O também
ModularAdderSynthesisDefaultfoi atualizado para seguir a seguinte sequência de sintetizadores somadores modulares:"ModularAdder.qft_d00"quando o número de qubits é ,"ModularAdder.modular_v17"em todos os outros casos. -
Adicionada uma nova passagem do
LitinskiTransformationtranspiler que implementa a transformação descrita em arXiv:1808.02892.A entrada para a passagem é um circuito com portas Clifford e portas de rotação RZ de qubit único, e a saída é um circuito com rotações Pauli de múltiplos qubits (implementadas como
PauliEvolutionGateportas) seguidas por portas Clifford. A passagem gera umaTranspilerErrorexceção se o circuito contiver portas não suportadas.A passagem suporta todos os portões Clifford na lista retornada por
get_clifford_gate_names(), ou seja,["id", "x", "y", "z", "h", "s", "sdg", "sx", "sxdg", "cx", "cz", "cy", "swap", "iswap", "ecr", "dcx"]. A lista de rotações RZ suportadas é["t", "tdg", "rz"](convertemos automaticamente portas T e Tdg em rotações RZ).Além disso, o
LitinskiTransformationconstrutor aceita um argumentofix_clifford. QuandoFalse(não padrão), o circuito retornado contém apenasPauliEvolutionGateportas, com as portas Clifford finais omitidas. Observe que, neste caso, os operadores dos circuitos original e sintetizado geralmente não serão equivalentes.Por exemplo:
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import LitinskiTransformation from qiskit.quantum_info import Operator # The following quantum circuit consists of 5 Clifford gates # and two single-qubits RZ-rotation gates (note that Tdg is # an RZ-rotation). qc = QuantumCircuit(2) qc.cx(0, 1) qc.rz(0.1, 0) qc.cz(0, 1) qc.tdg(1) qc.h(1) qc.s(1) qc.cz(1, 0) # The transformed circuit consists of two PauliEvolution gates # and the same Clifford gates as in the original circuit. qct = LitinskiTransformation()(qc) # The circuits before and after the transformation are equivalent assert Operator(qc) == Operator(qct) -
Adicionado um novo plug-in de síntese de
MCXSynthesisNoAuxHP24alto nível paraMCXGateobjetos. Além disso, o plug-in de sínteseMCXSynthesisDefaultpadrão paraMCXGateobjetos foi atualizado para sempre escolher o melhor método de síntese, dependendo do número disponível de qubits auxiliares. -
Adicionado suporte para especificar limites de
Targetângulo nas instruções. Antes desta versão,Targetera possível especificar que uma operação que recebia um parâmetro permitiria qualquer valor válido ou um valor específico. Por exemplo, seRZGate(Parameter("theta"))fosse adicionado ao alvo, isso indicaria queRZGatequalquer valor para theta seria permitido. SeRZGate(math.pi)fosse adicionado ao alvo, isso indicariaRZGateque apenas é o único valor permitido no alvo. Esse novo recurso permite restringir os ângulos permitidos a qualquerfloatvalor entre um limite inclusivo. Por exemplo, você pode adicionarRZGate(math.pi)a umTargete restringir o valor do ângulo entre os valores 0 e .Existem vários métodos disponíveis para trabalhar com os limites de ângulo no alvo. O primeiro é
Target.add_instruction()que possui um novo argumentoangle_boundsde palavra-chave usado para adicionar um limite angular a uma instrução noTarget. Para trabalhar com limites angulares, você também precisará registrar uma função de retorno de chamada no registroWRAP_ANGLE_REGISTRYglobal que informará ao transpilador eWrapAnglespassará como ajustar os portões para limites angulares. A função de retorno receberá uma lista de valoresfloatarbitrários representando os ângulos do portão do circuito, bem como os índices de qubit no circuito em que o portão estava operando, e retornará umDAGCircuitque representa um circuito equivalente para o portão com esse ângulo, mas respeitando os limites de ângulo e outrasTargetrestrições. Por exemplo:import math from qiskit.dagcircuit import DAGCircuit from qiskit.transpiler import Target from qiskit.transpiler.passes.utils.wrap_angles import WRAP_ANGLE_REGISTRY target = Target(num_qubits=1) target.add_instruction(RZGate(Parameter("theta")), angle_bounds=[(-math.pi, math.pi)]) def callback(angles: List[float], qubits: List[int]) -> DAGCircuit: """Callback function to wrap RZ gate angles Args: angles: The list of floating point parameter values for the instance of RZGate in the circuit qubits: The physical qubit indices that this gate is operating on Returns: The DAGCircuit of the equivalent circuit""" angle = angles[0] dag = DAGCircuit() dag.add_qubits([Qubit()]) if angle > 0: divisor = math.pi else: divisor = -math.pi gate_counts = int(angles[0] // divisor) rem = angles[0] % divisor for _ in range(gate_counts): dag.apply_operation_back(RZGate(math.pi), [dag.qubits[0]], check=True) dag.apply_operation_back(rem, [dag.qubits[0]], check=True) WRAP_ANGLE_REGISTRY.add_wrapper("rz", callback)Target.has_angle_bounds()pode ser usado para verificar se há limites de ângulo definidos no alvo eTarget.gate_has_angle_bounds().Se você deseja aplicar os limites de ângulo de um alvo a quaisquer portas em um circuito, a passagem
WrapAnglesdo transpiler deve ser usada para fazer isso. -
Adicionado um novo kwarg
check_angle_boundsao métodoTarget.instruction_supported(). Quando definido comoTrue(padrão), o método verificará se o especificadoparameterstambém está em conformidade com quaisquer limites de ângulo que possam existir para a instrução que está sendo consultada. -
Adicionada uma nova passagem do
WrapAnglestranspiler, que é usada para aplicar restrições de ângulo em portas noTarget. Se umTargettiver limites de ângulo definidos, esta passagem analisará todos os parâmetros para as portas no circuito e verificará isso em relação aos limites especificados no alvo. Por exemplo, se um alvo contiver um gate personalizado com limites de ângulo, a passagem decomporá esse gate em um gate que esteja em conformidade com os limites:from qiskit.circuit import Gate, Parameter, QuantumCircuit, Qubit from qiskit.dagcircuit import DAGCircuit from qiskit.transpiler import Target, WrapAngleRegistry from qiskit.transpiler.passes import WrapAngles class MyCustomGate(Gate): def __init__(self, angle): super().__init__("my_custom", 1, [angle]) param = Parameter("a") circuit = QuantumCircuit(1) circuit.append(MyCustomGate(6.0), [0]) target = Target(num_qubits=1) target.add_instruction(MyCustomGate(param), angle_bounds=[(0, 0.5)]) def callback(angles, _qubits): angle = angles[0] if angle > 0: number_of_gates = angle / 0.5 else: number_of_gates = (6.28 - angle) / 0.5 dag = DAGCircuit() dag.add_qubits([Qubit()]) for _ in range(int(number_of_gates)): dag.apply_operation_back(MyCustomGate(0.5), [dag.qubits[0]]) return dag registry = WrapAngleRegistry() registry.add_wrapper("my_custom", callback) wrap_pass = WrapAngles(target, registry) res = wrap_pass(circuit) res.draw('mpl')
-
DAGCircuitagora possui uma implementação manual de__deepcopy__(). Isso é muito mais rápido do que a implementação implícita anterior do protocolo pickle, especialmente para circuitos grandes. Isso também beneficia diretamente o desempenho da compilação ao executartranspile()ou executar os gerenciadores de passagem predefinidos retornados porgenerate_preset_pass_manager(),optimization_level=3pois o nível de otimização 3 copia internamente oDAGCircuitpara cada iteração do loop de otimização naoptimizationetapa. -
É fornecido um novo método,
DAGCircuit.make_physical(), que substitui eficientemente os qubits noDAGCircuitpelo registro canônico de qubits físicos, incluindo potencialmente a expansão. Um método semelhante também está disponívelQuantumCircuit.ensure_physical(). -
Um novo método,
DAGCircuit.structurally_equal(), pode ser usado se duasDAGCircuitinstâncias tiverem sido criadas e modificadas exatamente na mesma ordem. Este é um teste muito mais rigoroso do que a verificação padrão de equivalência semântica da==sobrecarga e pode ser usado pelos autores do transpiler-pass para verificar se suas ordens de modificação são determinísticas. -
Subclasses personalizadas de agora
BasePassManagerpodem modificar seuproperty_setatributo durante seu_passmanager_frontend()método, para inicializar propriedades iniciais. Isso proporciona simetria, já que anteriormente só era possível ler as propriedades finais durante_passmanager_backend(). -
Adicionada uma nova classe
OptimizationMetricque especifica o critério de otimização naHighLevelSynthesispassagem. Atualmente, as duas métricas suportadas são:COUNT_2Qotimiza o número de portas de dois qubits.COUNT_Totimiza o número de portas T ao fazer a transposição para um conjunto de bases Clifford+T.
O transpiler seleciona automaticamente a métrica de destino com base no conjunto de portas básicas, por exemplo, ele usará
COUNT_Tse um conjunto básico Clifford+T for detectado. No entanto, essa classe não pode ser definida manualmente no momento da execuçãotranspile()ou da execução de um gerenciador de passagem predefinido gerado porgenerate_preset_pass_manager(). -
Adicionado um novo argumento
optimization_metricao construtor para aHighLevelSynthesispassagem do transpiler que recebe umOptimizationMetricobjeto. Quando definido comoCOUNT_T, a passagem escolhe decomposições que são mais adequadas para o conjunto de portas Clifford+T. -
Os plug-ins padrão de síntese de alto nível para
ModularAdderGateeMultiplierGateproduzem melhores contagens T ao transpilá-los para o conjunto de bases Clifford+T. -
O plug-in de síntese de alto nível padrão para
MCXGateproduz melhores contagens T ao transpilando para o conjunto de bases Clifford+T, desde que pelo menos 1 qubit auxiliar esteja disponível. -
Adicionado um conjunto padrão de portas inversas para a passagem do
InverseCancellationtranspiler. Anteriormente, uma lista explícita de portas ou pares de portas a serem canceladas era um argumento obrigatório para o construtor do objeto pass. Agora, essa lista é opcional e, se nenhuma lista for fornecida, os portões inversos próprios são:e os pares inversos:
será cancelado pelo passe.
-
Adicionado um novo argumento ao
InverseCancellationconstrutor, que, quando definido comoTrue, executará a nova listarun_defaultpadrão de portas de cancelamento inverso, além de quaisquer portas personalizadas fornecidas. Isto destina-se a casos de uso em que você deseja executar um conjunto personalizado de cancelamentos inversos, além dos gates padrão. -
TranspileLayoutpossui dois novos métodos:from_property_set()ewrite_into_property_set(), que formalizam a estrutura ad hoc atual das propriedades de transpilagem e como elas são convertidas em umTranspileLayout. Isso permite que as passagens durante um pipeline de transpiler acessem o queTranspileLayoutserá, modifiquem-no na forma totalmente estruturada e, em seguida, o gravem novamente na forma canônica.Espera-se que, na versão futura 3.0 do Qiskit, o
TranspileLayout(ou algo semelhante a ele) seja um atributo direto da representação intermediária doDAGCircuittranspiler e exigido pelas passagens para manter a sincronia com o restante doDAGCircuit. -
Reativou a execução da
VF2PostLayoutpassagem do transpiler naoptimizationetapa paraoptimization_level=3com atranspile()função e os objetos gerenciadores de passagem gerados retornados pelagenerate_preset_pass_manager()função. A passagem é executadastrict_direction=Trueapós todas as otimizações físicas realizadas na etapa para tentar melhorar o layout uma última vez com o circuito de saída exato. Isso foi habilitado anteriormente no Qiskit v2.1.0, mas foi revertido em 2.1.2 devido a problemas com a implementação inicial. Esses problemas foram corrigidos e o layout será aplicado corretamente se for encontrado um melhor.
Recursos de visualização
-
Uma nova opção,
measure_arrows, foi adicionada aos backendsmpl``texte para o desenhista de circuitosqiskit.visualization.circuit_drawer()eqiskit.circuit.QuantumCircuit.draw(). Quando esta opção estiver definida comoTrue, a gaveta desenhará uma seta dameasurecaixa para os bits clássicos abaixo. Esse era o comportamento anterior nas gavetas. Se estiver definido comoFalse, nenhuma seta será desenhada e, em vez disso, o registro clássico e o bit usado pelomeasureserão indicados dentro dameasurecaixa. Isso permite quemeasureas caixas sejam empilhadas em uma camada vertical.Se nenhuma opção for definida, o padrão será
True. O usuário pode alterar o padrão no arquivo de configuração do usuário, por padrão no diretório~/.qiskit, no arquivosettings.conf. No cabeçalho[Default], um usuário pode inserircircuit_measure_arrows = Falsepara alterar o padrão.
Notas da Atualização
- A versão mínima de suporte do Rust para a criação do Qiskit a partir do código-fonte (incluindo a criação da API C em modo autônomo) foi aumentada de Rust 1.79 para Rust 1.85. Essa alteração foi necessária para permitir o uso de uma versão mais recente da biblioteca de álgebra linear Rust faer, que é usada no Qiskit. Foram identificados problemas ao executar o Qiskit no Windows com a versão anterior do faer. Esses problemas foram corrigidos na versão mais recente, mas é necessária uma versão mais recente do compilador Rust para criar a versão mais recente do faer.
Notas sobre atualização de circuitos
-
A definição do circuito de
ModularAdderGatefoi atualizada para usaradder_modular_v17(). Para obter o comportamento antigo, use a definição deadder_qft_d00()em vez disso. -
Os métodos
XGate.control(),CXGate.control(),CCXGate.control(),C3XGate.control()C4XGate.control(), eMCXGate.control()não retornam mais umAnnotatedOperationquando o argumentoannotatedé definido comoTrue, e, em vez disso, retornam o mesmo explícitoMCXGateque se obteria quandoannotatedéFalse. Isso é consistente com a forma como o argumentoannotatedé usado em toda a biblioteca de circuitos padrão, onde geralmente evitamos introduzir umAnnotatedOperationquando uma classe de porta nativa já está disponível. Na prática, isso leva a decomposições mais eficientes de portas com anotação de controle na família MCX.
Notas sobre a atualização da API C
-
A maioria dos usos de
uintptr_tfoi alterada parasize_t. Especificamente, os seguintes usos foram alterados:QkOpCount.countQkOpCounts.lenQkObsTerm.len- O tipo de retorno de
qk_circuit_num_instructions(). - O
indexargumento emqk_circuit_get_instruction(). - O
boundariesargumento emqk_obs_new(). - Os tipos de retorno de
qk_obs_num_terms(),qk_obs_len(), eqk_obs_boundaries(). - O tipo de retorno de
qk_target_entry_num_properties(), eqk_target_num_instructions().
Essa alteração foi necessária porque a ferramenta usada para gerar os arquivos de cabeçalho C a partir do código rust do Qiskit, cbindgen, estava usando
uintptr_tpor padrão em locais ondesize_tse alinhava com mais precisão ao uso de tipos no Rust. Essa alteração foi feita para deixar mais claro como os valores na API C devem ser usados.
Notas de atualização do QPY
- A versão padrão do QPY emitida pelo agora
qpy.dump()é a versão 16 do formato QPY. Se você precisar de uma versão de formato diferente, pode usar oversionargumento para especificar uma versão de formato anterior.
Notas sobre a atualização das informações quânticas
SparsePauliOp.assign_parameters()agora definirá o tipo de dados dacoeffsmatriz de saída comocomplexse todos os parâmetros estiverem totalmente vinculados a valores numéricos.
Notas sobre a atualização da síntese
- Os valores padrão dos argumentos
opt_a1eopt_a2agoraqs_decomposition()sãoopt_a1 = Noneeopt_a2 = None. Os novos padrões escolherão o valor ideal com base no fato de a unidade de entrada para omatargumento ser controlada ou não, para resultar na contagemCXGatemínima por padrão. Se você precisar do comportamento anterior, pode chamaropt_a1 = Trueexplicitamente eopt_a2 = Truepara manter o mesmo comportamento das versões anteriores.
Notas sobre a atualização do Transpiler
- O circuito
PassManageragora define sempre as propriedadesoriginal_circuit_indicesenum_input_qubitsantes do início da execução em passagens individuais. Essas são propriedades do circuito de entrada, que anteriormente dependiam de passagens individuais para serem definidas, muitas vezes como um efeito colateral de seu objetivo principal.
Circuitos obsoletos
-
As seguintes classes da biblioteca de circuitos estão obsoletas desde o Qiskit 2.2 e serão removidas no Qiskit 3.0. Eles foram substituídos por portões equivalentes modernos.
Correções de bugs
-
ApplyLayoutagora tratará corretamente o caso da aplicação de um qubit zeroLayout. Anteriormente, ele alegaria que nenhum layout havia sido definido, mesmo que o"layout"campo doPropertySetfosse igual aLayout(). -
Corrigidos problemas de vazamento de memória durante a criação de uma
QkOpCountsinstância e durante quaisquer chamadas sempreqk_opcounts_clear()que uma instância vazia é passada. -
Anteriormente, era possível definir um inválido
PauliEvolutionGatea partir de uma lista de operadores, em que os operadores não estavam todos definidos no mesmo número de qubits. Isso já foi corrigido e agora geramos um erro quando o gate é definido:from qiskit.quantum_info import Pauli, SparsePauliOp from qiskit.circuit.library import PauliEvolutionGate pauli = Pauli("XYZ") # 3 qubits op = SparsePauliOp(["XYIZ"], [1]) # 4 qubits evo = PauliEvolutionGate([pauli, op], time=1) -
Corrigimos um problema na passagem
VF2Layoutdo transpiler em que, mesmo com um conjunto de sementes fixo, a saída da passagem era potencialmente não determinística; especificamente, se o circuito de entrada tivesse quaisquer qubits ativos que contivessem apenas operações de qubit único. Corrigido #14729 -
Corrigido um bug em
PassManager.run()que acallbackfunção não era invocada ao executar com múltiplos circuitos. A chamada de retorno agora é acionada corretamente para cada passagem em cada circuito, inclusive na execução paralela. -
Corrigimos vários problemas na passagem do
CommutativeInverseCancellationtranspiler. A passagem agora funciona corretamente em circuitos que contêmCliffordoperações, operações de fluxo de controle e operações não invertíveis, comoInitialize.Além disso, a passagem agora sempre executa uma verificação sintática (não baseada em matriz) primeiro, ao identificar pares de portas inversas. Se as portas não forem sintaticamente iguais, o argumento
matrix_basedfor definido comoTruee a operação não atuar em mais demax_qubitsqubits, também será realizada uma verificação baseada em matriz. Isso melhora um pouco o potencial de redução do passe.Correção dos números 14407, 14635 e 14645.
-
Corrigimos vários problemas na passagem
CommutativeCancellationdo transpiler (e, consequentemente, emtranspile()), onde a fase global do circuito não era atualizada corretamente. Em particular, a fusão de um X-gate e um RX-gate introduziu uma incompatibilidade de fase, enquanto a remoção de um gate de rotação de Pauli com ângulo da forma , produziu incorretamente uma mudança de fase de . -
Corrigido um problema em
CommutationCheckerque portas controladas padrão não eram tratadas corretamente se fossem controladas em algo diferente do estado “todos uns”. Corrigido #14974 -
Corrigido um problema de indeterminismo em
CommutativeCancellation. Isso não afetou a ordem retornada porDAGCircuit.topological_nodes()outopological_op_nodes(), que normalmente devem ser usados quando o determinismo da ordem dos nós é importante, devido à sua função de classificação canônica integrada. No entanto, se inspecionar os nós por ordem arbitrária (DAGCircuit.op_nodes()) ou a estrutura de arestas (DAGCircuit.edges()), a ordem de iteração seria não determinística após uma chamada paraCommutativeCancellation. -
Corrigido um bug em
MCXGate.control()que adicionar mais controles a um controle abertoMCXGatenão levava em consideração o controlectrl_statedo gate MCX, levando a um controle incorretoctrl_statedo gate MCX estendido. Observe que as classes MCXCXGateexplícitas,CCXGate,C3XGatee jáC4XGateforam tratadas corretamente. -
Foi corrigido o aviso de descontinuidade do site Python 3.9 para que ele seja corretamente identificado como sendo causado pelo código do usuário ao importar o Qiskit. Anteriormente, ele não era identificado como sendo causado pelo código do usuário e isso significava que os filtros de aviso padrão do Python não exibiam o aviso ao usuário.
-
Corrigido um erro em
PhaseOracle,PhaseOracleGateeBitFlipOracleGateonde a tentativa de carregar a partir do arquivo dimacs gerava umTypeError. -
Corrigido um bug na passagem
ElidePermutationsdo transpiler, onde o mapeamento do qubit não era atualizado corretamente na presença dePermutationGates, levando a circuitos incorretos e atualizações no conjunto de propriedades do gerenciador de passagens. -
O transpiler integrado que define a
final_layoutpropriedade agora tratará corretamente a atualização desse campo, caso ele já tenha sido definido. Isso pode ser observado como o métodoTranspileLayout.routing_permutationagora retornando uma permutação correta após executar mais de uma passagem que definefinal_layout.Isso não afetou nenhuma chamada normal para
transpile()ougenerate_preset_pass_manager()usando os plug-ins integrados do Qiskit; nenhum pipeline construído dessa forma tentaria definirfinal_layoutmais de uma vez. -
Corrigido um bug na
HighLevelSynthesispassagem em que, se o circuito contivesse objetos de alto nível com registros clássicos, estes seriam mapeados para o índice relativo no objeto, em vez do índice correspondente no circuito externo. Os registros clássicos agora estão mapeados corretamente para o índice do circuito externo. -
Corrigido um bug em
Target.instruction_supported()que a verificação da ordem dos qubits da instrução era ignorada quando o método era chamado comoperation_name``parametersargumentos que correspondiam a uma instrução existente. -
Corrigido o comportamento do
max_trialsargumento paraVF2Layoutquando definido comoNoneou um número negativo. A passagem foi documentada como limitando a pesquisa com base no tamanho do circuito ou alvo, se a opção estivesse definida como,Nonee como aceitando valores negativos para especificar uma pesquisa ilimitada. No entanto, no 2.1.0, esse comportamento foi alterado incorretamente, de modo queNoneexecutava uma pesquisa ilimitada e tentar usar um número negativo gerava um erro. Essas omissões foram corrigidas para que o passe funcione conforme documentado e seja consistente com as versões anteriores. -
Corrigido um problema nos plug-ins de síntese de
MCXSynthesis1DirtyKG24alto nível eMCXSynthesis2DirtyKG24paraMCXGate, em que os plug-ins não consideravam os qubits auxiliares limpos disponíveis como qubits auxiliares sujos disponíveis. Em particular, o plug-inMCXSynthesis2DirtyKG24não se aplicava quando um qubit auxiliar limpo e um sujo estavam disponíveis. -
O
PauliEvolutionGate.to_matrix()método agora retorna a exponencial exata da matriz , onde é ooperatore é otimepassado para o gate. Isso corrige um comportamento inesperado, uma vez que oPauliEvolutionGateestá documentado para representar a evolução temporal exata, mas anteriormente a matriz dependia de como o compilador aproximava a evolução temporal. Oto_matrixmétodo agora está consistente com a documentação. -
Corrigida uma regressão de desempenho ao compilar incrementalmente
ParameterExpressiona partir da combinação de um grande número de subexpressões. Corrigido #14653 -
Foi corrigido um erro de correção ao exportar circuitos com instruções de atraso usando unidades 'ps' para QASM3.
-
Corrigido um caso extremo na exibição do
QFTcircuito. Anteriormente, quandoQFT.inverse()era chamado e, em seguida, os atributos do circuito QFT eram modificados, o QFT era exibido como"IQFT_dg". Isso estava incorreto e agora é exibido corretamente"IQFT". Corrigido #14758. -
Corrigido um bug no
PauliEvolutionSynthesisRustiqplugin que produzia circuitos incorretos no caso em que o operador de umPauliEvolutionGatecontém objetos do tipoSparseObservable.Por exemplo:
from qiskit.circuit.library import PauliEvolutionGate from qiskit.quantum_info import SparseObservable, Operator from qiskit.transpiler.passes.synthesis.hls_plugins import PauliEvolutionSynthesisRustiq obs = SparseObservable.from_sparse_list([("1+XY", (0, 1, 2, 3), 1.5)], num_qubits=4) evo = PauliEvolutionGate(obs, 1) qct = PauliEvolutionSynthesisRustiq().run(evo) assert Operator(qct) == Operator(evo) -
Corrigido um problema com a
generate_preset_pass_manager()função, que ignorava incorretamente os dados de restrições de tempo contidos em umTargetobjeto fornecido quando obackendargumento não estava definido. Corrigido #14329 -
Foi corrigido um bug no site
ObservablesArray.coerce_observable()em que uma exceção de que um observável não era hermitiano era acionada em excesso. Observáveis iguais azeronão são permitidos e agora invocam uma falha graciosa. -
qiskit.circuit.library.quantum_volume()foi atualizado para lidar com umnumpy.random.Generatorcomo entrada para seuseedargumento. Anteriormente, tal argumento gerador resultaria em umTypeError. -
QuantumCircuit.compose()agora remapará corretamente as variáveis e trechos usados nasDelayinstruções quando ovar_remapargumento for especificado. -
SabreLayoutusa um layout de “subconjunto denso” como uma de suas tentativas, seguindo o mesmo algoritmo queDenseLayout. Anteriormente, porém, a versão usada pela Sabre atribuía todos os qubits virtuais, incluindo ancillas fictícias, a um qubit físico, comprometendo a eficácia do algoritmo, mas não sua correção. A Sabre agora utilizará apenas os qubits virtuais definidos pelo usuário para este teste inicial, o que pode resultar em pequenas melhorias na seleção do layout quando calculada a média em grandes classes de circuitos. -
Corrigido um erro em
SparsePauliOp.simplify()que o método removia os termos de Pauli com base nas magnitudes de seus coeficientes antes de combinar duplicatas. Isso causou um comportamento incorreto em dois casos extremos importantes:- Quando vários termos de Pauli idênticos tinham coeficientes pequenos que estavam individualmente abaixo do limite de simplificação, mas cuja soma excedia o limite, esses termos eram removidos incorretamente.
- Quando vários termos de Pauli idênticos tinham coeficientes acima do limite, mas somados a quase zero, eles eram mantidos incorretamente.
Consulte #14194 para obter mais detalhes.
-
TranspileLayout.initial_index_layout()agora tratará corretamente ofilter_ancillas=Trueargumento se os qubits virtuais no nãoinitial_layoutforam especificados pelo construtor em ordem de índice. -
VF2Layoute agoraVF2PostLayoutincluirá corretamente atribuições de layout (arbitrárias) para qubits completamente ociosos. Anteriormente, isso poderia ter sido observado por chamadas queTranspileLayout.initial_index_layout()falhavam após uma compilação. -
Corrigido um problema na passagem do
VF2PostLayouttranspiler. Em determinadas situações, quando a passagem é executada com o argumento,strict_direction=Truehavia um potencial problema de dimensionamento de tempo de execução quando o gráfico de interação do circuito continha quaisquer qubits que tivessem apenas operações de 1 qubit. Esses problemas de mapeamento resultam em uma complexidade combinatória para a pontuação que levaria a passe quase sempre atingindo o tempo limite de pontuação e, normalmente, não melhorando o layout. Nostrict_direction=Falsemodo existe uma implementação de pesquisa otimizada para esses problemas, mas as restrições adicionais parastrict_direction=Truenão tornam essa abordagem viável. Em vez disso, nesses casos, a pesquisaVF2PostLayoutserá ignorada, uma vez que o problema de layout não é viável para a passagem.
Outras observações
- A implementação do roteamento Sabre usado por
SabreLayouteSabreSwapagora comprime sequências de nós que se tornarão automaticamente elegíveis para roteamento ao mesmo tempo dentro de sua representação de interação virtual interna. Isso melhora a eficiência do roteamento, reduz o uso de memória intermediária e evita que portas e 2q es influenciem os componenteslookaheadheurísticos.
2.1.0rc1
Notas de descontinuação
-
O suporte para a execução do Qiskit com Python 3.9 foi descontinuado e será removido na versão do Qiskit 2.3.0. O 2.3.0 é a primeira versão após o Python 3.9 entrar em fim de vida útil e não ter mais suporte. [1] Isso significa que, a partir da versão 2.3.0, será necessário atualizar a versão Python que você está usando para Python 3.9 ou superior.