From 6c4871e6d02d9c5449742a01266d88c19ca00ed4 Mon Sep 17 00:00:00 2001 From: mstechly Date: Wed, 6 Nov 2024 12:33:17 +0100 Subject: [PATCH] docs: update docs for repeated structure --- docs/examples/qpe.yaml | 84 +++++++++++++++++++ docs/format.md | 42 ++++++++++ src/qref/schema_v1.py | 7 +- .../repetition_2_geometric.yaml | 10 +-- 4 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 docs/examples/qpe.yaml diff --git a/docs/examples/qpe.yaml b/docs/examples/qpe.yaml new file mode 100644 index 0000000..411f8c9 --- /dev/null +++ b/docs/examples/qpe.yaml @@ -0,0 +1,84 @@ +description: Program representing QPE using geometric sequence +input: + program: + children: + - name: Hadamards + ports: + - direction: through + name: register + size: N + - name: Evolution + ports: + - direction: input + name: result_in + size: bits_of_precision + - direction: output + name: result_out + size: N + - direction: input + name: psi_in + size: None + - direction: output + name: psi_out + size: None + children: + - name: U + ports: + - direction: through + name: result + size: bits_of_precision + - direction: through + name: psi + size: N + resources: + - name: T_gates + type: additive + value: N**2 + connections: + - source: result_in + target: U.result + - source: U.result + target: result_out + - source: psi_in + target: U.psi + - source: U.psi + target: psi_out + repetition: + count: bits_of_precision + sequence: + type: geometric + ratio: 1 + - name: Inverse_QFT + ports: + - direction: through + name: register + size: N + connections: + - source: result_in + target: Hadamards.register + - source: Hadamards.register + target: Evolution.result_in + - source: Evolution.result_out + target: Inverse_QFT.register + - source: Inverse_QFT.register + target: result_out + - source: psi_in + target: Evolution.psi_in + - source: Evolution.psi_out + target: psi_out + name: QPE + ports: + - direction: input + name: result_in + size: ceil(log2(1/eps)) + - direction: output + name: result_out + size: ceil(log2(1/eps)) + - direction: input + name: psi_in + size: M + - direction: output + name: psi_out + size: M + + version: v1 diff --git a/docs/format.md b/docs/format.md index c4cd521..729edca 100644 --- a/docs/format.md +++ b/docs/format.md @@ -153,3 +153,45 @@ beginning looks as follows: ```yaml --8<-- "basic_program_concise.yaml" ``` + + +### Repetitions + +On top of the basic fileds listed above, one can also write a QREF routine which contains repetitions. + +This can be added with `repetition` field: + +```yaml +repetition: + count: ceil(1/eps) + sequence: + type: constant + multiplier: 1 +``` + +`repetition` consists of two parts: + +- `count` – defines how many times the child of the this routine should be repeated. +- `sequence` – defines how the costs for the repetition will be aggregated. Each `sequence` has a field `type` which defines the type of the sequence. Depending on the type there are extra fields, summarized in the table below. + + +There are 5 different sequences that one can currently use in QREF: + + +|
Sequence type
|
Additional fields
| Description | Example | +|-------|-------|-------|-------| +| `constant`| `multiplier` | In each iteration child is repeated `multiplier` number of times. | Trotterization | +| `arithmetic`| `difference`, `initial_term` | Iteration starts from `initial_term` repetitions of a child and then we increase the of repetitions by `difference` in every iteration. | QFT | +| `geometric` | `ratio` | In each iteration number of repetitions is multiplied by `ratio`, starts for 1 repetition in the first iteartion. | QPE | +| `closed_form` | `sum`, `prod`, `num_terms_symbol` | This can be used for cases, where we know the closed-form expression for the total cost of the routine given the number of repetitions is defined `num_terms_symbol`. `sum` is an expression for additive resources and `prod` is for multiplicative. | Any | +| `custom` | `term_expression`, `iterator_symbol` | This can be used in case where we don't know the formula for closed form, but we do know the formula for each term, which is defined using `term_expression`, and we use `iterator_symbol` to denote the iterator. | Any | + + +This representation abstracts out certain implementation details. Consider implementation of QPE using geometric sequence below. The child `U` of routine `Evolution` has two ports: `result` and `psi`, the with sizes `bits_of_precision` and `N`. Even though in the executable implementation each next controlled `U^2^i` only acts on one control qubit from the `result` register, there's currently no way of expressing it in QREF. + +=== "YAML" + + ```yaml + --8<-- "qpe.yaml" + ``` + diff --git a/src/qref/schema_v1.py b/src/qref/schema_v1.py index ed87732..24803ce 100644 --- a/src/qref/schema_v1.py +++ b/src/qref/schema_v1.py @@ -24,6 +24,7 @@ BaseModel, BeforeValidator, ConfigDict, + Field, StringConstraints, model_validator, ) @@ -230,10 +231,10 @@ class RoutineV1(BaseModel): """ name: _Name - children: Annotated[NamedList[RoutineV1], _name_sorter] = NamedList["RoutineV1"]() + children: Annotated[NamedList[RoutineV1], _name_sorter] = Field(default_factory=NamedList) type: str | None = None - ports: Annotated[NamedList[PortV1], _name_sorter] = NamedList[PortV1]() - resources: Annotated[NamedList[ResourceV1], _name_sorter] = NamedList[ResourceV1]() + ports: Annotated[NamedList[PortV1], _name_sorter] = Field(default_factory=NamedList) + resources: Annotated[NamedList[ResourceV1], _name_sorter] = Field(default_factory=NamedList) connections: Annotated[list[Annotated[ConnectionV1, _connection_parser]], _source_sorter] = [] input_params: list[_OptionallyMultiNamespacedName] = [] local_variables: dict[str, str] = {} diff --git a/tests/qref/data/valid_programs/programs_with_repetitions/repetition_2_geometric.yaml b/tests/qref/data/valid_programs/programs_with_repetitions/repetition_2_geometric.yaml index 9ccfbcf..411f8c9 100644 --- a/tests/qref/data/valid_programs/programs_with_repetitions/repetition_2_geometric.yaml +++ b/tests/qref/data/valid_programs/programs_with_repetitions/repetition_2_geometric.yaml @@ -11,22 +11,22 @@ input: ports: - direction: input name: result_in - size: N + size: bits_of_precision - direction: output name: result_out size: N - direction: input name: psi_in - size: M + size: None - direction: output name: psi_out - size: M + size: None children: - name: U ports: - direction: through name: result - size: N + size: bits_of_precision - direction: through name: psi size: N @@ -44,7 +44,7 @@ input: - source: U.psi target: psi_out repetition: - count: N + count: bits_of_precision sequence: type: geometric ratio: 1