Skip to content

Commit

Permalink
Basic Documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Haadi-Khan committed Jul 17, 2024
1 parent 61ee41f commit d509981
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 8 deletions.
1 change: 1 addition & 0 deletions operation_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(Operation)]
/// Derive macro generating an impl of the trait `Operation`
pub fn derive_operation(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

Expand Down
5 changes: 5 additions & 0 deletions src/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::register::AncillaRegister;
use crate::register::Register;

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// A generic bit
pub enum Bit {
Qubit(Qubit),
Clbit(Clbit),
Expand All @@ -17,18 +18,22 @@ pub trait BitOps {
}

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// A classical bit
pub struct Clbit {
register: Box<ClassicalRegister>,
index: usize,
}

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// A quantum bit
pub struct Qubit {
register: Box<QuantumRegister>,
index: usize,
}

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// An ancilla quantum bit (i.e. a quantum bit that is not part of the main
/// register)
pub struct AncillaQubit {
register: Box<AncillaRegister>,
index: usize,
Expand Down
2 changes: 2 additions & 0 deletions src/circuit_instruction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::instruction::{Instruction, InstructionType};
use crate::bit::{Qubit, Clbit};

/// Description of a Qiskit Circuit element. Provides a specific operation and the
/// qubits/classical bits it interacts with.
#[derive(Debug, PartialEq, Clone)]
pub struct CircuitInstruction {
operation: InstructionType,
Expand Down
4 changes: 4 additions & 0 deletions src/gates/singleton.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::instruction::{Gate, Instruction, Operation};
use operation_macro::Operation;

#[derive(Debug, PartialEq, Clone, Operation)]
/// A Pauli-X gate
pub struct XGate {
instruction: Instruction,
}
Expand Down Expand Up @@ -33,6 +34,7 @@ impl Gate for XGate {
}

#[derive(Debug, PartialEq, Clone, Operation)]
/// A Pauli-Y gate
struct YGate {
instruction: Instruction,
}
Expand Down Expand Up @@ -61,6 +63,7 @@ impl Gate for YGate {
}

#[derive(Debug, PartialEq, Clone, Operation)]
/// A Pauli-Z gate
struct ZGate {
instruction: Instruction,
}
Expand Down Expand Up @@ -89,6 +92,7 @@ impl Gate for ZGate {
}

#[derive(Debug, PartialEq, Clone, Operation)]
/// A Hadamard gate
pub struct HadamardGate {
instruction: Instruction,
}
Expand Down
32 changes: 30 additions & 2 deletions src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ use ndarray::Array2;
use numpy::Complex64;
use std::fmt::Debug;

/// An instruction is defined by a name, the number of qubits/classical bits it
/// acts on, and other optional parameters.
///
/// Instructions act as the most general operation in a a quantum circuit, and
/// are converted into an InstructionType enum for further processing.
#[derive(Debug, PartialEq, Clone)]
pub struct Instruction {
name: String,
Expand All @@ -13,6 +18,8 @@ pub struct Instruction {
label: Option<String>,
}

/// Operations are the most general trait for quantum operations. They provide
/// basic methods to retrieve information from an instruction.
pub trait Operation: Debug + PartialEq + Clone {
fn name(&self) -> &str;
fn num_qubits(&self) -> usize;
Expand All @@ -23,27 +30,40 @@ pub trait Operation: Debug + PartialEq + Clone {
fn label(&self) -> Option<&str>;
}

/// Contains the different types of instructions that can be used in a quantum
/// circuit.
#[derive(Debug, PartialEq, Clone)]
pub enum InstructionType {
Gate(Instruction),
Measurement(Instruction),
Reset(Instruction),
Barrier(Instruction),
Delay(Instruction),
Store(Instruction),
}

pub trait Gate: Operation {
fn to_matrix(&self) -> Array2<Complex64>; // Example of a method specific to gates
/// Gates are unitary operations that act on qubits. They can be converted into
/// a matrix representation.
pub trait Gate : Operation {
fn to_matrix(&self) -> Array2<Complex64>;
}

/// Measurements are operations that measure the state of a qubit and transform
/// them into classical bits.
pub trait Measurement: Operation {}

/// Resets irreversibly set a qubit to the |0> state.
pub trait Reset: Operation {}

/// Barriers are operations that separate different parts of a quantum circuit.
pub trait Barrier: Operation {}

/// Delays are operations that represent a time delay in a quantum circuit.
pub trait Delay: Operation {}

/// Stores write a real-time classical expression to a storage location.
pub trait Store : Operation {}

impl Instruction {
pub fn new(
name: String,
Expand Down Expand Up @@ -108,6 +128,7 @@ impl InstructionType {
"reset" => InstructionType::Reset(instruction),
"barrier" => InstructionType::Barrier(instruction),
"delay" => InstructionType::Delay(instruction),
"store" => InstructionType::Store(instruction),
_ => unimplemented!(),
}
}
Expand All @@ -121,6 +142,7 @@ impl Operation for InstructionType {
InstructionType::Reset(inst) => inst.name(),
InstructionType::Barrier(inst) => inst.name(),
InstructionType::Delay(inst) => inst.name(),
InstructionType::Store(inst) => inst.name(),
}
}

Expand All @@ -131,6 +153,7 @@ impl Operation for InstructionType {
InstructionType::Reset(inst) => inst.num_qubits(),
InstructionType::Barrier(inst) => inst.num_qubits(),
InstructionType::Delay(inst) => inst.num_qubits(),
InstructionType::Store(inst) => inst.num_qubits(),
}
}

Expand All @@ -141,6 +164,7 @@ impl Operation for InstructionType {
InstructionType::Reset(inst) => inst.num_clbits(),
InstructionType::Barrier(inst) => inst.num_clbits(),
InstructionType::Delay(inst) => inst.num_clbits(),
InstructionType::Store(inst) => inst.num_clbits(),
}
}

Expand All @@ -151,6 +175,7 @@ impl Operation for InstructionType {
InstructionType::Reset(inst) => inst.params(),
InstructionType::Barrier(inst) => inst.params(),
InstructionType::Delay(inst) => inst.params(),
InstructionType::Store(inst) => inst.params(),
}
}

Expand All @@ -161,6 +186,7 @@ impl Operation for InstructionType {
InstructionType::Reset(inst) => inst.duration(),
InstructionType::Barrier(inst) => inst.duration(),
InstructionType::Delay(inst) => inst.duration(),
InstructionType::Store(inst) => inst.duration(),
}
}

Expand All @@ -171,6 +197,7 @@ impl Operation for InstructionType {
InstructionType::Reset(inst) => inst.unit(),
InstructionType::Barrier(inst) => inst.unit(),
InstructionType::Delay(inst) => inst.unit(),
InstructionType::Store(inst) => inst.unit(),
}
}

Expand All @@ -181,6 +208,7 @@ impl Operation for InstructionType {
InstructionType::Reset(inst) => inst.label(),
InstructionType::Barrier(inst) => inst.label(),
InstructionType::Delay(inst) => inst.label(),
InstructionType::Store(inst) => inst.label(),
}
}
}
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod circuit_instruction;
mod instruction;
mod bit;
mod register;
mod parser;
mod gates;
pub mod circuit_instruction;
pub mod instruction;
pub mod bit;
pub mod register;
pub mod parser;
pub mod gates;
3 changes: 3 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::instruction::Instruction;

// TODO: Figure out how to use AncillaQubits. I don't have enough experience using them, and I can't find a good example online

/// A parser for the Qiskit circuit instructions
pub struct Parser {
input: String,
}
Expand All @@ -18,6 +19,8 @@ impl Parser {
Parser { input }
}

/// Parses the input string (a string representation of a Qiskit
/// QuantumCircuit's data field) into a vector of CircuitInstructions
pub fn parse(&self) -> Vec<CircuitInstruction> {
let mut instructions = Vec::new();

Expand Down
5 changes: 5 additions & 0 deletions src/register.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::bit::Bit;

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// Register for the system
pub enum Register {
QuantumRegister(QuantumRegister),
ClassicalRegister(ClassicalRegister),
Expand Down Expand Up @@ -28,6 +29,7 @@ impl Register {
}
}

/// Register Operations
pub trait RegisterOps {
fn new(size: Option<u32>, name: Option<String>, bits: Option<Bit>) -> Self;
fn get_size(&self) -> Option<u32>;
Expand All @@ -36,20 +38,23 @@ pub trait RegisterOps {
}

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// Quantum Register for the system
pub struct QuantumRegister {
size: Option<u32>,
name: Option<String>,
bits: Option<Bit>,
}

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// Classical Register for the system
pub struct ClassicalRegister {
size: Option<u32>,
name: Option<String>,
bits: Option<Bit>,
}

#[derive(Debug, PartialEq, Hash, Eq, Clone)]
/// Ancilla Register for the system
pub struct AncillaRegister {
size: Option<u32>,
name: Option<String>,
Expand Down

0 comments on commit d509981

Please sign in to comment.