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 Optional, Set, Union 

16 

17import pkg_resources 

18 

19from braket.annealing.problem import Problem 

20from braket.circuits import Circuit 

21from braket.devices.braket_simulator import BraketSimulator 

22from braket.devices.device import Device 

23from braket.tasks import AnnealingQuantumTaskResult, GateModelQuantumTaskResult 

24from braket.tasks.local_quantum_task import LocalQuantumTask 

25 

26_simulator_devices = { 

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

28} 

29 

30 

31class LocalSimulator(Device): 

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

33 

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

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

36 """ 

37 

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

39 """ 

40 Args: 

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

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

43 "default" simulator backend name. 

44 """ 

45 delegate = _get_simulator(backend) 

46 super().__init__( 

47 name=delegate.__class__.__name__, 

48 status="AVAILABLE", 

49 status_reason="Local simulator loaded successfully", 

50 ) 

51 self._delegate = delegate 

52 

53 def run( 

54 self, task_specification: Union[Circuit, Problem], *args, **kwargs, 

55 ) -> LocalQuantumTask: 

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

57 

58 Args: 

59 task_specification (Union[Circuit, Problem]): 

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

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

62 

63 Returns: 

64 LocalQuantumTask: A LocalQuantumTask object containing the results 

65 of the simulation 

66 

67 Note: 

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

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

70 

71 Examples: 

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

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

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

75 """ 

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

77 return LocalQuantumTask(result) 

78 

79 @staticmethod 

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

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

82 

83 Returns: 

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

85 into LocalSimulator's constructor 

86 """ 

87 return set(_simulator_devices.keys()) 

88 

89 

90@singledispatch 

91def _get_simulator(simulator): 

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

93 

94 

95@_get_simulator.register 

96def _(backend_name: str): 

97 if backend_name in _simulator_devices: 

98 device_class = _simulator_devices[backend_name].load() 

99 return device_class() 

100 else: 

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

102 

103 

104@_get_simulator.register 

105def _(backend_impl: BraketSimulator): 

106 return backend_impl 

107 

108 

109@singledispatch 

110def _run_internal( 

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

112): 

113 raise NotImplementedError("Unsupported task type") 

114 

115 

116@_run_internal.register 

117def _(circuit: Circuit, simulator: BraketSimulator, shots: Optional[int] = None, *args, **kwargs): 

118 program = circuit.to_ir() 

119 qubits = circuit.qubit_count 

120 shots_count = shots if shots else LocalQuantumTask.DEFAULT_SHOTS 

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

122 return GateModelQuantumTaskResult.from_dict(results_dict) 

123 

124 

125@_run_internal.register 

126def _(problem: Problem, simulator: BraketSimulator, shots: Optional[int] = None, *args, **kwargs): 

127 ir = problem.to_ir() 

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

129 return AnnealingQuantumTaskResult.from_dict(results_dict)