Skip to content
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

enhancement: restructure quantum element module, enhance docstrings #91

Merged
merged 2 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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