-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[unitaryHACK](#1) Cirq Support #20
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ | |
.venv | ||
coverage* | ||
dist | ||
.vscode |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,23 +19,71 @@ | |
## 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 cirq_google.engine import Engine | ||
from ..backend import QuantumBackend | ||
|
||
|
||
############################################################################### | ||
## CIRQ BACKEND (DECORATOR) | ||
############################################################################### | ||
class CirqBackend(QuantumBackend): | ||
def __init__(self) -> None: | ||
self.ERROR_MSG = f"{self.__class__.__name__}" # TODO | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
|
||
|
||
Comment on lines
+29
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generally speaking, adhere to the code style in other files. Here, remove unnecessary empty lines. |
||
class CirqBackend(QuantumBackend,Engine): | ||
""" | ||
|
||
Encapsulating Google Engine API with Quantum Backend | ||
|
||
Since API and Cirq is still in Alpha,Changes are expected | ||
|
||
methods from Engine class: | ||
|
||
create_program()->Wraps a Circuit for use with the Quantum Engine. i.e return engineprogram | ||
|
||
run()->Runs the supplied Circuit via Quantum Engine. i.e return study.result | ||
""" | ||
Comment on lines
+33
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not adhere to NumPy's docstring style. See the contributing guidelines. |
||
def __init__( | ||
self, | ||
engine: Engine, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you inheriting from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought maybe an Engine object had to be instantiated before |
||
shots:int =1, | ||
max_experiments:int=1 | ||
Comment on lines
+48
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does Cirq differentiate between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They use repetitions mainly. |
||
) -> None: | ||
self._backend: Engine = engine | ||
super(QuantumBackend, self).__init__( ) | ||
self._options = engine.service_args | ||
self._shots:int= shots, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
self._max_experiments = max_experiments | ||
self.max_shots=shots #Google API is still private | ||
|
||
############################### PUBLIC API ############################### | ||
@property | ||
def max_measurements(self) -> int: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
return (self._max_experiments*self._shots ) | ||
|
||
@property | ||
def max_experiments(self) -> int: | ||
return self._max_experiments | ||
|
||
@max_experiments.setter | ||
def max_experiments(self,max_experiments:int)->None: | ||
self._max_experiments:int=max_experiments | ||
|
||
""" | ||
@property | ||
def max_qubits(self) -> int: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
return ( | ||
|
||
) | ||
""" | ||
Comment on lines
+71
to
+77
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't figure out the maximum qubits part. Should we define this explicitly...?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not think that would be a good approach. We have to run the programs on physical backends/simulators, and they will have different capabilities. Also, have you tested your code? It should not have let you instantiate this class without defining this property. |
||
|
||
#Using Consitent Qiskit analogy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not add line comments. |
||
@property | ||
def shots(self) -> int: | ||
return self._shots | ||
|
||
@shots.setter | ||
def shots(self,shots:int) -> None: | ||
self._shots:int = shots | ||
Comment on lines
+80
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
def run(self, run_input, **options): | ||
return self._backend.run(run_input, self._shots,**options) | ||
Comment on lines
+88
to
+89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you implement this method? |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,85 +19,117 @@ | |
## 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 cirq | ||
from cirq.circuits import Circuit as CirqQuantumCircuit | ||
from ..circuit import QuantumCircuit | ||
|
||
from ...helpers import validate_natural_number, validate_type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe that you are not using |
||
|
||
############################################################################### | ||
## CIRQ CIRCUIT | ||
############################################################################### | ||
class CirqCircuit(QuantumCircuit): | ||
|
||
def __init__(self, num_qubits: int) -> None: | ||
self.ERROR_MSG = f"{self.__class__.__name__}" # TODO | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
self.qubits=cirq.LineQubit.range(num_qubits) | ||
self._num_qubits=num_qubits | ||
self.moment_list:list=[] | ||
|
||
def _validate_qubit_index(self, qubit_index: int) -> None: | ||
if qubit_index >= self.num_qubits: | ||
raise ValueError( | ||
f"Qubit index out of range {qubit_index} >= {self.num_qubits}." | ||
) | ||
|
||
|
||
|
||
Comment on lines
+37
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has been added as a |
||
@property | ||
def num_qubits(self) -> int: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
return self._num_qubits | ||
|
||
@num_qubits.setter | ||
def num_qubits(self,num_qubits:int) -> None: | ||
self._num_qubits=num_qubits | ||
|
||
############################## SPECIAL GATES ############################## | ||
def measure(self, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
self.moment_list.append(cirq.ops.measure(self.qubits[target_qubit])) | ||
########################### SINGLE QUBIT GATES ########################### | ||
def h(self, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.H(self.qubits[target_qubit])) | ||
|
||
|
||
def rx(self, radians: float, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.Rx(radians, self.qubits[target_qubit])) | ||
|
||
def ry(self, radians: float, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.Ry(radians,self.qubits[target_qubit])) | ||
|
||
def rz(self, radians: float, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.Rz(radians, self.qubits[target_qubit])) | ||
|
||
def s(self, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.S(self.qubits[target_qubit])) | ||
|
||
def t(self, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
def u1(self, theta: float, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
def u2(self, phi: float, lam: float, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
def u3( | ||
self, theta: float, phi: float, lam: float, target_qubit: int | ||
) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.T(self.qubits[target_qubit])) | ||
|
||
def x(self, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.X(self.qubits[target_qubit])) | ||
|
||
|
||
def y(self, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.Y(self.qubits[target_qubit])) | ||
|
||
|
||
def z(self, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self.moment_list.append(cirq.ops.Z(self.qubits[target_qubit])) | ||
|
||
############################# TWO QUBIT GATES ############################# | ||
def cs(self, control_qubit: int, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
def cx(self, control_qubit: int, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Official Implementation of CX, CS are WIP. Also some three-qubit gates too. We can wait until the CIRQ ships them officially. |
||
def cz(self, control_qubit: int, target_qubit: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit, True) | ||
validate_natural_number(control_qubit, True) | ||
self._validate_qubit_index(target_qubit) | ||
self._validate_qubit_index(control_qubit) | ||
self.moment_list.append(cirq.ops.CZ(self.qubits[control_qubit], self.qubits[target_qubit])) | ||
|
||
def swap(self, target_qubit_1: int, target_qubit_2: int) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit_1, True) | ||
self._validate_qubit_index(target_qubit_1) | ||
self._validate_qubit_index(target_qubit_2) | ||
self.moment_list.append(cirq.ops.SWAP(self.qubits[target_qubit_1], self.qubits[target_qubit_2])) | ||
|
||
############################ THREE QUBIT GATES ############################ | ||
def ccx( | ||
self, control_qubit_1: int, control_qubit_2: int, target_qubit: int | ||
) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
|
||
|
||
def cswap( | ||
self, control_qubit_1: int, control_qubit_2: int, target_qubit: int | ||
self, control_qubit: int, target_qubit_1: int, target_qubit_2: int | ||
) -> None: | ||
raise NotImplementedError(self.ERROR_MSG) | ||
validate_natural_number(target_qubit_1, True) | ||
validate_natural_number(target_qubit_2, True) | ||
validate_natural_number(control_qubit, True) | ||
self._validate_qubit_index(control_qubit) | ||
self._validate_qubit_index(target_qubit_1) | ||
self._validate_qubit_index(target_qubit_2) | ||
self.moment_list.append(cirq.ops.CSWAP(self.qubits[control_qubit], self.qubits[target_qubit_1], self.qubits[target_qubit_2])) | ||
|
||
def createcircuit(self): | ||
return CirqQuantumCircuit(self.moment_list) | ||
Comment on lines
+134
to
+135
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is better to inherit from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I the dependency
cirq
,cirq_google
, both, or are they the same? I am saying this to add list it appropriately. Also, did you include any extra depencies?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are different packages and no other extra dependency was used.