Skip to main content
IBM Quantum Platform

QPY 직렬화

qiskit.qpy

QPY는 바이너리 직렬화 형식입니다 QuantumCircuit 개체를 위한 바이너리 직렬화 형식이며, 크로스 플랫폼, Python 버전에 구애받지 않고 앞으로 이전 버전과 호환되도록 설계되었습니다. 시스템 간에 저장하거나 복사하는 메커니즘이 필요한 경우 QPY를 사용해야 합니다 QuantumCircuit 를 사용하여 전체 키스킷 객체 구조를 보존해야 합니다(키스킷 코드 외부에 정의된 사용자 정의 어트리뷰트 제외). 이것은 다음과 같은 다른 직렬화 형식과 다르다 OpenQASM ( 2.0 또는 3.0 )와는 다른 추상화 모델을 가지고 있으며 원래 회로에 포함된 정보가 손실될 수 있거나(또는 키스킷 객체의 일부 측면을 표현할 수 없음), Python 의 피클은 키스킷 객체를 정확하게 보존하지만 단일 키스킷 버전에서만 작동합니다(이 또한 잠재적으로 안전하지 않을 수 있음).


기본 사용법

QPY 사용법은 간단하며 Python 의 표준 라이브러리인 pickle 과 json 에 있는 직렬화기의 사용자 API를 미러링하도록 정의되어 있습니다. 두 가지 사용자 대면 기능이 있습니다: qiskit.qpy.dump() 과 qiskit.qpy.load() 는 각각 QPY 데이터를 파일 객체에 덤프하고 파일 객체에 있는 QPY 데이터에서 회로를 로드하는 데 사용됩니다. 예를 들어,

from qiskit.circuit import QuantumCircuit
from qiskit import qpy

qc = QuantumCircuit(2, name='Bell', metadata={'test': True})
qc.h(0)
qc.cx(0, 1)
qc.measure_all()

with open('bell.qpy', 'wb') as fd:
    qpy.dump(qc, fd)

with open('bell.qpy', 'rb') as fd:
    new_qc = qpy.load(fd)[0]

기능을 사용하면 qiskit.qpy.dump() 함수를 사용하면 단일 QPY 파일에 여러 회로를 포함할 수도 있습니다:

with open('twenty_bells.qpy', 'wb') as fd:
    qpy.dump([qc] * 20, fd)

을 클릭한 다음 해당 파일을 로드하면 모든 회로가 포함된 목록이 반환됩니다

with open('twenty_bells.qpy', 'rb') as fd:
    twenty_new_bells = qpy.load(fd)

API 문서

load

qiskit.qpy.load(file_obj, metadata_deserializer=None, annotation_factories=None)

GitHub

QPY 바이너리 파일 로드

이 함수는 직렬화된 QPY 키스킷 프로그램 파일을 로드하고 그 내용으로부터 QuantumCircuit 객체를 생성합니다. 예를 들어,

from qiskit import qpy

with open('bell.qpy', 'rb') as fd:
    circuits = qpy.load(fd)

또는 gzip 압축 파일을 사용합니다:

import gzip
from qiskit import qpy

with gzip.open('bell.qpy.gz', 'rb') as fd:
    circuits = qpy.load(fd)

를 호출하면 qpy의 내용을 읽고 파일의 객체 목록을 QuantumCircuit 객체 목록을 반환합니다.

매개변수

  • file_obj (BinaryIO) – 회로에 대한 QPY 바이너리 데이터를 포함하는 파일 형식의 객체입니다.
  • metadata_deserializer (type[JSONDecoder] | None) – QPY 파일 내의 모든 프로그램에서 속성에 .metadata 사용되는 JSON 페이로드를 역직렬화하는 데 쓰이는 내부 json.load 호출의 kwarg에 cls 사용될 선택적 JSONDecoder 클래스입니다. 이 항목이 지정되지 않은 경우, 회로 메타데이터는 기본 JSONDecoder 클래스를 사용하여 stdlib json.load() 함수를 통해 JSON 형식으로 파싱됩니다.
  • annotation_factories (Mapping[str, Callable[[], annotation.QPYSerializer]] | None) – 사용자 정의 Annotation 객체의 로딩을 처리하기 위해 annotation.QPUSerializer, 네임스페이스를 새로운 인스턴스를 생성하는 함수에 매핑합니다.

리턴

QPY 데이터에 포함된 키스킷 프로그램 목록입니다. QPY 데이터에 프로그램이 1개만 있어도 항상 목록이 반환됩니다.

레이즈

  • QiskitError - file_obj 가 유효한 QPY 파일이 아닌 경우
  • TypeError – 유효하지 않은 데이터 유형이 로드되었을 때 발생합니다.
  • MissingOptionalLibraryError – symengine 기호 인코딩을 사용하고 인스턴스를 포함하는 ParameterExpression QPY 버전 10, 11 또는 12 페이로드를 불러올 때 엔진 라이브러리가 symengine 설치되어 있지 않은 경우.
  • QpyError - 알 수 있지만 지원되지 않는 데이터 유형이 로드된 경우.

리턴 유형

목록[QPY_SUPPORTED_TYPES]

dump

qiskit.qpy.dump(programs, file_obj, metadata_serializer=None, use_symengine=False, version=18, annotation_factories=None)

GitHub

QPY 바이너리 데이터를 파일에 쓰기

이 기능은 나중에 사용하거나 컴퓨터 간에 전송할 수 있도록 회로를 파일에 저장하는 데 사용됩니다. QPY 형식은 이전 버전과 호환되며 향후 버전의 키스킷에서 로드할 수 있습니다.

예를 들어,

from qiskit.circuit import QuantumCircuit
from qiskit import qpy

qc = QuantumCircuit(2, name='Bell', metadata={'test': True})
qc.h(0)
qc.cx(0, 1)
qc.measure_all()

이를 통해 qpy 데이터를 파일에 쓸 수 있습니다:

with open('bell.qpy', 'wb') as fd:
    qpy.dump(qc, fd)

또는 gzip 압축 파일입니다:

import gzip

with gzip.open('bell.qpy.gz', 'wb') as fd:
    qpy.dump(qc, fd)

그러면 qpy 직렬화된 회로가 제공된 파일에 저장됩니다.

매개변수

  • programs (list[QPY_SUPPORTED_TYPES] | QPY_SUPPORTED_TYPES) – QPY에서 지원하는 객체를 object와 같이 지정된 파일에 저장합니다. QPY는 다음을 지원합니다 QuantumCircuit.

  • file_obj (BinaryIO) – QPY 데이터도 쓸 수 있는 객체와 같은 파일

  • metadata_serializer (type[JSONEncoder] | None) – 선택 사항인 JSONEncoder 클래스로, `` 내의 programs 각 프로그램에 대한 속성을 .metadata 전달받아, 해당 사전(dictionary)을 JSON으로 직렬화하기 위해 json.dump 호출 시 cls kwarg`로 사용됩니다.

  • use_symengine (bool) – 이 플래그는 이 함수가 지원하는 QPY 버전에서는 더 이상 사용되지 않으며, QPY v13 파일 헤더에 있는 사용되지 않는 필드를 설정하는 것 외에는 생성된 QPY 페이로드에 아무런 영향도 미치지 않습니다.

  • version (int) –

    내보낼 QPY 형식 버전입니다. 기본적으로 이것은 지원되는 최신 형식인 QPY_VERSION이지만, 호환성을 위해 이전 버전의 키스킷으로 생성된 QPY 페이로드를 로드해야 하는 경우, 키스킷 메이저 버전 릴리스 중에만 변경할 수 있는 최소 지원 내보내기 버전까지 이전 QPY 형식 버전을 선택해 이전 QPY 형식 버전을 생성할 수도 있습니다. 현재 QPY 버전 및 최소 호환 버전에 액세스할 수 있습니다 qpy.QPY_VERSION 및 qpy.QPY_COMPATIBILITY_VERSION 로 각각 확인할 수 있습니다.

    참고

    이전 버전의 QPY로 지정하면 해당 버전의 QPY 형식에서 발생하는 제한 사항과 잠재적 버그가 지속됩니다. 이전 버전의 키스킷으로 페이로드를 로드하는 데 호환성이 필요한 경우에만 이 방법을 사용해야 합니다.

  • annotation_factories (Mapping[str, Callable[[], annotation.QPYSerializer]] | None) – 사용자 정의 Annotation 객체의 덤프 처리를 위해 annotation.QPUSerializer, 네임스페이스를 새로운 인스턴스를 생성하는 함수로 매핑합니다. 이후에 호출되는 함수는 해당 직렬화기의 사용자 정의 출력 형식을 인식하는 유사한 직렬화 객체를 사용해야 합니다 load() .

레이즈

  • TypeError – 유효하지 않은 데이터 유형이 입력되었을 때 발생합니다.
  • ValueError – 인자로 version 지원되지 않는 버전 번호가 전달된 경우.

get_qpy_version

qiskit.qpy.get_qpy_version(file_obj)

GitHub

이 함수는 파일의 QPY 버전을 식별합니다.

이 함수는 file_obj 의 헤더를 읽고 QPY 형식 버전을 반환합니다. file_obj 의 커서가 진행되지 않습니다. 를 호출하는 등 후속 읽기에 사용하는 경우에는 load()를 호출하는 경우 file_obj 를 직접 전달할 수 있습니다. 예를 들어,

from qiskit import qpy

qpy_version = qpy.get_qpy_version(qpy_file)
if qpy_version > 12:
    qpy.load(qpy_file)

매개변수

file_obj (BinaryIO) – 회로에 대한 QPY 바이너리 데이터를 포함하는 파일 형식의 객체입니다.

리턴

지정한 파일의 QPY 버전입니다.

리턴 유형

int

이러한 함수는 직렬화 또는 역직렬화 중에 문제가 발생하면 QiskitError 의 커스텀 서브클래스를 발생시킵니다.

QpyError

exception qiskit.qpy.QpyError(*message)

GitHub

베이스: QiskitError

Qpy 모듈에서 발생한 오류입니다.

오류 메시지를 설정합니다.

직렬화를 위해 최대값보다 낮은 대상 QPY 버전이 설정되었지만 직렬화할 객체에 해당 형식으로 표현할 수 없는 기능이 포함되어 있으면, 다음의 서브 클래스가 발생합니다 QpyError 의 서브 클래스가 발생합니다:

UnsupportedFeatureForVersion

exception qiskit.qpy.UnsupportedFeatureForVersion(feature, required, target)

GitHub

베이스: QpyError

대상 덤프 버전이 너무 낮아 객체에 있는 기능을 직렬화할 수 없을 때 발생하는 QPY 오류입니다.

매개변수

  • feature (str) – 문제의 특징에 대한 설명.
  • required (int) – 이 기능을 구현하는 데 필요한 QPY의 최소 버전.
  • target (int) – 직렬화 과정에서 사용 중인 QPY 버전.

qiskit.qpy.QPY_VERSION

이 릴리스 기준 현재 QPY 형식 버전입니다. 이것은 version 키워드 인수의 기본값이며 qpy.dump() 의 기본값이며 동일한 인수에 대해 허용되는 값의 상한이기도 합니다. 이것은 또한 지원되는 버전의 상위 본드이기도 합니다 qpy.load().

유형

int

qiskit.qpy.QPY_COMPATIBILITY_VERSION

현재 최소 호환성 QPY 형식 버전입니다. 이것은 최소 버전입니다 qpy.dump() 가 version 키워드 인수에 허용하는 최소 버전입니다. qpy.load() 는 모든 릴리즈된 형식의 QPY를 로드할 수 있습니다( QPY_VERSION 까지).

유형

int


QPY 호환성

QPY 형식은 앞으로 이전 버전과 호환되도록 설계되었습니다. 즉, QPY를 생성한 키스킷 버전보다 최신 키스킷 버전으로 로드할 수 있어야 합니다. 그러나 이전 버전의 키스킷으로 QPY 파일을 로드하는 것은 지원되지 않으며 작동하지 않을 수 있습니다.

예를 들어, qiskit-terra 0.18.1 를 사용하여 QPY 파일을 생성했다면, 해당 QPY 파일을 qiskit-terra 0.19.0 와 가상의 qiskit-terra 0.29.0 로 로드할 수 있다. 그러나 0.18.0 으로 해당 QPY 파일을 로드하는 것은 지원되지 않으며 작동하지 않을 수 있습니다.

회로 메타데이터와 사용자 Annotation 정의 객체는 객체 자체가 완전히 사용자 정의된 것이므로, 사용자가 제공한 클래스를 통해 직렬화 및 역직렬화됩니다. 따라서 이러한 요소들의 전방 및 후방 호환성은 사용자가 제공하는 내용에 따라 제한을 받습니다.

로드 중인 기능이 해당 키스킷 릴리스에서 더 이상 사용되지 않는 경우, QPY는 해당 키스킷 릴리스에서 QPYLoadingDeprecatedFeatureWarning 를 발생시켜 사용 중단 기간과 해당 기능이 내부적으로 어떻게 처리될지 알립니다.

QPYLoadingDeprecatedFeatureWarning

exception qiskit.qpy.QPYLoadingDeprecatedFeatureWarning

GitHub

베이스: QiskitWarning

호출 스택에 안정 지점이 없는 QPY 로딩 함수에 대한 가시적 사용 중단 경고.

참고

1.2.4 이전 버전의 Qiskit에서는, 시리얼라이즈할 객체가 있는 ParameterExpression 경우 함수의 qpy.dump()use_symengine=True 인수가 하위 호환성 문제를 일으킬 수 있습니다. 즉

  • 키스킷의 로딩 버전이 1.2.4 이상이면, 모든 버전의 키스킷 >= 0.46.0 으로 생성된 QPY 파일을 로드할 수 있습니다. 파일을 생성하는 데 0.45.0 와 0.45.3 사이의 키스킷 버전이 사용되었고 기본값이 아닌 인자 use_symengine=True 가 주어진 경우 qpy.dump()로 지정한 경우, 생성 환경에 사용된 symengine 버전이 0.11 또는 0.13 계열인 경우에만 파일을 읽을 수 있지만, 키스킷 0.45 의 지원 기간 동안 환경이 생성되었다면 symengine==0.9.2 이 사용되었을 가능성이 높습니다.
  • 키스킷의 로딩 버전이 0.46.0 에서 1.2.2 사이인 경우, 로딩 환경에 설치된 symengine 의 버전이 생성 환경에 사용된 버전과 일치하는 경우에만 파일을 읽을 수 있습니다.

를 호출하는 동안 symengine 버전 관련 오류로 실패한 QPY 파일을 복구하려면 qpy.load()를 호출하는 동안 실패한 파일을 복구하려면 먼저 Qiskit >= 1.2.4 을 사용하여 파일을 로드하세요. 그래도 실패한다면, 키스킷 0.45.x 이 use_symengine=True 으로 파일을 생성하는 데 사용되었기 때문일 수 있습니다. 이 경우 키스킷 0.45.3 와 symengine==0.9.2 를 사용하여 파일을 로드한 다음, QPY 설정 use_symengine=False 으로 다시 내보내세요. 결과 파일은 이후 모든 버전의 키스킷에서 로드할 수 있습니다.

참고

라이브러리에서 펄스 모듈을 제거한 키스킷 버전 2.0.0 부터는 펄스 데이터가 포함된 페이로드 로딩을 제한적으로 지원합니다. ScheduleBlock 페이로드를 로드하면 QpyError 예외가 발생합니다. 펄스 게이트가 포함된 회로에 페이로드를 로드하면 출력 회로에 각 펄스 게이트에 대한 보정 데이터가 첨부되지 않은 사용자 지정 명령이 포함되어 정의되지 않은 상태로 남게 됩니다.

QPY 형식 버전 기록

서로 다른 키스킷 버전 사이에서 QPY 파일을 로드할 계획이라면 특정 릴리스에서 어떤 버전을 사용할 수 있는지 아는 것이 유용합니다. QPY는 이전 버전과 호환되지만 이전 버전과 호환되지 않으므로 호출하려는 릴리스에서 특정 QPY 형식 버전이 출시되었는지 확인해야 합니다 load() 를 사용해야 합니다. 다음 표에는 모든 키스킷(그리고 키스킷-테라 이전의 키스킷 1.0.0 ) 릴리스에서 지원되었던 QPY 버전이 나열되어 있으며, 이는 키스킷-테라 0.18.0 에서 QPY가 도입되기 이전으로 거슬러 올라간다.

키스킷(< 1.0.0 )용 키스킷-테라 버전
dump() 형식(들) 출력 버전
load() 최대 지원 버전(이전 형식 버전은 항상 읽을 수 있음)
2.6.113, 14, 15, 16, 17, 1818
2.6.013, 14, 15, 16, 17, 1818
2.5.213, 14, 15, 16, 1717
2.5.113, 14, 15, 16, 1717
2.5.013, 14, 15, 16, 1717
2.4.113, 14, 15, 16, 1717
2.4.013, 14, 15, 16, 1717
2.3.113, 14, 15, 16, 1717
2.3.013, 14, 15, 16, 1717
2.2.213, 14, 15, 16그림 16
2.2.113, 14, 15, 16그림 16
2.2.013, 14, 15, 16그림 16
2.1.213, 14, 15, 16그림 16
2.1.113, 14, 15, 16그림 16
2.1.013, 14, 1515
2.0.213, 1414
2.0.113, 1414
2.0.013, 1414
1.4.310, 11, 12, 1313
1.4.210, 11, 12, 1313
1.4.110, 11, 12, 1313
1.4.010, 11, 12, 1313
1.3.310, 11, 12, 1313
1.3.210, 11, 12, 1313
1.3.110, 11, 12, 1313
1.3.010, 11, 12, 1313
1.2.410, 11, 1212
1.2.3 (당겨짐)10, 11, 1212
1.2.210, 11, 1212
1.2.110, 11, 1212
1.2.010, 11, 1212
1.1.010, 11, 1212
1.0.210, 1111
1.0.110, 1111
1.0.010, 1111
0.46.11,000만1,000만
0.45.31,000만1,000만
0.45.21,000만1,000만
0.45.11,000만1,000만
0.45.01,000만1,000만
0.25.399
0.25.299
0.25.199
0.24.288
0.24.177
0.24.077
0.23.366
0.23.266
0.23.166
0.23.066
0.22.455
0.22.355
0.22.255
0.22.155
0.22.055
0.21.255
0.21.155
0.21.055
0.20.244
0.20.144
0.20.044
0.19.244
0.19.133
0.19.022
0.18.311
0.18.211
0.18.111
0.18.011

QPY 형식

QPY 직렬화 형식은 키스킷의 객체를 위한 이식 가능한 크로스 플랫폼 바이너리 직렬화 형식입니다 QuantumCircuit 객체를 위한 이식 가능한 바이너리 직렬화 형식입니다. 기본 파일 형식은 다음과 같습니다:

QPY 파일(또는 메모리 객체)은 항상 다음 6바이트 UTF8 문자열로 시작합니다: QISKIT 바로 뒤에는 전체 파일 헤더가 있습니다. C 구조체로 정의된 파일 헤더의 내용은 다음과 같습니다:

struct {
    uint8_t qpy_version;
    uint8_t qiskit_major_version;
    uint8_t qiskit_minor_version;
    uint8_t qiskit_patch_version;
    uint64_t num_circuits;
}

V10 부터는 파일 헤더 구조에 새 필드가 추가되어 기호 표현식에 사용되는 인코딩 체계를 나타냅니다:

struct {
    uint8_t qpy_version;
    uint8_t qiskit_major_version;
    uint8_t qiskit_minor_version;
    uint8_t qiskit_patch_version;
    uint64_t num_circuits;
    char symbolic_encoding;
}

V16 부터는 파일 헤더 구조체 바로 뒤에 파일 내 각 회로 페이로드의 바이트 오프셋이 포함된 회로 시작 테이블이 이어집니다. 회로 시작 테이블에는 num_circuits 항목이 있으며, 각 항목의 유형은 uint64_t 입니다. 이전 버전에서는 파일 헤더 바로 뒤에 중간에 패딩 없이 회로 페이로드가 순차적으로 이어졌습니다.

크로스 플랫폼 호환성을 위해 모든 값은 네트워크 바이트 순서 [1] (빅 엔디안)을 사용합니다. 단, QPY 형식 버전 17 이하에서는 정수 및 실수의 인코딩이 INSTRUCTION_PARAM 리틀 엔디안입니다.

각 개별 회로는 위에서 아래로 순서대로 다음과 같은 부분으로 구성됩니다:

HEADER
METADATA
REGISTERS
ANNOTATION_HEADER
STANDALONE_VARS
CUSTOM_DEFINITIONS
INSTRUCTIONS

버전 QPY에서 변경: 15 REGISTERS 과 STANDALONE_VARS 사이에 ANNOTATION_HEADER 이 추가되었습니다.

버전 QPY에서 변경: 12 REGISTERS 과 CUSTOM_DEFINITIONS 사이에 STANDALONE_VARS 이 추가되었습니다.

각 회로에 대한 회로 페이로드가 있습니다(총 개수는 파일 헤더의 num_circuits 에 명시되어 있습니다). 데이터의 회로 사이에는 패딩이 없습니다.

버전 18

버전 18에서는 회로 페이로드에서 CalibrationsPack 필드가 제거되었습니다. 2.0 버전부터 Qiskit에서 펄스 게이트 보정 기능이 제거되었으며, 그 이후로 해당 필드는 항상 빈 자리 표시자 ( num_cals = 0)로 작성되어 왔습니다. 이를 제거하면 회로당 2바이트를 절약할 수 있고 형식이 깔끔해집니다.

버전 18에서는 QPY 사양의 나머지 부분과 일관성을 유지하기 위해 정수 및 부동소수점 INSTRUCTION_PARAM 값의 인코딩을 빅엔디안 바이트 순서로 수정했습니다. 버전 1~17에서는 이들이 실수로 리틀 엔디안 형식으로 작성되었습니다.

PARAMETER_VECTOR_TABLE

버전 18은 각 요소를 회로 페이로드당 한 번씩 ParameterVector 저장하며, 모든 요소에서 벡터의 정체를 반복적으로 명시하는 대신 인덱스를 통해 해당 요소를 참조하도록 합니다.

회로 페이로드는 어노테이션 헤더 바로 PARAMETER_VECTOR_TABLE 뒤, 사용자 정의 명령어 정의 바로 앞에 다음과 같이 추가됩니다:

struct {
    uint16_t num_vectors;
}

그 다음으로 다음 num_vectors 항목들이 이어지며

struct {
    uint16_t vector_name_size;
    uint64_t vector_size;
    char     uuid[16];        // the vector's root UUID
}

각 항목 뒤에는 벡터 이름의 utf8vector_name_size 바이트가 바로 이어집니다.

PARAMETER_VECTOR_ELEMENT는 이에 따라 참조로 축소됩니다:

struct {
    uint16_t vector_index;    // index into PARAMETER_VECTOR_TABLE
    uint64_t index;           // index of this element within that vector
}

요소 자체의 UUID는 더 이상 저장되지 않습니다. 이는 벡터의 루트 UUID에 요소의 인덱스를 더한 값이기 때문이며, 리더는 항상 이 관계를 통해 소유 벡터를 찾아왔습니다. 따라서 하나의 요소는 34바이트에 벡터 이름의 길이를 더한 값이 아니라 10바이트를 차지하며, 회로가 매개변수 벡터를 전혀 사용하지 않을 경우 카운트에 회로당 2바이트의 비용이 발생합니다.

중첩된 페이로드(제어 흐름 블록이나 사용자 정의 명령어 정의)는 자체 테이블을 포함하고 있으므로, 각 회로는 개별적으로도 디코딩이 가능합니다.

새로운 ParamRegisterPack

버전 18에서는 레지스터 페이로드의 인코딩 방식이 변경되었으며, 이 페이로드는 전체 또는 ClassicalRegister 단일 값을 저장합니다 Clbit. 이는 명령어의 조건( ‘명령어’ 참조)으로 나타나며, 형식의 INSTRUCTION_PARAM 로 나타납니다 'R'.

버전 17까지 두 경우 모두 유형이 지정되지 않은 하나의 utf8 문자열을 공유했습니다. 레지스터는 이름 그대로였으며, clbit은 null 문자에 이어 "\x00" 회로 내 해당 비트의 인덱스를 10진수로 표기한 형태였습니다. 버전 18부터 페이로드는 다음 두 가지 중 어느 쪽인지 식별하는 태그 바이트로 시작됩니다:

struct {                    // classical register, tag == 1
  uint8_t kind;
  char    name[];           // to the end of the payload
}

struct {                    // single clbit, tag == 0
  uint8_t  kind;
  uint32_t index;           // index of the bit in the circuit
}

레지스터 이름 자체에는 길이가 필요하지 않습니다. 왜냐하면 이를 둘러싼 필드가 이미 페이로드를 구분해 주기 때문입니다. 조건의 경우 conditional_reg_name_size , INSTRUCTION_PARAM 헤더의 가 이를 구분하고, 매개변수의 경우 size 헤더의 가 이를 구분합니다.

버전 18에서는 SPARSE_OBSERVABLE 페이로드의 비트-텀 요소를 “!“H” (uint16_t)에서 “!"B" (uint8_t).

의 값은 항상 SparseObservable.BitTerm 단일 바이트에 들어맞기 때문에, 더 넓은 데이터형은 각 비트 항마다 1바이트의 패딩을 저장했습니다. 따라서 버전 18 페이로드는 비트 단위당 동등한 버전 17 페이로드보다 1바이트 더 작습니다. SPARSE_OBSERVABLE의 다른 필드는 변경되지 않으며, bitterm_data_len은 바이트가 아닌 요소 수를 세기 때문에 그 의미에도 영향을 미치지 않습니다.

등록부 변경 사항

QPY에서 REGISTERS 에 정의되고 버전 4 )에서 업데이트된 레지스터의 표현 방식이 버전 18에서 변경되었습니다. 첫 번째 변경 사항은 레지스터 인덱스 매핑 배열의 유형이 에서 int64_t 로 변경된 것입니다( uint32_t 이는 QPY v4 이전 버전의 방식과 동일합니다). 에 대한 초기 변경은 회로에 포함되지 않은 비트의 센티넬 값으로 -1 을 사용할 수 있도록 하기 위해 이루어졌습니다 int64_t . 실제로는 a의 최대값( uint32_t 4294967295)을 센티넬 값으로 사용할 수 있으므로, 이 작업은 필요하지 않습니다. 버전 18에서는 4294967295의 값을 이전 QPY에서 -1 로 처리했던 것과 마찬가지로 취급해야 하며, 해당 배열 위치의 비트는 회로에 포함되지 않습니다.

버전 18에서는 또한 필드의 type 값으로 'a' 를 추가하여 를 나타냅니다 AncillaRegister. 이전에는 ancilla 레지스터가 로 인코딩되었기 때문에 'q' , 일반적인 객체로 QuantumRegister 역직렬화되었습니다. 기존의 및 'q' 'c' 값은 각각 양자 레지스터와 고전적 레지스터를 계속 나타냅니다.

REGISTERS 헤더 형식도 다음과 같이 업데이트되었습니다

struct {
    char type;
    _Bool standalone;
    uint32_t size;
    uint16_t name_size;
    _bool in_circuit;
    char register_attachment;
}

해당 필드를 register_attachment 위해 구조체 끝에 바이트 하나를 추가함으로써. 이 값이 1인 경우, 이는 회로에 연결된 연속 레지스터를 나타냅니다. 이렇게 하면 비트 인덱스가 포함된 이름 뒤에 오는 배열의 길이가 1이 되며, 이 배열에는 레지스터의 시작 인덱스가 포함됩니다. 따라서 인덱스는 해당 시작 인덱스를 기준으로 size 한 길이 범위입니다. 예를 들어, 시작 인덱스가 5이고 가 10이라면 size 인덱스는 5, 6, 7, 8, 9, 10, 11, 12, 13, 14가 됩니다.

CUSTOM_INSTRUCTION 이름 변경

버전 11부터 17까지, 블록 CUSTOM_INSTRUCTION 이름 뒤에는 무작위로 생성된 UUID 16진수 문자열이 접미사로 붙었습니다(예: "my_gate_b3ecab5b4d6a4eb6bc2b2dbf18d83e1e"), 버전 11 에 설명된 바와 같이. 모든 dump() 호출마다 UUID가 생성되었기 때문에, 동일한 회로에 대해 덤프를 반복적으로 수행하면 서로 다른 바이트 스트림이 생성되었으며, QPY 출력은 결정론적이지 않았습니다.

버전 18부터는 UUID 접미사가 각 호출 dump() 시작 시 재설정되는 카운터로 대체됩니다 (예: "my_gate_0").

버전 17

버전 17에서는 연산자로 포함된 SparseObservable 에 대한 직렬화 및 역직렬화 PauliEvolutionGate 기능이 추가되었습니다.

PAULI_EVOLUTION 변경 사항

PAULI_EVOLUTION 자체의 형식은 변함이 없지만, 압축된 진화 게이트 바로 뒤에 오는 연산자의 형식은 업데이트되었습니다. SparseObservable이제 페이로드는 SPARSE_PAULI_OP_LIST_ELEM 형식으로 정의된 operator_count 개 요소 대신, 형식 SparsePauliOp 또는 형식의 연산자를 모두 포함할 수 있도록 각 연산자의 유형을 명시합니다.

PAULI_EVOLUTION 다음에 오는 새로운 페이로드에는 bool ("!?")이 operator_count 개 연속으로 나열된 뒤, 그 뒤에 operator가 오는 형태가 정확히 포함되어 있습니다. Truebool 값이 인 경우, 연산자는 가 SparseObservable 되며 새로운 SPARSE_OBSERVABLE 형식으로 해석됩니다(아래 참조). False만약 그렇다면, 해당 연산자는 이며 SparsePauliOp , 기존의 SPARSE_PAULI_OP_LIST_ELEM 형식에 따라 해석됩니다.

새로운 SPARSE_OBSERVABLE

SparseObservableSPARSE_OBSERVABLE 형식은 다음 식으로 주어지는 의 인스턴스를 나타냅니다

struct {
  uint32_t num_qubits;
  uint64_t coeff_data_len;
  uint64_t bitterm_data_len;
  uint64_t inds_data_len;
  uint64_t bounds_data_len;
}

그 바로 뒤에는 큐비트 수가 오고, 이어서 관측량의 계수, 비트 항, 인덱스 및 경계를 나타내는 데이터 배열이 나옵니다. 네 개의 필드 *_len 각각은 해당 배열에 포함된 요소의 개수를 나타내며, 배열이 차지하는 바이트 수는 아닙니다. 요소 유형의 크기를 곱해야 바이트 길이를 구할 수 있습니다.

  • 각 계수는 두 개의 연속된 “!d” 요소로 저장되며, 첫 번째는 실수부이고 두 번째는 허수부이므로, 계수의 수는 두 배가 됩니다 coeff_data_len .
  • 비트 항의 원소들은 “!” 유형입니다“H”는 해당 값의 u8 값을 나타냅니다 SparseObservable.BitTerm. 버전 18부터는 이들이 “!대신 “B”를 입력하세요.
  • 인덱스의 요소들은 "!" 유형이다나.
  • 경계 요소들은 "!" 유형입니다Q”.

버전 16

버전 16은 QPY 파일 형식에 회로 시작 테이블을 추가했습니다. 파일에 있는 각 회로 페이로드의 바이트 오프셋의 인덱스 역할을 합니다. 이러한 변경의 동기는 향후 QPY 역직렬화기의 Rust 구현에서 멀티스레딩을 사용하여 회로를 보다 효율적으로 로드할 수 있도록 하기 위함입니다.

기간 변경

피코초 단위의 기존 DURATION 유형 인코딩에 새로운 변형이 추가되었습니다. 이는 다음과 같이 인코딩되며 이전에 지원되는 변형에 추가됩니다.

키스킷 클래스
유형 코드
페이로드
psp하나 double value.

버전 15

버전 15에서는 페이로드 형식에 사용자 지정 어노테이션 개념을 추가했습니다. 어노테이션은 사용자 지정 사용자 객체이므로 QPY 자체는 어노테이션을 직렬화하거나 역직렬화하는 방법을 지정하지 않습니다. 그러나 이 형식은 하위 직렬화기와 함께 작동합니다.

버전 15에서는 단일 서킷 페이로드의 최상위 레벨에 STANDALONE_VARS 및 CUSTOM_DEFINITIONS 필드 사이에 ANNOTATION_HEADER 필드가 추가되었습니다. INSTRUCTION 구조의 한 필드에 대한 해석을 ABI 호환 방식으로 수정하고 INSTRUCTION_ANNOTATIONS 트레일러를 INSTRUCTION 에 추가하여 INSTRUCTION 페이로드의 설정된 비트에 조건부로 존재하도록 합니다.

새로운 주석 헤더

ANNOTATION_HEADER 필드는 헤더의 가변 크기 페이로드입니다. C 구조체인 ANNOTATION_HEADER_STATIC 의 인스턴스로 시작합니다:

struct ANNOTATION_HEADER_STATIC {
    uint32_t num_namespaces;
}

바로 뒤에는 ANNOTATION_STATE 페이로드의 num_namespaces 인스턴스가 이어집니다. 이후의 INSTRUCTION_ANNOTATION 페이로드가 색인되므로 역직렬화 프로세스 중에 이 순서가 중요하며 유지되어야 합니다.

ANNOTATION_STATE 페이로드는 고정된 C 구조체로 시작됩니다:

struct ANNOTATION_STATE_HEADER {
    uint32_t namespace_size;
    uint64_t state_size;
}

이 헤더 바로 뒤에는 네임스페이스를 구성하는 UTF-8 인코딩된 텍스트의 namespace_size 바이트가 이어집니다. 이 바이트 바로 뒤에는 state_size 바이트의 임의 데이터가 있습니다. 이 "상태" 페이로드의 형식은 QPY에 정의되어 있지 않습니다. 대신 저장된 네임스페이스와 연결된 외부 객체의 책임입니다. 형식은 이러한 객체를 생성하는 방법을 지시하지 않으며, 주석은 전적으로 사용자 정의이므로 사용자가 직렬화 및 역직렬화 방법을 제공해야 합니다.

지침 변경 사항

INSTRUCTION 구조체는 버전 9의 이전 정의와 ABI 호환 방식으로 수정되었습니다. 새 구조체는 C 구조체입니다(필드 사이나 구조체 끝에는 패딩이 없다는 점을 기억하세요):

struct INSTRUCTION {
    uint16_t name_size;
    uint16_t label_size;
    uint16_t num_parameters;
    uint32_t num_qargs;
    uint32_t num_cargs;
    uint8_t extras_key;
    uint16_t conditional_reg_name_size;
    int64_t conditional_value;
    uint32_t num_ctrl_qubits;
    uint32_t ctrl_state;
}

여기서 uint8_t extras_key 필드는 이전 uint8_t conditional_key 을 대체합니다. 그 차이는 순전히 해석의 차이입니다. 바이트의 하위 두 비트는 여전히 조건과 그 유형을 정의하는 것으로 해석됩니다. 이제 바이트의 상위 비트는 INSTRUCTION 구조체의 후행 데이터에 INSTRUCTION_ANNOTATIONS_HEADER 필드가 있는지 여부(비트가 설정된 경우)를 나타내는 플래그가 됩니다.

데이터 스트림에는 후행 객체를 포함하고 요소 사이에 패딩 바이트가 전혀 없는 완전한 명령 페이로드가 다음과 같이 나타납니다

struct INSTRUCTION;
uint8_t name[name_size];
uint8_t label[label_size];
uint8_t register[conditional_reg_name_size]; (1)
struct INSTRUCTION_PARAM;                    (2)
struct INSTRUCTION_ARG[num_qargs];
struct INSTRUCTION_ARG[num_cargs];
struct INSTRUCTION_PARAM[num_parameters];
INSTRUCTION_ANNOTATIONS;                     (3)

다음과 같이 적용됩니다.

  1. extras_key 의 두 하위 비트가 2 값이면 조건이 EXPRESSION 이며, conditional_reg_name_size 은 항상 0입니다.
  2. 이 필드는 extras_key 의 두 하위 비트에 2 값이 있는 경우에만 존재하며, 이는 조건이 EXPRESSION 임을 나타냅니다.
  3. 이 필드는 extras_key 의 상위 비트가 설정된 경우에만 존재합니다. 이 필드의 크기는 가변적입니다( 새 지침_주석 참조).

새로운 지시문_주석

INSTRUCTION_ANNOTATIONS 페이로드는 C 구조체로 시작합니다:

struct INSTRUCTION_ANNOTATIONS_HEADER {
    uint32_t num_annotations;
}

이 페이로드 바로 뒤에 가변 크기인 INSTRUCTION_ANNOTATION 페이로드의 num_annotations 인스턴스가 이어집니다.

INSRTUCTION_ANNOTATION 페이로드는 다음 C 구조체에 ANNOTATION_PAYLOAD 이라는 payload_size 과 같은 바이트 수를 더한 값으로 정의됩니다.

struct INSTRUCTION_ANNOTATION {
    uint32_t namespace_index;
    uint32_t payload_size;
}

namespace_index 은 ANNOTATION_HEADER 에 정의된 ANNOTATION_NAMESPACE 객체 목록에 대한 정수 인덱스입니다. 어노테이션의 직렬화 네임스페이스는 관련 페이로드의 UTF-8 인코딩된 문자열입니다.

ANNOTATION_PAYLOAD객체의 형식은 QPY에서 지정하지 않습니다. 이는namespace_index가 참조하는 네임스페이스와 연관된 외부 직렬화 객체와 ANNOTATION_HEADER`의 연관된 직렬화기 상태에 의해 정의됩니다.

PARAM_EXPR_ELEM_V13 내부의 변화

구조체 자체는 변함이 없습니다. 그러나 ( op_code = 15, 따라서 lhs_type = 'p' 및 rhs_type = 'n')를 ParameterExpression.subs()PARAM_EXPR_ELEM_V13 나타내는 호출의 경우, 뒤따르는 MAPPING 은 이제 UUID의 Parameter 원시 바이트 키를 대체된 값으로 매핑합니다. 이전(QPY 버전 13 및 14)에는 이 매핑이 매개변수 이름을 키로 저장했습니다.

버전 14

버전 14에는 새로운 핵심 DURATION 유형이 추가되고 추가 Type 클래스 Float 와 Duration와 새로운 표현식 노드 유형 Stretch.

DURATION

Duration 은 타입의 종류를 인코딩하는 단일 바이트 ASCII char 로 인코딩되고, 그 뒤에 타입에 따라 달라지는 페이로드가 뒤따릅니다. 정의된 코드는 다음과 같습니다:

키스킷 클래스
유형 코드
페이로드
dtt하나 unsigned long long value.
nsn하나 double value.
usu하나 double value.
msm하나 double value.
ss하나 double value.

EXPR_VAR_DECLARATION 변경 사항

EXPR_VAR_DECLARATION 유형은 이제 독립형 변수와 Var 독립형 변수와 Stretch 식별자를 나타냅니다. 이 변경 사항을 지원하기 위해 사용 유형 코드에 기존 항목 외에 두 가지 항목이 새로 추가되었습니다:

유형 코드
의미
Acapture 으로 연결됩니다.
O로컬로 선언된 서킷에 대한 스트레치입니다.

EXPRESSION 변경 사항

표현식 유형 코드에는 s, 에 해당하는 새로운 항목이 있습니다 expr.Stretch 노드에 해당합니다.

키스킷 클래스
유형 코드
페이로드
하위
Stretchs하나 unsigned short var_index0

EXPR_TYPE 변경 사항

다음 표는 이번 버전에 추가된 새로운 유형 클래스를 보여줍니다:

키스킷 클래스
유형 코드
페이로드
Floatf없음.
Durationd없음.

EXPR_VALUE 변경 사항

이제 클래식 표현식의 유형 시스템은 기존의 int 및 bool 인코딩에 더해 값 리터럴에 대한 새로운 인코딩 유형을 지원합니다. 새로운 값 유형 인코딩은 다음과 같습니다:

Python 유형
유형 코드
페이로드
floatf하나 double value.
Durationt하나 DURATION.

버전 13

ParameterExpression버전 13에서는.에 대한 네이티브 Qiskit 직렬화 표현 방식이 추가되었습니다. 이전 버전의 QPY는 기본이 되는 기호 표현식을 직렬화하기 위해 또는 symengine 중 sympy 하나를 사용했습니다. ParameterExpression버전 13부터 QPY는.을 생성하는 데 사용되는 API 호출 순서를 나타냅니다.

직렬화 형식의 주요 변경 사항은 PARAMETER_EXPR 페이로드에 있습니다. 헤더 뒤에 오는 바이트에는 expr_size 이제 구조체 배열이 PARAM_EXPR_ELEM_V13 포함되어 있습니다. ParameterExpression이 배열은 한 번에 하나의 구조체씩 읽히도록 되어 있으며, 각 구조체는 재구성을 위해 수행해야 할 호출 중 하나를 설명합니다.

PARAM_EXPR_ELEM_V13

구조 형식은 다음과 같이 정의됩니다:

struct {
    unsigned char op_code;
    char lhs_type;
    char lhs[16];
    char rhs_type;
    char rhs[16];
} PARAM_EXPR_ELEM_V13;

ParameterExpression이 op_code 필드는 에 추가되는 연산을 정의하는 데 사용됩니다. 값은 다음과 같습니다.

op_code
0__add__()
1__sub__()
2__mul__()
3__truediv__()
4__pow__()
5sin()
6cos()
7tan()
8arcsin()
9arccos()
1,000만exp()
11log()
12sign()
13gradient()
14conjugate()
15subs()
그림 16abs()
17arctan()
255널(null)

NULL 값 255는 실제 연산은 아니지만 재귀적 정의를 나타내는 항목의 연산 코드 필드를 채우는 데만 사용됩니다. 그런 다음 lhs_type 및 rhs_type 필드는 피연산자 유형을 설명하는 데 사용되며 다음 UTF-8 인코딩 문자 중 하나 일 수 있습니다:

값
유형
nNone
pParameter
ffloat
ccomplex
iint
s재귀적 ParameterExpression 정의 시작
e재귀적 ParameterExpression 정의 중지
u대체

f형식 값이, c, 또는 i인 경우, 해당 lhs 또는 rhs 필드의 너비는 각각 128비트입니다. 부동소수점 숫자의 경우, 리터럴 값은 0으로 채운 더블 형식으로 인코딩되는 반면, 복소수는 실수부와 허수부 순서로 인코딩되며, 각각 64비트를 차지합니다. i의 경우, 해당 값은 128비트 전체 폭을 채우기 위해 0으로 패딩된 64비트 부호 있는 정수 형태로 인코딩됩니다. n 는 를 None 나타내는 데 사용되며, 일반적으로 사용되지 않는 인수를 나타내기 때문에 직접 사용되지는 않습니다. 이 p 데이터는 의 UUID이며, Parameter 이는 outer PARAMETER_EXPR 페이로드에 map_elements 설명된 심볼 맵에서 조회할 수 있습니다. ParameterExpression유형 값이 인 s 경우, 이는 중첩된 에 대한 새로운 재귀 섹션의 시작을 나타냅니다. 예를 들어, 다음 코드 조각에서는 안에 final_expr 가 expr 포함되어 있어 중첩된 표현식을 이루고 있습니다:

from qiskit.circuit import Parameter

x = Parameter("x")
y = Parameter("y")
z = Parameter("z")

expr = (x + y) / 2
final_expr = z**2 + expr

이 s 문자가 나타나면, 와 e 유형이 나올 e` struct is reached, the next structs are used for a recursive definition. For both ``s 때까지는 해당 데이터 값이 사용되지 않으며, 항상 0으로 설정됨을 나타냅니다. 의 u 타입 값은 대입 호출을 나타내는 데 사용됩니다. n이는 오직 에만 lhs_type 사용되며, 항상 의 rhs_type 와 짝을 이룹니다. 데이터 값은 해당 subs() 호출에 대한 Parameter 이름과 그 값 간의 매핑을 MAPPING 방식으로 인코딩한 것의 바이트 단위 크기입니다. 매핑 데이터는 구조체 바로 뒤에 위치하며, 다음 구조체는 매핑 데이터 바로 뒤에 시작됩니다.

버전 12

버전 12에서는 다음에 대한 지원이 추가되었습니다:

  • 메모리를 소유하는 expr.Var 변수를 포함하는 회로.

헤더 변경 사항

개별 회로의 HEADER 구조는 입력, 캡처 및 로컬로 선언된 변수의 uint32_t 개수를 회로에 추가했습니다. 새 양식은 다음과 같습니다:

struct {
    uint16_t name_size;
    char global_phase_type;
    uint16_t global_phase_size;
    uint32_t num_qubits;
    uint32_t num_clbits;
    uint64_t metadata_size;
    uint32_t num_registers;
    uint64_t num_instructions;
    uint32_t num_vars;
} HEADER_V12;

HEADER_V12 구조체 바로 뒤에는 V2 버전의 헤더와 동일한 이름, 글로벌-단계, 메타데이터 및 등록 정보가 나옵니다. 레지스터 바로 뒤에는 이 회로의 변수를 정의하는 EXPR_VAR_STANDALONE 의 num_vars 인스턴스가 있습니다. 그 이후에는 이전 버전의 QPY에서와 마찬가지로 사용자 정의 정의와 지침이 계속 적용됩니다.

EXPR_VAR_DECLARATION

EXPR_VAR_DECLARATION 은 독립형인 expr.Var 인스턴스를 정의합니다. 즉, 독립형, 즉 래핑하는 대신 자체 소유 메모리 위치를 나타냅니다 Clbit 또는 ClassicalRegister. 페이로드는 C 구조체입니다:

struct {
    char uuid_bytes[16];
    char usage;
    uint16_t name_size;
}

바로 뒤에 EXPR_TYPE 페이로드와 변수 이름이 포함된 UTF-8 인코딩 문자열 데이터의 name_size 바이트가 이어집니다.

char 사용 유형 코드는 다음 값을 사용합니다:

유형 코드
의미
I회로에 input 변수를 추가합니다.
C회로에 capture 변수를 추가합니다.
L회로에 로컬로 선언된 변수입니다.

EXPR_VAR에 대한 변경 사항

EXPR_VAR 변수에 기존 코드와 페이로드 외에 새로운 유형 코드와 페이로드가 추가되었습니다:

Python 클래스
유형 코드
페이로드
UUIDU변수의 uint32_t 인덱스 하나를 회로 헤더 바로 뒤에 쓰여진 일련의 EXPR_VAR_STANDALONE 변수에 넣습니다.

특히, 이 새로운 유형 코드는 변수가 사용되는 각 위치에서 변수를 다시 정의하는 대신 회로 헤더에서 미리 정의된 변수로 색인화합니다.

EXPRESSION 변경 사항

표현식 유형 코드에는 i, 에 해당하는 새로운 항목이 있습니다 expr.Index 노드에 해당합니다.

키스킷 클래스
유형 코드
페이로드
하위
Indexi추가 페이로드가 없습니다. 자녀는 대상과 인덱스 순서로 표시됩니다.2

버전 11

버전 11은 다음 사항을 제외하고는 버전 10과 동일합니다. UUID.hex먼저, CUSTOM_INSTRUCTION 블록에 포함된 이름들은 형식의 "_{uuid_hex}" 접미사를 가지며, 여기서 uuid_hex 는 명령어가 반환하는 것과 같은 UUID 16진수 문자열입니다. 예를 들어, "b3ecab5b4d6a4eb6bc2b2dbf18d83e1e"입니다. 둘째, 객체에 대한 AnnotatedOperation 지원을 추가합니다. Modifier주석이 달린 연산의 기본 연산 내용은 INSTRUCTION 블록을 사용하여 저장되며, 매개변수의 유형을 나타내기 위해 추가 type 값이 'a'``is added to indicate that the custom instruction is an annotated operation. The list of modifiers are stored as instruction parameters using INSTRUCTION_PARAM, with an additional value ``'m' 더해집니다. 각 수정자는 MODIFIER 구조체를 사용하여 저장됩니다.

수정자

이는 다음을 나타냅니다 Modifier

struct {
    char type;
    uint32_t num_ctrl_qubits;
    uint32_t ctrl_state;
    double power;
}

AnnotatedOperation이는 유형의 객체를 직렬화하는 데 필요한 다양한 유형의 수정자를 저장하기에 충분합니다. 'i'이 필드는 type , 'c' 또는 'p'중 하나이며, 각각 수식자가 역수식자, 제어 수식자, 지수 수식자 중 어느 것에 해당하는지를 나타냅니다. 두 번째 경우, 및 ctrl_state 필드는 num_ctrl_qubits 기본 연산의 제어 논리를 지정하며, 세 번째 경우 필드는 power 기본 연산의 지수를 나타냅니다.

버전 10

버전 10에서는 다음에 대한 지원이 추가되었습니다:

  • Pulse 스케줄 블록 내의 유형 ParameterExpression 객체 및 기호 표현식에 대한 symengine-native 직렬화.
  • Qiskit 0.45.0 릴리스에서 추가된 클래스의 TranspileLayout 새로운 필드들.

파일 헤더에 symbol_encoding 필드가 추가되고 새로운 인코딩 유형 char가 도입되어 각 심볼릭 라이브러리에 다음과 같이 매핑됩니다. p 은 심파이 인코딩을, e 은 심엔진 인코딩을 참조합니다.

FILE_HEADER 변경 사항

V10 이후의 FILE_HEADER의 내용은 다음과 같이 C 구조체로 정의됩니다:

struct {
    uint8_t qpy_version;
    uint8_t qiskit_major_version;
    uint8_t qiskit_minor_version;
    uint8_t qiskit_patch_version;
    uint64_t num_circuits;
    char symbolic_encoding;
} FILE_HEADER_V10;

레이아웃 변경 사항

LAYOUT 구조가 input_qubit_count 필드가 추가되도록 업데이트됩니다. 버전 10에서는 LAYOUT 구조가 추가되었습니다:

struct {
    char exists;
    int32_t initial_layout_size;
    int32_t input_mapping_size;
    int32_t final_layout_size;
    uint32_t extra_registers;
    int32_t input_qubit_count;
}

struct LAYOUT 이후의 나머지 레이아웃 데이터는 이전 버전과 동일한 방식으로 표현됩니다. None만약 input qubit_count 가 < 0이라면, 이는 객체 TranspileLayout 내의 와 _output_qubit_list 모두가 _input_qubit_count 임을 나타냅니다.

버전 9

버전 9에는 클래식 노드에 대한 지원이 추가되었습니다 Expr 노드 및 관련 Types.

expression

노드는 Expr 노드는 가변 폭 데이터 스트림으로 표시됩니다. 노드 자체는 (바이트 스트림의 순서대로) 다음과 같이 표시됩니다:

  1. 1바이트 유형 코드 판별기입니다;
  2. eXPR_TYPE 객체입니다;
  3. 유형 코드별 추가 페이로드입니다;
  4. 유형 코드별 하위 EXPRESSION 페이로드 수(이 수는 유형 코드에 의해 암시되며 명시적으로 저장되지 않음).

각 항목은 다음 표에 설명되어 있습니다:

키스킷 클래스
유형 코드
페이로드
하위
Varx하나 EXPR_VAR.0
Valuev하나 EXPR_VALUE.0
Castcimplicit 의 값에 해당하는 _Bool 하나.1
Unaryu하나 uint8_t 와 같은 숫자 값을 가진 Unary.Op.1
Binaryb하나 uint8_t 와 같은 숫자 값을 가진 Binary.Op.2

EXPR_TYPE

A Type 는 타입의 종류를 인코딩하는 단일 바이트 ASCII char 로 인코딩되고, 그 뒤에 타입에 따라 달라지는 페이로드가 뒤따릅니다. 정의된 코드는 다음과 같습니다:

키스킷 클래스
유형 코드
페이로드
Boolb없음.
Uintu하나 uint32_t width.

EXPR_VAR

이것은 노드의 런타임 변수를 나타냅니다 Var 노드의 런타임 변수를 나타냅니다. 유형 코드와 유형 코드별 페이로드가 뒤따릅니다:

Python 클래스
유형 코드
페이로드
ClbitC하나 uint32_t index 이는 포함 회로의 인덱스인 Clbit 의 인덱스입니다.
ClassicalRegisterRuint16_t reg_name_size 하나 뒤에 등록 이름의 해당 바이트 수만큼의 UTF-8 문자열 데이터가 이어집니다.

EXPR_VALUE

이는 정수와 같은 고전적인 타입 시스템에서 리터럴 객체를 나타냅니다. 현재 이러한 리터럴은 거의 없습니다. 이는 유형 코드로 인코딩되고 유형 코드별 페이로드가 뒤따릅니다.

Python 유형
유형 코드
페이로드
boolb하나 _Bool value.
inti하나 uint8_t num_bytes, 그 뒤에 2의 보수 표현으로 그 수만큼의 바이트(네트워크 순서)로 인코딩된 정수를 입력합니다.

지침 변경 사항

SwitchCaseOp.targetIfElseOp.condition, WhileLoopOp.condition 및 필드에서 노드의 Expr 사용을 지원하기 위해, INSTRUCTION 구조체는 ABI 호환성을 유지하면서 이전 정의로 변경되었습니다. 새로운 구조체는 C 언어의 구조체입니다:

struct {
    uint16_t name_size;
    uint16_t label_size;
    uint16_t num_parameters;
    uint32_t num_qargs;
    uint32_t num_cargs;
    uint8_t conditional_key;
    uint16_t conditional_reg_name_size;
    int64_t conditional_value;
    uint32_t num_ctrl_qubits;
    uint32_t ctrl_state;
}

여기서 유일한 변경 사항은 uint8_t conditional_key 항목이 _Bool has_conditional 으로 대체되었다는 것입니다. 이 새로운 conditional_key 에는 다음과 같은 효과가 있는 숫자 값이 사용됩니다:

값
결과
0명령의 '.condition' 필드가 None으로 설정되어 있습니다. 조건부_reg_name_size및조건부_값` 필드는 무시해야 합니다.
1이 명령에는 .condition 필드가 a 또는 Clbit 또는 a ClassicalRegister와 conditional_value 값의 정수로 설정됩니다. 후행 데이터를 포함한 INSTRUCTION 페이로드는 QPY 버전 8 미만에서와 동일하게 구문 분석됩니다.
2이 인스트럭션의 .condition 필드는 Expr 노드로 설정되어 있습니다. conditional_reg_name_size 및 conditional_value 필드는 무시해야 합니다. 구조체 뒤에 오는 데이터는 (9 미만 QPY 버전에서와 같이) 클래스 이름에 대한 name_size 바이트의 UTF-8 문자열 데이터와 레이블에 대한 label_size 바이트의 UTF-8 문자열 데이터(있는 경우)가 뒤따릅니다. 그런 다음 하나의 INSTRUCTION_PARAM이 있으며, 여기에는 표현식이 포함됩니다. 그 후 구문 분석은 이전 버전의 QPY와 마찬가지로 INSTRUCTION_ARG 구조체를 사용하여 계속됩니다.

INSTRUCTION_PARAM 변경 사항

EXPRESSION 매개변수를 정의하는 새로운 유형 코드 x 가 추가되었습니다.

버전 8

버전 8에서는 속성에 QuantumCircuit.layout 저장된 값을 TranspileLayout 처리하는 기능이 추가되었습니다. 버전 8에서는 회로 페이로드 끝부분의 보정 블록 바로 뒤에 이제 struct가 LAYOUT 있습니다. 이 구조체는 클래스의 TranspileLayout 세 가지 속성의 크기를 나타냅니다.

레이아웃

struct {
    char exists;
    int32_t initial_layout_size;
    int32_t input_mapping_size;
    int32_t final_layout_size;
    uint32_t extra_registers;
}

부호화된 값 중 하나라도 -1 인 경우 해당 속성이 None 임을 나타냅니다.

struct LAYOUT 바로 다음에는 회로에 존재하지 않는 독립형 레지스터 정의(특히 버전 4 에서 도입된 형식)를 위한 extra_registers REGISTERS struct가 있습니다. 그리고 속성을 TranspileLayout.initial_layout 정의하는 구조체도 INITIAL_LAYOUT_BIT 있습니다 initial_layout_size .

초기 레이아웃 비트

struct {
    int32_t index;
    int32_t register_size;
}

여기서 -1 값은 None (비트와 연결된 레지스터가 없음을 의미)을 나타냅니다. 각 INITIAL_LAYOUT_BIT 구조체 뒤에는 등록 이름에 대한 utf8 인코딩된 문자열에 대한 register_size 바이트가 있습니다.

참고

버전 18부터는 익명 큐비트(index == -1)에서 register_size 필드가 완전히 생략됩니다. 이 구조체는 단순히 하나의 로만 구성됩니다 int32_t. 이름이 지정된 큐비트는 변경되지 않습니다.

초기 레이아웃 다음에는 초기 레이아웃에서 물리적 비트의 위치를 나타내는 uint32_t 정수의 input_mapping_size 배열이 있습니다. 이를 통해 배열 인덱스가 입력 매핑 위치인 가상 비트 목록을 구성할 수 있습니다.

마지막으로 final_layout_size uint32_t 정수의 배열이 있습니다. 각 요소는 회로의 qubits 속성에 있는 인덱스로, 큐비트 시작 위치에서 회로 끝의 출력 위치까지 매핑을 구축할 수 있습니다.

버전 7

버전 7에서는 하위 루틴에 대한 참조를 유지하면서 ScheduleBlock 프로그램의 Reference 명령어 및 직렬화에 대한 지원이 추가되었습니다:

from qiskit import pulse
from qiskit import qpy

with pulse.build() as schedule:
    pulse.reference("cr45p", "q0", "q1")
    pulse.reference("x", "q0")
    pulse.reference("cr45p", "q0", "q1")

with open('template_ecr.qpy', 'wb') as fd:
    qpy.dump(schedule, fd)

기존의 SCHEDULE_BLOCK 데이터 모델은 유지되지만 버전 7에서는 바로 뒤에 참조된 서브루틴의 데이터를 나타내는 추가 MAPPING utf8 바이트 블록이 추가됩니다.

Reference 인스트럭션에 대한 SCHEDULE_BLOCK_INSTRUCTIONS 그룹에 새 유형 키 문자가 추가됩니다.

  • y: Reference 지침

문자열의 튜플인 Reference 명령의 피연산자(예: ( “cr45p”, “q0”, “q1” )에 대한 새로운 유형의 키 문자가 SCHEDULE_BLOCK_OPERANDS 그룹에 추가됩니다.

  • o문자열(피연산자 문자열)

이는 기본 제공 Python 문자열과 동일한 인코딩이지만, QPY의 표준 값 인코딩은 문자열 데이터에 s 유형 문자를 사용하므로 펄스 명령 피연산자의 범위에서 SymbolicPulse 와 충돌합니다. 펄스 명령 피연산자에 표시되는 문자열 데이터에는 특수 유형 문자 o 가 예약되어 있습니다.

또한 버전 7에서는 INSTRUCTION_PARM 구조체에 두 개의 새로운 유형 키가 추가되었습니다. "d" 뒤에는 데이터가 없으며 리터럴 값( CASE_DEFAULT 을 나타냅니다. "R" 는 ClassicalRegister 또는 Clbit로 표시되며, 그 뒤에는 INSTRUCTION 필드의 조건의 첫 번째 요소에 사용된 레지스터 또는 클래식 비트 설명과 동일한 형식이 이어집니다.

버전 6

버전 6에서는 ScalableSymbolicPulse 에 대한 지원이 추가되었습니다. 이러한 객체는 SymbolicPulse 객체처럼 저장되고 읽혀지며, 클래스 선택을 올바르게 처리하기 위해 클래스 이름이 데이터에 추가됩니다.

SymbolicPulse 블록은 이제 SYMBOLIC_PULSE_V2 헤더로 시작합니다:

struct {
    uint16_t class_name_size;
    uint16_t type_size;
    uint16_t envelope_size;
    uint16_t constraints_size;
    uint16_t valid_amp_conditions_size;
    _bool amp_limited;
}

버전 5와 비교했을 때 유일한 변경 사항은 class_name_size가 추가되었다는 점입니다. 그런 다음 헤더 바로 뒤에 클래스 이름이 포함된 class_name_size utf8 바이트가 이어집니다. 현재 SymbolicPulse 또는 ScalableSymbolicPulse 이 지원됩니다. 나머지 데이터는 버전 5와 동일합니다.

버전 5

버전 5는 버전 4와 비교하여 에 ScheduleBlock 대한 지원을 추가하고, INSTRUCTION 메타데이터 페이로드와 CUSTOM_INSTRUCTION 블록이라는 두 가지 페이로드를 변경한 점이 다릅니다. 이제 회로 내의 개체를 더 정확하게 반영할 ControlledGate 수 있도록 새로운 필드가 추가되었습니다. 또한, MAPPING 블록을 구현하기 위해 새로운 페이로드 MAP_ITEM이 정의되었습니다.

참고

펄스 스케줄 및 사용자 정의 보정값 표현에 대한 지원이 Qiskit v2.0 에서 제거되었습니다. QPY 페이로드를 로드할 때, 이러한 데이터 필드는 이제 무시되거나 Qiskit을 사용하여 역직렬화할 때 오류를 발생시킵니다.

QPY 버전 5 이상에서,

struct {
    char type;
}

는 파일 헤더 블록 바로 뒤에 파일에 저장된 프로그램 유형을 나타냅니다.

  • type==c, QuantumCircuit 페이로드는 다음과 같습니다
  • type==s, ScheduleBlock 페이로드는 다음과 같습니다
참고

서로 다른 프로그램은 같은 파일에 함께 담을 수 없습니다. 프로그램 유형에 따라 다른 파일을 만들어야 합니다. 동일한 유형의 여러 개체를 하나의 파일에 저장할 수 있습니다.

SCHEDULE_BLOCK

ScheduleBlock 는 QPY 버전 5에서 처음 지원됩니다. 이를 통해 사용자는 다음과 같이 펄스 프로그램을 QPY 바이너리 형식으로 저장할 수 있습니다:

from qiskit import pulse, qpy

with pulse.build() as schedule:
    pulse.play(pulse.Gaussian(160, 0.1, 40), pulse.DriveChannel(0))

with open('schedule.qpy', 'wb') as fd:
    qpy.dump(schedule, fd)

with open('schedule.qpy', 'rb') as fd:
    new_schedule = qpy.load(fd)[0]

회로 및 스케줄 블록은 동일한 QPY 인터페이스를 통해 직렬화 및 역직렬화된다는 점에 유의하세요. 입력 데이터 유형은 암시적으로 분석되며 일정 블록을 저장하는 데 추가 옵션이 필요하지 않습니다.

스케줄 블록 헤더

ScheduleBlock 블록은 다음 헤더로 시작합니다:

struct {
    uint16_t name_size;
    uint64_t metadata_size;
    uint16_t num_element;
}

바로 뒤에 name_size utf8 바이트의 일정 이름과 metadata_size utf8 바이트의 JSON 직렬화된 메타데이터 사전이 일정에 첨부됩니다.

스케줄 블록 정렬

그런 다음 일정 블록의 정렬 컨텍스트는 지원되는 컨텍스트 유형을 나타내는 char 로 시작하여 정렬 컨텍스트와 관련된 매개 변수를 나타내는 SEQUENCE 블록 AlignmentKind._context_params 으로 이어집니다. 컨텍스트 유형 문자는 다음과 같이 각 정렬 하위 클래스에 매핑됩니다:

  • l: AlignLeft
  • r: AlignRight
  • s: AlignSequential
  • e: AlignEquispaced

컨텍스트 매개변수에 저장된 콜백 함수 때문에 AlignFunc 컨텍스트는 지원되지 않습니다.

스케줄 블록 지침

이 정렬 블록 뒤에는 중첩된 스케줄 블록과 스케줄 지침으로 구성될 수 있는 num_element 길이의 블록 요소가 이어집니다. 각 스케줄 인스트럭션은 인스트럭션 유형을 나타내는 char 으로 시작하고 그 뒤에 인스트럭션 operands 을 나타내는 SEQUENCE 블록이 있습니다. 펄스 Instruction 의 데이터 구조는 클래스와 피연산자의 튜플에 의해 인스턴스가 고유하게 결정될 수 있도록 통합되어 있습니다. 인스트럭션 서브클래스에 대한 char 타입의 매핑은 다음과 같이 정의됩니다:

  • a: Acquire 지침
  • p: Play 지침
  • d: Delay 지침
  • f: SetFrequency 지침
  • g: ShiftFrequency 지침
  • q: SetPhase 지침
  • r: ShiftPhase 지침
  • b: RelativeBarrier 지침
  • t: TimeBlockade 지침
  • y: Reference 지침 (버전에 새로 추가됨 0.7 )

스케줄 블록 연산자

이러한 인스턴스의 피연산자는 표준 QPY 값 직렬화 메커니즘을 통해 직렬화할 수 있지만, 일정 피연산자에만 나타나는 특수 객체 유형이 있습니다. 피연산자는 SEQUENCE로 직렬화되므로 각 요소는 INSTRUCTION_PARAM 팩 구조로 패킹되어야 하며, 각 페이로드는 헤더 블록으로 시작하는 type 및 uint64_t size 으로 구성됩니다. 특수 객체는 다음 유형 키로 시작합니다:

  • c: Channel
  • w: Waveform
  • s: SymbolicPulse
  • o: 문자열(피연산자 문자열, 버전 0.7 에 추가됨)

채널

채널 블록은 객체 데이터를 Channel 하위 클래스에 매핑하는 채널 하위 유형 char 으로 시작합니다. 매핑은 다음과 같이 정의됩니다:

  • d: DriveChannel
  • c: ControlChannel
  • m: MeasureChannel
  • a: AcquireChannel
  • e: MemorySlot
  • r: RegisterSlot

키 바로 뒤에는 INSTRUCTION_PARAM으로 직렬화된 채널 인덱스가 있습니다.

파형

파형 블록은 웨이브폼 헤더로 시작합니다:

struct {
    double epsilon;
    uint32_t data_size;
    _bool amp_limited;
}

뒤에 data_size 바이트의 복잡한 ndarray 바이너리가 생성됩니다 numpy.save. 이는 양자 디바이스에서 재생되는 복잡한 IQ 데이터 포인트를 나타냅니다. name 은 문자열 또는 None 일 수 있는 INSTRUCTION_PARAM 팩 구조체의 샘플 뒤에 저장됩니다.

SymbolicPulse

SymbolicPulse 블록은 SYMBOLIC_PULSE 헤더로 시작합니다:

struct {
    uint16_t type_size;
    uint16_t envelope_size;
    uint16_t constraints_size;
    uint16_t valid_amp_conditions_size;
    _bool amp_limited;
}

뒤에 "가우시안" 또는 “GaussianSquare” 과 같은 파형 클래스를 나타내는 SymbolicPulse.pulse_type 문자열의 type_size utf8 바이트가 이어집니다. 그런 다음 envelope_size, constraints_size, valid_amp_conditions_size utf8 바이트의 직렬화된 기호 표현식이 각각 SymbolicPulse.envelope, SymbolicPulse.constraints, SymbolicPulse.valid_amp_conditions 에 대해 생성됩니다. 이러한 표현식의 문자열 표현은 일반적으로 길이가 길기 때문에 데이터 압축을 통해 파이썬 zlib 모듈에서 바이너리 표현식을 생성합니다.

펄스 인스턴스를 고유하게 지정하려면 duration 및 나머지 파라미터로 구성된 관련 파라미터도 딕셔너리로 저장해야 합니다. 딕셔너리 매개변수는 먼저 MAPPING 형식으로 덤프된 다음 duration 이 INSTRUCTION_PARAM 팩 구조와 함께 덤프됩니다. 마지막으로 name 는 문자열 또는 None 일 수 있는 INSTRUCTION_PARAM 팩 구조체와 함께 저장됩니다.

맵핑

매핑은 임의의 매핑 객체에 대한 표현입니다. 이는 MAP_ITEM 페이로드로 표시되는 키-값 쌍의 고정 길이 SEQUENCE입니다.

MAP_ITEM은 다음과 같이 정의된 헤더로 시작됩니다:

struct {
    uint16_t key_size;
    char type;
    uint16_t size;
}

바로 뒤에 문자열로 된 사전 키를 나타내는 key_size utf8 바이트와 QPY 직렬화 가능한 type 의 임의의 객체 데이터 size utf8 바이트가 이어집니다.

회로 보정

CIRCUIT_CALIBRATIONS 블록은 사용자 지정 명령어 세트의 펄스 보정을 정의하는 딕셔너리입니다. 이 블록은 다음 캘리브레이션 헤더로 시작합니다:

struct {
    uint16_t num_cals;
}

뒤에 num_cals 길이의 보정 항목이 있으며, 각 보정 항목은 CALIBRATION_DEF 헤더로 시작됩니다:

struct {
    uint16_t name_size;
    uint16_t num_qubits;
    uint16_t num_params;
    char type;
}

캘리브레이션 정의 헤더 뒤에 name_size utf8 바이트의 게이트 이름, num_qubits 길이의 큐비트 시퀀스를 나타내는 정수, num_params 길이의 사용자 지정 명령에 연결된 파라미터에 대한 INSTRUCTION_PARAM 페이로드가 이어집니다. type 은 펄스 프로그램의 클래스를 나타내며, 원칙적으로 ScheduleBlock 또는 Schedule 입니다. QPY 버전 5부터는 ScheduleBlock 페이로드만 지원됩니다. 마지막으로, SCHEDULE_BLOCK 페이로드는 각 CALIBRATION_DEF 항목에 대해 패킹됩니다.

지시사항

INSTRUCTION 블록이 수정되어, 및 ControlledGate.ctrl_state 속성을 ControlledGate.num_ctrl_qubits 모델링하는 데 사용되는 두 개의 새로운 필드인 num_ctrl_qubits 와 ctrl_state 가 추가되었습니다. 새로운 페이로드 패킹 구조체 형식은 다음과 같습니다:

struct {
    uint16_t name_size;
    uint16_t label_size;
    uint16_t num_parameters;
    uint32_t num_qargs;
    uint32_t num_cargs;
    _Bool has_conditional;
    uint16_t conditional_reg_name_size;
    int64_t conditional_value;
    uint32_t num_ctrl_qubits;
    uint32_t ctrl_state;
}

나머지 인스트럭션 페이로드는 동일합니다. 전체 페이로드에 대한 자세한 내용은 지침을 참조하세요.

사용자 정의 지시문

QPY 버전 5의 CUSTOM_INSTRUCTION 블록은 사용자 ControlledGate 정의 객체의 속성에 ControlledGate.base_gate 저장된 객체의 qiskit.circuit.Instruction 크기를 정의하는 데 사용되는 새로운 필드를 base_gate_size 추가합니다. 이 변경 사항에 따라 CUSTOM_INSTRUCTION 메타데이터 블록은 다음과 같이 변경됩니다:

struct {
    uint16_t name_size;
    char type;
    uint32_t num_qubits;
    uint32_t num_clbits;
    _Bool custom_definition;
    uint64_t size;
    uint32_t num_ctrl_qubits;
    uint32_t ctrl_state;
    uint64_t base_gate_size
}

CUSTOM_INSTRUCTION 구조체 바로 뒤에는 name_size 크기의 utf8 인코딩된 이름이 있습니다.

만약 custom_definition 라면, True 이는 바로 뒤따르는 size 바이트에 해당 게이트의 사용자 정의에 사용할 수 있는 QPY 회로 데이터가 포함되어 있음을 의미합니다. 만약 custom_definition 라면 False , 해당 명령어는 불투명한 것으로 간주될 수 있다(즉, 정의가 없음). 이 type 필드는 사용자 정의에 따라 어떤 유형의 객체가 생성될지를 결정합니다. 만약 'g' 라면 객체가 Gate 되고, 'i' 라면 객체가 Instruction 됩니다.

그 다음 base_gate_size 바이트에는 ControlledGate.base_gate 에 대한 INSTRUCTION 페이로드가 포함되어 있습니다.

ControlledGate또한, 사용자 정의 명령어가 사용자 정의 명령어임을 나타내기 위해 에 대한 type 추가 값이 더해집니다 'c' .

버전 4

버전 4는 INSTRUCTION_PARAM 구조체에 2개의 새로운 타입 문자열, None (데이터 없음으로 인코딩됨)을 나타내는 z , a를 나타내는 q ( QuantumCircuit (QPY 회로로 인코딩됨), r 는 range 의 정수를 나타내고( RANGE로 인코딩됨), t 는 sequence ( SEQUENCE로 정의된 대로 인코딩됨)을 나타냅니다. 또한 버전 4에서는 레지스터 인덱스 매핑 배열의 유형이 uint32_t 에서 int64_t 로 변경되었습니다. 배열 요소의 값이 음수이면 회로에 존재하지 않는 레지스터 비트를 나타냅니다.

REGISTERS 헤더 형식도 다음과 같이 업데이트되었습니다

struct {
    char type;
    _Bool standalone;
    uint32_t size;
    uint16_t name_size;
    _bool in_circuit;
}

레지스터가 회로의 일부인지 여부를 나타내는 in_circuit 필드를 추가하기만 하면 됩니다.

RANGE

RANGE는 range 객체의 표현입니다. 다음과 같이 정의됩니다:

struct {
    int64_t start;
    int64_t stop;
    int64_t step;
}

sequence

SEQUENCE는 임의의 시퀀스 객체를 표현한 것입니다. 시퀀스는 임의의 파이썬 객체의 고정 길이 컨테이너에 불과하므로 QPY는 어떤 시퀀스도 완전히 표현할 수 없지만, 시퀀스의 내용이 INSTRUCTION_PARAM 페이로드에 대해 다른 QPY 직렬화 가능한 유형인 한 sequence 객체를 직렬화할 수 있습니다.

시퀀스 명령 매개변수는 다음과 같이 정의된 헤더로 시작됩니다:

struct {
    uint64_t size;
}

뒤에 INSTRUCTION_PARAM 페이로드인 size 요소가 있으며, 각 요소는 시퀀스의 요소를 정의합니다. 시퀀스 객체는 적절한 유형으로 타입 캐스팅됩니다(예: tuple), 이후에는

버전 3

QPY 형식의 버전 3은 QPY 내에서 구조체를 직접 PauliEvolutionGate 표현하기 위한 구조체 형식을 정의한다는 점을 제외하면 버전 2와 동일합니다. 이를 위해 CUSTOM_DEFINITIONS 구조체는 이제 PauliEvolutionGate.을 'p' 나타내는 새로운 유형 값을 지원합니다. 사용자 정의 지시문 테이블의 항목에는 문자로 시작하고 그 뒤에 "###PauliEvolutionGate_" UUID 문자열(버전 11~17) 또는 카운터(버전 18 이상, ‘버전 18’ 참조)가 이어지는 고유한 이름이 생성됩니다. 이 게이트 이름은 QPY에서 예약되어 있으므로, 정의 세트가 설정된 사용자 정의 Instruction 객체에 해당 이름 접두사가 포함되어 있으면 오류가 발생합니다. 형식이 인 경우, 데이터 페이로드는 'p' 다음과 같이 정의됩니다:

PAULI_EVOLUTION

이는 높은 수준을 나타냅니다 PauliEvolutionGate

struct {
    uint64_t operator_count;
    _Bool standalone_op;
    char time_type;
    uint64_t time_size;
    uint64_t synthesis_size;
}

그 바로 뒤에는 operator_count SPARSE_PAULI_OP_LIST_ELEM 페이로드로 정의된 요소들이 이어집니다. 그 다음에는 속성을 time 나타내는 바이트가 이어집니다 time_size . 만약 standalone_op 라면 True , 연산자는 단 하나만 존재해야 한다. time_type이 바이트들의 인코딩은 의 값에 따라 결정됩니다. 'e'``'f'의 time_type 가능한 값은, 'p', 및 입니다. Parameter만약 time_type 라면, 'f' 이는 더블이며, 'p' 는 PARAMETER로 표현되는 객체를 Parameter 정의하고, e 는 PARAMETER_EXPR 로 표현되는 (가 아닌) 객체를 ParameterExpression 정의합니다. 그 다음에는 게이트에서 사용하는 클래스를 EvolutionSynthesis 나타내는, utf8 로 인코딩된 JSON 페이로드인 바이트가 이어집니다 synthesis_size .

스파스 파울리 연산자 목록 요소

SparsePauliOp이는 ~의 한 예입니다.

struct {
    uint32_t pauli_op_size;
}

SparsePauliOp그 바로 뒤에는 pauli_op_size .npy 형식 [2] 의 데이터인 바이트가 이어지며, 이는.를 나타냅니다.

ParameterQPY 형식의 버전 3에서는 또한 를 ParameterVectorElement 와 별개의 하위 클래스로 표현하기 위한 구조체 형식도 정의하고 있습니다. 이를 통해 새로운 매개변수 유형 char가 'v' 추가되어, ParameterVectorElement 이제 INSTRUCTION_PARAM의 유형 문자열 값으로 지원됩니다. 이러한 매개변수의 페이로드는 아래에서 PARAMETER_VECTOR_ELEMENT 로 정의되어 있습니다.

매개변수_벡터_요소

PARAMETER_VECTOR_ELEMENT는 INSTRUCTION_PARAM의 데이터를 나타내는 객체를 ParameterVectorElement 나타냅니다. PARAMETER_VECTOR_ELEMENT의 내용은 다음과 같이 정의됩니다:

struct {
    uint16_t vector_name_size;
    uint64_t vector_size;
    char uuid[16];
    uint64_t index;
}

바로 뒤에 매개변수의 벡터 이름을 나타내는 vector_name_size utf8 바이트가 이어집니다.

QPY 버전 18에서 변경됨

이 벡터는 회로에 한 번 저장되며 PARAMETER_VECTOR_TABLE , 이 페이로드는 해당 벡터를 참조하는 참조가 되었고 uint64_t index, 그 뒤를 이어 uint16_t vector_index 이름, 크기 또는 고유 식별자(UUID)가 없는 상태로 이어집니다. 버전 18을 참조하십시오.

매개변수_표현식

또한, QPY 형식 버전 v3 부터는 와 ParameterVectorElement 를 Parameter 구분하므로, 두 유형을 구분할 수 있도록 의 ParameterExpression 페이로드를 업데이트해야 합니다. 다음은 수정된 페이로드 형식으로, 버전 1 및 버전 2 의 형식과 대체로 동일하지만, 심볼 유형 필드를 포함하도록 구조체 map_elements (struct)만 수정된 것입니다.

PARAMETER_EXPR은 INSTRUCTION_PARAM의 데이터를 나타내는 객체를 ParameterExpression 의미합니다. PARAMETER_EXPR의 내용은 다음과 같이 정의됩니다:

struct {
    uint64_t map_elements;
    uint64_t expr_size;
}

헤더 바로 뒤에는 매개변수 표현식에 대한 표현식 문자열이 포함된 utf8 데이터의 expr_size 바이트가 있으며, 이 데이터는 표현식의 심파이 srepr입니다. 다음은 map_elements 형식의 요소가 포함된 심볼 맵입니다

struct {
    char symbol_type;
    char type;
    uint64_t size;
}

이 symbol_type 키는 해당 요소의 기호 표현에 대한 페이로드 유형을 결정합니다. ParameterVectorElement만약 라면 p 을 Parameter 나타내고, 만약 라면 v 을 나타냅니다. map 요소 구조체 바로 뒤에는 심볼 맵 키 페이로드가 이어지며, 인 p 경우 symbol_type 그 바로 뒤에 PARAMETER 객체(구조체 및 utf8 이름 바이트 모두)가 오고, 인 v 경우 symbol_type 구조체 바로 뒤에 PARAMETER_VECTOR_ELEMENT (구조체 및 utf8 이름 바이트 모두)가 온다. 그 다음에는 심볼의 데이터를 담는 바이트가 size 이어집니다. type데이터 형식은 의 값에 따라 달라집니다. 만약 type 라면 p , 이는 를 Parameter 나타내며 크기는 0이 되고, 값은 키와 동일해집니다. 마찬가지로, 만약 가 v``type 라면, 이는 를 ParameterVectorElement 나타내며, 값이 키와 동일하므로 size는 0이 됩니다. 만약 type 라면 f , 이는 배정밀도 부동소수점을 나타냅니다. 만약 type 라면 c , 이는 COMPLEX 로 표현되는 배정밀도 복소수를 나타냅니다. int64_t마지막으로, type이 인 i 경우, 이는 인 정수를 나타냅니다.

버전 2

QPY 형식의 버전 2는 헤더 섹션이 약간 다르다는 점을 제외하면 버전 1과 동일합니다. 나머지 페이로드 형식에 대한 자세한 내용은 버전 1 섹션을 참조하세요.

헤더

HEADER의 내용은 C 구조체로 정의됩니다:

struct {
    uint16_t name_size;
    char global_phase_type;
    uint16_t global_phase_size;
    uint32_t num_qubits;
    uint32_t num_clbits;
    uint64_t metadata_size;
    uint32_t num_registers;
    uint64_t num_instructions;
}

그 바로 뒤에는 name_size 회로 이름을 나타내는 utf8 형 데이터가 바이트 단위로 이어집니다. 그 다음에는 바로 global_phase_size 전역 위상을 나타내는 바이트가 이어집니다. global_phase_type해당 데이터의 내용은 의 값에 따라 결정됩니다. double만약 라면, 'f' 데이터는 부동소수점형이며 크기는 입니다. Parameterif it’s는 'p' PARAM 구조체(아래 참조)로 표현되는 객체를 Parameter 정의하는 반면, e 는 PARAM_EXPR 구조체(아래 참조)로 표현되는 (가 아닌) 객체를 ParameterExpression 정의합니다.

버전 1

헤더

C 구조체로 정의된 HEADER의 내용은 다음과 같습니다:

struct {
    uint16_t name_size;
    double global_phase;
    uint32_t num_qubits;
    uint32_t num_clbits;
    uint64_t metadata_size;
    uint32_t num_registers;
    uint64_t num_instructions;
}

그 바로 뒤에 회로 이름에 대한 utf8 데이터의 name_size 바이트가 이어집니다.

메타데이터

메타데이터 필드는 UTF8 인코딩된 JSON 문자열입니다. QPY 파일의 시작 부분에 고정된 크기인 HEADER와 name 문자열을 읽은 후 metadata_size 바이트 수를 읽고 JSON을 파싱하여 회로의 메타데이터를 얻습니다.

REGISTERS

REGISTERS의 내용은 여러 개의 REGISTER 객체입니다. Num_registers가 0보다 크면 메타데이터를 읽은 후 다음과 같이 정의된 레지스터 구조의 수를 읽습니다:

struct {
    char type;
    _Bool standalone;
    uint32_t size;
    uint16_t name_size;
}

type 는 'q' 또는 'c' 입니다.

REGISTER 구조체 바로 뒤에는 name_size 크기의 utf8 인코딩된 레지스터 이름이 있습니다. name utf8 바이트 뒤에는 회로의 큐비트 인덱스에 대한 레지스터의 인덱스 맵이 포함된 size 크기의 int64_t 값 배열이 있습니다. 예를 들어, 배열 요소 0’s 값은 포함된 회로의 큐비트 목록에서 register[0]의 위치 인덱스입니다.

참고

QPY 버전 4 이전에는 배열 요소의 유형이 uint32_t 이었습니다. 회로에 존재하지 않는 배열의 비트를 나타내는 음수 값을 사용할 수 있도록 변경되었습니다

독립형 부울은 레지스터가 회로에 추가된 독립형 레지스터로 구성되는지 아니면 기존 비트에서 생성된 레지스터로 구성되는지를 결정합니다. 예를 들어 레지스터의 일부로만 구성된 비트가 있는 경우 레지스터는 독립형 레지스터로 간주됩니다:

qr = QuantumRegister(2)
qc = QuantumCircuit(qr)

qr 레지스터는 독립형 레지스터가 됩니다. 같은 경우

bits = [Qubit(), Qubit()]
qr2 = QuantumRegister(bits=bits)
qc = QuantumCircuit(qr2)

qr2 는 standalone 를 False 로 설정합니다.

사용자 정의

이 섹션에서는 회로의 모든 명령어에 대한 사용자 정의 정의를 지정합니다.

CUSTOM_DEFINITION_HEADER 내용은 다음과 같이 정의됩니다:

struct {
    uint64_t size;
}

크기가 0보다 크면 회로에 사용자 지정 명령어가 포함되어 있음을 의미합니다. 각 사용자 지정 인스트럭션은 다음과 같이 정의된 CUSTOM_INSTruction 블록으로 정의됩니다:

struct {
    uint16_t name_size;
    char type;
    uint32_t num_qubits;
    uint32_t num_clbits;
    _Bool custom_definition;
    uint64_t size;
}

CUSTOM_INSTRUCTION 구조체 바로 뒤에는 name_size 크기의 utf8 인코딩된 이름이 있습니다.

만약 custom_definition 라면, True 이는 바로 뒤따르는 size 바이트에 해당 게이트의 사용자 정의에 사용할 수 있는 QPY 회로 데이터가 포함되어 있음을 의미합니다. 만약 custom_definition 라면 False , 해당 명령어는 불투명한 것으로 간주될 수 있다(즉, 정의가 없음). 이 type 필드는 사용자 정의에 따라 어떤 유형의 객체가 생성될지를 결정합니다. 만약 'g' 라면 객체가 Gate 되고, 'i' 라면 객체가 Instruction 됩니다.

지침

지침의 내용은 지침 메타데이터 객체의 목록입니다

struct {
    uint16_t name_size;
    uint16_t label_size;
    uint16_t num_parameters;
    uint32_t num_qargs;
    uint32_t num_cargs;
    _Bool has_conditional;
    uint16_t conditional_reg_name_size;
    int64_t conditional_value;
}

이 메타데이터 객체 바로 뒤에 name 에 대한 utf8 바이트의 name_size 바이트가 이어집니다. name 는 키스킷에 정의된 경우 Instruction 클래스의 키스킷 클래스 이름입니다. 그렇지 않으면 사용자 지정 인스트럭션 이름으로 되돌아갑니다. name 바이트 뒤에는 인스트럭션에 설정된 경우 라벨에 대한 label_size 바이트의 utf8 데이터가 있습니다. 레이블 바이트 다음에 has_conditional 가 True 인 경우 조건부 레지스터 이름에 대한 conditional_reg_name_size 바이트의 utf8 데이터가 있습니다. 단일 클래식 비트 조건의 경우 레지스터 이름 utf8 데이터 앞에 널 문자 “x00” 와 조건이 설정된 회로의 클래식 비트 인덱스를 나타내는 utf8 문자열 정수가 접두사로 붙습니다.

QPY 버전 18에서 변경됨: 이 페이로드는 utf8 문자열이 아닌 태그가 지정된 구조체입니다. 버전 18을 참조하십시오.

그 바로 뒤에 해당 명령어의 인자 목록에 대한 INSTRUCTION_ARG 구조체가 이어집니다. 모든 양자 인자(num_qargs가 있음), 모든 클래식 인자(num_cargs가 있음) 순서로 나열됩니다.

각 INSTRUCTION_ARG의 내용은 다음과 같습니다:

struct {
    char type;
    uint32_t index;
}

type 는 'q' 또는 'c' 입니다.

인스트럭션의 모든 인자 뒤에 num_parameters INSTRUCTION_PARAM 구조체를 사용하여 파라미터를 지정합니다.

각 INSTRUCTION_PARAM의 내용은 다음과 같습니다:

struct {
    char type;
    uint64_t size;
}

각 INSTRUCTION_PARAM 뒤에는 해당 매개변수의 데이터가 바이트 단위로 이어집니다 size . 'i'이 type 필드는, 'f', 'p', 'e', 's', 'c' 또는 'n' 일 수 있으며, 이 값들이 형식을 결정합니다. 정수인 경우 'i' , 'f' 실수인 경우, 's' 문자열인 경우( utf8 로 인코딩됨), 'c' 복소수인 경우, 그리고 데이터는 PARAMETER_EXPR 섹션의 구조체 형식으로 표현됩니다. Parameter'p' PARAMETER 구조체로 표현되는 객체를 Parameter 정의하며, e PARAMETER_EXPR 구조체로 표현되는 (가 아닌) 객체를 ParameterExpression 정의합니다 (QPY 형식 버전 3 에서는 형식이 약간 조정되었습니다. 참조: PARAMETER_EXPR ), 'n' 는 numpy의 객체( 또는 numpy 유형)를 ndarray 나타내며, 이는 데이터가.npy 형식 [2] 데이터임을 의미합니다. 또한 QPY 버전 3 에서 'v' 는 PARAMETER_VECTOR_ELEMENT 구조체로 표현되는 를 ParameterVectorElement 나타냅니다.

매개변수

매개변수(PARAMETER)는 INSTRUCTION_PARAM에 대한 데이터를 나타내는 객체입니다 Parameter . PARAMETER의 내용은 다음과 같이 정의됩니다:

struct {
    uint16_t name_size;
    char uuid[16];
}

바로 뒤에 매개변수 이름을 나타내는 name_size utf8 바이트가 이어집니다.

매개변수_표현식

PARAMETER_EXPR은 INSTRUCTION_PARAM의 데이터를 나타내는 객체를 ParameterExpression 의미합니다. PARAMETER_EXPR의 내용은 다음과 같이 정의됩니다:

PARAMETER_EXPR 데이터는 헤더로 시작합니다:

struct {
    uint64_t map_elements;
    uint64_t expr_size;
}

헤더 바로 뒤에는 매개변수 표현식에 대한 표현식 문자열이 포함된 utf8 데이터의 expr_size 바이트가 있으며, 이 데이터는 표현식의 심파이 srepr입니다. 다음은 map_elements 형식의 요소가 포함된 심볼 맵입니다

struct {
    char type;
    uint64_t size;
}

그 직후에는 심볼 맵 키에 해당하는 객체(구조체 및 utf8 이름 바이트 모두)가 PARAMETER 이어집니다. 그 다음에는 심볼의 데이터를 담는 바이트가 size 이어집니다. type데이터 형식은 의 값에 따라 달라집니다. 만약 type 라면 p , 이는 를 Parameter 나타내며, size는 0이 되고, 값은 키와 동일해집니다. 만약 type 라면 f , 이는 배정밀도 부동소수점을 나타냅니다. 만약 type 라면 c , 이는 COMPLEX 로 표현되는 배정밀도 복소수를 나타냅니다. int64_t마지막으로, type이 인 i 경우, 이는 인 정수를 나타냅니다.

복잡도

QPY로 배정밀도 복소수 값을 표현할 때는 다음 구조가 사용됩니다:

struct {
    double real;
    double imag;
}

이는 Python 의 복합 유형에 대한 내부 C 표현과 일치합니다. [3]


참조

[ 1 ]

https://tools.ietf.org/html/rfc1700

[2] (1,2 )

https://numpy.org/doc/stable/reference/generated/numpy.lib.format.html

[ 3 ]

https://docs.python.org/3/c-api/complex.html# c.Py_complex

이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.