Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions quick/circuit/from_framework/from_pennylane.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,6 @@ def extract_params(

tape = qml.workflow.construct_tape(circuit)()

print(tape.operations)

for gate in tape.operations:
gate_name = gate.name
self.gate_mapping[gate_name](gate, params)
Expand Down
4 changes: 2 additions & 2 deletions quick/compiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

__all__ = ["Compiler"]
__all__ = ["ShendeCompiler"]

from quick.compiler.compiler import Compiler
from quick.compiler.shende_compiler import ShendeCompiler
62 changes: 10 additions & 52 deletions quick/compiler/compiler.py → quick/compiler/shende_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,35 @@

from __future__ import annotations

__all__ = ["Compiler"]
__all__ = ["ShendeCompiler"]

from collections.abc import Sequence
import numpy as np
from numpy.typing import NDArray
from typing import TypeAlias

from quick.circuit import Circuit
from quick.optimizer import Optimizer
from quick.primitives import Bra, Ket, Operator
from quick.synthesis.statepreparation import StatePreparation, Isometry
from quick.synthesis.unitarypreparation import UnitaryPreparation, ShannonDecomposition

""" Type aliases for the primitives to be compiled:
- `PRIMITIVE` is a single primitive object, which can be a `Bra`, `Ket`, `Operator`, or a `numpy.ndarray`.
- `PRIMITIVE` is a single primitive object, which can be a `Bra`, `Ket`, `Operator`,or a `numpy.ndarray`.
- `PRIMITIVES` is a list of tuples containing the primitive object and the qubits they need to be applied to.
"""
PRIMITIVE: TypeAlias = Bra | Ket | Operator | NDArray[np.complex128]
PRIMITIVES: TypeAlias = list[tuple[PRIMITIVE, Sequence[int]]]


class Compiler:
""" `quick.compiler.Compiler` is the base class for creating quantum compilation passes
from primitives to circuits. The `compile` method is the main interface for the compiler,
which takes in a primitives object and returns a circuit object.
class ShendeCompiler:
""" `quick.compiler.ShendeCompiler` provides compilation of states and unitaries
into circuits using the Shende et al. method. The `compile` method is the main
interface for the compiler, which takes in a primitives object and returns a
circuit object.

Notes
-----
To create a custom compiler, subclass `quick.compiler.Compiler` and overwrite the
To create a custom compiler, subclass `quick.compiler.ShendeCompiler` and overwrite the
`state_preparation`, `unitary_preparation`, and `compile` methods. The default compiler
uses Shende et al for compilation.

Expand All @@ -61,8 +61,6 @@ class Compiler:
The state preparation schema for the compiler. Use `Shende` for the default schema.
`unitary_prep` : type[quick.synthesis.unitarypreparation.UnitaryPreparation], optional, default=ShannonDecomposition
The unitary preparation schema for the compiler. Use `ShannonDecomposition` for the default schema.
`optimizer` : quick.optimizer.Optimizer, optional, default=None
The optimizer for the compiler. Use `None` for no optimization.

Attributes
----------
Expand All @@ -72,8 +70,6 @@ class Compiler:
The state preparation schema for the compiler.
`unitary_prep` : quick.synthesis.unitarypreparation.UnitaryPreparation
The unitary preparation schema for the compiler.
`optimizer` : quick.optimizer.Optimizer, optional, default=None
The optimizer for the compiler. Uses `None` for no optimization.

Raises
------
Expand All @@ -93,7 +89,6 @@ def __init__(
circuit_framework: type[Circuit],
state_prep: type[StatePreparation] = Isometry,
unitary_prep: type[UnitaryPreparation] = ShannonDecomposition,
optimizer: Optimizer | None = None
) -> None:
""" Initialize a `quick.compiler.Compiler` object.
"""
Expand All @@ -103,13 +98,10 @@ def __init__(
raise TypeError("Invalid state preparation schema.")
if not issubclass(unitary_prep, UnitaryPreparation):
raise TypeError("Invalid unitary preparation schema.")
if not isinstance(optimizer, (Optimizer, type(None))):
raise TypeError("Invalid optimizer.")

self.circuit_framework = circuit_framework
self.state_prep = state_prep(circuit_framework)
self.unitary_prep = unitary_prep(circuit_framework)
self.optimizer = optimizer

def state_preparation(
self,
Expand Down Expand Up @@ -155,37 +147,6 @@ def unitary_preparation(
"""
return self.unitary_prep.prepare_unitary(unitary)

def optimize(
self,
circuit: Circuit
) -> Circuit:
""" Optimize the given circuit.

Parameters
----------
`circuit` : quick.circuit.Circuit
The circuit to be optimized.

Returns
-------
`optimized_circuit` : quick.circuit.Circuit
The optimized circuit.

Raises
------
ValueError
- If the optimizer is None.

Usage
-----
>>> optimized_circuit = compiler.optimize(circuit)
"""
if self.optimizer is None:
raise ValueError("No optimizer is defined. Add an optimizer to use this method.")

optimized_circuit = self.optimizer.optimize(circuit)
return optimized_circuit

@staticmethod
def _check_primitive(primitive: PRIMITIVE) -> None:
""" Check if the primitive object is valid.
Expand Down Expand Up @@ -259,8 +220,8 @@ def _check_primitives(primitives: PRIMITIVES) -> None:
preparing the primitive object.
"""
for primitive, qubit_indices in primitives:
Compiler._check_primitive(primitive)
Compiler._check_primitive_qubits(primitive, qubit_indices)
ShendeCompiler._check_primitive(primitive)
ShendeCompiler._check_primitive_qubits(primitive, qubit_indices)

def _compile_primitive(
self,
Expand Down Expand Up @@ -346,7 +307,4 @@ def compile(
compiled_circuit = self._compile_primitive(primitive)
circuit.add(compiled_circuit, qubits)

if self.optimizer is not None:
circuit = self.optimize(circuit)

return circuit
5 changes: 0 additions & 5 deletions tests/circuit/test_circuit_to_controlled.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,6 @@ def test_rz_control(
check_multiple_controlled_circuit.MCRZ(0.5, [0, 1], 2)
check_multiple_controlled_circuit.MCRZ(0.5, [0, 1], [2, 3])

print(single_controlled_circuit.circuit_log)
print(check_single_controlled_circuit.circuit_log)

print(multiple_controlled_circuit.circuit_log)
print(check_multiple_controlled_circuit.circuit_log)
assert single_controlled_circuit == check_single_controlled_circuit
assert multiple_controlled_circuit == check_multiple_controlled_circuit

Expand Down
2 changes: 0 additions & 2 deletions tests/circuit/test_control_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,6 @@ def test_CRX_control_state(
checker_circuit.CRX(0.1, 0, 1)
checker_circuit.X(0)

print(repr(circuit))
print(repr(checker_circuit))
# Check the circuit is equivalent to the checker circuit
assert circuit == checker_circuit

Expand Down
6 changes: 1 addition & 5 deletions tests/compiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

__all__ = [
"Template",
"TestShendeCompiler"
]
__all__ = ["TestShendeCompiler"]

from tests.compiler.test_compiler import Template
from tests.compiler.test_shende_compiler import TestShendeCompiler
138 changes: 0 additions & 138 deletions tests/compiler/test_compiler.py

This file was deleted.

Loading
Loading