QkTranspileLayout
typedef struct QkTranspileLayout QkTranspileLayoutO tipo QkTranspileLayout é usado para modelar as permutações introduzidas pelo transpilador. Em geral, o transpilador do Qiskit preserva a unidade até o layout inicial e as permutações de saída. O layout inicial é o mapeamento dos qubits do circuito virtual para os qubits físicos no destino, e a permutação de saída é causada pela inserção da porta de troca ou pela elisão da permutação antes que o layout inicial seja definido no pipeline do transpilador. Esse tipo rastreia esses detalhes e fornece uma interface para raciocinar sobre essas permutações.
Por exemplo, se você tivesse um circuito construído como:
#include <qiskit.h>
QkCircuit *qc = qk_circuit_new(3, 0)
uint32_t h_qargs[1] = {0};
qk_circuit_gate(qc, QkGate_H, h_qargs, NULL);
uint32_t cx_0_qargs[2] = {0, 1};
qk_circuit_gate(qc, QkGate_CX, cx_0_qargs, NULL);
uint32_t cx_1_qargs[2] = {0, 2};
qk_circuit_gate(qc, QkGate_CX, cx_1_qargs, NULL);e, durante o estágio de layout, o transpilador mapeia os qubits virtuais nesse circuito para os circuitos físicos como:
0 -> 2, 1 -> 1, 2 -> 0assim, o circuito teria a seguinte aparência:
#include <qiskit.h>
QkCircuit *qc = qk_circuit_new(3, 0)
uint32_t h_qargs[1] = {2};
qk_circuit_gate(qc, QkGate_H, h_qargs, NULL);
uint32_t cx_0_qargs[2] = {2, 1};
qk_circuit_gate(qc, QkGate_CX, cx_0_qargs, NULL);
uint32_t cx_1_qargs[2] = {2, 0};
qk_circuit_gate(qc, QkGate_CX, cx_1_qargs, NULL);então o resultado de qk_transpile_layout_initial_layout será uma matriz: [2, 1, 0]
Se o roteamento tiver sido necessário para inserir uma porta de troca no circuito após a aplicação do layout, isso resultará na definição de uma permutação de saída. Por exemplo, se uma troca foi inserida como:
#include <qiskit.h>
QkCircuit *qc = qk_circuit_new(3, 0)
uint32_t h_qargs[1] = {2};
qk_circuit_gate(qc, QkGate_H, h_qargs, NULL);
uint32_t cx_0_qargs[2] = {2, 1};
qk_circuit_gate(qc, QkGate_CX, cx_0_qargs, NULL);
uint32_t swap_qargs[2] = {1, 0};
qk_circuit_gate(qc, QkGate_Swap, swap_qargs, NULL);
uint32_t cx_1_qargs[2] = {2, 1};
qk_circuit_gate(qc, QkGate_CX, cx_1_qargs, NULL);isso resulta no estado de saída do qubit 0 movendo-se para o qubit 1 e do qubit 1’s para o qubit 0. Isso faz com que o site qk_transpile_layout_output_permutation retorne a matriz: [1, 0, 2] para indicar que essa é a posição final do estado de cada qubit após o mapeamento inicial do layout. Se nenhuma troca ou elisão de permutação tiver sido feita durante a transpilação, essa será uma matriz trivial do formato [0, 1, 2] , pois o estado de saída do qubit não é movido pelo transpilador.
Em seguida, a combinação desses dois é o layout final, que serve para rastrear a posição final de um qubit virtual no circuito de entrada. Portanto, a partir do exemplo acima (com a troca), a função qk_transpile_layout_final_layout retornaria [2, 0, 1] porque, seguindo o layout inicial e depois qualquer permutação de roteamento, a posição final do qubit 0 no circuito de entrada é agora o qubit físico 2, o qubit virtual 1 no circuito de entrada é o qubit físico 0 e o qubit virtual 2 no circuito de entrada é o qubit físico 1.
O transpilador também alocará qubits auxiliares ao circuito se o destino tiver mais qubits disponíveis do que o circuito de entrada original. Isso é o que resulta na necessidade de duas funções qk_transpile_layout_num_input_qubits e qk_transpile_layout_num_output_qubits que rastreiam o número de qubits no circuito de entrada e no circuito de saída, respectivamente. Além disso, as funções qk_transpile_layout_initial_layout e qk_transpile_layout_final_layout recebem um argumento para filtrar os ancillas da matriz de saída. Se definido como true, a matriz de saída será filtrada apenas para os qubits virtuais no circuito de entrada original para a chamada do transpilador que gerou o QkTranspileLayout.
Funções
qk_transpile_layout_num_input_qubits
uint32_t qk_transpile_layout_num_input_qubits(const QkTranspileLayout *layout)
Retorna o número de qubits no circuito de entrada para o transpilador.
Segurança
O comportamento é indefinido se layout não for um ponteiro válido e não nulo para um QkTranspileLayout.
Parâmetros
- layout - Um ponteiro para o site
QkTranspileLayout.
Retorna
O número de qubits de entrada
qk_transpile_layout_num_output_qubits
uint32_t qk_transpile_layout_num_output_qubits(const QkTranspileLayout *layout)
Retorna o número de qubits no circuito de saída do transpilador.
Segurança
O comportamento é indefinido se layout não for um ponteiro válido e não nulo para um QkTranspileLayout.
Parâmetros
- layout - Um ponteiro para o site
QkTranspileLayout.
Retorna
O número de qubits de saída
qk_transpile_layout_initial_layout
bool qk_transpile_layout_initial_layout(const QkTranspileLayout *layout, bool filter_ancillas, uint32_t *initial_layout)
Consultar o layout inicial de um site QkTranspileLayout.
A matriz de saída desta função representa o mapeamento dos qubits virtuais do circuito de entrada original para o qubit físico no circuito de saída. O índice na matriz corresponde ao qubit virtual, e o valor corresponde ao qubit físico. Por exemplo, uma matriz de saída com:
[1, 0, 2]indica que o layout mapeia o qubit virtual 0 -> qubit físico 1, o qubit virtual 1 -> qubit físico -> 0 e o qubit virtual 2 -> qubit físico 2.
Segurança
O comportamento é indefinido se layout não for um ponteiro válido e não nulo para um QkTranspileLayout. initial_layout deve ser um ponteiro válido e não nulo com uma alocação grande o suficiente para armazenar o tamanho necessário para o layout inicial. Se filter_ancillas for verdadeiro, esse será o número de qubits de entrada (que pode ser verificado com qk_transpile_layout_num_input_qubits()) ou o número de qubits de saída se filter_ancillas for falso (que pode ser consultado com qk_transpile_layout_num_output_qubits()).
Parâmetros
- layout - Um ponteiro para o site
QkTranspileLayout. - filter_ancillas – Se definido como true, a matriz de saída não incluirá índices para nenhum ancilla adicionado pelo transpiler.
- initial_layout - Um ponteiro para a matriz na qual essa função gravará o layout inicial. Isso deve ter espaço suficiente para a matriz completa, que será
qk_transpile_layout_num_input_qubits()ouqk_transpile_layout_num_output_qubits()parafilter_ancillasser verdadeiro ou falso, respectivamente.
Retorna
True se houver um initial_layout gravado em initial_layout e false se não houver um layout inicial.
qk_transpile_layout_output_permutation
bool qk_transpile_layout_output_permutation(const QkTranspileLayout *layout, uint32_t *output_permutation)
Consultar a permutação de saída de um QkTranspileLayout
A matriz de saída dessa função representa a permutação induzida pelo transpilador, em que o índice indica o qubit no início do circuito e o valor é a posição do qubit no final do circuito. Por exemplo, uma matriz de saída de:
[1, 2, 0]indica que o qubit 0 do início do circuito está no qubit 1 no final do circuito, 1 -> 2 e 2 -> 0.
Segurança
O comportamento é indefinido se layout não for um ponteiro válido e não nulo para um QkTranspileLayout. output_permutation deve ser um ponteiro válido e não nulo com uma alocação grande o suficiente para armazenar o tamanho necessário para a saída_permutation. Esse será sempre o número de qubits de saída no site QkTranspileLayout que pode ser consultado com qk_transpile_layout_num_output_qubits().
Parâmetros
- layout - Um ponteiro para o site
QkTranspileLayout. - output_permutation - Um ponteiro para a matriz na qual essa função gravará a permutação de saída. Isso deve ter espaço suficiente para a saída, que será o número de qubits de saída no layout. Isso pode ser consultado em
qk_transpile_layout_num_output_qubits.
Retorna
True (verdadeiro) se houver uma permutação de saída que foi gravada em output_permutation false (falso) se o QkTranspileLayout não contiver uma permutação de saída.
qk_transpile_layout_final_layout
void qk_transpile_layout_final_layout(const QkTranspileLayout *layout, bool filter_ancillas, uint32_t *final_layout)
Consultar o layout final de um QkTranspileLayout
A matriz de saída representa o mapeamento do qubit virtual no circuito de entrada original para o qubit físico no final do circuito de transpilação que tem o estado desse qubit. O índice da matriz representa o qubit virtual e o valor representa o qubit físico no final do circuito transpilado que tem o estado desse qubit virtual. Por exemplo, uma matriz de saída de:
[2, 0, 1]indica que o estado do qubit virtual 0’s no circuito original está no qubit físico 2 no final do circuito transpilado, 1 -> 0 e 2 -> 1.
Segurança
O comportamento é indefinido se layout não for um ponteiro válido e não nulo para um QkTranspileLayout. final_layout deve ser um ponteiro válido e não nulo com uma alocação grande o suficiente para armazenar o tamanho necessário para o layout final. Se filter_ancillas for verdadeiro, esse será o número de qubits de entrada (que pode ser verificado com qk_transpile_layout_num_input_qubits()) ou o número de qubits de saída se filter_ancillas for falso (que pode ser consultado com qk_transpile_layout_num_output_qubits()).
Parâmetros
- layout - Um ponteiro para o site
QkTranspileLayout. - filter_ancillas – Se definido como true, a matriz de saída não incluirá índices para nenhum ancilla adicionado pelo transpiler.
- final_layout - Um ponteiro para a matriz na qual essa função gravará o layout final. Isso deve ter espaço suficiente para a saída, que será o número de qubits de entrada ou de saída, dependendo do valor de filter_ancillas.
qk_transpile_layout_generate_from_mapping
QkTranspileLayout *qk_transpile_layout_generate_from_mapping(const QkDag *original_dag, const QkTarget *target, const uint32_t *qubit_mapping)
Gerar um layout inicial QkTranspileLayout a partir de um mapeamento inicial
Isso irá gerar um QkTranspileLayout com o layout inicial definido (e sem permutação de saída) a partir de um mapeamento fornecido. A intenção desta função é permitir a criação de uma passagem de layout personalizada que também crie um QkTranspileLayout que você pode usar com funções de estágio subsequentes, como qk_transpile_stage_routing.
Segurança
O comportamento é indefinido se original_dag e o destino não target forem um ponteiro válido, alinhado e diferente de nulo para um QkDag ou um, QkTarget respectivamente. qubit_mapping deve ser um ponteiro válido para uma matriz contígua com uint32_t espaço suficiente para o número de qubits indicado em target.
Parâmetros
- original_dag – Um ponteiro para o dag original antes de executar uma passagem de layout personalizada. Este dag deve ter menos ou o mesmo número de qubits que
target. - target – Um ponteiro para o destino em que o layout foi executado. Este alvo deve ter um número fixo de qubits definido.
- qubit_mapping – Um ponteiro para a matriz de mapeamento do layout. Esta matriz deve ter o mesmo número de elementos que há qubits no alvo e cada elemento é um número inteiro único e todos devem estar no intervalo de 0 a,
num_qubitsondenum_qubitsé o número de qubits indicado no valor fornecido paratarget. Os primeiros elementos representam os qubits virtuais emoriginal_dage o valor representa o qubit físico no alvo ao qual o qubit virtual está mapeado. Por exemplo, uma matriz de[1, 0, 2]mapearia o qubit virtual 0 -> qubit físico 1, o qubit virtual 1 -> qubit físico 0 e o qubit virtual 2 -> qubit físico 2. Os elementos que não estão no dag original são tratados como qubits auxiliares, mas ainda assim devem ser mapeados para um qubit físico. Esta matriz será copiada para a saída,QkTranspileLayoutportanto, você ainda deve liberá-la após chamar esta função.
Retorna
O objeto QkTranspileLayout com o layout inicial definido
qk_transpile_layout_free
void qk_transpile_layout_free(QkTranspileLayout *layout)
Liberar um objeto QkTranspileLayout
Segurança
O comportamento é indefinido se layout não for um ponteiro válido e não nulo para um QkTranspileLayout.
Parâmetros
- layout - um ponteiro para o layout a ser liberado
qk_transpile_layout_to_python
PyObject *qk_transpile_layout_to_python(const QkTranspileLayout *layout, const QkCircuit *circuit)
Gerar um objeto PythonTranspileLayout -space a partir de um QkTranspileLayout.
O objeto de espaço criado Python é uma cópia do QkTranspileLayout fornecido, a representação dos dados é diferente entre C e Python e os dados não são movidos para Python como em algumas outras *_to_python funções.
Segurança
O comportamento é indefinido se layout e não circuit forem ponteiros válidos e diferentes de nulo para e QkTranspileLayout , QkCircuit respectivamente. Presume-se que o thread que está executando essa função atualmente mantém o GIL ( Python ). Isso é necessário para criar o objeto Python retornado por esta função.
Parâmetros
- layout – um ponteiro para um
QkTranspileLayout. - circuito – um ponteiro para o original
QkCircuit.
Retorna
o ponteiro PyObject para o objeto TranspileLayout do espaço Python.