2021년 7월 13일 화요일

Qiskit tutorial - 4. Advanced Circuits

이 글은 Qiskit 공식 홈페이지에서 제공하는 튜토리얼을 직접 해보고 요약하거나 덧붙이거나 교정한 글입니다. 원문은 [1]이며, Anaconda 의 Jupyter notebook 을 사용하는 원문과 달리 순수 Python 으로 실행가능하도록 소스코드를 수정하고, 중간마다 양자 상태를 시각화하는 코드 등이 추가되어 코드도 원문과 차이가 있습니다. 제가 작성한 코드는 [2]에 공개합니다.

우선 기본 import 와 gate 선언은 다음과 같다.

코드4.1. 기본 import

4.1. 불투명한 게이트

임의의 게이트를 선언하고 큐비트에 적용할 수 있다. 코드는 다음과 같다.

코드4.2. 불투명 게이트 구현

코드 9번에서 게이트를 선언한다. 코드 10번에서 3-큐비트 레지스터를 선언하고 회로를 생성한다. 코드 12번과 13번 라인에서 두 큐비트 게이트를 적용하고 14번 라인에서 도식한다. 15번 라인의 출력은 다음과 같다. 

그림4.1. 불투명 게이트 도식

4.2. 합성 게이트

하위 회로를 합성하여 게이트 연산을 합성할 수 있다. 구현 코드는 다음과 같다.

코드4.3 합성 게이트 구현

코드 20번에서 2-큐비트 레지스터를 선언하고, 코드 21번 라인에서 이 양자 레지스터를 가진 회로 sub_circ을 생성한다. 코드 29번 라인에서 sub_circ 회로는 하위 로직으로 변경된다. 코드 31번에서는 다른 회로를 선언하고, 36번에서 이 회로에 sub_inst 를 붙인다. 코드 38번의 출력은 다음과 같다.

그림4.2. 하위 회로를 붙인 회로의 도식

코드 29번에서 회로가 to_instruction() 에 의해 바로 분해되지는 않으며, 이는 회로 설계를 더 고차원의 추상화 단계에서 가능하게 한다. 임의로 지정된 순간 또는 컴파일 전에 하위 회로들은 decompose() 에 의해 분해된다. 코드 42번의 출력은 다음과 같다.

그림4.3. 하위 회로를 분해한 회로의 도식

4.3. 매개변수화된 회로

매개변수화된 회로의 구현은 다음과 같다.

코드4.4. 매개변수를 가진 회로 구현

코드 47번에서 매개변수 theta 를 선언한다. 코드 49번 라인에서 5개의 큐비트와 1개의 전통적인 비트를 갖는 회로를 생성한다. 코드 50번 라인에서 0번 큐비트에 하다마드 게이트를 적용한다. 코드 51번의 반복문은 5개의 큐비트를 CX 게이트로 순차적으로 얽힘 상태로 만든다. 코드 54번부터, 두 개의 배리어 사이에서 매개변수 theta를 이용하여 Z축 표준회전 게이트인 RZ 게이트를 큐비트들에 적용한다. 코드 58~59번 라인에서 CX 게이트를 역순으로 추가하고, 코드 60번 라인에서 큐비트 0 에 다시 하다마드 게이트를 적용한다. 코드 61번에서 큐비트 0의 값을 측정하여 전통적인 비트에 기록한다. 코드 63번 라인에서 회로를 도식하고 64번 라인에서 출력한다. 결과는 다음과 같다.

그림4.4. 매개변수를 가진 회로 도식

코드 66번에서 회로의 매개변수를 출력한다. 결과는 다음과 같다.

ParameterView([Parameter(θ)])

4.3.1 매개변수를 실제 값에 연결하기

모든 회로의 매개변수는 회로를 백엔드로 보내기 전에 값을 연결해야 한다. 이 작업은 다음의 두 가지 방법 중 하나로 수행 가능하다. bind_parameters() 는 Parameter 에 값을 할당하는 딕셔너리를 받아 각각의 해당하는 매개변수가 그에 알맞는 값으로 바뀐 새로운 회로를 되돌려준다. 부분적인 값 지정도 지원되는 데, 이 경우 반환된 회로는 특정 값에 연결되지 않은 Parameter 들로 매개변수가 지정된다. 예제 코드의 구현은 다음과 같다.

코드4.5. 매개변수의 연결 구현

코드 70번 라인에서 theta_range는 0 ~ 2π 까지의 선형값을 128단계로 나누어 갖는다. 이 값들을 매개변수 theta 에 연결한다. 반복문이 종료된 마지막 회로를 코드 73번 라인에서 도식하고, 74번 라인에서 출력하면 다음과 같다.

그림4.5. 매개변수 Θ에 2π가 연결된 회로의 도식 

코드 76번 라인에서 execute()는 parameter_binds 에 할당되는 인자들을 받아들이며, Parameter 들을 해당 value 에 할당하는 딕셔너리들로 구성된 리스트가 지정된 경우, 그 리스트에 들어 있는 모든 딕셔너리들을 각각 회로에 적용하고 벡엔드에서 실행한다. 

예제 회로에서 RZ(θ) 회전을 5 큐비트 얽힘 상태에 적용하였으므로, 큐비트 0에서 5θ의 진동을 관찰할 수 있다. 코드 92번 라인의 출력은 다음과 같다.

그림4.6. 큐비트0의 측정 결과 도식

4.3.2 컴파일 비용 줄이기

특정 경우, 값의 연결 전에 매개변수화된 회로를 컴파일하면, 연결된 회로의 집합을 컴파일하는 것보다 컴파일 시간을 상당히 줄일 수 있다. 구현 코드는 다음과 같다.

코드4.6. 회로 컴파일 시간 비교 구현

코드 102 ~ 116번 라인에서, θ 를 0 ~ 2π 까지 32등분한 값들인 theta_range를 이용하여 양자 회로들을 생성하고 qcs 에 할당한다. 이후 qcs 리스트의 회로들을 컴파일하고 소요된 시간을 122번 라인에서 출력한다. 반대로, 코드 125 ~ 137번 라인은 매개변수화된 양자 회로를 135번 라인에서 컴파일하고, 136번 라인에서 매개변수들을 theta_range 에 할당한다. 이후 소요 시간을 139번 라인에서 출력한다. 두 출력 결과는 다음과 같다.

Time compiling over set of bound circuits :  4.91303277015686
Time compiling over parameterized circuit, then binding :  0.6330001354217529

4.3.3 합성(Composition)

매개변수화된 회로는 일반적인 QuantumCircuit 처럼 구성될 수 있다. 보통 두 매개변수화된 회로를 구성할 때, 출력 회로는 입력 회로의 매개변수들의 결합에 의해 매개변수화된다. 그러나 매개변수의 이름은 회로에서 고유해야한다. 회로에 이미 존재하는 이름을 가진 매개변수를 추가하려고 시도할 때, 만약 출처(source)와 대상(target)이 같은 Parameter 인스턴스를 공유하면, 매개변수들은 동일한 것으로 간주되어 결합된다. 만약 출처와 대상이 다른 Parameter 인스턴스를 가지면 에러가 발생한다. 예제 코드는 다음과 같다.

코드4.7. 회로 합성 구현

코드 142번 라인에서 phi 라는 이름의 Parameter 인스턴스를 생성한다. 144~150번 라인에서 두개의 2-큐비트 회로를 생성하고 각각 sc_1 과 sc_2로 명명한다. 152번 라인에서 4-큐비트 회로를 생성하고, 153번 라인에서 회로의 큐비트에 접근할 수 있는 변수 qr 을 만든다. 155~158번 라인에서 기생성한 2-큐비트 회로들을 하위회로로 이용하여 4-큐비트 회로를 구성한다. 코드 160번 라인에서 양자회로를 도식하고, 161번 라인에서 출력한다. 출력 결과는 다음과 같다.

그림4.7. 매개변수화된 회로 합성 결과

하위 회로에 다른 매개변수를 추가하기 위해 to_instruction() 은 추가 전달인자로  parameter_map 을 가질 수 있다. 이 것이 설정된 경우 출처의 매개변수들이 새로운 매개변수들로 치환된 명령어들을 생성한다. 구현은 다음과 같다.

코드4.8. 합성된 회로의 매개변수 변경 구현

코드 166번 라인에서 생성한 회로는 매개변수 p 를 포함하고 있다. 코드 173~175번 라인에서 새로운 매개변수들을 선언한다. 코드 177~178번 라인에서 9-큐비트 회로를 선언하고, 코드 179~181 라인에서 3-큐비트 회로를 합성하여 9-큐비트 회로를 구성한다. 이 때, to_instruction() 에 인자로 매개변수 p 를 각각 theta, phi, gamma 로 교체한다. 코드 184번에서 이 회로의 도식을 출력하면 다음과 같다. 

그림4.8. 합성 회로의 매개변수 변경

[1] 원문: 
https://qiskit.org/documentation/tutorials/circuits_advanced/01_advanced_circuits.html
[2] 내 코드:
https://github.com/sungmin-net/python-qiskit-tutorials/blob/main/tutorial04_AdvancedCircuits.py

댓글 없음:

댓글 쓰기