Source code for braket.devices.local_simulator

# Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
#     http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# 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.

from functools import singledispatch
from typing import Set, Union

import pkg_resources

from braket.annealing.problem import Problem
from braket.circuits import Circuit
from braket.devices.braket_simulator import BraketSimulator
from braket.devices.device import Device
from braket.tasks import AnnealingQuantumTaskResult, GateModelQuantumTaskResult
from braket.tasks.local_quantum_task import LocalQuantumTask

_simulator_devices = {
    entry.name: entry for entry in pkg_resources.iter_entry_points("braket.simulators")
}


[docs]class LocalSimulator(Device): """ A simulator meant to run directly on the user's machine. This class wraps a BraketSimulator object so that it can be run and returns results using constructs from the SDK rather than Braket IR. """ def __init__(self, backend: Union[str, BraketSimulator]): """ Args: backend (Union[str, BraketSimulator]): The name of the simulator backend or the actual simulator instance to use for simulation """ delegate = _get_simulator(backend) super().__init__( name=delegate.__class__.__name__, status="AVAILABLE", status_reason="Local simulator loaded successfully", ) self._delegate = delegate
[docs] def run( self, task_specification: Union[Circuit, Problem], *args, **kwargs, ) -> LocalQuantumTask: """ Runs the given task with the wrapped local simulator. Args: task_specification (Union[Circuit, Problem]): *args: Positional args to pass to the IR simulator **kwargs: Keyword arguments to pass to the IR simulator Returns: LocalQuantumTask: A LocalQuantumTask object containing the results of the simulation Note: If running a circuit, the number of qubits will be passed to the backend as the argument after the circuit itself. """ result = _run_internal(task_specification, self._delegate, *args, **kwargs) return LocalQuantumTask(result)
[docs] @staticmethod def registered_backends() -> Set[str]: """ Gets the backends that have been registered as entry points Returns: Set[str]: The names of the available backends that can be passed into LocalSimulator's constructor """ return set(_simulator_devices.keys())
@singledispatch def _get_simulator(simulator): raise TypeError("Simulator must either be a string or a BraketSimulator instance") @_get_simulator.register def _(backend_name: str): if backend_name in _simulator_devices: device_class = _simulator_devices[backend_name].load() return device_class() else: raise ValueError(f"Only the following devices are available {_simulator_devices.keys()}") @_get_simulator.register def _(backend_impl: BraketSimulator): return backend_impl @singledispatch def _run_internal(task_specification, simulator: BraketSimulator, *args, **kwargs): raise NotImplementedError("Unsupported task type") @_run_internal.register def _(circuit: Circuit, simulator: BraketSimulator, *args, **kwargs): program = circuit.to_ir() qubits = circuit.qubit_count results_dict = simulator.run(program, qubits, *args, **kwargs) return GateModelQuantumTaskResult.from_dict(results_dict) @_run_internal.register def _(problem: Problem, simulator: BraketSimulator, *args, **kwargs): ir = problem.to_ir() results_dict = simulator.run(ir, *args, *kwargs) return AnnealingQuantumTaskResult.from_dict(results_dict)