Skip to content

Commit

Permalink
QrackCircuit (v0.7.0)
Browse files Browse the repository at this point in the history
  • Loading branch information
WrathfulSpatula committed May 29, 2023
1 parent abf9545 commit 12fc4d3
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "qook"
version = "0.6.0"
version = "0.7.0"
license = "MIT"
description = "qook - Pure Rust unitaryfund/qrack Wrapper"
documentation = "https://pyqrack.readthedocs.io/en/latest/"
Expand Down
20 changes: 16 additions & 4 deletions include/pinvoke_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ MICROSOFT_QUANTUM_DECL void MACU(_In_ uintq sid, _In_ uintq n, _In_reads_(n) uin
MICROSOFT_QUANTUM_DECL void MACMtrx(
_In_ uintq sid, _In_ uintq n, _In_reads_(n) uintq* c, _In_reads_(8) double* m, _In_ uintq q);

MICROSOFT_QUANTUM_DECL void UCMtrx(
_In_ uintq sid, _In_ uintq n, _In_reads_(n) uintq* c, _In_reads_(8) double* m, _In_ uintq q, _In_ uintq p);

MICROSOFT_QUANTUM_DECL void Multiplex1Mtrx(
_In_ uintq sid, _In_ uintq n, _In_reads_(n) uintq* c, _In_ uintq q, double* m);

Expand Down Expand Up @@ -247,12 +250,9 @@ MICROSOFT_QUANTUM_DECL void destroy_qneuron(_In_ uintq nid);
#if FPPOW < 6
MICROSOFT_QUANTUM_DECL void set_qneuron_angles(_In_ uintq nid, _In_ float* angles);
MICROSOFT_QUANTUM_DECL void get_qneuron_angles(_In_ uintq nid, _In_ float* angles);
#elif FPPOW < 7
#else
MICROSOFT_QUANTUM_DECL void set_qneuron_angles(_In_ uintq nid, _In_ double* angles);
MICROSOFT_QUANTUM_DECL void get_qneuron_angles(_In_ uintq nid, _In_ double* angles);
#else
MICROSOFT_QUANTUM_DECL void set_qneuron_angles(_In_ uintq nid, _In_ boost::multiprecision::float128* angles);
MICROSOFT_QUANTUM_DECL void get_qneuron_angles(_In_ uintq nid, _In_ boost::multiprecision::float128* angles);
#endif

MICROSOFT_QUANTUM_DECL void set_qneuron_alpha(_In_ uintq nid, _In_ double alpha);
Expand All @@ -268,4 +268,16 @@ MICROSOFT_QUANTUM_DECL double qneuron_learn_cycle(_In_ uintq nid, _In_ bool e);

MICROSOFT_QUANTUM_DECL void qneuron_learn(_In_ uintq nid, _In_ double eta, _In_ bool e, _In_ bool r);
MICROSOFT_QUANTUM_DECL void qneuron_learn_permutation(_In_ uintq nid, _In_ double eta, _In_ bool e, _In_ bool r);

MICROSOFT_QUANTUM_DECL uintq init_qcircuit();
MICROSOFT_QUANTUM_DECL uintq init_qcircuit_clone(_In_ uintq cid);
MICROSOFT_QUANTUM_DECL void destroy_qcircuit(_In_ uintq cid);
MICROSOFT_QUANTUM_DECL uintq get_qcircuit_qubit_count(_In_ uintq cid);
MICROSOFT_QUANTUM_DECL void qcircuit_swap(_In_ uintq cid, _In_ uintq q1, _In_ uintq q2);
MICROSOFT_QUANTUM_DECL void qcircuit_append_1qb(_In_ uintq cid, _In_reads_(8) double* m, _In_ uintq q);
MICROSOFT_QUANTUM_DECL void qcircuit_append_mc(
_In_ uintq cid, _In_reads_(8) double* m, _In_ uintq n, _In_reads_(n) uintq* c, _In_ uintq q, _In_ uintq p);
MICROSOFT_QUANTUM_DECL void qcircuit_run(_In_ uintq cid, _In_ uintq sid);
MICROSOFT_QUANTUM_DECL void qcircuit_out_to_file(_In_ uintq cid, _In_ char* f);
MICROSOFT_QUANTUM_DECL void qcircuit_in_from_file(_In_ uintq cid, _In_ char* f);
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ pub mod qrack_error;
pub mod qrack_system;
pub mod qrack_simulator;
pub mod qrack_neuron;
pub mod qrack_circuit;
154 changes: 154 additions & 0 deletions src/qrack_circuit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
//
// Use of this source code is governed by an MIT-style license that can be
// found in the LICENSE file or at https://opensource.org/licenses/MIT.

use std::ffi::CString;

use qrack_error::QrackError;
use qrack_simulator::QrackSimulator;
use qrack_system;

pub struct QrackCircuit {
// Class that exposes the QNeuron class of Qrack
//
// This model of a "quantum neuron" is based on the concept of a "uniformly controlled"
// rotation of a single output qubit around the Pauli Y axis, and has been developed by
// others. In our case, the primary relevant gate could also be called a
// single-qubit-target multiplexer.
//
// (See https://arxiv.org/abs/quant-ph/0407010 for an introduction to "uniformly controlled
// gates.)
//
// QrackNeuron is meant to be interchangeable with a single classical neuron, as in
// conventional neural net software. It differs from classical neurons in conventional
// neural nets, in that the "synaptic cleft" is modelled as a single qubit. Hence, this
// neuron can train and predict in superposition.
//
// Attributes:
// cid(u64): Corresponding circuit id.
cid: u64
}

impl Clone for QrackCircuit {
fn clone(&self) -> Self {
let cid;
unsafe {
cid = qrack_system::init_qcircuit_clone(self.cid);
}
Self{
cid
}
}
}

impl Drop for QrackCircuit {
fn drop(&mut self) {
unsafe {
qrack_system::destroy_qcircuit(self.cid);
}
}
}

impl QrackCircuit {
// constructors
pub fn new() -> Self {
let cid;
unsafe {
cid = qrack_system::init_qcircuit();
}
Self{cid}
}

pub fn get_qubit_count(&self) -> u64 {
// Get count of qubits in circuit
unsafe {
qrack_system::get_qcircuit_qubit_count(self.cid)
}
}

pub fn swap(&self, q1: u64, q2: u64) -> () {
// Add a 'Swap' gate to the circuit
//
// Args:
// q1: qubit index #1
// q2: qubit index #2
unsafe {
qrack_system::qcircuit_swap(self.cid, q1, q2)
}
}

pub fn mtrx(&self, m: &[f64;8], q: u64) -> () {
// Operation from matrix.
//
// Applies arbitrary operation defined by the given matrix.
//
// Args:
// m(&[f64;8]): row-major complex list representing the operator.
// q(u64): the qubit number on which the gate is applied to.
let mut _m = [m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7]];
unsafe {
qrack_system::qcircuit_append_1qb(self.cid, _m.as_mut_ptr(), q)
}
}

pub fn ucmtrx(&self, c: Vec<u64>, m: &[f64;8], q: u64, p: u64) -> () {
// Multi-controlled arbitrary operator with arbitrary controls
//
// If all control qubits match 'p' permutation by bit order, then the arbitrary
// operation by parameters is applied to the target qubit.
//
// Args:
// c(Vec<u64>): list of controlled qubits
// m(&[f64;8]): row-major complex list representing the operator.
// q(u64): target qubit
// p(u64): permutation of list of control qubits
let mut _m = [m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7]];
let mut _c = c.to_vec();
unsafe {
qrack_system::qcircuit_append_mc(self.cid, _m.as_mut_ptr(), _c.len() as u64, _c.as_mut_ptr(), q, p);
}
}

pub fn run(&self, qsim: &QrackSimulator) -> Result<(), QrackError> {
// Run circuit on simulator
//
// Run the encoded circuit on a specific simulator. The
// result will remain in this simulator.
//
// Args:
// qsim(&QrackSimulator): QrackSimulator on which to run circuit
// Raises:
// RuntimeError: QrackCircuit raised an exception.
unsafe {
qrack_system::qcircuit_run(self.cid, qsim.get_sid())
}
qsim.check_error()
}

pub fn out_to_file(&self, filename: &str) -> () {
// Output optimized circuit to file
//
// Outputs the (optimized) circuit to a file named
// according to the "filename" parameter.
//
// Args:
// filename: Name of file
unsafe {
qrack_system::qcircuit_out_to_file(self.cid, CString::new(filename).unwrap().into_bytes_with_nul().as_mut_ptr() as *mut i8)
}
}

pub fn in_from_file(&self, filename: &str) -> () {
// Read in optimized circuit from file
//
// Reads in an (optimized) circuit from a file named
// according to the "filename" parameter.
//
// Args:
// filename: Name of file
unsafe {
qrack_system::qcircuit_in_from_file(self.cid, CString::new(filename).unwrap().into_bytes_with_nul().as_mut_ptr() as *mut i8)
}
}
}
51 changes: 37 additions & 14 deletions src/qrack_simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,6 @@ impl Drop for QrackSimulator {
}

impl QrackSimulator {
// private functions
fn get_error(&self) -> i32 {
unsafe {
qrack_system::get_error(self.sid)
}
}
fn check_error(&self) -> Result<(), QrackError> {
if self.get_error() != 0 {
return Err(QrackError{});
}
return Ok(());
}

// constructors
pub fn new(qubit_count: u64) -> Result<Self, QrackError> {
let sid;
Expand Down Expand Up @@ -108,8 +95,21 @@ impl QrackSimulator {
}

// non-quantum
pub fn get_error(&self) -> i32 {
unsafe {
qrack_system::get_error(self.sid)
}
}

pub fn check_error(&self) -> Result<(), QrackError> {
if self.get_error() != 0 {
return Err(QrackError{});
}
return Ok(())
}

pub fn get_sid(&self) -> u64 {
return self.sid;
return self.sid
}

pub fn seed(&self, s: u64) -> Result<(), QrackError> {
Expand Down Expand Up @@ -765,6 +765,29 @@ impl QrackSimulator {
self.check_error()
}

pub fn ucmtrx(&self, c: Vec<u64>, m: &[f64;8], q: u64, p: u64) -> Result<(), QrackError> {
// Multi-controlled arbitrary operator with arbitrary controls
//
// If all control qubits match 'p' permutation by bit order, then the arbitrary
// operation by parameters is applied to the target qubit.
//
// Args:
// c(Vec<u64>): list of controlled qubits
// m(&[f64;8]): row-major complex list representing the operator.
// q(u64): target qubit
// p(u64): permutation of list of control qubits
//
// Raises:
// RuntimeError: QrackSimulator raised an exception.

let mut _m = [m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7]];
let mut _c = c.to_vec();
unsafe {
qrack_system::UCMtrx(self.sid, _c.len() as u64, _c.as_mut_ptr(), _m.as_mut_ptr(), q, p);
}
self.check_error()
}

pub fn multiplex1_mtrx(&self, c: Vec<u64>, q: u64, m: Vec<f64>) -> Result<(), QrackError> {
// Multiplex gate
//
Expand Down
33 changes: 33 additions & 0 deletions src/qrack_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ extern "C" {
extern "C" {
pub fn MACMtrx(sid: uintq, n: uintq, c: *mut uintq, m: *mut f64, q: uintq);
}
extern "C" {
pub fn UCMtrx(sid: uintq, n: uintq, c: *mut uintq, m: *mut f64, q: uintq, p: uintq);
}
extern "C" {
pub fn Multiplex1Mtrx(sid: uintq, n: uintq, c: *mut uintq, q: uintq, m: *mut f64);
}
Expand Down Expand Up @@ -617,3 +620,33 @@ extern "C" {
extern "C" {
pub fn qneuron_learn_permutation(nid: uintq, eta: f64, e: bool, r: bool);
}
extern "C" {
pub fn init_qcircuit() -> uintq;
}
extern "C" {
pub fn init_qcircuit_clone(cid: uintq) -> uintq;
}
extern "C" {
pub fn destroy_qcircuit(cid: uintq);
}
extern "C" {
pub fn get_qcircuit_qubit_count(cid: uintq) -> uintq;
}
extern "C" {
pub fn qcircuit_swap(cid: uintq, q1: uintq, q2: uintq);
}
extern "C" {
pub fn qcircuit_append_1qb(cid: uintq, m: *mut f64, q: uintq);
}
extern "C" {
pub fn qcircuit_append_mc(cid: uintq, m: *mut f64, n: uintq, c: *mut uintq, q: uintq, p: uintq);
}
extern "C" {
pub fn qcircuit_run(cid: uintq, sid: uintq);
}
extern "C" {
pub fn qcircuit_out_to_file(cid: uintq, f: *mut ::std::os::raw::c_char);
}
extern "C" {
pub fn qcircuit_in_from_file(cid: uintq, f: *mut ::std::os::raw::c_char);
}

0 comments on commit 12fc4d3

Please sign in to comment.