Skip to content

Commit

Permalink
Merge pull request #60 from chensgit169/master
Browse files Browse the repository at this point in the history
integrate oracle and register into circuit
  • Loading branch information
Zhaoyilunnn authored Aug 17, 2023
2 parents b29b71b + ed59462 commit 64d0165
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 3 deletions.
22 changes: 20 additions & 2 deletions src/quafu/circuits/quantum_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
SingleQubitGate,
XYResonance,
)
from .quantum_register import QuantumRegister
from ..exceptions import CircuitError


Expand All @@ -38,7 +39,7 @@ def __init__(self, num: int, *args, **kwargs):
Args:
num (int): Total qubit number used
"""
self.num = num
self.qregs = [QuantumRegister(num)] if num > 0 else []
self.gates = []
self.openqasm = ""
self.circuit = []
Expand All @@ -53,6 +54,10 @@ def parameterized_gates(self):
self._parameterized_gates = [g for g in self.gates if g.paras is not None]
return self._parameterized_gates

@property
def num(self):
return sum([len(qreg) for qreg in self.qregs])

@property
def used_qubits(self) -> List:
self.layered_circuit()
Expand Down Expand Up @@ -279,7 +284,9 @@ def from_openqasm(self, openqasm: str):
operations = operations_qbs[0]
if operations == "qreg":
qbs = operations_qbs[1]
self.num = int(re.findall("\d+", qbs)[0])
num = int(re.findall("\d+", qbs)[0])
reg = QuantumRegister(num)
self.qregs.append(reg)
elif operations == "creg":
pass
elif operations == "measure":
Expand Down Expand Up @@ -416,6 +423,17 @@ def to_openqasm(self) -> str:
self.openqasm = qasm
return qasm

def wrap_to_gate(self, name: str):
"""
Wrap the circuit to a subclass of QuantumGate, create by metaclass.
"""
# TODO: error check
from quafu.elements.quantum_element.quantum_gate import customize_gate
customized = customize_gate(cls_name=name.lower(),
qubit_num=self.num,
gate_structure=self.gates)
return customized

def id(self, pos: int) -> "QuantumCircuit":
"""
Identity gate.
Expand Down
70 changes: 69 additions & 1 deletion src/quafu/elements/quantum_element/quantum_gate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
from abc import ABC, abstractmethod
# (C) Copyright 2023 Beijing Academy of Quantum Information Sciences
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License 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 abc import ABC, abstractmethod, ABCMeta
from typing import List, Union, Iterable

import numpy as np
Expand Down Expand Up @@ -207,3 +221,57 @@ def get_targ_matrix(self, reverse_order=False):
tensorm = targ_matrix.reshape([2] * 2 * qnum)
targ_matrix = np.transpose(tensorm, order).reshape([dim, dim])
return targ_matrix


class OracleGate(QuantumGate):
name = None
gate_structure = []

def __init__(self, pos, paras, label: str = None):
super().__init__(pos=pos, paras=paras)
self.label = label if label is not None else self.name

@property
def matrix(self):
# TODO: this should be finished according to usage in simulation
# to avoid store very large matrix
raise NotImplemented


class OracleGateMeta(ABCMeta):
"""
Metaclass to create OracleGate class which is its instance.
"""
def __init__(cls, name, bases, attrs):
for attr_name in ['cls_name', 'gate_structure', 'qubit_num']:
assert attr_name in attrs, f"OracleGateMeta: {attr_name} is required."
super().__init__(name, bases, attrs)
cls.name = attrs.__getitem__('cls_name')
cls.gate_structure = attrs.__getitem__('gate_structure')
cls.qubit_num = attrs.__getitem__('qubit_num')
# TODO: check gate_structure and resolve it


def customize_gate(cls_name: str,
gate_structure: list,
qubit_num: int,
):
"""
helper function to create customized gate class
:param cls_name:
:param gate_structure:
:param qubit_num:
:return:
"""
if cls_name in QuantumGate.gate_classes:
raise ValueError(f"Gate class {cls_name} already exists.")

attrs = {'cls_name': cls_name,
'gate_structure': gate_structure, # TODO: translate
'qubit_num': qubit_num,
}

customized_cls = OracleGateMeta(cls_name, (OracleGate,), attrs)
assert issubclass(customized_cls, OracleGate)
QuantumGate.register_gate(customized_cls)
return customized_cls

0 comments on commit 64d0165

Please sign in to comment.