Skip to main content
IBM Quantum Platform

QkDag

typedef struct QkDag QkDag

La QkDag estructura expone una interfaz de bajo nivel a la representación del gráfico acíclico dirigido (DAG) del transpilador Qiskit de un circuito cuántico para su uso en pasadas del transpilador. Solo expone lo que se define en el modelo de datos interno de Qiskit. Por lo tanto, le faltan algunas funciones que están disponibles en la clase de nivel DAGCircuit superior Python.

Actualmente, la API C solo admite la creación de DAG que contengan operaciones definidas en el modelo de datos interno Rust de Qiskit. Por lo general, esto incluye solo puertas de la biblioteca de puertas estándar, operaciones estándar no unitarias (actualmente Barrier, Measure, Reset, y Delay) y UnitaryGate. Esta funcionalidad se ampliará con el tiempo a medida que el modelo de datos de Rust se amplíe para admitir de forma nativa más funcionalidades.


Tipos de datos

QkDagNodeType

enum QkDagNodeType

El tipo de nodo en un QkDag.

Los nodos de operación representan una instrucción aplicada. El resto de los nodos se consideran nodos «de conexión» y representan los extremos de las cadenas de dependencia de datos del DAG.

Valores:

enumerador QkDagNodeType_Operation

Nodo de operación.

enumerador QkDagNodeType_QubitIn

Nodo de inicio del cable Qubit.

enumerador QkDagNodeType_QubitOut

Nodo terminal del cable Qubit.

enumerador QkDagNodeType_ClbitIn

Nodo inicial del cable Clbit.

enumerador QkDagNodeType_ClbitOut

Nodo terminal de cable Clbit.

enumerador QkDagNodeType_VarIn

Nodo clásico de inicio de cable variable.

enumerador QkDagNodeType_VarOut

Nodo terminal de cable variable clásico.

QkOperationKind

enum QkOperationKind

El tipo de operación.

Esto se devuelve al consultar un nodo concreto del gráfico con qk_dag_op_node_kind, y su finalidad es permitir al llamante distribuir (por ejemplo, mediante un «switch») llamadas específicas para el tipo de operación contenida.

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 se utiliza como tipo opaco para operaciones que aún no se han implementado en el modelo de datos nativo.

encuestador QkOperationKind_PauliProductRotation

QkDagNeighbors

struct QkDagNeighbors

Una estructura para almacenar información sobre sucesores y predecesores obtenida de qk_dag_successors y qk_dag_predecessors, respectivamente.

Este objeto es de solo lectura desde C. Para cumplir con las garantías de seguridad de qk_dag_neighbors_clear, no debe sobrescribir ningún dato inicializado por qk_dag_successors o qk_dag_predecessors, incluidos los datos a los que se apunta.

const uint32_t *vecinos

Matriz de tamaño num_neighbors de índices de nodos.

tamaño_t número_vecinos

La longitud de la neighbors matriz.


Funciones

qk_dag_new

QkDag *qk_dag_new(void)

Construye un nuevo DAG vacío.

Debe liberar el DAG devuelto con qk_dag_free cuando haya terminado de utilizarlo.

Ejemplo

QkDag *empty = qk_dag_new();

Devuelve

Un puntero al DAG creado.

qk_dag_add_quantum_register

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

Añadir un registro cuántico al DAG.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag y si no reg es un puntero válido y distinto de nulo a un QkQuantumRegister.

Parámetros

  • dag : un puntero al DAG.
  • reg : un puntero al registro cuántico.

qk_dag_add_classical_register

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

Añadir un registro clásico al DAG.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag y si no reg es un puntero válido y distinto de nulo a un QkClassicalRegister.

Parámetros

  • dag : un puntero al DAG.
  • reg – Un puntero al registro clásico.

qk_dag_num_qubits

uint32_t qk_dag_num_qubits(const QkDag *dag)

Obtenga el número de qubits que contiene el DAG.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.

Devuelve

El número de qubits en los que se define el DAG.

qk_dag_num_clbits

uint32_t qk_dag_num_clbits(const QkDag *dag)

Obtenga el número de clbits que contiene el DAG.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.

Devuelve

El número de clbits en los que se define el DAG.

qk_dag_num_op_nodes

size_t qk_dag_num_op_nodes(const QkDag *dag)

Devuelve el número total de nodos de operación en el DAG.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.

Devuelve

El número total de instrucciones en el DAG.

qk_dag_node_type

QkDagNodeType qk_dag_node_type(const QkDag *dag, uint32_t node)

Obtener el tipo del nodo especificado.

El resultado se puede utilizar en una instrucción switch para enviar el manejo adecuado al iterar sobre nodos de tipo desconocido.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo del que se desea obtener el tipo.

Devuelve

El tipo del nodo.

qk_dag_qubit_in_node

uint32_t qk_dag_qubit_in_node(const QkDag *dag, uint32_t qubit)

Recupera el índice del nodo de entrada del cable correspondiente al qubit dado.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • qubit : el qubit del que se obtiene el índice del nodo de entrada.

Devuelve

El nodo de entrada del cable cuántico.

qk_dag_qubit_out_node

uint32_t qk_dag_qubit_out_node(const QkDag *dag, uint32_t qubit)

Recupera el índice del nodo de salida del cable correspondiente al qubit dado.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • qubit : el qubit del que se obtiene el índice del nodo de salida.

Devuelve

El nodo de salida del cable cuántico.

qk_dag_clbit_in_node

uint32_t qk_dag_clbit_in_node(const QkDag *dag, uint32_t clbit)

Recupera el índice del nodo de entrada del cable correspondiente al clbit dado.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • clbit : el clbit para obtener el índice del nodo de entrada.

Devuelve

El nodo de entrada del cable clbit.

qk_dag_clbit_out_node

uint32_t qk_dag_clbit_out_node(const QkDag *dag, uint32_t clbit)

Recupera el índice del nodo de salida del cable correspondiente al clbit dado.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • clbit : el clbit del que se obtiene el índice del nodo de salida.

Devuelve

El nodo de salida del cable clbit.

qk_dag_wire_node_value

uint32_t qk_dag_wire_node_value(const QkDag *dag, uint32_t node)

Recuperar el valor de un nodo de punto final de cable.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo final del que se obtiene el valor del cable.

Devuelve

El valor (por ejemplo, qubit, clbit o var) dentro del nodo del punto final.

qk_dag_op_node_num_qubits

uint32_t qk_dag_op_node_num_qubits(const QkDag *dag, uint32_t node)

Obtiene el número de qubits del nodo de operación especificado.

Entra en pánico si el nodo no es una operación.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo de operación del que se desea obtener el número de qubits.

Devuelve

El número de qubits de la operación.

qk_dag_op_node_num_clbits

uint32_t qk_dag_op_node_num_clbits(const QkDag *dag, uint32_t node)

Obtiene el número de clbits del nodo de operación especificado.

Entra en pánico si el nodo no es una operación.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo de operación del que se obtiene el número de clbits.

Devuelve

El número de clbits de la operación.

qk_dag_op_node_num_params

uint32_t qk_dag_op_node_num_params(const QkDag *dag, uint32_t node)

Obtiene el número de parámetros del nodo de operación especificado.

Entra en pánico si el nodo no es una operación.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo de operación del que se obtiene el número de parámetros.

Devuelve

El número de parámetros de la operación.

qk_dag_op_node_qubits

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

Recupera los qubits del nodo de operación especificado.

Entra en pánico si el nodo no es una operación.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo de operación del que se obtienen los qubits.

Devuelve

Un puntero a los qubits. Utilice qk_dag_op_node_num_qubits para determinar el número de elementos.

qk_dag_op_node_clbits

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

Recupera los clbits del nodo de operación especificado.

Entra en pánico si el nodo no es una operación.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo de operación del que se obtienen los clbits.

Devuelve

Un puntero a clbits. Utilice qk_dag_op_node_num_clbits para determinar el 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)

Aplicar un QkGate al DAG.

Ejemplo

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);

Seguridad

Se espera que los qubits``params tipos y sean punteros a una matriz de uint32_t y double respectivamente, donde la longitud coincida con las expectativas para la puerta estándar. Si la matriz no es lo suficientemente larga, el comportamiento de esta función es indefinido, ya que leerá fuera de los límites de la matriz. Puede ser un puntero nulo si no hay qubits o parámetros para una puerta determinada. Puede consultar qk_gate_num_qubits y qk_gate_num_params para determinar cuántos qubits y parámetros se requieren para una puerta determinada.

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG al que se aplicará la puerta.
  • gate – El « StandardGate » que se debe aplicar.
  • qubits : el puntero a la matriz de índices uint32_t de qubits a los que se va a añadir la puerta. Esto puede ser un puntero nulo si no hay qubits para gate (por ejemplo, QkGate_GlobalPhase).
  • params : el puntero a la matriz de double valores que se utilizarán para los parámetros de la puerta. Esto puede ser un puntero nulo si no hay parámetros para gate (por ejemplo, QkGate_H).
  • front – Si true, la puerta se aplica como la primera operación en los qubits especificados, en lugar de como la última.

Devuelve

El índice del nodo de operación recién añadido.

qk_dag_apply_measure

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

Aplicar una medida a un DAG.

Ejemplo

Mida todos los qubits en el índice clbit correspondiente al final del 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);
}

Seguridad

El comportamiento es indefinido si no dag es un puntero alineado y distinto de nulo a un válido QkDag, o si qubit o clbit están fuera de rango.

Parámetros

  • dag – El circuito al que se aplica.
  • qubit : el índice qubit que se va a medir.
  • clbit : el índice clbit en el que se almacenará el resultado.
  • front : si se debe aplicar la medida al inicio del circuito. Normalmente false.

Devuelve

El índice de nodo de la instrucción creada.

qk_dag_apply_reset

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

Aplica un restablecimiento al DAG.

Ejemplos

Aplicar reinicios iniciales en todos los 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);
}

Seguridad

El comportamiento es indefinido si no dag es un puntero alineado y distinto de nulo a un válido QkDag, o si qubit está fuera de rango.

Parámetros

  • dag – El circuito al que se aplica.
  • qubit : el índice del qubit que se va a restablecer.
  • front : si se debe aplicar el reinicio al inicio del circuito. Normalmente false.

Devuelve

El índice de nodo de la instrucción creada.

qk_dag_apply_barrier

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

Aplica una barrera al DAG.

Ejemplos

Aplicar una barrera final en todos los qubits:

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

Aplica una barrera al comienzo de un circuito en índices de qubits específicos:

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);

Seguridad

El comportamiento es indefinido si:

  • dag no es un puntero alineado y distinto de nulo a un válido QkDag,
  • qubits no está alineado o no es válido para num_qubits lecturas de índices inicializados, dentro de los límites y no duplicados, a menos que qubits sea nulo.

Parámetros

  • dag – El circuito al que se aplica.
  • qubits : los índices de qubits a los que se aplicará la barrera. Esto puede ser nulo, en cuyo caso no num_qubits se lee, y la barrera se aplica a todos los qubits del DAG.
  • num_qubits : a cuántos qubits se aplica la barrera.
  • frente : si se debe aplicar la barrera al inicio del circuito. Normalmente false.

Devuelve

El índice de nodo de la instrucción creada.

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)

Aplicar una puerta unitaria a un DAG.

Los valores en matrix deben formar una matriz unitaria de tamaño correcto para el número de qubits. Los datos se copian desde el puntero y solo deben ser válidos para lecturas hasta que esta función regrese.

Véase: Convenciones de circuitos para obtener más detalles sobre las convenciones de etiquetado de bits y matrices de Qiskit.

Seguridad

El comportamiento es indefinido si se da cualquiera de las siguientes condiciones:

  • dag no es un puntero alineado y distinto de nulo a un válido QkDag,
  • matrix no es un puntero alineado a valores 4**num_qubits inicializados,
  • qubits no es un puntero alineado con valores num_qubits inicializados.

Parámetros

  • dag – El circuito al que se aplica.
  • matriz : una matriz unitaria inicializada con prioridad de filas y un tamaño 4**num_qubitstotal de.
  • qubits : una matriz de índices uint32_t distintos de los qubits.
  • num_qubits : el número de qubits a los que se aplica la puerta.
  • front : si se debe aplicar la puerta al inicio del circuito. Normalmente false.

Devuelve

El índice de nodo de la instrucción creada.

qk_dag_op_node_gate_op

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

Recuperar la puerta estándar del nodo especificado.

Entra en pánico si el nodo no es una operación de puerta estándar.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag. Si out_params no es NULL, debe apuntar a un búfer lo suficientemente grande como para contener todos los parámetros de la puerta; de lo contrario, el comportamiento es indefinido, ya que esta función escribirá más allá de sus límites. Puede comprobar qk_dag_op_node_num_params para determinar cuántos parámetros se requieren para cualquier nodo de operación dado.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo de operación del que se obtiene la puerta estándar.
  • out_params : un búfer que se rellenará con los parámetros de la puerta o NULL si no se desean.

Devuelve

El valor de la puerta.

qk_dag_op_node_unitary

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

Copia la matriz unitaria del índice de nodo correspondiente.

Entra en pánico si el nodo no es una puerta unitaria.

Seguridad

El comportamiento es indefinido si no dag es un puntero distinto de nulo a un válido QkDag, si out no está alineado o si no out es válido para 4**num_qubits escrituras de QkComplex64.

Parámetros

  • dag : el circuito desde el que se lee.
  • nodo : el índice del nodo de la instrucción de matriz unitaria.
  • out – Memoria asignada y alineada para valores 4**num_qubits complejos en orden de fila mayor, donde num_qubits es el número de qubits al que se aplica la puerta.

qk_dag_op_node_kind

QkOperationKind qk_dag_op_node_kind(const QkDag *dag, uint32_t node)

Obtener el «tipo» de un nodo de operación.

El resultado se puede utilizar en una instrucción switch para enviar el manejo adecuado al iterar sobre los nodos de operación.

Entra en pánico si no node es un nodo de operación.

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo de operación del que se obtiene el «tipo».

Devuelve

El «tipo» del nodo.

qk_dag_successors

QkDagNeighbors qk_dag_successors(const QkDag *dag, uint32_t node)

Recupera los sucesores del nodo especificado.

La matriz de sucesores y su longitud se devuelven como una QkDagNeighbors estructura, donde cada elemento de la matriz corresponde a un índice de nodo DAG. Debe llamar a la qk_dag_neighbors_clear función cuando haya terminado para liberar la memoria asignada a la estructura.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo del que se obtienen los sucesores.

Devuelve

Una instancia de la QkDagNeighbors estructura con la información de los sucesores.

qk_dag_predecessors

QkDagNeighbors qk_dag_predecessors(const QkDag *dag, uint32_t node)

Recupera los predecesores del nodo especificado.

La matriz de predecesores y su longitud se devuelven como una QkDagNeighbors estructura, donde cada elemento de la matriz corresponde a un índice de nodo DAG. Debe llamar a la qk_dag_neighbors_clear función cuando haya terminado para liberar la memoria asignada a la estructura.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el nodo del que se obtienen los predecesores.

Devuelve

Una instancia de la QkDagNeighbors estructura con la información de los predecesores.

qk_dag_neighbors_clear

void qk_dag_neighbors_clear(QkDagNeighbors *neighbors)

Borrar los campos de la estructura de QkDagNeighbors entrada.

La función desasigna la memoria apuntada por el neighbors campo y la establece en NULL. También establece el num_neighbors campo en 0.

Seguridad

El comportamiento es indefinido si no neighbors es un puntero válido y distinto de nulo a un QkDagNeighbors objeto rellenado con o qk_dag_successors qk_dag_predecessors.

Parámetros

  • vecinos : un puntero a un QkDagNeighbors objeto.

qk_dag_get_instruction

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

Devuelve los detalles de una instrucción en el circuito.

Esto es un espejo de qk_circuit_get_instruction. También puede utilizar métodos individuales como qk_dag_op_node_gate_op para obtener propiedades individuales.

Debe llamar qk_circuit_instruction_clear para restablecer el QkCircuitInstruction antes de volver a utilizarlo o desecharlo.

Ejemplos

Iterar a través de un DAG para encontrar qué qubits tienen 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);

Seguridad

El comportamiento es indefinido si o dag no instruction son punteros válidos, alineados y distintos de nulo al tipo de datos relevante. Los campos de no instruction es necesario inicializarlos.

Parámetros

  • dag : el circuito desde el que se recupera la instrucción.
  • índice : el índice del nodo. Es un error pasar un índice que no es un nodo operativo válido.
  • instrucción : un punto donde escribir el QkCircuitInstruction.

qk_dag_compose

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

Componer el other DAG en la dag instancia con la opción de que un subconjunto de cables de entrada de other se asigne a un subconjunto de cables de salida de dag.

other puede incluir un número menor o igual de cables para cada tipo.

Ejemplo

// 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);

Seguridad

El comportamiento es indefinido si dag o no other son punteros válidos y distintos de nulo a un QkDag. Si qubit ni clbit son NULL, debe contener una cantidad menor o igual a la que posee el circuito.

Parámetros

  • dag : un puntero al DAG que se va a componer.
  • otro : un puntero al DAG con el que dagcomponer.
  • qubits : una lista de índices que representan los cables qubit sobre los que se va a componer.
  • clbits : una lista de índices que representan los cables clbit sobre los que componer.

Devuelve

QkExitCode_Success tras una descomposición satisfactoria; de lo contrario, un código de error específico de DAG que indica la causa del fallo.

qk_dag_free

void qk_dag_free(QkDag *dag)

Libera el DAG.

Ejemplo

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

Seguridad

El comportamiento es indefinido si no dag es nulo ni un puntero válido a un QkDag.

Parámetros

  • dag : un puntero al DAG que se va a liberar.

qk_dag_to_circuit

QkCircuit *qk_dag_to_circuit(const QkDag *dag)

Convertir un DAG dado en un circuito.

El nuevo circuito se copia del DAG; la referencia dag original sigue siendo propiedad del llamante y sigue siendo necesario liberarla con qk_dag_free. Debe liberar el circuito devuelto con qk_circuit_free cuando haya terminado de utilizarlo.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG desde el que crear el circuito.

Devuelve

Un indicador del nuevo circuito.

qk_dag_topological_op_nodes

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

Devuelve los nodos de operación en el DAG ordenados por orden topológico.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido y distinto de nulo a un QkDag o si no out_order es un puntero válido y distinto de nulo a una secuencia de qk_dag_num_op_nodes(dag) elementos consecutivos de uint32_t.

Parámetros

  • dag : un puntero al DAG.
  • out_order : un puntero a una matriz de qk_dag_num_op_nodes(dag) elementos de tipo uint32_t, donde esta función escribirá la salida.

qk_dag_substitute_node_with_dag

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

Sustituir un nodo de un circuito QkDag por un subcircuito especificado por otro QkDag

Ejemplo

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);

Seguridad

El comportamiento es indefinido si dag y no replacement son punteros válidos y distintos de nulo a un QkDag.

Parámetros

  • dag : un puntero al DAG.
  • nodo : el índice del nodo de la operación que se va a sustituir por el otro QkDag. Este debe ser el índice de nodo para un nodo de operación en dag y el recuento de qargs y cargs debe coincidir con el número de qubits y clbits en replacement.
  • reemplazo – El otro QkDag para reemplazar node con. Este dag debe tener el mismo número de qubits que la operación para node. El orden de los bits del nodo se gestionará por orden, por lo que qargs[0] para node se asignará a qubits[0] en replacement, qargs[1] a qubits[0], etc. El mismo patrón se aplica también a los bits clásicos.

qk_dag_copy_empty_like

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

Devuelve una copia de sí mismo con la misma estructura, pero vacía.

Esa estructura incluye:

  • nombre y otros metadatos
  • fase global
  • duración
  • todos los qubits y clbits, incluidos los registros.

Ejemplo

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);

Seguridad

El comportamiento es indefinido si no dag es un puntero válido a un QkDag.

Parámetros

  • dag : un puntero al DAG que se va a copiar.
  • vars_mode : modo para manejar variables clásicas.
  • blocks_mode : modo para gestionar bloques.

Devuelve

El puntero al 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)

Sustituye un bloque contiguo no vacío de nodos en un QkDag por una única puerta unitaria correspondiente a la matriz unitaria especificada.

Al realizar la sustitución, los nodos del bloque se eliminan y se sustituyen por un nuevo nodo que actúa sobre los qubits indicados.

Ejemplo

// 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);

Seguridad

El comportamiento es indefinido si se da cualquiera de las siguientes condiciones:

  • dag no es un puntero alineado y distinto de nulo a un válido QkDag,
  • qubits no es un puntero alineado con valores num_qubits inicializados.
  • matrix no es un puntero alineado a valores 4**num_qubits inicializados,
  • block_ids no es un puntero alineado a valores num_block_ids inicializados.

Parámetros

  • dag – Puntero al DAG.
  • num_block_ids – Número de entradas en block_ids. Este número debe ser distinto de cero.
  • block_ids : puntero a una matriz no vacía de nodos que se van a sustituir.
  • matriz – Puntero a una matriz unitaria inicializada con orden de filas de tamaño 4**num_qubits.
  • num_qubits : el número de qubits sobre los que actúa la puerta unitaria resultante.
  • qubits : puntero a una matriz de índices de qubits uint32_t distintos. Cada entrada especifica el índice del qubit DAG que corresponde a la posición del argumento respectivo en la puerta unitaria.
  • cycle_check – Si truese activa, la función comprueba si sustituir el nodo proporcionado block_ids por un único nodo introduciría un ciclo en el DAG (lo que invalidaría el DAG). Si se creara un ciclo, el DAG no se modificaría y UINT32_MAX se devolvería tal cual. Esta comprobación conlleva una pérdida de rendimiento. Si puedes garantizar que el bloque proporcionado block_ids es contiguo y que no dará lugar a un ciclo al reducirse a un único nodo, se puede establecer en false.

Devuelve

El índice del nodo de operación recién añadido, o UINT32_MAX si cycle_check es true y la sustitución daría lugar a un 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)

Sustituye una operación en un nodo de un grafo QkDag por una puerta unitaria correspondiente a la matriz unitaria especificada.

La nueva operación debe tener la misma forma que la operación sustituida. Los qargs y cargs del nodo seguirán siendo los mismos.

Ejemplo

// 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);

Seguridad

El comportamiento es indefinido si se da cualquiera de las siguientes condiciones:

  • dag no es un puntero alineado y distinto de nulo a un válido QkDag,
  • matrix no es un puntero alineado a valores 4**num_qubits inicializados,

Parámetros

  • dag – Puntero al DAG.
  • nodo : el nodo cuya operación se sustituye. El número de qubits en la operación sustituida debe ser igual a num_qubits y el número de clbits debe ser 0.
  • matriz – Puntero a una matriz unitaria inicializada con orden de filas de tamaño 4**num_qubits.
  • num_qubits : el número de qubits sobre los que actúa el operador unitario.

qk_dag_to_python

PyObject *qk_dag_to_python(QkDag *dag)

Pasa la propiedad de un QkDag objeto a « Python ».

No es seguro utilizar el QkDag puntero después de llamar a esta función. En particular, no debes intentar borrarlo ni liberarlo. El autor de la llamada debe ser el propietario del objeto QkDag, y no tener una referencia prestada (por ejemplo, un objeto QkDag * recuperado de no qk_dag_borrow_from_python es de su propiedad).

Seguridad

La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no dag es un puntero válido y no nulo a un objeto inicializado y del que se tiene propiedad QkDag.

Parámetros

  • dag – El objeto en cuestión.

Devuelve

Una referencia de tipo « Python » al objeto.

qk_dag_borrow_from_python

QkDag *qk_dag_borrow_from_python(PyObject *ob)

Obtener un QkDag puntero de un objeto Python.

Esto toma prestada una referencia de tipo « Python » y extrae el QkDag puntero correspondiente, siempre que sea del tipo adecuado. El puntero devuelto se toma prestado del ob puntero. Si el PyObject tipo no es el correcto, el valor de retorno es NULL y se establece el estado de excepción del intérprete de Python.

Para llamar a esta función, debes estar conectado a un intérprete de Python.

También puedes utilizar qk_dag_convert_from_python, que lógicamente es exactamente igual que esta función, pero que se puede emplear directamente como función «convertidora» para la PyArg_Parse* familia de funciones de conversión de Python.

Seguridad

La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no ob es un puntero válido y no nulo a un objeto Python.

Parámetros

  • ob : un objeto de tipo « Python » tomado de otro lenguaje.

Devuelve

Un puntero al objeto nativo, o bien, NULL si el objeto Python es de un tipo incorrecto.

qk_dag_convert_from_python

int qk_dag_convert_from_python(PyObject *object, void *address)

Recuperar un puntero DAG de un objeto Python.

Esto toma prestada una referencia de tipo « Python » y extrae el QkDag puntero correspondiente a address, siempre que sea del tipo correcto. El puntero devuelto se toma prestado del object puntero. Si no es PyObject del tipo correcto, el valor de retorno es 1, se establece el estado de excepción del intérprete de Python, y address no sufre cambios.

Para llamar a esta función, debes estar conectado a un intérprete de Python.

También puedes usar qk_dag_borrow_from_python, que, lógicamente, es exactamente lo mismo que esto, pero con una sintaxis más natural para su uso directo.

Seguridad

La persona que llama debe estar conectada a un intérprete de Python. El comportamiento es indefinido si no object es un puntero válido y no nulo a un objeto Python, o si no address es un puntero a datos modificables del tipo correcto.

Parámetros

  • objeto : un objeto de tipo Python tomado en préstamo.
  • dirección : la ubicación en la que se escribirá la salida.

Devuelve

1 si se realiza correctamente, 0 si falla.

¿Le ha resultado útil esta página?
Informe de un error, de una errata o solicite contenido en GitHub.