Skip to content

Commit

Permalink
Changing default value of use_static_result_alloc to True (#106)
Browse files Browse the repository at this point in the history
* Changing default value of use_static_result_alloc to True
  • Loading branch information
idavis authored Apr 18, 2022
1 parent fc6ae2b commit d3c43c4
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 4 deletions.
27 changes: 27 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,33 @@
## [Unreleased]

- Adding static result allocation by @idavis in https://github.com/qir-alliance/pyqir/pull/103
- Bumping version to `0.4.0a1` by @idavis in https://github.com/qir-alliance/pyqir/pull/105
- Changing default value of use_static_result_alloc to True by @idavis in https://github.com/qir-alliance/pyqir/pull/106

PR [#106](https://github.com/qir-alliance/pyqir/pull/106) changes
the default way `Result`s are emitted in emitted QIR.

The previous approach
used `call %Result* @__quantum__qis__m__body(%Qubit* null)` for
measurement saving to a `Result` variable. Along with this, branching
used `__quantum__rt__result_equal(%Result*, %Result*)` along with
`__quantum__rt__result_get_zero` and `__quantum__rt__result_get_one`
to perform branching.

The new default usage in `0.4.0a1` uses static `Result` identifiers
instead of dynamic `Result` values. With that, measurement now uses
`"call void @__quantum__qis__mz__body(%Qubit*, %Result*)`
which accepts the static `Result` identifier. As a result, the
`pyqir-evaluator` can now see which `Result` is being written to.
Branching has also changed to use
`call i1 @__quantum__qir__read_result(%Result*)` which returns the
boolean value of the `Result`.

For the `pyqir-generator`, the use of static and dynamic `Qubit` and `Result` can now be configured via two new methods on the `SimpleModule`
class:

- `use_static_qubit_alloc(bool)`
- `use_static_result_alloc(bool)`

## [0.3.2a1] - 2022-04-05

Expand Down
2 changes: 1 addition & 1 deletion pyqir-generator/pyqir/generator/_native.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class SimpleModule:
def use_static_result_alloc(self, value: bool):
"""
Configures code generation to use static or dynamic result allocation
based on the provided value. Default is `False`.
based on the provided value. Default is `True`.
:param name: The value indicating to use static result
allocation (`True`) or dynamic allocation (`False`)
Expand Down
2 changes: 1 addition & 1 deletion pyqir-generator/src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl SimpleModule {
qubits,
instructions: Vec::new(),
use_static_qubit_alloc: true,
use_static_result_alloc: false,
use_static_result_alloc: true,
};

let builder = Py::new(py, Builder::new())?;
Expand Down
34 changes: 32 additions & 2 deletions pyqir-generator/tests/test_external_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,49 @@ def test_call_bool_false(self) -> None:
mod.builder.call(f, [False])
self.assertIn("call void @test_function(i1 false)", mod.ir())

def test_call_single_result(self) -> None:
def test_call_single_static_result(self) -> None:
mod = SimpleModule("test", 1, 1)
qis = BasicQisBuilder(mod.builder)
qis.m(mod.qubits[0], mod.results[0])

f = mod.add_external_function(
"test_function", types.Function([types.RESULT], types.VOID)
)
mod.builder.call(f, [mod.results[0]])
self.assertIn("call void @test_function(%Result* null)", mod.ir())

def test_call_single_dynamic_result(self) -> None:
mod = SimpleModule("test", 1, 1)
mod.use_static_result_alloc(False)
qis = BasicQisBuilder(mod.builder)
qis.m(mod.qubits[0], mod.results[0])

f = mod.add_external_function(
"test_function", types.Function([types.RESULT], types.VOID)
)
mod.builder.call(f, [mod.results[0]])
self.assertIn("call void @test_function(%Result* %result0)", mod.ir())

def test_call_two_results(self) -> None:
def test_call_two_static_results(self) -> None:
mod = SimpleModule("test", 1, 2)
qis = BasicQisBuilder(mod.builder)
qis.m(mod.qubits[0], mod.results[0])
qis.m(mod.qubits[0], mod.results[1])

f = mod.add_external_function(
"test_function",
types.Function([types.RESULT, types.RESULT], types.VOID)
)
mod.builder.call(f, [mod.results[1], mod.results[0]])

self.assertIn(
"call void @test_function(%Result* inttoptr (i64 1 to %Result*), %Result* null)",
mod.ir(),
)

def test_call_two_dynamic_results(self) -> None:
mod = SimpleModule("test", 1, 2)
mod.use_static_result_alloc(False)
qis = BasicQisBuilder(mod.builder)
qis.m(mod.qubits[0], mod.results[0])
qis.m(mod.qubits[0], mod.results[1])
Expand Down
8 changes: 8 additions & 0 deletions pyqir-generator/tests/test_qis.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,15 @@ def test_rotated(self) -> None:

def test_m(self) -> None:
mod = SimpleModule("test_m", 1, 1)
mod.use_static_result_alloc(False)
qis = BasicQisBuilder(mod.builder)
qis.m(mod.qubits[0], mod.results[0])
call = f"call %Result* @__quantum__qis__m__body(%Qubit* null)"
self.assertIn(call, mod.ir())

def test_mz(self) -> None:
mod = SimpleModule("test_mz", 1, 1)
qis = BasicQisBuilder(mod.builder)
qis.m(mod.qubits[0], mod.results[0])
call = f"call void @__quantum__qis__mz__body(%Qubit* null, %Result* null)"
self.assertIn(call, mod.ir())

0 comments on commit d3c43c4

Please sign in to comment.