QkTranspileLayout
typedef struct QkTranspileLayout QkTranspileLayoutDer Typ QkTranspileLayout wird verwendet, um die durch den Transpiler eingeführten Permutationen zu modellieren. Im Allgemeinen ist der Transpiler von Qiskit bis auf die anfänglichen Layout- und Ausgabe-Permutationen unitär-erhaltend. Das ursprüngliche Layout ist die Zuordnung von virtuellen Schaltkreis-Qubits zu physischen Qubits auf dem Ziel, und die Ausgangspermutation wird durch das Einfügen von Swap-Gates oder die Elision von Permutationen verursacht, bevor das ursprüngliche Layout in der Transpiler-Pipeline festgelegt wird. Dieser Typ verfolgt diese Details und bietet eine Schnittstelle, um über diese Permutationen nachzudenken.
Wenn Sie zum Beispiel eine Schaltung wie folgt aufgebaut haben:
#include <qiskit.h>
QkCircuit *qc = qk_circuit_new(3, 0)
uint32_t h_qargs[1] = {0};
qk_circuit_gate(qc, QkGate_H, h_qargs, NULL);
uint32_t cx_0_qargs[2] = {0, 1};
qk_circuit_gate(qc, QkGate_CX, cx_0_qargs, NULL);
uint32_t cx_1_qargs[2] = {0, 2};
qk_circuit_gate(qc, QkGate_CX, cx_1_qargs, NULL);und während der Layout-Phase ordnet der Transpiler die virtuellen Qubits in diesem Schaltkreis den physischen Schaltkreisen als zu:
0 -> 2, 1 -> 1, 2 -> 0die Schaltung würde also wie folgt aussehen:
#include <qiskit.h>
QkCircuit *qc = qk_circuit_new(3, 0)
uint32_t h_qargs[1] = {2};
qk_circuit_gate(qc, QkGate_H, h_qargs, NULL);
uint32_t cx_0_qargs[2] = {2, 1};
qk_circuit_gate(qc, QkGate_CX, cx_0_qargs, NULL);
uint32_t cx_1_qargs[2] = {2, 0};
qk_circuit_gate(qc, QkGate_CX, cx_1_qargs, NULL);dann wird das Ergebnis von qk_transpile_layout_initial_layout ein Array sein: [2, 1, 0]
Wenn das Routing erforderlich war, um ein Swap-Gate in die Schaltung einzufügen, nachdem das Layout angewendet wurde, führt dies dazu, dass eine Ausgangspermutation gesetzt wird. Zum Beispiel, wenn ein Swap eingefügt wurde wie:
#include <qiskit.h>
QkCircuit *qc = qk_circuit_new(3, 0)
uint32_t h_qargs[1] = {2};
qk_circuit_gate(qc, QkGate_H, h_qargs, NULL);
uint32_t cx_0_qargs[2] = {2, 1};
qk_circuit_gate(qc, QkGate_CX, cx_0_qargs, NULL);
uint32_t swap_qargs[2] = {1, 0};
qk_circuit_gate(qc, QkGate_Swap, swap_qargs, NULL);
uint32_t cx_1_qargs[2] = {2, 1};
qk_circuit_gate(qc, QkGate_CX, cx_1_qargs, NULL);dies führt dazu, dass der Ausgangszustand von Qubit 0 auf Qubit 1 und von Qubit 1’s auf Qubit 0 wechselt. Dies führt dazu, dass qk_transpile_layout_output_permutation das Array: [1, 0, 2] zurückgibt, um anzuzeigen, dass dies die endgültige Position des Zustands jedes Qubits nach der anfänglichen Layout-Zuordnung ist. Wenn während der Transpilierung keine Vertauschungen oder Permutationselisionen vorgenommen wurden, handelt es sich um ein triviales Array der Form [0, 1, 2] , da der Ausgangszustand des Qubits durch den Transpiler nicht verändert wird.
Die Kombination dieser beiden Elemente ergibt dann das endgültige Layout, mit dem die endgültige Position eines virtuellen Qubits im Eingangskreis verfolgt werden kann. Im obigen Beispiel (mit der Vertauschung) würde die Funktion qk_transpile_layout_final_layout also [2, 0, 1] zurückgeben, weil nach der anfänglichen Anordnung und einer beliebigen Routing-Permutation die endgültige Position des Qubits 0 im Eingangsschaltkreis nun das physische Qubit 2 ist, das virtuelle Qubit 1 im Eingangsschaltkreis das physische Qubit 0 und das virtuelle Qubit 2 im Eingangsschaltkreis das physische Qubit 1.
Der Transpiler weist der Schaltung auch zusätzliche Qubits zu, wenn das Ziel mehr Qubits zur Verfügung hat als die ursprüngliche Eingangsschaltung. Dies führt dazu, dass zwei Funktionen qk_transpile_layout_num_input_qubits und qk_transpile_layout_num_output_qubits notwendig sind, die die Anzahl der Qubits im Eingangs- bzw. Ausgangsschaltkreis verfolgen. Zusätzlich nehmen die Funktionen qk_transpile_layout_initial_layout und qk_transpile_layout_final_layout ein Argument, um Ancillas aus dem Ausgabe-Array zu filtern. Bei true wird das Ausgabe-Array auf die virtuellen Qubits gefiltert, die in der ursprünglichen Eingabeschaltung des Transpiler-Aufrufs, der die QkTranspileLayout erzeugt hat, enthalten sind.
Funktionen
qk_transpile_layout_num_input_qubits
uint32_t qk_transpile_layout_num_input_qubits(const QkTranspileLayout *layout)
Rückgabe der Anzahl der Qubits in der Eingangsschaltung an den Transpiler.
Sicherheit
Das Verhalten ist undefiniert, wenn layout kein gültiger, nicht-null Zeiger auf QkTranspileLayout ist.
Parameter
- layout - Ein Zeiger auf das
QkTranspileLayout.
Rückgabe
Die Anzahl der Eingangsqubits
qk_transpile_layout_num_output_qubits
uint32_t qk_transpile_layout_num_output_qubits(const QkTranspileLayout *layout)
Gibt die Anzahl der Qubits in der Ausgangsschaltung des Transpilers zurück.
Sicherheit
Das Verhalten ist undefiniert, wenn layout kein gültiger, nicht-null Zeiger auf QkTranspileLayout ist.
Parameter
- layout - Ein Zeiger auf das
QkTranspileLayout.
Rückgabe
Die Anzahl der Ausgangsqubits
qk_transpile_layout_initial_layout
bool qk_transpile_layout_initial_layout(const QkTranspileLayout *layout, bool filter_ancillas, uint32_t *initial_layout)
Abfrage des ursprünglichen Layouts einer QkTranspileLayout.
Das Ausgabearray dieser Funktion stellt die Zuordnung der virtuellen Qubits im ursprünglichen Eingangsschaltkreis zum physikalischen Qubit im Ausgangsschaltkreis dar. Der Index im Array ist das virtuelle Qubit, und der Wert ist das physikalische Qubit. Zum Beispiel ein Ausgabearray mit folgenden Werten:
[1, 0, 2]zeigt an, dass das Layout virtuelles Qubit 0 -> physikalisches Qubit 1, virtuelles Qubit 1 -> physikalisches Qubit -> 0 und virtuelles Qubit 2 -> physikalisches Qubit 2 abbildet.
Sicherheit
Das Verhalten ist undefiniert, wenn layout kein gültiger, nicht-null Zeiger auf QkTranspileLayout ist. initial_layout muss ein gültiger Zeiger sein, der nicht leer ist und dessen Zuweisung groß genug ist, um die für das anfängliche Layout erforderliche Größe zu speichern. Wenn filter_ancillas wahr ist, ist dies die Anzahl der Eingangsqubits (was mit qk_transpile_layout_num_input_qubits() überprüft werden kann) oder die Anzahl der Ausgangsqubits, wenn filter_ancillas falsch ist (was mit qk_transpile_layout_num_output_qubits() abgefragt werden kann).
Parameter
- layout - Ein Zeiger auf das
QkTranspileLayout. - filter_ancillas – Wenn dieser Wert auf „true“ gesetzt ist, enthält das Ausgabearray keine Indizes für vom Transpiler hinzugefügte Ancillas.
- initial_layout - Ein Zeiger auf das Array, in das diese Funktion das anfängliche Layout schreibt. Dieser muss genügend Platz für das gesamte Array haben, das entweder
qk_transpile_layout_num_input_qubits()oderqk_transpile_layout_num_output_qubits()sein wird, wenn es wahr bzw. falsch ist (filter_ancillas).
Rückgabe
True, wenn ein initial_layout in initial_layout geschrieben wurde, und false, wenn es kein initiales Layout gibt.
qk_transpile_layout_output_permutation
bool qk_transpile_layout_output_permutation(const QkTranspileLayout *layout, uint32_t *output_permutation)
Abfrage der Ausgangspermutation einer QkTranspileLayout
Das Ausgangs-Array dieser Funktion stellt die durch den Transpiler induzierte Permutation dar, wobei der Index das Qubit am Anfang der Schaltung angibt und der Wert die Position des Qubits am Ende der Schaltung ist. Zum Beispiel ein Ausgabe-Array von:
[1, 2, 0]bedeutet, dass das Qubit 0 am Anfang der Schaltung auf dem Qubit 1 am Ende der Schaltung liegt, 1 -> 2 und 2 -> 0.
Sicherheit
Das Verhalten ist undefiniert, wenn layout kein gültiger, nicht-null Zeiger auf QkTranspileLayout ist. output_permutation muss ein gültiger Zeiger sein, der nicht null ist und dessen Zuweisung groß genug ist, um die für die Ausgabe_Permutation erforderliche Größe zu speichern. Dies ist immer die Anzahl der Ausgangsqubits in der QkTranspileLayout , die mit qk_transpile_layout_num_output_qubits() abgefragt werden kann.
Parameter
- layout - Ein Zeiger auf das
QkTranspileLayout. - output_permutation - Ein Zeiger auf das Array, in das diese Funktion die Ausgabe-Permutation schreibt. Dieser muss genügend Platz für die Ausgabe haben, die die Anzahl der Ausgangsqubits im Layout sein wird. Diese kann mit
qk_transpile_layout_num_output_qubitsabgefragt werden.
Rückgabe
True, wenn es eine Ausgabe-Permutation gibt, die auf output_permutation geschrieben wurde false, wenn die QkTranspileLayout keine Ausgabe-Permutation enthält.
qk_transpile_layout_final_layout
void qk_transpile_layout_final_layout(const QkTranspileLayout *layout, bool filter_ancillas, uint32_t *final_layout)
Abfrage des endgültigen Layouts einer QkTranspileLayout
Das Ausgangs-Array stellt die Abbildung des virtuellen Qubits in der ursprünglichen Eingangsschaltung auf das physikalische Qubit am Ende der Transpile-Schaltung dar, das den Zustand dieses Qubits hat. Der Array-Index steht für das virtuelle Qubit und der Wert für das physische Qubit am Ende der transponierten Schaltung, die den Zustand dieses virtuellen Qubits hat. Zum Beispiel, ein Ausgabe-Array von:
[2, 0, 1]zeigt an, dass der Zustand des virtuellen Qubits 0’s in der ursprünglichen Schaltung auf dem physikalischen Qubit 2 am Ende der transponierten Schaltung liegt, 1 -> 0 und 2 -> 1.
Sicherheit
Das Verhalten ist undefiniert, wenn layout kein gültiger, nicht-null Zeiger auf QkTranspileLayout ist. final_layout muss ein gültiger Zeiger sein, der nicht leer ist und dessen Zuweisung groß genug ist, um die für das endgültige Layout erforderliche Größe zu speichern. Wenn filter_ancillas wahr ist, ist dies die Anzahl der Eingangsqubits (was mit qk_transpile_layout_num_input_qubits() überprüft werden kann) oder die Anzahl der Ausgangsqubits, wenn filter_ancillas falsch ist (was mit qk_transpile_layout_num_output_qubits() abgefragt werden kann).
Parameter
- layout - Ein Zeiger auf das
QkTranspileLayout. - filter_ancillas – Wenn dieser Wert auf „true“ gesetzt ist, enthält das Ausgabearray keine Indizes für vom Transpiler hinzugefügte Ancillas.
- final_layout - Ein Zeiger auf das Array, in das diese Funktion das endgültige Layout schreiben wird. Dieser muss genügend Platz für die Ausgabe haben, die je nach dem Wert von filter_ancillas entweder die Anzahl der Eingangs- oder der Ausgangsqubits sein wird.
qk_transpile_layout_generate_from_mapping
QkTranspileLayout *qk_transpile_layout_generate_from_mapping(const QkDag *original_dag, const QkTarget *target, const uint32_t *qubit_mapping)
Erstellen Sie ein QkTranspileLayout aus einem anfänglichen Layout-Mapping
Dadurch wird ein QkTranspileLayout mit dem anfänglichen Layout (und ohne Ausgabepermutation) aus einer bereitgestellten Zuordnung generiert. Der Zweck dieser Funktion besteht darin, die Erstellung eines benutzerdefinierten Layout-Durchgangs zu ermöglichen, der auch ein erstellt QkTranspileLayout , das Sie mit nachfolgenden Stufenfunktionen wie qk_transpile_stage_routing verwenden können.
Sicherheit
Das Verhalten ist undefiniert, wenn original_dag und target kein gültiger, ausgerichteter, target nicht-null Zeiger auf ein QkDag bzw. QkTarget ein sind. qubit_mapping muss ein gültiger Zeiger auf ein zusammenhängendes Array von uint32_t mit ausreichend Platz für die in angegebene targetAnzahl von Qubits sein.
Parameter
- original_dag – Ein Zeiger auf den ursprünglichen DAG vor der Ausführung eines benutzerdefinierten Layout-Durchlaufs. Dieser Dag muss weniger oder genauso viele Qubits haben wie
target. - Ziel – Ein Zeiger auf das Ziel, auf dem das Layout ausgeführt wurde. Dieses Ziel muss eine feste Anzahl von Qubits haben.
- qubit_mapping – Ein Zeiger auf das Layout-Mapping-Array. Dieses Array muss dieselbe Anzahl an Elementen haben wie es Qubits im Ziel gibt, und jedes Element ist eine eindeutige ganze Zahl, wobei alle im Bereich von 0 bis liegen
num_qubitsmüssen, wobei die Anzahlnum_qubitsder Qubits ist, die im angegebenen Wert für angegebentargetist. Die ersten Elemente repräsentieren die virtuellen Qubits inoriginal_dagund der Wert repräsentiert das physikalische Qubit im Ziel, auf das das virtuelle Qubit abgebildet ist. Beispielsweise würde ein Array[1, 0, 2]von das virtuelle Qubit 0 -> physikalisches Qubit 1, das virtuelle Qubit 1 -> physikalisches Qubit 0 und das virtuelle Qubit 2 -> physikalisches Qubit 2 abbilden. Elemente, die nicht im ursprünglichen DAG enthalten sind, werden als Ancilla-Qubits behandelt, müssen jedoch weiterhin einem physikalischen Qubit zugeordnet werden. Dieses Array wird in die Ausgabe kopiertQkTranspileLayout, daher müssen Sie es nach dem Aufruf dieser Funktion noch freigeben.
Rückgabe
Das Objekt „ QkTranspileLayout “ mit dem anfänglichen Layout
qk_transpile_layout_free
void qk_transpile_layout_free(QkTranspileLayout *layout)
Freigeben eines QkTranspileLayout Objekts
Sicherheit
Das Verhalten ist undefiniert, wenn layout kein gültiger, nicht-null Zeiger auf QkTranspileLayout ist.
Parameter
- layout - ein Zeiger auf das freizugebende Layout
qk_transpile_layout_to_python
PyObject *qk_transpile_layout_to_python(const QkTranspileLayout *layout, const QkCircuit *circuit)
Erzeugen Sie ein Objekt vom Typ „ PythonTranspileLayout -space“ aus einer QkTranspileLayout.
Das erstellte Objekt „ Python ” ist eine Kopie des QkTranspileLayout bereitgestellten Objekts, die Datendarstellung unterscheidet sich zwischen C und „ Python ” und die Daten werden nicht wie bei einigen anderen *_to_python Funktionen nach „ Python ” verschoben.
Sicherheit
Das Verhalten ist undefiniert, wenn layout und keine gültigen, von Null verschiedenen circuit Zeiger auf bzw QkCircuit``QkTranspileLayout . sind. Es wird davon ausgegangen, dass der Thread, der diese Funktion derzeit ausführt, die GIL „ Python “ hält. Dies ist erforderlich, um das von dieser Funktion zurückgegebene Objekt „ Python “ zu erstellen.
Parameter
- Layout – ein Zeiger auf eine
QkTranspileLayout. - Schaltkreis – ein Zeiger auf das Original
QkCircuit.
Rückgabe
Der Zeiger „ PyObject ” für das Objekt „ Python ” im Speicherbereich „ TranspileLayout ”.