Installation der Qiskit C API
Dieser Leitfaden beschreibt, wie du die Qiskit C API installierst und verwendest. Um zu erfahren, wie du deinen Qiskit-Python-Workflow mit C erweitern kannst, lies Erweitere Python mit der Qiskit C API.
Das folgende Beispiel erstellt ein Observable mit C:
// file: example.c
#include <stdio.h>
#include <stdint.h>
#include <qiskit.h>
int main(int argc, char *argv[]) {
// build a 100-qubit empty observable
uint32_t num_qubits = 100;
QkObs *obs = qk_obs_zero(num_qubits);
// add the term 2 * (X0 Y1 Z2) to the observable
QkComplex64 coeff = {2, 0};
QkBitTerm bit_terms[3] = {QkBitTerm_X, QkBitTerm_Y, QkBitTerm_Z}; // bit terms: X Y Z
uint32_t indices[3] = {0, 1, 2}; // indices: 0 1 2
QkObsTerm term = {coeff, 3, bit_terms, indices, num_qubits};
qk_obs_add_term(obs, &term); // append the term
// print some properties and the observable itself
printf("num_qubits: %i\n", qk_obs_num_qubits(obs));
printf("num_terms: %lu\n", qk_obs_num_terms(obs));
printf("observable: %s\n", qk_obs_str(obs));
// free the memory allocated for the observable
qk_obs_free(obs);
return 0;
}
UNIX-ähnliche Systeme
Dieser Abschnitt enthält Build-Anweisungen für UNIX-ähnliche Systeme.
Voraussetzungen
Für die Kompilierung sind folgende Tools erforderlich:
- Ein Rust-Compiler: siehe zum Beispiel die Anleitung zur Installation von Qiskit aus dem Quellcode
- Ein C-Compiler: zum Beispiel GCC unter Linux und Clang unter MacOS. Die C API von Qiskit ist kompatibel mit einem Compiler, der dem C11-Standard entspricht.
cbindgen: ein Tool zur Erstellung des C-Headers, das du mitcargo install cbindgeninstallieren kannst. Beachte, dass das Ausführen des Tools über die Kommandozeile aktiviert sein sollte, was möglicherweise das Exportieren deinerPATH-Variable einschließlich/path/to/.cargo/binerfordert.- Installierte Python-Bibliothek (Python 3.9+): Die Python-Bibliothek wird während des dynamischen Linkens benötigt. Beachte, dass Python zur Laufzeit nicht verwendet wird und der Interpreter nie initialisiert wird; nur einige Symbole aus
libpythonmüssen definiert sein. Weitere Details finden sich in diesem Issue. - (GNU) Make: Dies ist optional, wird aber für automatisierte Installationsprozesse empfohlen.
Dieser Code überprüft, ob alles installiert wurde:
rustc --version
gcc --version
cbindgen --version
make --version # optional, but recommended
Build
Um den C-Header und die Bibliothek zu erstellen, kannst du folgenden Make-Befehl1 im Qiskit-Root-Verzeichnis ausführen:
make c
Dies stellt die kompilierte Shared Library in dist/c/lib und den qiskit.h-Header mit allen Funktionsdeklarationen in dist/c/include bereit. Beachte, dass der genaue Bibliotheksname von der Plattform abhängt; zum Beispiel libqiskit.so unter UNIX und libqiskit.dylib unter MacOS.
(Beachte, dass dieser Schritt derzeit viele Warnungen ausgibt, was zu erwarten ist und kein Grund zur Besorgnis. Zukünftige Versionen werden die Warnungen entfernen.)
Du kannst dann ein C-Programm unter Verwendung des Qiskit C-Headers und der Bibliothek kompilieren:
gcc example.c -o example.o -I /path/to/dist/c/include -L /path/to/dist/c/lib -lqiskit
Um sicherzustellen, dass die Qiskit-Bibliothek beim Linken gefunden wird, setze den Laufzeit-Bibliothekspfad so, dass er /path/to/dist/c/lib enthält. Wenn die Python-Bibliothek standardmäßig nicht beim dynamischen Linken verfügbar ist, muss dies ebenfalls hinzugefügt werden. Diese Befehle sind plattformabhängig. Unter Linux:
export LD_LIBRARY_PATH=/path/to/dist/c/lib:$LD_LIBRARY_PATH
# on Linux, the Python library is typically included in the dynamic library path per default
export LD_LIBRARY_PATH=/path/to/python/lib:$LD_LIBRARY_PATH
Unter MacOS:
export DYLD_LIBRARY_PATH=/path/to/dist/c/lib:$DYLD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=/path/to/python/lib:$DYLD_LIBRARY_PATH
Alternativ kannst du den Laufzeit-Bibliothekspfad während der Kompilierung festlegen, indem du
-Wl,-rpath,/path/to/dist/c/lib
# same for Python
zu den Compiler-Flags hinzufügen. Zusätzlich muss die Python-Bibliothek beim dynamischen Linken verfügbar sein. In Linux-Umgebungen ist dies normalerweise standardmäßig der Fall.
Jetzt kannst du die Binärdatei ausführen:
./example.o
was, wenn du das zuvor gezeigte Beispiel-Snippet verwendest, ausgeben sollte:
num_qubits: 100
num_terms: 1
observable: SparseObservable { num_qubits: 100, coeffs: [Complex { re: 2.0, im: 0.0 }], bit_terms: [X, Y, Z], indices: [0, 1, 2], boundaries: [0, 3] }
Windows
Dieser Abschnitt enthält Build-Anweisungen für Windows-Systeme.
Voraussetzungen
Für die Kompilierung sind folgende Tools erforderlich:
- Ein Rust-Compiler: siehe zum Beispiel die Anleitung zur Installation von Qiskit aus dem Quellcode
- Ein C-Compiler: zum Beispiel MSVC und die native Eingabeaufforderung, die den
cl-Befehl anbietet - Eine Python-Installation mit Zugriff sowohl auf
python3.libals auch aufpython3.dll cbindgen: ein Tool zur Erstellung des C-Headers, das du mitcargo install cbindgeninstallieren kannst. Beachte, dass das Ausführen des Tools über die Kommandozeile aktiviert sein sollte, was möglicherweise das Aktualisieren deinerPATH-Variable einschließlich des Cargo-Pfads erfordert.
Build
Kompiliere zunächst die dynamische Bibliothek qiskit_cext, indem du Folgendes im Qiskit-Root-Verzeichnis ausführst:
set PATH="\path\to\pythonlib";%PATH%
cargo rustc --release --crate-type cdylib -p qiskit-cext
Dies generiert die .dll dynamische Bibliothek und die zugehörige .dll.lib-Datei in target/release.
Generiere als Nächstes den Header mit:
cbindgen --crate qiskit-cext --output dist\c\include\qiskit.h
Dies schreibt den MSVC-kompatiblen Header in dist\c\include.
Jetzt kannst du cl verwenden, um das C-Programm zu kompilieren. Um sicherzustellen, dass der Compiler die Qiskit-Bibliothek findet, fügen wir target\release zur PATH-Variable hinzu.
set PATH="\path\to\target\release";%PATH%
cl example.c qiskit_cext.dll.lib -I\path\to\dist\c\include
Vor dem Ausführen musst du den Pfad zu deiner python3.dll einschließen.
set PATH="\path\to\python3-dll";%PATH%
.\example.exe
sollte dann ausgeben:
num_qubits: 100
num_terms: 1
observable: SparseObservable { num_qubits: 100, coeffs: [Complex { re: 2.0, im: 0.0 }], bit_terms: [X, Y, Z], indices: [0, 1, 2], boundaries: [0, 3] }