QkDag
typedef struct QkDag QkDagLa QkDag struttura espone un'interfaccia di basso livello alla rappresentazione del grafico aciclico diretto (DAG) del transpiler Qiskit di un circuito quantistico da utilizzare nei passaggi del transpiler. Espone solo ciò che è definito nel modello di dati interno di Qiskit. Pertanto manca alcune funzionalità disponibili nella classe di DAGCircuit livello superiore Python.
L'API C attualmente supporta solo la creazione di DAG che contengono operazioni definite nel modello di dati Rust interno di Qiskit. In genere questo include solo i gate presenti nella libreria standard dei gate, le operazioni standard non unitarie (attualmente Barrier, Measure, Reset, e Delay) e UnitaryGate. Questa funzionalità verrà ampliata nel tempo, man mano che il modello di dati Rust verrà esteso per supportare in modo nativo ulteriori funzionalità.
Tipi di dati
QkDagNodeType
enum QkDagNodeType
Il tipo di nodo in un QkDag.
I nodi operativi rappresentano un'istruzione applicata. Il resto dei nodi sono considerati nodi "wire" e rappresentano i punti finali delle catene di dipendenza dei dati del DAG.
Valori:
enumeratore QkDagNodeType_Operation
Nodo operativo.
enumeratore QkDagNodeType_QubitIn
Nodo di inizio cavo Qubit.
enumeratore QkDagNodeType_QubitOut
Nodo terminale del cavo Qubit.
enumeratore QkDagNodeType_ClbitIn
Nodo iniziale del filo Clbit.
enumeratore QkDagNodeType_ClbitOut
Nodo terminale del cavo Clbit.
enumeratore QkDagNodeType_VarIn
Nodo classico con avvio a filo variabile.
enumeratore QkDagNodeType_VarOut
Nodo terminale classico a filo variabile.
QkOperationKind
enum QkOperationKind
Il tipo di operazione.
Questo viene restituito quando si interroga un particolare nodo nel grafico con qk_dag_op_node_kind, e ha lo scopo di consentire al chiamante di inviare (ad esempio tramite uno "switch") chiamate specifiche per il tipo di operazione contenuta.
Valori:
enumeratore QkOperationKind_Gate
enumeratore QkOperationKind_Barrier
enumeratore QkOperationKind_Delay
enumeratore QkOperationKind_Measure
enumeratore QkOperationKind_Reset
enumeratore QkOperationKind_Unitary
enumeratore QkOperationKind_PauliProductMeasurement
enumeratore QkOperationKind_ControlFlow
enumeratore QkOperationKind_Unknown
Questa variante è utilizzata come tipo opaco per operazioni non ancora implementate nel modello di dati nativo.
censitore QkOperationKind_PauliProductRotation
QkDagNeighbors
struct QkDagNeighbors
Una struttura per memorizzare le informazioni sui successori e sui predecessori recuperate rispettivamente da qk_dag_successors e qk_dag_predecessors.
Questo oggetto è di sola lettura da C. Per soddisfare le garanzie di sicurezza di qk_dag_neighbors_clear, non è consentito sovrascrivere alcun dato inizializzato da qk_dag_successors o qk_dag_predecessors, compresi i dati puntati.
const uint32_t *vicini
Matrice di dimensione num_neighbors degli indici dei nodi.
dimensione_t numero_vicini
La lunghezza neighbors dell'array.
Funzioni
qk_dag_new
QkDag *qk_dag_new(void)
Costruisci un nuovo DAG vuoto.
Una volta terminato, è qk_dag_free necessario liberare il DAG restituito con.
Esempio
QkDag *empty = qk_dag_new();Risultati
Un puntatore al DAG creato.
qk_dag_add_quantum_register
void qk_dag_add_quantum_register(QkDag *dag, const QkQuantumRegister *reg)
Aggiungi un registro quantistico al DAG.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e diverso da null a un QkDag e se non reg è un puntatore valido e diverso da null a un QkQuantumRegister.
Parametri
- dag – Un puntatore al DAG.
- reg – Un puntatore al registro quantistico.
qk_dag_add_classical_register
void qk_dag_add_classical_register(QkDag *dag, const QkClassicalRegister *reg)
Aggiungi un registro classico al DAG.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e diverso da null a un QkDag e se non reg è un puntatore valido e diverso da null a un QkClassicalRegister.
Parametri
- dag – Un puntatore al DAG.
- reg – Un puntatore al registro classico.
qk_dag_num_qubits
uint32_t qk_dag_num_qubits(const QkDag *dag)
Ottieni il numero di qubit contenuti nel DAG.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
Risultati
Il numero di qubit su cui è definito il DAG.
qk_dag_num_clbits
uint32_t qk_dag_num_clbits(const QkDag *dag)
Ottieni il numero di clbit contenuti nel DAG.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
Risultati
Il numero di clbit su cui è definito il DAG.
qk_dag_num_op_nodes
size_t qk_dag_num_op_nodes(const QkDag *dag)
Restituisce il numero totale di nodi operativi nel DAG.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
Risultati
Il numero totale di istruzioni nel DAG.
qk_dag_global_phase
QkParam *qk_dag_global_phase(const QkDag *dag)
Recupera la fase globale del DAG.
Questa funzione restituisce una copia della fase globale del DAG e il valore deve essere liberato tramite :c:func:qk_param_free dopo l'utilizzo.
Esempio
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(24, "my_register");
qk_dag_add_quantum_register(dag, qr);
QkParam *global_phase = qk_dag_global_phase(dag);
qk_param_free(global_phase);
qk_quantum_register_free(qr);
qk_dag_free(dag);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
Risultati
La fase globale del DAG.
qk_dag_set_global_phase
QkExitCode qk_dag_set_global_phase(QkDag *dag, const QkParam *phase)
Imposta la fase globale del DAG.
Questa funzione copia la nuova fase globale al momento della sua impostazione, pertanto chi la chiama mantiene la proprietà della QkParam fase, e il valore della fase deve essere liberato tramite :c:func:qk_param_free dopo l'impostazione.
Esempio
QkDag *dag = qk_dag_new();
QkParam *new_global_phase = qk_param_from_double(1.23);
qk_dag_set_global_phase(dag, new_global_phase);
qk_param_free(new_global_phase);
qk_dag_free(dag);Sicurezza
Il comportamento è indefinito se dag non è un puntatore valido e non nullo a un QkDag e se phase non è un puntatore valido e non nullo a un QkParam.
Parametri
- dag – Un puntatore al DAG.
- fase – Un puntatore alla fase globale da impostare.
Risultati
QkExitCode_Success una volta impostata correttamente la fase globale. In caso di errore, QkExitCode_ParameterError descrive gli errori generici che si verificano quando si tenta di tracciare i simboli dei parametri, come ad esempio valori di parametro non validi. In caso contrario, QkExitCode_DagError indica una causa dell'errore specifica del DAG.
qk_dag_node_type
QkDagNodeType qk_dag_node_type(const QkDag *dag, uint32_t node)
Ottieni il tipo del nodo specificato.
Il risultato può essere utilizzato in un'istruzione switch per inviare la gestione corretta durante l'iterazione su nodi di tipo sconosciuto.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo di cui ottenere il tipo.
Risultati
Il tipo del nodo.
qk_dag_qubit_in_node
uint32_t qk_dag_qubit_in_node(const QkDag *dag, uint32_t qubit)
Recupera l'indice del nodo di ingresso del filo corrispondente al qubit specificato.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- qubit – Il qubit da cui ottenere l'indice del nodo di input.
Risultati
Il nodo di ingresso del filo qubit.
qk_dag_qubit_out_node
uint32_t qk_dag_qubit_out_node(const QkDag *dag, uint32_t qubit)
Recupera l'indice del nodo di uscita del filo corrispondente al qubit specificato.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- qubit – Il qubit da cui ottenere l'indice del nodo di output.
Risultati
Il nodo di uscita del filo qubit.
qk_dag_clbit_in_node
uint32_t qk_dag_clbit_in_node(const QkDag *dag, uint32_t clbit)
Recupera l'indice del nodo di ingresso del cavo corrispondente al clbit specificato.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- clbit – Il clbit da cui ottenere l'indice del nodo di input.
Risultati
Il nodo di ingresso del cavo clbit.
qk_dag_clbit_out_node
uint32_t qk_dag_clbit_out_node(const QkDag *dag, uint32_t clbit)
Recupera l'indice del nodo di uscita del cavo corrispondente al clbit specificato.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- clbit – Il clbit da cui ottenere l'indice del nodo di output.
Risultati
Il nodo di uscita del cavo clbit.
qk_dag_wire_node_value
uint32_t qk_dag_wire_node_value(const QkDag *dag, uint32_t node)
Recupera il valore di un nodo endpoint wire.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo finale da cui ottenere il valore del cavo.
Risultati
Il valore (ad esempio qubit, clbit o var) all'interno del nodo endpoint.
qk_dag_op_node_num_qubits
uint32_t qk_dag_op_node_num_qubits(const QkDag *dag, uint32_t node)
Ottiene il numero di qubit del nodo operativo specificato.
Va nel panico se il nodo non è un'operazione.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo operativo da cui ottenere il numero di qubit.
Risultati
Il numero di qubit dell'operazione.
qk_dag_op_node_num_clbits
uint32_t qk_dag_op_node_num_clbits(const QkDag *dag, uint32_t node)
Ottiene il numero di clbit del nodo operativo specificato.
Va nel panico se il nodo non è un'operazione.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo operativo da cui ottenere il numero di clbit.
Risultati
Il numero di clbit dell'operazione.
qk_dag_op_node_num_params
uint32_t qk_dag_op_node_num_params(const QkDag *dag, uint32_t node)
Ottiene il numero di parametri del nodo operazione specificato.
Va nel panico se il nodo non è un'operazione.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo operativo da cui ottenere il numero di parametri.
Risultati
Il numero di parametri dell'operazione.
qk_dag_op_node_qubits
const uint32_t *qk_dag_op_node_qubits(const QkDag *dag, uint32_t node)
Recupera i qubit del nodo operativo specificato.
Va nel panico se il nodo non è un'operazione.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo operativo da cui ottenere i qubit.
Risultati
Un puntatore ai qubit. Utilizzare qk_dag_op_node_num_qubits per determinare il numero di elementi.
qk_dag_op_node_clbits
const uint32_t *qk_dag_op_node_clbits(const QkDag *dag, uint32_t node)
Recupera i clbit del nodo operativo specificato.
Va nel panico se il nodo non è un'operazione.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo operativo da cui ottenere i clbit.
Risultati
Un puntatore ai clbits. Utilizzare qk_dag_op_node_num_clbits per determinare il numero di elementi.
qk_dag_apply_gate
uint32_t qk_dag_apply_gate(QkDag *dag, QkGate gate, const uint32_t *qubits, const double *params, bool front)
Applicare un QkGate al DAG.
Esempio
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);Sicurezza
I tipi qubits``params e devono essere puntatori a un array di uint32_t e double rispettivamente, dove la lunghezza corrisponde alle aspettative per il gate standard. Se l'array non è sufficientemente lungo, il comportamento di questa funzione è indefinito poiché leggerà al di fuori dei limiti dell'array. Può essere un puntatore nullo se non ci sono qubit o parametri per un dato gate. È possibile controllare qk_gate_num_qubits e qk_gate_num_params per determinare quanti qubit e parametri sono necessari per un determinato gate.
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG a cui applicare il gate.
- gate – L' StandardGate o da compilare.
- qubit – Il puntatore all'array degli indici
uint32_tdei qubit su cui aggiungere il gate. Questo può essere un puntatore nullo se non ci sono qubit pergate(ad esempioQkGate_GlobalPhase). - params – Il puntatore all'array di
doublevalori da utilizzare per i parametri del gate. Questo può essere un puntatore nullo se non ci sono parametri pergate(ad esempioQkGate_H). - front – Se
true, il gate viene applicato come prima operazione sui qubit specificati, anziché come ultima.
Risultati
L'indice del nodo operativo appena aggiunto.
qk_dag_apply_measure
uint32_t qk_dag_apply_measure(QkDag *dag, uint32_t qubit, uint32_t clbit, bool front)
Applicare una misura a un DAG.
Esempio
Misura tutti i qubit nell'indice clbit corrispondente alla fine 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);
}Sicurezza
Il comportamento è indefinito se non dag è un puntatore allineato e diverso da null a un valido QkDag, oppure se qubit o clbit sono fuori intervallo.
Parametri
- dag – Il circuito a cui applicarsi.
- qubit – L'indice qubit da misurare.
- clbit – L'indice clbit in cui memorizzare il risultato.
- front – Se applicare la misura all'inizio del circuito. Di solito
false.
Risultati
L'indice del nodo dell'istruzione creata.
qk_dag_apply_reset
uint32_t qk_dag_apply_reset(QkDag *dag, uint32_t qubit, bool front)
Applicare un ripristino al DAG.
Esempi
Applicare i reset iniziali su tutti i qubit.
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);
}Sicurezza
Il comportamento è indefinito se non dag è un puntatore allineato e diverso da null a un valido QkDag, oppure se qubit è fuori intervallo.
Parametri
- dag – Il circuito a cui applicarsi.
- qubit – L'indice qubit da reimpostare.
- frontale – Se applicare il reset all'inizio del circuito. Di solito
false.
Risultati
L'indice del nodo dell'istruzione creata.
qk_dag_apply_barrier
uint32_t qk_dag_apply_barrier(QkDag *dag, const uint32_t *qubits, uint32_t num_qubits, bool front)
Applicare una barriera al DAG.
Esempi
Applicare una barriera finale su tutti i qubit:
qk_dag_apply_barrier(dag, NULL, qk_dag_num_qubits(dag), false);Applicare una barriera all'inizio di un circuito su indici qubit specificati:
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);Sicurezza
Il comportamento è indefinito se:
dagnon è un puntatore allineato e diverso da zero a un validoQkDag,qubitsnon è allineato o non è valido pernum_qubitsle letture di indici inizializzati, entro i limiti e non duplicati, a meno chequbitsnon sia nullo.
Parametri
- dag – Il circuito a cui applicarsi.
- qubit – Gli indici dei qubit a cui applicare la barriera. Questo valore può essere nullo, nel qual caso non
num_qubitsviene letto e la barriera viene applicata a tutti i qubit nel DAG. - num_qubits – A quanti qubit si applica la barriera.
- frontale – Se applicare la barriera all'inizio del circuito. Di solito
false.
Risultati
L'indice del nodo dell'istruzione creata.
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)
Applicare un gate unitario a un DAG.
I valori in matrix devono formare una matrice unitaria row-major delle dimensioni corrette per il numero di qubit. I dati vengono copiati dal puntatore e devono essere validi per la lettura solo fino al ritorno di questa funzione.
Vedi: Convenzioni dei circuiti per i dettagli sulle convenzioni di etichettatura dei bit e delle matrici di Qiskit.
Sicurezza
Il comportamento è indefinito se si verifica una delle seguenti condizioni:
dagnon è un puntatore allineato e diverso da zero a un validoQkDag,matrixnon è un puntatore allineato a4**num_qubitsvalori inizializzati,qubitsnon è un puntatore allineato ainum_qubitsvalori inizializzati.
Parametri
- dag – Il circuito a cui applicarsi.
- matrice – Una matrice unitaria inizializzata con priorità sulle righe di dimensione totale
4**num_qubits. - qubit – Un array di indici
uint32_tdistinti dei qubit. - num_qubits – Il numero di qubit a cui si applica il gate.
- frontale – Se applicare il gate all'inizio del circuito. Di solito
false.
Risultati
L'indice del nodo dell'istruzione creata.
qk_dag_op_node_gate_op
QkGate qk_dag_op_node_gate_op(const QkDag *dag, uint32_t node, double *out_params)
Recupera il gate standard del nodo specificato.
Va in panico se il nodo non è un'operazione di gate standard.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag. Se out_params non è NULL, deve puntare a un buffer sufficientemente grande da contenere tutti i parametri del gate, altrimenti il comportamento è indefinito poiché questa funzione scriverà oltre i suoi limiti. È possibile verificare qk_dag_op_node_num_params per determinare quanti parametri sono richiesti per un dato nodo operativo.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo operativo da cui ottenere il gate standard.
- out_params – Un buffer da riempire con i parametri del gate o NULL se non sono richiesti.
Risultati
Il valore del gate.
qk_dag_op_node_unitary
void qk_dag_op_node_unitary(const QkDag *dag, uint32_t node, QkComplex64 *out)
Copia la matrice unitaria dell'indice del nodo corrispondente.
Va nel panico se il nodo non è un gate unitario.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore non nullo a un valido QkDag, se out non è allineato o se non out è valido per 4**num_qubits scritture di QkComplex64.
Parametri
- dag – Il circuito da cui leggere.
- nodo – L'indice del nodo dell'istruzione della matrice unitaria.
- out – Memoria allocata e allineata per
4**num_qubitsvalori complessi in ordine row-major, dovenum_qubitsè il numero di qubit a cui si applica il gate.
qk_dag_op_node_kind
QkOperationKind qk_dag_op_node_kind(const QkDag *dag, uint32_t node)
Ottieni il "tipo" di un nodo operativo.
Il risultato può essere utilizzato in un'istruzione switch per inviare la gestione corretta durante l'iterazione sui nodi operativi.
Va nel panico se non node è un nodo operativo.
Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo operativo da cui ottenere il "tipo".
Risultati
Il "tipo" del nodo.
qk_dag_successors
QkDagNeighbors qk_dag_successors(const QkDag *dag, uint32_t node)
Recupera i successori del nodo specificato.
L'array dei successori e la sua lunghezza vengono restituiti come una QkDagNeighbors struttura, in cui ogni elemento dell'array corrisponde a un indice di nodo DAG. È necessario chiamare la qk_dag_neighbors_clear funzione al termine per liberare la memoria allocata per la struttura.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo da cui ottenere i successori.
Risultati
Un'istanza della QkDagNeighbors struttura con le informazioni sui successori.
qk_dag_predecessors
QkDagNeighbors qk_dag_predecessors(const QkDag *dag, uint32_t node)
Recupera i predecessori del nodo specificato.
L'array dei predecessori e la sua lunghezza vengono restituiti come una QkDagNeighbors struttura, in cui ogni elemento dell'array corrisponde a un indice di nodo DAG. È necessario chiamare la qk_dag_neighbors_clear funzione al termine per liberare la memoria allocata per la struttura.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – Il nodo da cui ottenere i predecessori.
Risultati
Un'istanza della QkDagNeighbors struttura con le informazioni sui predecessori.
qk_dag_neighbors_clear
void qk_dag_neighbors_clear(QkDagNeighbors *neighbors)
Cancella i campi della struttura di QkDagNeighbors input.
La funzione dealloca la memoria puntata dal neighbors campo e la imposta su NULL. Imposta anche il num_neighbors campo su 0.
Sicurezza
Il comportamento è indefinito se non neighbors è un puntatore valido e non nullo a un QkDagNeighbors oggetto popolato con o qk_dag_successors qk_dag_predecessors.
Parametri
- vicini – Un puntatore a un
QkDagNeighborsoggetto.
qk_dag_get_instruction
void qk_dag_get_instruction(const QkDag *dag, uint32_t index, QkCircuitInstruction *instruction)
Restituisce i dettagli relativi a un'istruzione nel circuito.
Questo è un mirror di qk_circuit_get_instruction. È inoltre possibile utilizzare metodi individuali come qk_dag_op_node_gate_op per ottenere singole proprietà.
È necessario chiamare qk_circuit_instruction_clear per reimpostare il QkCircuitInstruction prima di riutilizzarlo o smaltirlo.
Esempi
Iterare attraverso un DAG per trovare quali qubit hanno misure su di essi:
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);Sicurezza
Il comportamento è indefinito se o dag non instruction sono puntatori validi, allineati e non nulli al tipo di dati pertinente. I campi instruction non devono essere inizializzati.
Parametri
- dag – Il circuito da cui recuperare l'istruzione.
- indice – L'indice del nodo. È un errore passare un indice che è un nodo non valido.
- istruzione – Un punto in cui scrivere il
QkCircuitInstruction.
qk_dag_compose
QkExitCode qk_dag_compose(QkDag *dag, const QkDag *other, const uint32_t *qubits, const uint32_t *clbits)
Comporre il other DAG dag sull'istanza con l'opzione di mappare un sottoinsieme other dei fili di ingresso di su un sottoinsieme dei fili di uscita di dag.
other può includere un numero inferiore o uguale di fili per ciascun tipo.
Esempio
// 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);Sicurezza
Il comportamento è indefinito se dag o non other sono puntatori validi e non nulli a un QkDag. Se qubit né clbit sono NULL, deve contenere un importo inferiore o uguale a quello posseduto dal circuito.
Parametri
- dag – Un puntatore al DAG su cui comporre.
- altro – Un puntatore al DAG con cui
dagcomporre. - qubit – Un elenco di indici che rappresentano i fili qubit su cui comporre.
- clbits – Un elenco di indici che rappresentano i fili clbit su cui comporre.
Risultati
QkExitCode_Success in caso di decomposizione riuscita, altrimenti un codice di errore specifico DAG che indica la causa dell'errore.
qk_dag_free
void qk_dag_free(QkDag *dag)
Libera il DAG.
Esempio
QkDag *dag = qk_dag_new();
qk_dag_free(dag);Sicurezza
Il comportamento è indefinito se non dag è né nullo né un puntatore valido a un QkDag.
Parametri
- dag – Un puntatore al DAG da liberare.
qk_dag_to_circuit
QkCircuit *qk_dag_to_circuit(const QkDag *dag)
Converti un dato DAG in un circuito.
Il nuovo circuito viene copiato dal DAG; il riferimento dag originale rimane di proprietà del chiamante e deve ancora essere liberato con qk_dag_free. Una volta terminato, è necessario qk_circuit_free liberare il circuito restituito con.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag.
Parametri
- dag – Un puntatore al DAG da cui creare il circuito.
Risultati
Un puntatore al nuovo circuito.
qk_dag_topological_op_nodes
void qk_dag_topological_op_nodes(const QkDag *dag, uint32_t *out_order)
Restituisce i nodi operativi nel DAG elencati in ordine topologico.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido e non nullo a un QkDag o se non out_order è un puntatore valido e non nullo a una sequenza di qk_dag_num_op_nodes(dag) elementi consecutivi di uint32_t.
Parametri
- dag – Un puntatore al DAG.
- out_order – Un puntatore a un array di
qk_dag_num_op_nodes(dag)elementi di tipouint32_t, dove questa funzione scriverà l'output.
qk_dag_substitute_node_with_dag
void qk_dag_substitute_node_with_dag(QkDag *dag, uint32_t node, const QkDag *replacement)
Sostituire un nodo in un circuito QkDag con un sottocircuito specificato da un altro QkDag
Esempio
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);Sicurezza
Il comportamento è indefinito se dag e non replacement sono puntatori validi e non nulli a un QkDag.
Parametri
- dag – Un puntatore al DAG.
- nodo – L'indice del nodo dell'operazione da sostituire con l'altro
QkDag. Questo deve essere l'indice del nodo per un nodo operativo indage il conteggio qargs e cargs deve corrispondere al numero di qubit e clbit inreplacement. - sostituzione – L'altro
QkDagda sostituirenodecon. Questo dag deve avere lo stesso numero di qubit dell'operazione pernode. L'ordinamento dei bit dei nodi sarà gestito in ordine, quindiqargs[0]pernodesarà mappato suqubits[0]inreplacement,qargs[1]suqubits[0], ecc. Lo stesso schema si applica anche ai bit classici.
qk_dag_copy_empty_like
QkDag *qk_dag_copy_empty_like(const QkDag *dag, QkVarsMode vars_mode, QkBlocksMode blocks_mode)
Restituisce una copia di sé stessa con la stessa struttura ma vuota.
Tale struttura comprende:
- nome e altri metadati
- fase globale
- durata
- tutti i qubit e i clbit, compresi i registri.
Esempio
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);Sicurezza
Il comportamento è indefinito se non dag è un puntatore valido a un QkDag.
Parametri
- dag – Un puntatore al DAG da copiare.
- vars_mode – La modalità per la gestione delle variabili classiche.
- blocks_mode – La modalità di gestione dei blocchi.
Risultati
Il puntatore al circuito DAG copiato.
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)
Sostituisci un blocco contiguo non vuoto di nodi in un QkDag con un singolo gate unitario corrispondente alla matrice unitaria specificata.
Al momento della sostituzione, i nodi presenti nel blocco vengono rimossi e sostituiti da un nuovo nodo che agisce sui qubit specificati.
Esempio
// 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);Sicurezza
Il comportamento è indefinito se si verifica una delle seguenti condizioni:
dagnon è un puntatore allineato e diverso da zero a un validoQkDag,qubitsnon è un puntatore allineato ainum_qubitsvalori inizializzati.matrixnon è un puntatore allineato a4**num_qubitsvalori inizializzati,block_idsnon è un puntatore allineato a valorinum_block_idsinizializzati.
Parametri
- dag – Puntatore al DAG.
- num_block_ids – Numero di voci in
block_ids. Questo numero deve essere diverso da zero. - block_ids – Puntatore a un array non vuoto di nodi da sostituire.
- matrice – Puntatore a una matrice unitaria con disposizione delle righe inizializzata di dimensione
4**num_qubits. - num_qubits – Il numero di qubit su cui agisce il gate unitario risultante.
- qubit – Puntatore a un array di indici di qubit
uint32_tdistinti. Ogni voce specifica l'indice del qubit DAG corrispondente alla rispettiva posizione dell'argomento nel gate unitario. - cycle_check – Se
true, la funzione verifica se la sostituzione del nodo specificatoblock_idscon un singolo nodo introdurrebbe un ciclo nel DAG (il che renderebbe il DAG non valido). Se venisse creato un ciclo, il DAG rimane invariato eUINT32_MAXviene restituito. Questo controllo comporta una perdita di prestazioni. Se è possibile garantire che il blocco fornitoblock_idssia contiguo e non crei un ciclo una volta ridotto a un singolo nodo, è possibile impostare questo valore sufalse.
Risultati
L'indice del nodo di operazione appena aggiunto, oppure UINT32_MAX se cycle_check è true e la sostituzione comporterebbe 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)
Sostituisci un'operazione in un nodo di un grafo QkDag con una porta unitaria corrispondente alla matrice unitaria specificata.
La nuova operazione dovrebbe corrispondere alla forma dell'operazione sostituita. I qarg e i carg del nodo rimarranno invariati.
Esempio
// 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);Sicurezza
Il comportamento è indefinito se si verifica una delle seguenti condizioni:
dagnon è un puntatore allineato e diverso da zero a un validoQkDag,matrixnon è un puntatore allineato a4**num_qubitsvalori inizializzati,
Parametri
- dag – Puntatore al DAG.
- nodo – Il nodo la cui operazione viene sostituita. Il numero di qubit nell'operazione sostituita dovrebbe essere pari a
num_qubitse il numero di clbit dovrebbe essere0. - matrice – Puntatore a una matrice unitaria con disposizione delle righe inizializzata di dimensione
4**num_qubits. - num_qubits – Il numero di qubit su cui agisce l'operatore unitario.
qk_dag_to_python
PyObject *qk_dag_to_python(QkDag *dag)
Trasferisci la proprietà di un QkDag oggetto a Python.
Non è sicuro utilizzare il QkDag puntatore dopo aver chiamato questa funzione. In particolare, non dovresti cercare di ripulirlo o liberarlo. Chi effettua la chiamata deve essere il proprietario dell'oggetto QkDag, non possedere un riferimento preso in prestito (ad esempio, un oggetto QkDag * recuperato da non qk_dag_borrow_from_python è di sua proprietà).
Sicurezza
Chi chiama deve essere collegato a un interprete dell' Python. Il comportamento è indefinito se non dag è un puntatore non nullo valido a un oggetto inizializzato e di proprietà dell'utente QkDag.
Parametri
- dag – L'oggetto di proprietà.
Risultati
Un riferimento di tipo " Python " all'oggetto.
qk_dag_borrow_from_python
QkDag *qk_dag_borrow_from_python(PyObject *ob)
Recupera un QkDag puntatore da un oggetto Python.
Questa operazione prende in prestito un riferimento a un oggetto di tipo Python ed estrae il QkDag puntatore corrispondente, se è del tipo corretto. Il puntatore restituito viene preso in prestito dal ob puntatore. Se il non PyObject è del tipo corretto, il valore restituito è NULL e viene impostato lo stato di eccezione dell'interprete di Python.
Per chiamare questa funzione è necessario essere collegati a un interprete Python.
È inoltre possibile utilizzare qk_dag_convert_from_python, che dal punto di vista logico è esattamente identico a questa funzione, ma può essere utilizzato direttamente come funzione di "conversione" per la PyArg_Parse* famiglia di funzioni di conversione di Python.
Sicurezza
Chi chiama deve essere collegato a un interprete dell' Python. Il comportamento è indefinito se non ob è un puntatore valido e non nullo a un oggetto Python.
Parametri
- ob – Un oggetto preso in prestito dall' Python.
Risultati
Un puntatore all'oggetto nativo, oppure NULL se l'oggetto Python è di tipo errato.
qk_dag_convert_from_python
int qk_dag_convert_from_python(PyObject *object, void *address)
Recupera un puntatore DAG da un oggetto Python.
Questa operazione prende in prestito un riferimento di tipo Python ed estrae il QkDag puntatore corrispondente in address,, se è del tipo corretto. Il puntatore restituito viene preso in prestito dal object puntatore. Se il tipo PyObject non è corretto, il valore restituito è 1, viene impostato lo stato di eccezione dell'interprete di Python e e address rimane invariato.
Per chiamare questa funzione è necessario essere collegati a un interprete Python.
Puoi anche usare qk_dag_borrow_from_python, che dal punto di vista logico è esattamente uguale a questo, ma presenta una sintassi più intuitiva per l'uso diretto.
Sicurezza
Chi chiama deve essere collegato a un interprete dell' Python. Il comportamento è indefinito se non object è un puntatore valido e non nullo a un oggetto Python, oppure se non address è un puntatore a dati scrivibili del tipo corretto.
Parametri
- oggetto – Un oggetto Python preso in prestito.
- destinazione – La posizione in cui scrivere l'output.
Risultati
1 in caso di successo, 0 in caso di fallimento.