Qiskit C API 설치
이 가이드에서는 Qiskit C API를 설치하고 사용하는 방법을 설명합니다. C를 사용하여 Qiskit Python 워크플로를 확장하는 방법은 Qiskit C API로 Python 확장하기를 참조하세요.
다음 예제는 C로 observable을 빌드합니다:
// 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 계열
이 섹션에서는 UNIX 계열 시스템에 대한 빌드 방법을 안내합니다.
요구 사항
컴파일에는 다음 도구들이 필요합니다:
- Rust 컴파일러: 예를 들어 소스에서 Qiskit 설치 가이드를 참조하세요.
- C 컴파일러: 예를 들어 Linux에서는 GCC, MacOS에서는 Clang을 사용합니다. Qiskit의 C API는 C11 표준을 준수하는 컴파일러와 호환됩니다.
cbindgen: C 헤더를 생성하는 도구로,cargo install cbindgen명령으로 설치할 수 있습니다. 커맨드 라인에서 도구를 실행할 수 있어야 하며,/path/to/.cargo/bin을 포함하도록PATH변수를 내보내야 할 수도 있습니다.- Python 라이브러리 설치 (Python 3.9+): 동적 링크 시 Python 라이브러리가 필요합니다. Python은 런타임에 사용되지 않으며 인터프리터가 초기화되지 않습니다.
libpython의 일부 심볼만 정의되어야 합니다. 자세한 내용은 이 이슈를 참조하세요. - (GNU) Make: 선택 사항이지만 자동화된 설치 프로세스를 사용하기 위해 권장됩니다.
다음 코드로 모든 것이 올바르게 설치되었는지 확인할 수 있습니다:
rustc --version
gcc --version
cbindgen --version
make --version # optional, but recommended
빌드
C 헤더와 라이브러리를 빌드하려면 Qiskit 루트에서 다음 Make 명령1을 실행하세요.
make c
이 명령을 실행하면 컴파일된 공유 라이브러리가 dist/c/lib에, 모든 함수 선언이 포함된 qiskit.h 헤더가 dist/c/include에 제공됩니다. 라이브러리 이름은 플랫폼에 따라 다릅니다. 예를 들어 UNIX에서는 libqiskit.so, MacOS에서는 libqiskit.dylib입니다.
(현재 이 단계에서 많은 경고가 출력되는데, 이는 예상된 동작이므로 걱정하지 않아도 됩니다. 향후 버전에서는 경고가 제거될 예정입니다.)
그런 다음 Qiskit C 헤더와 라이브러리를 사용하여 C 프로그램을 컴파일할 수 있습니다:
gcc example.c -o example.o -I /path/to/dist/c/include -L /path/to/dist/c/lib -lqiskit
링크 시 Qiskit 라이브러리를 찾을 수 있도록, 런타임 라이브러리 경로에 /path/to/dist/c/lib를 포함시키세요. Python 라이브러리가 동적 링크 시 기본적으로 사용 불가능한 경우, 해당 경로도 추가해야 합니다. 이 명령은 플랫폼에 따라 다릅니다. 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
MacOS의 경우:
export DYLD_LIBRARY_PATH=/path/to/dist/c/lib:$DYLD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=/path/to/python/lib:$DYLD_LIBRARY_PATH
또는 컴파일 시 다 음을 추가하여 런타임 라이브러리 경로를 설정할 수도 있습니다:
-Wl,-rpath,/path/to/dist/c/lib
# same for Python
컴파일러 플래그에 위 옵션을 추가하세요. 또한 동적 링크 시 Python 라이브러리를 사용할 수 있어야 합니다. Linux 환경에서는 일반적으로 기본값으로 설정되어 있습니다.
이제 바이너리를 실행할 수 있습니다:
./example.o
앞서 보여준 예제 코드를 사용한 경우 다음과 같이 출력됩니다:
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
이 섹션에서는 Windows 시스템에 대한 빌드 방법을 안내합니다.
요구 사항
컴파일에는 다음 도구들이 필요합니다:
- Rust 컴파일러: 예를 들어 소스에서 Qiskit 설치 가이드를 참조하세요.
- C 컴파일러: 예를 들어 MSVC 및
cl명령을 제공하는 네이티브 커맨드 프롬프트 python3.lib와python3.dll모두에 접근할 수 있는 Python 설치cbindgen: C 헤더를 생성하는 도구로,cargo install cbindgen명령으로 설치할 수 있습니다. 커맨드 라인에서 도구를 실행할 수 있어야 하며, cargo 경로를 포함하도록PATH변수를 업데이트해야 할 수도 있습니다.
빌드
먼저 Qiskit 루트에서 다음 명령을 실행하여 qiskit_cext 동적 라이브러리를 컴파일합니다:
set PATH="\path\to\pythonlib";%PATH%
cargo rustc --release --crate-type cdylib -p qiskit-cext
이 명령을 실행하면 target/release에 .dll 동적 라이브러리와 관련 .dll.lib 파일이 생성됩니다.
다음으로, 헤더를 생성합니다:
cbindgen --crate qiskit-cext --output dist\c\include\qiskit.h
이 명령은 dist\c\include에 MSVC 호환 헤더를 작성합니다.
이제 cl을 사용하여 C 프로그램을 컴파일할 수 있습니다. 컴파일러가 qiskit 라이브러리를 찾을 수 있도록 PATH 변수에 target\release를 포함시킵니다:
set PATH="\path\to\target\release";%PATH%
cl example.c qiskit_cext.dll.lib -I\path\to\dist\c\include
실행하기 전에 python3.dll의 경로를 포함시켜야 합니다:
set PATH="\path\to\python3-dll";%PATH%
.\example.exe
그러면 다음과 같이 출력됩니다:
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] }