Skip to main content
IBM Quantum Platform

QkDag

typedef struct QkDag QkDag

A QkDag estrutura expõe uma interface de baixo nível para a representação do gráfico acíclico direcionado (DAG) do transpilador Qiskit de um circuito quântico para uso em passagens do transpilador. Ele expõe apenas o que está definido no modelo de dados interno do Qiskit. Portanto, faltam algumas funcionalidades que estão disponíveis na classe de nível superior PythonDAGCircuit .

Atualmente, a API C só suporta a construção de DAGs que contenham operações definidas no modelo de dados Rust interno do Qiskit. Geralmente, isso inclui apenas portas na biblioteca padrão de portas, operações padrão não unitárias (atualmente Barrier, Measure, Reset e Delay) e UnitaryGate. Essa funcionalidade será ampliada ao longo do tempo, à medida que o modelo de dados Rust for expandido para oferecer suporte nativo a mais funcionalidades.


Tipos de dados

QkDagNodeType

enum QkDagNodeType

O tipo de nó em um QkDag.

Os nós de operação representam uma instrução aplicada. Os demais nós são considerados nós “wire” e representam os pontos finais das cadeias de dependência de dados do DAG.

Valores:

enumerador QkDagNodeType_Operation

Nó de operação.

enumerador QkDagNodeType_QubitIn

Nó inicial do fio qubit.

enumerador QkDagNodeType_QubitOut

Nó terminal do fio qubit.

enumerador QkDagNodeType_ClbitIn

Nó inicial do fio Clbit.

enumerador QkDagNodeType_ClbitOut

Nó terminal do fio Clbit.

enumerador QkDagNodeType_VarIn

Nó clássico de início de fio variável.

enumerador QkDagNodeType_VarOut

Nó terminal de fio variável clássico.

QkOperationKind

enum QkOperationKind

O tipo de operação.

Isso é retornado ao consultar um nó específico no gráfico com qk_dag_op_node_kinde tem como objetivo permitir que o chamador despache (por exemplo, por meio de um “switch”) chamadas específicas para o tipo de operação contida.

Valores:

enumerador QkOperationKind_Gate

enumerador QkOperationKind_Barrier

enumerador QkOperationKind_Delay

enumerador QkOperationKind_Measure

enumerador QkOperationKind_Reset

enumerador QkOperationKind_Unitary

enumerador QkOperationKind_PauliProductMeasurement

enumerador QkOperationKind_ControlFlow

enumerador QkOperationKind_Unknown

Esta variante é usada como um tipo opaco para operações ainda não implementadas no modelo de dados nativo.

QkOperationKind_PauliProductRotation, recenseador

QkDagNeighbors

struct QkDagNeighbors

Uma estrutura para armazenar informações sobre sucessores e predecessores recuperadas de qk_dag_successors e qk_dag_predecessors, respectivamente.

Este objeto é somente leitura a partir de C. Para satisfazer as garantias de segurança do qk_dag_neighbors_clear, você não deve sobrescrever nenhum dado inicializado pelo qk_dag_successors ou qk_dag_predecessors, incluindo quaisquer dados apontados.

const uint32_t *vizinhos

Matriz de tamanho num_neighbors de índices de nós.

tamanho_t número_de_vizinhos

O comprimento da neighbors matriz.


Funções

qk_dag_new

QkDag *qk_dag_new(void)

Construa um novo DAG vazio.

Você deve liberar o DAG retornado com qk_dag_free quando terminar de usá-lo.

Exemplo

QkDag *empty = qk_dag_new();

Retorna

Um ponteiro para o DAG criado.

qk_dag_add_quantum_register

void qk_dag_add_quantum_register(QkDag *dag, const QkQuantumRegister *reg)

Adicione um registro quântico ao DAG.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1024, "my_register");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag e se não reg for um ponteiro válido e diferente de nulo para um QkQuantumRegister.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • reg – Um ponteiro para o registro quântico.

qk_dag_add_classical_register

void qk_dag_add_classical_register(QkDag *dag, const QkClassicalRegister *reg)

Adicione um registro clássico ao DAG.

Exemplo

QkDag *dag = qk_dag_new();
QkClassicalRegister *cr = qk_classical_register_new(24, "my_register");
qk_dag_add_classical_register(dag, cr);
qk_classical_register_free(cr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag e se não reg for um ponteiro válido e diferente de nulo para um QkClassicalRegister.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • reg – Um ponteiro para o registro clássico.

qk_dag_num_qubits

uint32_t qk_dag_num_qubits(const QkDag *dag)

Obtenha o número de qubits que o DAG contém.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(24, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t num_qubits = qk_dag_num_qubits(dag);  // num_qubits==24
qk_quantum_register_free(qr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.

Retorna

O número de qubits em que o DAG é definido.

qk_dag_num_clbits

uint32_t qk_dag_num_clbits(const QkDag *dag)

Obtenha o número de clbits que o DAG contém.

Exemplo

QkDag *dag = qk_dag_new();
QkClassicalRegister *cr = qk_classical_register_new(24, "my_register");
qk_dag_add_classical_register(dag, cr);
uint32_t num_clbits = qk_dag_num_clbits(dag);  // num_clbits==24
qk_classical_register_free(cr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.

Retorna

O número de clbits em que o DAG é definido.

qk_dag_num_op_nodes

size_t qk_dag_num_op_nodes(const QkDag *dag)

Retorne o número total de nós de operação no DAG.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);

uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
size_t num = qk_dag_num_op_nodes(dag); // 1

qk_dag_free(dag);
qk_quantum_register_free(qr);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.

Retorna

O número total de instruções no DAG.

qk_dag_node_type

QkDagNodeType qk_dag_node_type(const QkDag *dag, uint32_t node)

Obter o tipo do nó especificado.

O resultado pode ser usado em uma instrução switch para enviar o tratamento adequado ao iterar sobre nós de tipo desconhecido.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • – O nó do qual se deseja obter o tipo.

Retorna

O tipo do nó.

qk_dag_qubit_in_node

uint32_t qk_dag_qubit_in_node(const QkDag *dag, uint32_t qubit)

Recupera o índice do nó de entrada do fio correspondente ao qubit fornecido.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • qubit – O qubit para obter o índice do nó de entrada.

Retorna

O nó de entrada do fio qubit.

qk_dag_qubit_out_node

uint32_t qk_dag_qubit_out_node(const QkDag *dag, uint32_t qubit)

Recupera o índice do nó de saída do fio correspondente ao qubit fornecido.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • qubit – O qubit para obter o índice do nó de saída.

Retorna

O nó de saída do fio qubit.

qk_dag_clbit_in_node

uint32_t qk_dag_clbit_in_node(const QkDag *dag, uint32_t clbit)

Recupera o índice do nó de entrada do fio correspondente ao clbit fornecido.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • clbit – O clbit para obter o índice do nó de entrada.

Retorna

O nó de entrada do fio clbit.

qk_dag_clbit_out_node

uint32_t qk_dag_clbit_out_node(const QkDag *dag, uint32_t clbit)

Recupera o índice do nó de saída do fio correspondente ao clbit fornecido.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • clbit – O clbit para obter o índice do nó de saída.

Retorna

O nó de saída do fio clbit.

qk_dag_wire_node_value

uint32_t qk_dag_wire_node_value(const QkDag *dag, uint32_t node)

Recupera o valor de um nó terminal de fio.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • – O nó final para obter o valor do fio.

Retorna

O valor (por exemplo, qubit, clbit ou var) dentro do nó de ponto final.

qk_dag_op_node_num_qubits

uint32_t qk_dag_op_node_num_qubits(const QkDag *dag, uint32_t node)

Obtém o número de qubits do nó de operação especificado.

Entra em pânico se o nó não for uma operação.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • node – O nó de operação para obter o número de qubits.

Retorna

O número de qubits da operação.

qk_dag_op_node_num_clbits

uint32_t qk_dag_op_node_num_clbits(const QkDag *dag, uint32_t node)

Obtém o número de clbits do nó de operação especificado.

Entra em pânico se o nó não for uma operação.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • node – O nó de operação para obter o número de clbits.

Retorna

O número de bits da operação.

qk_dag_op_node_num_params

uint32_t qk_dag_op_node_num_params(const QkDag *dag, uint32_t node)

Obtém o número de parâmetros do nó de operação especificado.

Entra em pânico se o nó não for uma operação.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • node – O nó de operação para obter o número de parâmetros.

Retorna

O número de parâmetros da operação.

qk_dag_op_node_qubits

const uint32_t *qk_dag_op_node_qubits(const QkDag *dag, uint32_t node)

Recupera os qubits do nó de operação especificado.

Entra em pânico se o nó não for uma operação.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • node – O nó de operação para obter os qubits.

Retorna

Um ponteiro para os qubits. Use qk_dag_op_node_num_qubits para determinar o número de elementos.

qk_dag_op_node_clbits

const uint32_t *qk_dag_op_node_clbits(const QkDag *dag, uint32_t node)

Recupera os bits de cl do nó de operação especificado.

Entra em pânico se o nó não for uma operação.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • node – O nó de operação do qual obter os clbits.

Retorna

Um ponteiro para os clbits. Use qk_dag_op_node_num_clbits para determinar o número de elementos.

qk_dag_apply_gate

uint32_t qk_dag_apply_gate(QkDag *dag, QkGate gate, const uint32_t *qubits, const double *params, bool front)

Aplique um QkGate ao DAG.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);

uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);

qk_dag_free(dag);
qk_quantum_register_free(qr);

Segurança

Espera-se que os qubits``params tipos e sejam um ponteiro para uma matriz de uint32_t e, double respectivamente, onde o comprimento corresponde às expectativas para o gate padrão. Se a matriz não tiver comprimento suficiente, o comportamento desta função é indefinido, pois ela irá ler fora dos limites da matriz. Pode ser um ponteiro nulo se não houver qubits ou parâmetros para um determinado portão. Você pode verificar qk_gate_num_qubits e qk_gate_num_params para determinar quantos qubits e parâmetros são necessários para um determinado portão.

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG ao qual aplicar o gate.
  • gate – O endereço StandardGate para se inscrever.
  • qubits – O ponteiro para a matriz de índices uint32_t de qubits aos quais adicionar o portão. Isso pode ser um ponteiro nulo se não houver qubits para gate (por exemplo QkGate_GlobalPhase).
  • params – O ponteiro para a matriz de double valores a serem usados para os parâmetros da porta. Isso pode ser um ponteiro nulo se não houver parâmetros para gate (por exemplo QkGate_H).
  • frente – Se true, o portão é aplicado como a primeira operação nos qubits especificados, em vez de como a última.

Retorna

O índice do nó de operação recém-adicionado.

qk_dag_apply_measure

uint32_t qk_dag_apply_measure(QkDag *dag, uint32_t qubit, uint32_t clbit, bool front)

Aplique uma medida a um DAG.

Exemplo

Meça todos os qubits no índice clbit correspondente no final do circuito.

uint32_t num_qubits = qk_dag_num_qubits(dag);
for (uint32_t i = 0; i < num_qubits; i++) {
    qk_dag_apply_measure(dag, i, i, false);
}

Segurança

O comportamento é indefinido se não dag for um ponteiro alinhado e diferente de nulo para um válido QkDag, ou se qubit ou clbit estiverem fora do intervalo.

Parâmetros

  • dag – O circuito ao qual se aplica.
  • qubit – O índice qubit a ser medido.
  • clbit – O índice clbit para armazenar o resultado.
  • frente – Se a medida deve ser aplicada no início do circuito. Normalmente false.

Retorna

O índice do nó da instrução criada.

qk_dag_apply_reset

uint32_t qk_dag_apply_reset(QkDag *dag, uint32_t qubit, bool front)

Aplique uma reinicialização ao DAG.

Exemplos

Aplique reinicializações iniciais em todos os qubits.

uint32_t num_qubits = qk_dag_num_qubits(dag);
for (uint32_t qubit = 0; qubit < num_qubits; qubit++) {
    qk_dag_apply_reset(dag, qubit, true);
}

Segurança

O comportamento é indefinido se não dag for um ponteiro alinhado e diferente de nulo para um válido QkDag, ou se qubit estiver fora do intervalo.

Parâmetros

  • dag – O circuito ao qual se aplica.
  • qubit – O índice do qubit a ser reiniciado.
  • frente – Se deve aplicar a reinicialização no início do circuito. Normalmente false.

Retorna

O índice do nó da instrução criada.

qk_dag_apply_barrier

uint32_t qk_dag_apply_barrier(QkDag *dag, const uint32_t *qubits, uint32_t num_qubits, bool front)

Aplique uma barreira ao DAG.

Exemplos

Aplique uma barreira final em todos os qubits:

qk_dag_apply_barrier(dag, NULL, qk_dag_num_qubits(dag), false);

Aplique uma barreira no início de um circuito em índices qubit especificados:

uint32_t qubits[] = {0, 2, 4, 5};
uint32_t num_qubits = sizeof(qubits) / sizeof(qubits[0]);
qk_dag_apply_barrier(dag, qubits, num_qubits, true);

Segurança

O comportamento é indefinido se:

  • dag não é um ponteiro alinhado e diferente de nulo para um válido QkDag,
  • qubits não está alinhado ou não é válido para num_qubits leituras de índices inicializados, dentro dos limites e não duplicados, a menos que qubits seja nulo.

Parâmetros

  • dag – O circuito ao qual se aplica.
  • qubits – Os índices qubit aos quais aplicar a barreira. Isso pode ser nulo, caso em num_qubits que não é lido, e a barreira é aplicada a todos os qubits no DAG.
  • num_qubits – A quantos qubits a barreira se aplica.
  • frente – Se deve aplicar a barreira no início do circuito. Normalmente false.

Retorna

O índice do nó da instrução criada.

qk_dag_apply_unitary

uint32_t qk_dag_apply_unitary(QkDag *dag, const QkComplex64 *matrix, const uint32_t *qubits, uint32_t num_qubits, bool front)

Aplique um gate unitário a um DAG.

Os valores em matrix devem formar uma matriz unitária row-major do tamanho correto para o número de qubits. Os dados são copiados do ponteiro e só precisam ser válidos para leitura até que essa função retorne.

Consulte: Convenções de circuito para obter detalhes sobre as convenções de rotulagem de bits e matrizes do Qiskit.

Segurança

O comportamento é indefinido se qualquer uma das seguintes condições se verificar:

  • dag não é um ponteiro alinhado e diferente de nulo para um válido QkDag,
  • matrix não é um ponteiro alinhado para valores 4**num_qubits inicializados,
  • qubits não é um ponteiro alinhado para valores num_qubits inicializados.

Parâmetros

  • dag – O circuito ao qual se aplica.
  • matriz – Uma matriz unitária inicializada com prioridade nas linhas, de tamanho total 4**num_qubits.
  • qubits – Uma matriz de índices uint32_t distintos dos qubits.
  • num_qubits – O número de qubits aos quais o portão se aplica.
  • frente – Se deve aplicar o gate no início do circuito. Normalmente false.

Retorna

O índice do nó da instrução criada.

qk_dag_op_node_gate_op

QkGate qk_dag_op_node_gate_op(const QkDag *dag, uint32_t node, double *out_params)

Recuperar o gate padrão do nó especificado.

Entra em pânico se o nó não for uma operação de porta padrão.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);

uint32_t qubit[1] = {0};
uint32_t h_gate_idx = qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);

QkGate gate = qk_dag_op_node_gate_op(dag, h_gate_idx, NULL);

qk_dag_free(dag);
qk_quantum_register_free(qr);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag. Se out_params não for NULL, deve apontar para um buffer grande o suficiente para armazenar todos os parâmetros do gate, caso contrário, o comportamento é indefinido, pois esta função irá escrever além dos seus limites. Você pode verificar qk_dag_op_node_num_params para determinar quantos parâmetros são necessários para qualquer nó de operação.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • – O nó de operação para obter o portão padrão.
  • out_params – Um buffer a ser preenchido com os parâmetros do gate ou NULL se eles não forem desejados.

Retorna

O valor do gate.

qk_dag_op_node_unitary

void qk_dag_op_node_unitary(const QkDag *dag, uint32_t node, QkComplex64 *out)

Copie a matriz unitária do índice do nó correspondente.

Entra em pânico se o nó não for um portão unitário.

Segurança

O comportamento é indefinido se não dag for um ponteiro diferente de nulo para um válido QkDag, se out não estiver alinhado ou se não out for válido para 4**num_qubits gravações de QkComplex64.

Parâmetros

  • dag – O circuito a partir do qual se deve ler.
  • – O índice do nó da instrução da matriz unitária.
  • out – Memória alocada e alinhada para valores 4**num_qubits complexos em ordem row-major, onde num_qubits é o número de qubits aos quais o gate se aplica.

qk_dag_op_node_kind

QkOperationKind qk_dag_op_node_kind(const QkDag *dag, uint32_t node)

Obtenha o “tipo” de um nó de operação.

O resultado pode ser usado em uma instrução switch para despachar o tratamento adequado ao iterar sobre os nós de operação.

Entra em pânico se não node for um nó de operação.

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • – O nó de operação para obter o “tipo” de.

Retorna

O “tipo” do nó.

qk_dag_successors

QkDagNeighbors qk_dag_successors(const QkDag *dag, uint32_t node)

Recupera os sucessores do nó especificado.

A matriz de sucessores e seu comprimento são retornados como uma QkDagNeighbors estrutura, onde cada elemento da matriz corresponde a um índice de nó DAG. Você deve chamar a qk_dag_neighbors_clear função quando terminar para liberar a memória alocada para a estrutura.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);

uint32_t node_cx = qk_dag_apply_gate(dag, QkGate_CX, (uint32_t[]){0, 1}, NULL, false);

QkDagNeighbors successors = qk_dag_successors(dag, node_cx);

qk_dag_neighbors_clear(&successors);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • – O nó do qual obter os sucessores.

Retorna

Uma instância da QkDagNeighbors estrutura com as informações dos sucessores.

qk_dag_predecessors

QkDagNeighbors qk_dag_predecessors(const QkDag *dag, uint32_t node)

Recupera os predecessores do nó especificado.

A matriz de predecessores e seu comprimento são retornados como uma QkDagNeighbors estrutura, onde cada elemento da matriz corresponde a um índice de nó DAG. Você deve chamar a qk_dag_neighbors_clear função quando terminar para liberar a memória alocada para a estrutura.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);

uint32_t node_cx = qk_dag_apply_gate(dag, QkGate_CX, (uint32_t[]){0, 1}, NULL, false);

QkDagNeighbors predecessors = qk_dag_predecessors(dag, node_cx);

qk_dag_neighbors_clear(&predecessors);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • node – O nó para obter os predecessores.

Retorna

Uma instância da QkDagNeighbors estrutura com as informações dos predecessores.

qk_dag_neighbors_clear

void qk_dag_neighbors_clear(QkDagNeighbors *neighbors)

Limpe os campos da estrutura de QkDagNeighbors entrada.

A função desaloca a memória apontada pelo neighbors campo e a define como NULL. Ele também define o num_neighbors campo como 0.

Segurança

O comportamento é indefinido se não neighbors for um ponteiro válido e diferente de nulo para um QkDagNeighbors objeto preenchido com ou qk_dag_successors qk_dag_predecessors.

Parâmetros

  • vizinhos – Um ponteiro para um QkDagNeighbors objeto.

qk_dag_get_instruction

void qk_dag_get_instruction(const QkDag *dag, uint32_t index, QkCircuitInstruction *instruction)

Retorne os detalhes de uma instrução no circuito.

Este é um espelho de qk_circuit_get_instruction. Você também pode usar métodos individuais, como qk_dag_op_node_gate_op para obter propriedades individuais.

Você deve ligar qk_circuit_instruction_clear para redefinir o QkCircuitInstruction antes de reutilizá-lo ou descartá-lo.

Exemplos

Itere através de um DAG para encontrar quais qubits têm medidas:

bool *measured = calloc(qk_dag_num_qubits(dag), sizeof(*measured));
uint32_t num_ops = qk_dag_num_op_nodes(dag);
uint32_t *ops = malloc(num_ops * sizeof(*ops));
qk_dag_topological_op_nodes(dag, ops);

// Storage space for the instruction.
QkCircuitInstruction inst;
for (uint32_t i = 0; i < num_ops; i++) {
    qk_dag_get_instruction(dag, ops[i], &inst);
    if (!strcmp(inst.name, "measure"))
        measured[inst.qubits[0]] = true;
    qk_circuit_instruction_clear(&inst);
}

free(ops);
free(measured);

Segurança

O comportamento é indefinido se ou dag não instruction forem ponteiros válidos, alinhados e diferentes de nulo para o tipo de dados relevante. Os instruction campos não precisam ser inicializados.

Parâmetros

  • dag – O circuito do qual a instrução deve ser recuperada.
  • índice – O índice do nó. É um erro passar um índice que não é um nó operacional válido.
  • instrução – Um ponto para onde escrever o QkCircuitInstruction.

qk_dag_compose

QkExitCode qk_dag_compose(QkDag *dag, const QkDag *other, const uint32_t *qubits, const uint32_t *clbits)

Componha o other DAG na dag instância com a opção de um subconjunto de fios de entrada other sendo mapeado para um subconjunto de fios de saída dag.

other pode incluir um número menor ou igual de fios para cada tipo.

Exemplo

// Build the following dag
// rqr_0: ──■───────
//          │  ┌───┐
// rqr_1: ──┼──┤ Y ├
//        ┌─┴─┐└───┘
// rqr_2: ┤ X ├─────
//        └───┘
QkDag *dag_right = qk_dag_new();
QkQuantumRegister *rqr = qk_quantum_register_new(3, "rqr");
qk_dag_add_quantum_register(dag_right, rqr);
qk_dag_add_classical_register(dag_right, rcr);
qk_dag_apply_gate(dag_right, QkGate_CX, (uint32_t[]){0, 2}, NULL, false);
qk_dag_apply_gate(dag_right, QkGate_Y, (uint32_t[]){1}, NULL, false);

// Build the following dag
//          ┌───┐
// lqr_0: ──┤ H ├───
//        ┌─┴───┴──┐
// lqr_1: ┤ P(0.1) ├
//        └────────┘
QkDag *dag_left = qk_dag_new();
QkQuantumRegister *lqr = qk_quantum_register_new(2, "lqr");
qk_dag_add_quantum_register(dag_left, lqr);
qk_dag_add_classical_register(dag_left, lcr);
qk_dag_apply_gate(dag_left, QkGate_H, (uint32_t[]){0}, NULL, false);
qk_dag_apply_gate(dag_left, QkGate_Phase, (uint32_t[]){1}, (double[]){0.1}, false);

// Compose left circuit onto right circuit
// Should result in circuit
//             ┌───┐
// rqr_0: ──■──┤ H ├──────────
//          │  ├───┤┌────────┐
// rqr_1: ──┼──┤ Y ├┤ P(0.1) ├
//        ┌─┴─┐└───┘└────────┘
// rqr_2: ┤ X ├───────────────
//        └───┘
qk_dag_compose(dag_right, dag_left, NULL, NULL);

// Clean up after you're done
qk_dag_free(dag_left);
qk_dag_free(dag_right);
qk_quantum_register_free(lqr);
qk_quantum_register_free(rqr);

Segurança

O comportamento é indefinido se dag ou não other forem ponteiros válidos e diferentes de nulo para um QkDag. Se qubit nem clbit forem NULL, deve conter uma quantidade menor ou igual à que o circuito possui.

Parâmetros

  • dag – Um ponteiro para o DAG a ser composto.
  • outro – Um ponteiro para o DAG a ser composto dag.
  • qubits – Uma lista de índices que representam os fios qubit a serem compostos.
  • clbits – Uma lista de índices que representam os fios clbit a serem compostos.

Retorna

QkExitCode_Success após a decomposição bem-sucedida, caso contrário, um código de erro específico do DAG indicando a causa da falha.

qk_dag_free

void qk_dag_free(QkDag *dag)

Liberte o DAG.

Exemplo

QkDag *dag = qk_dag_new();
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for nulo ou um ponteiro válido para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG a ser liberado.

qk_dag_to_circuit

QkCircuit *qk_dag_to_circuit(const QkDag *dag)

Converta um determinado DAG em um circuito.

O novo circuito é copiado do DAG; a referência dag original ainda pertence ao chamador e ainda precisa ser liberada com qk_dag_free. Você deve liberar o circuito retornado com qk_circuit_free quando terminar de usá-lo.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);

QkCircuit *qc = qk_dag_to_circuit(dag);

qk_circuit_free(qc);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG a partir do qual criar o circuito.

Retorna

Um indicador para o novo circuito.

qk_dag_topological_op_nodes

void qk_dag_topological_op_nodes(const QkDag *dag, uint32_t *out_order)

Retorne os nós de operação no DAG listados em ordem topológica.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);

uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
qk_dag_apply_gate(dag, QkGate_S, qubit, NULL, false);

// get the number of operation nodes
uint32_t num_ops = qk_dag_num_op_nodes(dag); // 2
uint32_t *out_order = malloc(sizeof(uint32_t) * num_ops);

// get operation nodes listed in topological order
qk_dag_topological_op_nodes(dag, out_order);

// do something with the ordered nodes
for (uint32_t i = 0; i < num_ops; i++) {
    QkGate gate = qk_dag_op_node_gate_op(dag, out_order[i], NULL);
    printf("The gate at location %u is %u.\n", i, gate);
}

// free the out_order array, register, and dag pointer when done
free(out_order);
qk_quantum_register_free(qr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um QkDag ou se não out_order for um ponteiro válido e diferente de nulo para uma sequência de qk_dag_num_op_nodes(dag) elementos consecutivos de uint32_t.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • out_order – Um ponteiro para uma matriz de qk_dag_num_op_nodes(dag) elementos do tipo uint32_t, onde esta função irá gravar a saída.

qk_dag_substitute_node_with_dag

void qk_dag_substitute_node_with_dag(QkDag *dag, uint32_t node, const QkDag *replacement)

Substituir um nó em um QkDag por um subcircuito especificado por outro QkDag

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);

uint32_t qubit[1] = {0};
uint32_t node_to_replace = qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
qk_dag_apply_gate(dag, QkGate_S, qubit, NULL, false);

// Build replacement dag for H
QkDag *replacement = qk_dag_new();
QkQuantumRegister *replacement_qr = qk_quantum_register_new(1, "other");
qk_dag_add_quantum_register(replacement, replacement_qr);
double pi_param[1] = {3.14159};
qk_dag_apply_gate(replacement, QkGate_RZ, qubit, pi_param, false);
qk_dag_apply_gate(replacement, QkGate_SX, qubit, NULL, false);
qk_dag_apply_gate(replacement, QkGate_RZ, qubit, pi_param, false);

qk_dag_substitute_node_with_dag(dag, node_to_replace, replacement);

// Free the replacement dag, register, dag, and register
qk_quantum_register_free(replacement_qr);
qk_dag_free(replacement);
qk_quantum_register_free(qr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se dag e não replacement forem ponteiros válidos e diferentes de nulo para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG.
  • – O índice do nó da operação a ser substituída pela outra QkDag. Este deve ser o índice do nó para um nó de operação em dag e a contagem de qargs e cargs deve corresponder ao número de qubits e clbits em replacement.
  • substituição – O outro QkDag para substituir node . Este dag deve ter o mesmo número de qubits que a operação para node. A ordenação dos bits do nó será tratada em ordem, portanto, node``qargs[0] para será mapeado para qubits[0] em replacement, qargs[1] para qubits[0], etc. O mesmo padrão se aplica também aos bits clássicos.

qk_dag_copy_empty_like

QkDag *qk_dag_copy_empty_like(const QkDag *dag, QkVarsMode vars_mode, QkBlocksMode blocks_mode)

Retorna uma cópia de si mesmo com a mesma estrutura, mas vazia.

Essa estrutura inclui:

  • nome e outros metadados
  • fase global
  • duração
  • todos os qubits e clbits, incluindo os registros.

Exemplo

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);

uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);

// As the DAG does not contain any control-flow instructions,
// vars_mode and blocks_mode do not have any effect.
QkDag *copied_dag = qk_dag_copy_empty_like(dag, QkVarsMode_Alike, QkBlocksMode_Drop);
uint32_t num_ops_in_copied_dag = qk_dag_num_op_nodes(copied_dag); // 0

// do something with copied_dag

qk_quantum_register_free(qr);
qk_dag_free(dag);
qk_dag_free(copied_dag);

Segurança

O comportamento é indefinido se não dag for um ponteiro válido para um QkDag.

Parâmetros

  • dag – Um ponteiro para o DAG a ser copiado.
  • vars_mode – O modo para lidar com variáveis clássicas.
  • blocks_mode – O modo para lidar com blocos.

Retorna

O ponteiro para o circuito DAG copiado.

qk_dag_replace_block_with_unitary

uint32_t qk_dag_replace_block_with_unitary(QkDag *dag, uint32_t num_block_ids, const uint32_t *block_ids, const QkComplex64 *matrix, uint32_t num_qubits, const uint32_t *qubits, bool cycle_check)

Substitua um bloco contíguo não vazio de nós em um QkDag por um único portão unitário correspondente à matriz unitária especificada.

Após a substituição, os nós do bloco são removidos e substituídos por um novo nó que atua sobre os qubits em questão.

Exemplo

// Create a DAG with H, T, S, T, H gates on the second qubit
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {1};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
uint32_t idx1 = qk_dag_apply_gate(dag, QkGate_T, qubit, NULL, false);
uint32_t idx2 = qk_dag_apply_gate(dag, QkGate_S, qubit, NULL, false);
uint32_t idx3 = qk_dag_apply_gate(dag, QkGate_T, qubit, NULL, false);
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);

// Replace the inner T, S, T gates by a unitary gate (representing Z)
uint32_t replaced_ids[3] = {idx1, idx2, idx3};
static const QkComplex64 mat_z[4] = {{1, 0}, {0, 0}, {0, 0}, {-1, 0}};
uint32_t new_node_idx =
    qk_dag_replace_block_with_unitary(dag, 3, replaced_ids, mat_z, 1, qubit, false);

// free the register and dag pointer when done
qk_quantum_register_free(qr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se qualquer uma das seguintes condições se verificar:

  • dag não é um ponteiro alinhado e diferente de nulo para um válido QkDag,
  • qubits não é um ponteiro alinhado para valores num_qubits inicializados.
  • matrix não é um ponteiro alinhado para valores 4**num_qubits inicializados,
  • block_ids não é um ponteiro alinhado a valores num_block_ids inicializados.

Parâmetros

  • dag – Ponteiro para o DAG.
  • num_block_ids – Número de entradas em block_ids. Esse número não pode ser zero.
  • block_ids – Ponteiro para uma matriz não vazia de nós a serem substituídos.
  • matriz – Ponteiro para uma matriz unitária com disposição por linhas, inicializada, de tamanho 4**num_qubits.
  • num_qubits – O número de qubits sobre os quais a porta unitária resultante atua.
  • qubits – Ponteiro para uma matriz de índices de qubits uint32_t distintos. Cada entrada especifica o índice do qubit DAG que corresponde à respectiva posição do argumento na porta unitária.
  • cycle_check – Se true, a função verifica se a substituição do nó fornecido block_ids por um único nó introduziria um ciclo no DAG (o que invalidaria o DAG). Se for criado um ciclo, o DAG permanece inalterado e UINT32_MAX é retornado. Essa verificação acarreta uma perda de desempenho. Se for possível garantir que o bloco fornecido block_ids é contíguo e não criará um ciclo ao ser reduzido a um único nó, esse valor pode ser definido como false.

Retorna

O índice do nó de operação recém-adicionado, ou UINT32_MAX se cycle_check for true e a substituição introduzir um ciclo.

qk_dag_substitute_node_with_unitary

void qk_dag_substitute_node_with_unitary(QkDag *dag, uint32_t node, const QkComplex64 *matrix, uint32_t num_qubits)

Substitua uma operação em um nó de uma rede QkDag por uma porta unitária correspondente à matriz unitária especificada.

A nova operação deve ter a mesma forma que a operação substituída. Os qargs e cargs do nó permanecerão os mesmos.

Exemplo

// Create a DAG with a Z-gate
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
uint32_t idx_z = qk_dag_apply_gate(dag, QkGate_Z, (uint32_t[]){1}, NULL, false);

static const QkComplex64 mat[4] = {{1, 0}, {0, 0}, {0, 0}, {-1, 0}};

// Replace the Z-gate by a unitary matrix
qk_dag_substitute_node_with_unitary(dag, idx_z, mat, 1);

// free the register and dag pointer when done
qk_quantum_register_free(qr);
qk_dag_free(dag);

Segurança

O comportamento é indefinido se qualquer uma das seguintes condições se verificar:

  • dag não é um ponteiro alinhado e diferente de nulo para um válido QkDag,
  • matrix não é um ponteiro alinhado para valores 4**num_qubits inicializados,

Parâmetros

  • dag – Ponteiro para o DAG.
  • – O nó cuja operação é substituída. O número de qubits na operação substituída deve ser igual a num_qubits e o número de clbits deve ser 0.
  • matriz – Ponteiro para uma matriz unitária com disposição por linhas, inicializada, de tamanho 4**num_qubits.
  • num_qubits – O número de qubits sobre os quais a operação unitária atua.

qk_dag_to_python

PyObject *qk_dag_to_python(QkDag *dag)

Passe a propriedade de um QkDag objeto para Python.

Não é seguro usar o QkDag ponteiro após chamar esta função. Em particular, você não deve tentar apagá-lo ou liberá-lo. O chamador deve ser o proprietário do objeto QkDag, e não possuir uma referência emprestada (por exemplo, um objeto QkDag * recuperado de um retrieved from não qk_dag_borrow_from_python é de sua propriedade).

Segurança

O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não dag for um ponteiro válido e diferente de nulo para um objeto inicializado e de propriedade do usuário QkDag.

Parâmetros

  • dag – O objeto em questão.

Retorna

Uma referência de propriedade do tipo Python ao objeto.

qk_dag_borrow_from_python

QkDag *qk_dag_borrow_from_python(PyObject *ob)

Recuperar um QkDag ponteiro de um objeto Python.

Isso utiliza uma referência de tipo Python e extrai o QkDag ponteiro correspondente, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro ob . Se o não PyObject for do tipo correto, o valor de retorno é NULL e o estado de exceção do interpretador do Python é definido.

Você deve estar conectado a um interpretador Python para chamar esta função.

Você também pode usar qk_dag_convert_from_python, que é, em termos lógicos, exatamente igual a esta função, mas pode ser usada diretamente como uma função “conversora” para a PyArg_Parse* família de funções conversoras do Python.

Segurança

O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não ob for um ponteiro válido e diferente de nulo para um objeto Python.

Parâmetros

  • ob – Um objeto de empréstimo do tipo Python.

Retorna

Um ponteiro para o objeto nativo, ou NULL se o objeto Python for do tipo incorreto.

qk_dag_convert_from_python

int qk_dag_convert_from_python(PyObject *object, void *address)

Recuperar um ponteiro DAG de um objeto Python.

Isso utiliza uma referência do tipo Python e extrai o QkDag ponteiro correspondente para address``,, caso seja do tipo correto. O ponteiro retornado é obtido do ponteiro object . Se o não PyObject for do tipo correto, o valor de retorno é 1, o estado de exceção do interpretador do Python é definido e address permanece inalterado.

Você deve estar conectado a um interpretador Python para chamar esta função.

Você também pode usar qk_dag_borrow_from_python, que é, na prática, exatamente o mesmo que isto, mas com uma sintaxe mais natural para uso direto.

Segurança

O chamador deve estar conectado a um intérprete do tipo Python. O comportamento é indefinido se não object for um ponteiro válido e diferente de nulo para um objeto Python, ou se não address for um ponteiro para dados graváveis do tipo correto.

Parâmetros

  • objeto – Um objeto Python obtido por empréstimo.
  • endereço – O local onde a saída deve ser gravada.

Retorna

1 em caso de sucesso, 0 em caso de falha.

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