Skip to content

Commit

Permalink
restructure quantum element module, enhance docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
chensgit169 committed Sep 22, 2023
1 parent 1bf75ab commit 3c6a8c5
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 134 deletions.
16 changes: 15 additions & 1 deletion doc/source/apiref/apiref_0.3.5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,30 @@ API Reference

This page is still under refinement, the contents you see may be incomplete at present.

Quantum Circuit
------------------

.. autoclass:: quafu.QuantumCircuit
:members: cnot, add_gate, barrier
:undoc-members: add_pulse

.. autoclass:: quafu.User
Quantum Elements
------------------
.. hint::
hello

.. autoclass:: quafu.elements.quantum_element.Instruction
:members:


Task and User
------------------

.. autoclass:: quafu.Task
:members: config, send, retrieve

.. autoclass:: quafu.User
:members:

.. autoclass:: quafu.results.results.Result
:members:
17 changes: 16 additions & 1 deletion src/quafu/circuits/quantum_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import numpy as np

import quafu.elements.element_gates as qeg
from quafu.elements.quantum_element.pulses.quantum_pulse import QuantumPulse
from quafu.elements.quantum_element.pulses import QuantumPulse
from ..elements.quantum_element import (
Barrier,
Delay,
Expand Down Expand Up @@ -51,6 +51,9 @@ def used_qubits(self) -> List:
return self._used_qubits

def add_gate(self, gate: QuantumGate):
"""
Add quantum gate to circuit, with some checking.
"""
pos = np.array(gate.pos)
if np.any(pos >= self.num):
raise CircuitError(f"Gate position out of range: {gate.pos}")
Expand Down Expand Up @@ -570,6 +573,9 @@ def cnot(self, ctrl: int, tar: int) -> "QuantumCircuit":
return self

def cx(self, ctrl: int, tar: int) -> "QuantumCircuit":
"""
Ally of cnot.
"""
return self.cnot(ctrl=ctrl, tar=tar)

def cy(self, ctrl: int, tar: int) -> "QuantumCircuit":
Expand Down Expand Up @@ -597,6 +603,7 @@ def cz(self, ctrl: int, tar: int) -> "QuantumCircuit":
def cs(self, ctrl: int, tar: int) -> "QuantumCircuit":
"""
Control-S gate.
Args:
ctrl (int): control qubit.
tar (int): target qubit.
Expand All @@ -607,6 +614,7 @@ def cs(self, ctrl: int, tar: int) -> "QuantumCircuit":
def ct(self, ctrl: int, tar: int) -> "QuantumCircuit":
"""
Control-T gate.
Args:
ctrl (int): control qubit.
tar (int): target qubit.
Expand Down Expand Up @@ -700,6 +708,7 @@ def delay(self, pos, duration, unit="ns") -> "QuantumCircuit":
def xy(self, qs: int, qe: int, duration: int, unit: str = "ns") -> "QuantumCircuit":
"""
XY resonance time evolution for quantum simulator
Args:
qs: start position of resonant qubits.
qe: end position of resonant qubits.
Expand All @@ -713,6 +722,7 @@ def xy(self, qs: int, qe: int, duration: int, unit: str = "ns") -> "QuantumCircu
def rxx(self, q1: int, q2: int, theta):
"""
Rotation about 2-qubit XX axis.
Args:
q1 (int): qubit the gate act.
q2 (int): qubit the gate act.
Expand All @@ -724,6 +734,7 @@ def rxx(self, q1: int, q2: int, theta):
def ryy(self, q1: int, q2: int, theta):
"""
Rotation about 2-qubit YY axis.
Args:
q1 (int): qubit the gate act.
q2 (int): qubit the gate act.
Expand All @@ -735,6 +746,7 @@ def ryy(self, q1: int, q2: int, theta):
def rzz(self, q1: int, q2: int, theta):
"""
Rotation about 2-qubit ZZ axis.
Args:
q1 (int): qubit the gate act.
q2 (int): qubit the gate act.
Expand All @@ -746,6 +758,7 @@ def rzz(self, q1: int, q2: int, theta):
def mcx(self, ctrls: List[int], targ: int):
"""
Multi-controlled X gate.
Args:
ctrls: A list of control qubits.
targ: Target qubits.
Expand All @@ -755,6 +768,7 @@ def mcx(self, ctrls: List[int], targ: int):
def mcy(self, ctrls: List[int], targ: int):
"""
Multi-controlled Y gate.
Args:
ctrls: A list of control qubits.
targ: Target qubits.
Expand All @@ -764,6 +778,7 @@ def mcy(self, ctrls: List[int], targ: int):
def mcz(self, ctrls: List[int], targ: int):
"""
Multi-controlled Z gate.
Args:
ctrls: A list of control qubits.
targ: Target qubits.
Expand Down
4 changes: 4 additions & 0 deletions src/quafu/elements/element_gates/matrices/mat_lib.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import numpy as np

"""
Matrices library for quantum gates.
"""

IdMatrix = np.eye(2, dtype=complex)
XMatrix = np.array([[0., 1.], [1., 0.]], dtype=complex)
YMatrix = np.array([[0., -1.j], [1.j, 0.]], dtype=complex)
Expand Down
6 changes: 4 additions & 2 deletions src/quafu/elements/quantum_element/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from .quantum_element import Barrier, Delay, XYResonance, Measure
from .instruction import Instruction, Barrier, Measure
from .pulses import Delay, XYResonance

from .quantum_gate import QuantumGate, SingleQubitGate, MultiQubitGate, \
ParaSingleQubitGate, ParaMultiQubitGate, ControlledGate, FixedSingleQubitGate, FixedMultiQubitGate
from .instruction import Instruction

77 changes: 51 additions & 26 deletions src/quafu/elements/quantum_element/instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,30 @@
from typing import Union, List


__all__ = ['Instruction', 'Barrier', 'Measure', 'PosType', 'ParaType']

PosType = Union[int, List[int]]
ParaType = Union[float, int]
ParaType = Union[float, int, List]


class Instruction(ABC):
"""Base class for ALL the possible instructions on Quafu superconducting quantum circuits.
Attributes:
pos: Qubit position(s) of the instruction on the circuit.
paras: Parameters of the instruction.
"""
ins_classes = {}

def __init__(self, pos: PosType, paras: ParaType = None, *args, **kwargs):
self.pos = pos
self.paras = paras

@property
@abstractmethod
def name(self) -> str:
"""Name of the instruction."""
raise NotImplementedError('name is not implemented for %s' % self.__class__.__name__
+ ', this should never happen.')

Expand All @@ -44,32 +58,43 @@ def register_ins(cls, subclass, name: str = None):
raise ValueError(f"Name {name} already exists.")
cls.ins_classes[name] = subclass

def __init__(self, pos: PosType, paras: ParaType = None, *args, **kwargs):
self.pos = pos
self.paras = paras

# @_ins_id.setter
# def sd_name(self, name: str):
# if self.sd_name is None:
# self.sd_name = name
# else:
# import warnings
# warnings.warn(message='Invalid assignment, names of standard '
# 'instructions are not alterable.')

# def to_dag_node(self):
# name = self.get_ins_id()
# label = self.__repr__()
#
# pos = self.pos
# paras = self.paras
# paras = {} if paras is None else paras
# duration = paras.get('duration', None)
# unit = paras.get('unit', None)
# channel = paras.get('channel', None)
# time_func = paras.get('time_func', None)
#
# return InstructionNode(name, pos, paras, duration, unit, channel, time_func, label)
class Barrier(Instruction):
"""
Barrier instruction.
"""
name = "barrier"

def __init__(self, pos):
super().__init__(pos)
self.symbol = "||"

@property
def pos(self):
return self.__pos

@pos.setter
def pos(self, pos):
self.__pos = pos

def __repr__(self):
return f"{self.__class__.__name__}"

def to_qasm(self):
return "barrier " + ",".join(["q[%d]" % p for p in range(min(self.pos), max(self.pos) + 1)])


class Measure(Instruction):
"""
Measure instruction.
"""
name = "measure"

def __init__(self, bitmap: dict):
super().__init__(list(bitmap.keys()))
self.qbits = bitmap.keys()
self.cbits = bitmap.values()


Instruction.register_ins(Barrier)
Instruction.register_ins(Measure)
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,44 @@ def __call__(self,
return super().__call__(t, shift, offset, args)


class Delay(Instruction):
name = "delay"

def __init__(self, pos: int, duration: int, unit="ns"):
if isinstance(duration, int):
self.duration = duration
else:
raise TypeError("duration must be int")
super().__init__(pos)
self.unit = unit
self.symbol = "Delay(%d%s)" % (duration, unit)

def __repr__(self):
return f"{self.__class__.__name__}"

def to_qasm(self):
return "delay(%d%s) q[%d]" % (self.duration, self.unit, self.pos)


class XYResonance(Instruction):
name = "XY"

def __init__(self, qs: int, qe: int, duration: int, unit="ns"):
if isinstance(duration, int):
self.duration = duration
else:
raise TypeError("duration must be int")
super().__init__(list(range(qs, qe + 1)))
self.unit = unit
self.symbol = "XY(%d%s)" % (duration, unit)

def to_qasm(self):
return "xy(%d%s) " % (self.duration, self.unit) + ",".join(
["q[%d]" % p for p in range(min(self.pos), max(self.pos) + 1)])


QuantumPulse.register_pulse(RectPulse)
QuantumPulse.register_pulse(FlattopPulse)
QuantumPulse.register_pulse(GaussianPulse)
Instruction.register_ins(Delay)
Instruction.register_ins(XYResonance)
11 changes: 0 additions & 11 deletions src/quafu/elements/quantum_element/pulses/__init__.py

This file was deleted.

Loading

0 comments on commit 3c6a8c5

Please sign in to comment.