Skip to content

Commit

Permalink
feat: Create OpenQASMSimulator class (#203)
Browse files Browse the repository at this point in the history
This exposes an easy-to-use `parse_program` method to be used in conjunction a custom program contexts to handle the instantiation of the `Interpreter` and calling its `run` method.

Also reversed the dependency of `run` on `build_circuit`.
  • Loading branch information
speller26 authored Aug 5, 2023
1 parent 6b07c3a commit 46cf59a
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 31 deletions.
13 changes: 6 additions & 7 deletions src/braket/default_simulator/openqasm/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ def build_circuit(
self, source: str, inputs: Optional[Dict[str, io_type]] = None, is_file: bool = False
) -> Circuit:
"""Interpret an OpenQASM program and build a Circuit IR."""
return self.run(source, inputs, is_file).circuit

def run(
self, source: str, inputs: Optional[Dict[str, io_type]] = None, is_file: bool = False
) -> ProgramContext:
"""Interpret an OpenQASM program and return the program state"""
if inputs:
self.context.load_inputs(inputs)

Expand All @@ -141,13 +147,6 @@ def build_circuit(
"This program uses OpenQASM language features that may "
"not be supported on QPUs or on-demand simulators."
)
return self.context.circuit

def run(
self, source: str, inputs: Optional[Dict[str, io_type]] = None, is_file: bool = False
) -> ProgramContext:
"""Interpret an OpenQASM program and return the program state"""
self.build_circuit(source, inputs, is_file)
return self.context

@singledispatchmethod
Expand Down
80 changes: 66 additions & 14 deletions src/braket/default_simulator/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.

import uuid
import warnings
from abc import abstractmethod
from abc import ABC, abstractmethod
from typing import Any, Callable, Dict, List, Union

from braket.device_schema import DeviceActionType, DeviceCapabilities
from braket.device_schema import DeviceActionType
from braket.ir.jaqcd import Program as JaqcdProgram
from braket.ir.jaqcd.program_v1 import Results
from braket.ir.openqasm import Program as OpenQASMProgram
Expand All @@ -29,6 +30,7 @@
from braket.default_simulator.observables import Hermitian, TensorProduct
from braket.default_simulator.openqasm.circuit import Circuit
from braket.default_simulator.openqasm.interpreter import Interpreter
from braket.default_simulator.openqasm.program_context import AbstractProgramContext, ProgramContext
from braket.default_simulator.operation import Observable, Operation
from braket.default_simulator.operation_helpers import from_braket_instruction
from braket.default_simulator.result_types import (
Expand Down Expand Up @@ -57,7 +59,65 @@
)


class BaseLocalSimulator(BraketSimulator):
class OpenQASMSimulator(BraketSimulator, ABC):
"""An abstract simulator that runs an OpenQASM 3 program.
Translation of individual operations and observables from OpenQASM to the desired format
is handled by implementing the `AbstractProgramContext` interface. This implementation is
exposed by implementing the `create_program_context` method, which enables the `parse_program`
method to translate an entire OpenQASM program:
>>> class MyProgramContext(AbstractProgramContext):
>>> def __init__(self):
>>> ...
>>>
>>> def add_gate_instruction(self, gate_name: str, target: Tuple[int], ...):
>>> ...
>>>
>>> # Implement other MyProgramContext interface methods
>>>
>>> class MySimulator(OpenQASMSimulator):
>>> def create_program_context(self) -> AbstractProgramContext:
>>> return MyProgramContext()
>>>
>>> # Implement other BraketSimulator interface methods
>>>
>>> parsed = MySimulator().parse_program(program)
To register a simulator so the Amazon Braket SDK recognizes its name,
the name and class must be added as an entry point for "braket.simulators".
This is done by adding an entry to entry_points in the simulator package's setup.py:
>>> entry_points = {
>>> "braket.simulators": [
>>> "backend_name = <backend_class>"
>>> ]
>>> }
"""

@abstractmethod
def create_program_context(self) -> AbstractProgramContext:
"""Creates a new program context to handle translation of OpenQASM into a desired format."""

def parse_program(self, program: OpenQASMProgram) -> AbstractProgramContext:
"""Parses an OpenQASM program and returns a program context.
Args:
program (OpenQASMProgram): The program to parse.
Returns:
AbstractProgramContext: The program context after the program has been parsed.
"""
is_file = program.source.endswith(".qasm")
interpreter = Interpreter(self.create_program_context())
return interpreter.run(
source=program.source,
inputs=program.inputs,
is_file=is_file,
)


class BaseLocalSimulator(OpenQASMSimulator):
def run(
self, circuit_ir: Union[OpenQASMProgram, JaqcdProgram], *args, **kwargs
) -> GateModelTaskResult:
Expand Down Expand Up @@ -87,10 +147,8 @@ def run(
return self.run_openqasm(circuit_ir, *args, **kwargs)
return self.run_jaqcd(circuit_ir, *args, **kwargs)

@property
@abstractmethod
def properties(self) -> DeviceCapabilities:
"""simulator properties"""
def create_program_context(self) -> AbstractProgramContext:
return ProgramContext()

@abstractmethod
def initialize_simulation(self, **kwargs) -> Simulation:
Expand Down Expand Up @@ -365,13 +423,7 @@ def run_openqasm(
as a result type when shots=0. Or, if StateVector and Amplitude result types
are requested when shots>0.
"""
is_file = openqasm_ir.source.endswith(".qasm")
interpreter = Interpreter()
circuit = interpreter.build_circuit(
source=openqasm_ir.source,
inputs=openqasm_ir.inputs,
is_file=is_file,
)
circuit = self.parse_program(openqasm_ir).circuit
qubit_count = circuit.num_qubits

self._validate_ir_results_compatibility(
Expand Down
20 changes: 10 additions & 10 deletions src/braket/simulator/braket_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@
from typing import Union

from braket.device_schema import DeviceCapabilities
from braket.ir.annealing import Problem
from braket.ir.ahs import Program as AHSProgram
from braket.ir.jaqcd import Program as JaqcdProgram
from braket.ir.openqasm import Program as OQ3Program
from braket.task_result import AnnealingTaskResult, GateModelTaskResult
from braket.task_result import AnalogHamiltonianSimulationTaskResult, GateModelTaskResult


class BraketSimulator(ABC):
"""An abstract simulator that locally runs a quantum task.
The task can be either a circuit-based program or an annealing problem,
specified by the given IR.
The task can be either a quantum circuit defined in an OpenQASM or JAQCD program,
or an analog Hamiltonian simulation (AHS) program.
For users creating their own simulator: to register a simulator so the
Braket SDK recognizes its name, the name and class must added as an
Braket SDK recognizes its name, the name and class must be added as an
entry point for "braket.simulators". This is done by adding an entry to
entry_points in the simulator package's setup.py:
Expand All @@ -43,20 +43,20 @@ class BraketSimulator(ABC):

@abstractmethod
def run(
self, ir: Union[JaqcdProgram, OQ3Program, Problem], *args, **kwargs
) -> Union[GateModelTaskResult, AnnealingTaskResult]:
self, ir: Union[OQ3Program, AHSProgram, JaqcdProgram], *args, **kwargs
) -> Union[GateModelTaskResult, AnalogHamiltonianSimulationTaskResult]:
"""
Run the task specified by the given IR.
Extra arguments will contain any additional information necessary to run the task,
such as number of qubits.
Args:
ir (Union[JaqcdProgram, OQ3Program, Problem]): The IR representation of the program
ir (Union[OQ3Program, AHSProgram, JaqcdProgram]): The IR representation of the program
Returns:
Union[GateModelTaskResult, AnnealingTaskResult]: An object representing
the results of the simulation.
Union[GateModelTaskResult, AnalogHamiltonianSimulationTaskResult]: An object
representing the results of the simulation.
"""

@property
Expand Down

0 comments on commit 46cf59a

Please sign in to comment.