Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"). You 

4# may not use this file except in compliance with the License. A copy of 

5# the License is located at 

6# 

7# http://aws.amazon.com/apache2.0/ 

8# 

9# or in the "license" file accompanying this file. This file is 

10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 

11# ANY KIND, either express or implied. See the License for the specific 

12# language governing permissions and limitations under the License. 

13 

14from functools import singledispatch 

15from typing import Any, Dict, Optional, Set, Union 

16 

17import pkg_resources 

18 

19from braket.annealing.problem import Problem 

20from braket.circuits import Circuit 

21from braket.circuits.circuit_helpers import validate_circuit_and_shots 

22from braket.devices.device import Device 

23from braket.simulator import BraketSimulator 

24from braket.tasks import AnnealingQuantumTaskResult, GateModelQuantumTaskResult 

25from braket.tasks.local_quantum_task import LocalQuantumTask 

26 

27_simulator_devices = { 

28 entry.name: entry for entry in pkg_resources.iter_entry_points("braket.simulators") 

29} 

30 

31 

32class LocalSimulator(Device): 

33 """ A simulator meant to run directly on the user's machine. 

34 

35 This class wraps a BraketSimulator object so that it can be run and returns 

36 results using constructs from the SDK rather than Braket IR. 

37 """ 

38 

39 def __init__(self, backend: Union[str, BraketSimulator] = "default"): 

40 """ 

41 Args: 

42 backend (Union[str, BraketSimulator]): The name of the simulator backend or 

43 the actual simulator instance to use for simulation. Defaults to the 

44 "default" simulator backend name. 

45 """ 

46 delegate = _get_simulator(backend) 

47 super().__init__( 

48 name=delegate.__class__.__name__, 

49 status="AVAILABLE", 

50 status_reason="Local simulator loaded successfully", 

51 ) 

52 self._delegate = delegate 

53 

54 def run( 

55 self, task_specification: Union[Circuit, Problem], shots: int = 0, *args, **kwargs, 

56 ) -> LocalQuantumTask: 

57 """ Runs the given task with the wrapped local simulator. 

58 

59 Args: 

60 task_specification (Union[Circuit, Problem]): 

61 shots (int, optional): The number of times to run the circuit or annealing problem. 

62 Default is 0, which means that the simulator will compute the exact 

63 results based on the task specification. 

64 Sampling is not supported for shots=0. 

65 *args: Positional args to pass to the IR simulator 

66 **kwargs: Keyword arguments to pass to the IR simulator 

67 

68 Returns: 

69 LocalQuantumTask: A LocalQuantumTask object containing the results 

70 of the simulation 

71 

72 Note: 

73 If running a circuit, the number of qubits will be passed 

74 to the backend as the argument after the circuit itself. 

75 

76 Examples: 

77 >>> circuit = Circuit().h(0).cnot(0, 1) 

78 >>> device = LocalSimulator("default") 

79 >>> device.run(circuit, shots=1000) 

80 """ 

81 result = _run_internal(task_specification, self._delegate, shots, *args, **kwargs) 

82 return LocalQuantumTask(result) 

83 

84 @property 

85 def properties(self) -> Dict[str, Any]: 

86 """ Dict[str, Any]: Properties of the LocalSimulator device """ 

87 return self._delegate.properties 

88 

89 @staticmethod 

90 def registered_backends() -> Set[str]: 

91 """ Gets the backends that have been registered as entry points 

92 

93 Returns: 

94 Set[str]: The names of the available backends that can be passed 

95 into LocalSimulator's constructor 

96 """ 

97 return set(_simulator_devices.keys()) 

98 

99 

100@singledispatch 

101def _get_simulator(simulator): 

102 raise TypeError("Simulator must either be a string or a BraketSimulator instance") 

103 

104 

105@_get_simulator.register 

106def _(backend_name: str): 

107 if backend_name in _simulator_devices: 

108 device_class = _simulator_devices[backend_name].load() 

109 return device_class() 

110 else: 

111 raise ValueError(f"Only the following devices are available {_simulator_devices.keys()}") 

112 

113 

114@_get_simulator.register 

115def _(backend_impl: BraketSimulator): 

116 return backend_impl 

117 

118 

119@singledispatch 

120def _run_internal( 

121 task_specification, simulator: BraketSimulator, shots: Optional[int] = None, *args, **kwargs 

122): 

123 raise NotImplementedError("Unsupported task type") 

124 

125 

126@_run_internal.register 

127def _(circuit: Circuit, simulator: BraketSimulator, shots, *args, **kwargs): 

128 validate_circuit_and_shots(circuit, shots) 

129 program = circuit.to_ir() 

130 qubits = circuit.qubit_count 

131 results_dict = simulator.run(program, qubits, shots, *args, **kwargs) 

132 return GateModelQuantumTaskResult.from_dict(results_dict) 

133 

134 

135@_run_internal.register 

136def _(problem: Problem, simulator: BraketSimulator, shots, *args, **kwargs): 

137 ir = problem.to_ir() 

138 results_dict = simulator.run(ir, shots, *args, *kwargs) 

139 return AnnealingQuantumTaskResult.from_dict(results_dict)