Browse Source

Get ready for publishing

Adam Kelly 5 years ago
parent
commit
0fd18057af
5 changed files with 232 additions and 243 deletions
  1. 32 0
      README.md
  2. 0 41
      README.rst
  3. 195 5
      qcgpu/backend.py
  4. 0 193
      qcgpu/kernels/brute-force.cl
  5. 5 4
      setup.py

+ 32 - 0
README.md

@@ -0,0 +1,32 @@
+# QCGPU
+
+[![Travis
+(.org)](https://img.shields.io/travis/QCGPU/qcgpu.svg?style=for-the-badge)](https://travis-ci.org/QCGPU/qcgpu)
+[![PyPi
+Version](https://img.shields.io/pypi/v/qcgpu.svg?style=for-the-badge)](https://pypi.python.org/pypi/qcgpu)
+[![License](https://img.shields.io/pypi/l/qcgpu.svg?style=for-the-badge)](https://pypi.python.org/pypi/qcgpu/)
+[![GitHub
+stars](https://img.shields.io/github/stars/qcgpu/qcgpu.svg?style=for-the-badge&label=Stars)](https://github.com/QCGPU/qcgpu)
+
+Open Source, High Performance & Hardware Accelerated, Quantum Computer
+Simulator. Read the [research paper](https://arxiv.org/abs/1805.00988).
+
+**Features:**
+
+  - Written with OpenCL. Accelerated your simulations with GPUs and other
+    accelerators, while still running cross device and cross platform.
+  - Simulation of arbitrary quantum circuits
+  - Includes example algorithm implementations
+  - Support for arbitrary gate creation/application, with many built in.
+
+## Installing
+
+This library is distributed on
+[PyPI](https://pypi.python.org/pypi/qcgpu) and can be installed using
+pip:
+
+```bash
+$ pip install qcgpu
+```
+
+For more information read the full [installing docs](https://qcgpu.github.io/qcgpu/install.html).

+ 0 - 41
README.rst

@@ -1,41 +0,0 @@
-QCGPU
-=====
-
-.. image:: https://img.shields.io/travis/QCGPU/qcgpu.svg?style=for-the-badge   
-   :alt: Travis (.org)   
-   :target: https://travis-ci.org/QCGPU/qcgpu
-.. image:: https://img.shields.io/pypi/v/qcgpu.svg?style=for-the-badge
-   :target: https://pypi.python.org/pypi/qcgpu
-   :alt: PyPi Version
-.. image:: https://img.shields.io/pypi/l/qcgpu.svg?style=for-the-badge
-   :target: https://pypi.python.org/pypi/qcgpu/
-   :alt: License
-.. image:: https://img.shields.io/github/stars/qcgpu/qcgpu.svg?style=for-the-badge&label=Stars
-   :alt: GitHub stars
-   :target: https://github.com/QCGPU/qcgpu
-
-Open Source, High Performance & Hardware Accelerated, Quantum Computer Simulator.
-Read the `research paper`_.
-
-.. _`research paper`: https://arxiv.org/abs/1805.00988
-
-**Features:**
-
-* Written with OpenCL. Accelerated your simuations with GPUs and other accelerators, while still running cross device and cross platform.
-* Simulation of arbitrary quantum circuits
-* Includes example algorthm implementations
-* Support for arbitrary gate creation/application, with many built in.
-
-Installing
-==========
-
-This library is distributed on PyPI_ and can be installed using pip::
-
-    pip install qcgpu
-
-For more information read the full installing docs, :ref:`installing`.
-
-TODO: Fix this link
-
-.. _PyPI: https://pypi.python.org/pypi/qcgpu
-

+ 195 - 5
qcgpu/backend.py

@@ -8,11 +8,201 @@ from collections import defaultdict
 
 
 # Get the OpenCL kernel
-kernel_path = os.path.join(
-    os.path.dirname(__file__),
-    "kernels/brute-force.cl"
-)
-kernel = open(kernel_path, "r").read()
+kernel = """
+#include <pyopencl-complex.h>
+
+/*
+ * Returns the nth number where a given digit
+ * is cleared in the binary representation of the number
+ */
+static int nth_cleared(int n, int target)
+{
+    int mask = (1 << target) - 1;
+    int not_mask = ~mask;
+
+    return (n & mask) | ((n & not_mask) << 1);
+}
+
+///////////////////////////////////////////////
+// KERNELS
+///////////////////////////////////////////////
+
+/*
+ * Applies a single qubit gate to the register.
+ * The gate matrix must be given in the form:
+ *
+ *  A B
+ *  C D
+ */
+__kernel void apply_gate(
+    __global cfloat_t *amplitudes,
+    int target,
+    cfloat_t A,
+    cfloat_t B,
+    cfloat_t C,
+    cfloat_t D)
+{
+    int const global_id = get_global_id(0);
+
+    int const zero_state = nth_cleared(global_id, target);
+
+    // int const zero_state = state & (~(1 << target)); // Could just be state
+    int const one_state = zero_state | (1 << target);
+
+    cfloat_t const zero_amp = amplitudes[zero_state];
+    cfloat_t const one_amp = amplitudes[one_state];
+
+    amplitudes[zero_state] = cfloat_add(cfloat_mul(A, zero_amp), cfloat_mul(B, one_amp));
+    amplitudes[one_state] = cfloat_add(cfloat_mul(D, one_amp), cfloat_mul(C, zero_amp));
+}
+
+/*
+ * Applies a controlled single qubit gate to the register.
+ */
+__kernel void apply_controlled_gate(
+    __global cfloat_t *amplitudes,
+    int control,
+    int target,
+    cfloat_t A,
+    cfloat_t B,
+    cfloat_t C,
+    cfloat_t D)
+{
+    int const global_id = get_global_id(0);
+    int const zero_state = nth_cleared(global_id, target);
+    int const one_state = zero_state | (1 << target); // Set the target bit
+
+    int const control_val_zero = (((1 << control) & zero_state) > 0) ? 1 : 0;
+    int const control_val_one = (((1 << control) & one_state) > 0) ? 1 : 0;
+
+    cfloat_t const zero_amp = amplitudes[zero_state];
+    cfloat_t const one_amp = amplitudes[one_state];
+
+    if (control_val_zero == 1)
+    {
+        amplitudes[zero_state] = cfloat_add(cfloat_mul(A, zero_amp), cfloat_mul(B, one_amp));
+    }
+
+    if (control_val_one == 1)
+    {
+        amplitudes[one_state] = cfloat_add(cfloat_mul(D, one_amp), cfloat_mul(C, zero_amp));
+    }
+
+
+}
+
+/*
+ * Applies a controlled-controlled single qubit gate to the register.
+ * NOT MIGRATED
+ */
+__kernel void apply_controlled_controlled_gate(
+    __global cfloat_t *const amplitudes,
+    __global cfloat_t *amps,
+    int control1,
+    int control2,
+    int target,
+    cfloat_t A,
+    cfloat_t B,
+    cfloat_t C,
+    cfloat_t D)
+{
+    int const state = get_global_id(0);
+    cfloat_t const amp = amplitudes[state];
+
+    int const zero_state = state & (~(1 << target));
+    int const one_state = state | (1 << target);
+
+    int const bit_val = (((1 << target) & state) > 0) ? 1 : 0;
+    int const control1_val = (((1 << control1) & state) > 0) ? 1 : 0;
+    int const control2_val = (((1 << control2) & state) > 0) ? 1 : 0;
+
+    if (control1_val == 0 || control2_val == 0)
+    {
+        // Control is 0, don't apply gate
+        amps[state] = amp;
+    }
+    else
+    {
+        // control is 1, apply gate.
+        if (bit_val == 0)
+        {
+            // Bitval = 0
+            amps[state] = cfloat_add(cfloat_mul(A, amp), cfloat_mul(B, amplitudes[one_state]));
+        }
+        else
+        {
+            amps[state] = cfloat_add(cfloat_mul(D, amp), cfloat_mul(C, amplitudes[zero_state]));
+        }
+    }
+}
+
+/*
+ * Swaps the states of two qubits in the register
+ * NOT MIGRATED
+ */
+// __kernel void swap(
+//     __global cfloat_t *const amplitudes,
+//     __global cfloat_t *amps,
+//     int first_qubit,
+//     int second_qubit)
+// {
+//     int const state = get_global_id(0);
+
+//     int const first_bit_mask = 1 << first_qubit;
+//     int const second_bit_mask = 1 << second_qubit;
+
+//     int const new_second_bit = ((state & first_bit_mask) >> first_qubit) << second_qubit;
+//     int const new_first_bit = ((state & second_bit_mask) >> second_qubit) << first_qubit;
+
+//     int const new_state = (state & !first_bit_mask & !second_bit_mask) | new_first_bit | new_second_bit;
+
+//     amps[new_state] = amplitudes[state];
+// }
+
+
+/**
+ * Get a single amplitude
+ */
+__kernel void get_single_amplitude(
+    __global cfloat_t *const amplitudes,
+    __global cfloat_t *out,
+    int i)
+{
+    out[0] = amplitudes[i];
+}
+
+/**
+ * Calculates The Probabilities Of A State Vector
+ */
+__kernel void calculate_probabilities(
+    __global cfloat_t *const amplitudes,
+    __global float *probabilities)
+{
+    int const state = get_global_id(0);
+    cfloat_t amp = amplitudes[state];
+
+    probabilities[state] = cfloat_abs(cfloat_mul(amp, amp));
+}
+
+/**
+ * Initializes a register to the value 1|0..100...0>
+ *                                          ^ target
+ */
+__kernel void initialize_register(
+    __global cfloat_t *amplitudes,
+    int const target)
+{
+    int const state = get_global_id(0);
+    if (state == target)
+    {
+        amplitudes[state] = cfloat_new(1, 0);
+    }
+    else
+    {
+        amplitudes[state] = cfloat_new(0, 0);
+    }
+}
+"""
 
 
 class Backend:

+ 0 - 193
qcgpu/kernels/brute-force.cl

@@ -1,193 +0,0 @@
-#include <pyopencl-complex.h>
-
-/*
- * Returns the nth number where a given digit
- * is cleared in the binary representation of the number
- */
-static int nth_cleared(int n, int target)
-{
-    int mask = (1 << target) - 1;
-    int not_mask = ~mask;
-
-    return (n & mask) | ((n & not_mask) << 1);
-}
-
-///////////////////////////////////////////////
-// KERNELS
-///////////////////////////////////////////////
-
-/*
- * Applies a single qubit gate to the register.
- * The gate matrix must be given in the form:
- *
- *  A B
- *  C D
- */
-__kernel void apply_gate(
-    __global cfloat_t *amplitudes,
-    int target,
-    cfloat_t A,
-    cfloat_t B,
-    cfloat_t C,
-    cfloat_t D)
-{
-    int const global_id = get_global_id(0);
-
-    int const zero_state = nth_cleared(global_id, target);
-
-    // int const zero_state = state & (~(1 << target)); // Could just be state
-    int const one_state = zero_state | (1 << target);
-
-    cfloat_t const zero_amp = amplitudes[zero_state];
-    cfloat_t const one_amp = amplitudes[one_state];
-
-    amplitudes[zero_state] = cfloat_add(cfloat_mul(A, zero_amp), cfloat_mul(B, one_amp));
-    amplitudes[one_state] = cfloat_add(cfloat_mul(D, one_amp), cfloat_mul(C, zero_amp));
-}
-
-/*
- * Applies a controlled single qubit gate to the register.
- */
-__kernel void apply_controlled_gate(
-    __global cfloat_t *amplitudes,
-    int control,
-    int target,
-    cfloat_t A,
-    cfloat_t B,
-    cfloat_t C,
-    cfloat_t D)
-{
-    int const global_id = get_global_id(0);
-    int const zero_state = nth_cleared(global_id, target);
-    int const one_state = zero_state | (1 << target); // Set the target bit
-
-    int const control_val_zero = (((1 << control) & zero_state) > 0) ? 1 : 0;
-    int const control_val_one = (((1 << control) & one_state) > 0) ? 1 : 0;
-
-    cfloat_t const zero_amp = amplitudes[zero_state];
-    cfloat_t const one_amp = amplitudes[one_state];
-
-    if (control_val_zero == 1)
-    {
-        amplitudes[zero_state] = cfloat_add(cfloat_mul(A, zero_amp), cfloat_mul(B, one_amp));
-    }
-
-    if (control_val_one == 1)
-    {
-        amplitudes[one_state] = cfloat_add(cfloat_mul(D, one_amp), cfloat_mul(C, zero_amp));
-    }
-
-
-}
-
-/*
- * Applies a controlled-controlled single qubit gate to the register.
- * NOT MIGRATED
- */
-__kernel void apply_controlled_controlled_gate(
-    __global cfloat_t *const amplitudes,
-    __global cfloat_t *amps,
-    int control1,
-    int control2,
-    int target,
-    cfloat_t A,
-    cfloat_t B,
-    cfloat_t C,
-    cfloat_t D)
-{
-    int const state = get_global_id(0);
-    cfloat_t const amp = amplitudes[state];
-
-    int const zero_state = state & (~(1 << target));
-    int const one_state = state | (1 << target);
-
-    int const bit_val = (((1 << target) & state) > 0) ? 1 : 0;
-    int const control1_val = (((1 << control1) & state) > 0) ? 1 : 0;
-    int const control2_val = (((1 << control2) & state) > 0) ? 1 : 0;
-
-    if (control1_val == 0 || control2_val == 0)
-    {
-        // Control is 0, don't apply gate
-        amps[state] = amp;
-    }
-    else
-    {
-        // control is 1, apply gate.
-        if (bit_val == 0)
-        {
-            // Bitval = 0
-            amps[state] = cfloat_add(cfloat_mul(A, amp), cfloat_mul(B, amplitudes[one_state]));
-        }
-        else
-        {
-            amps[state] = cfloat_add(cfloat_mul(D, amp), cfloat_mul(C, amplitudes[zero_state]));
-        }
-    }
-}
-
-/*
- * Swaps the states of two qubits in the register
- * NOT MIGRATED
- */
-// __kernel void swap(
-//     __global cfloat_t *const amplitudes,
-//     __global cfloat_t *amps,
-//     int first_qubit,
-//     int second_qubit)
-// {
-//     int const state = get_global_id(0);
-
-//     int const first_bit_mask = 1 << first_qubit;
-//     int const second_bit_mask = 1 << second_qubit;
-
-//     int const new_second_bit = ((state & first_bit_mask) >> first_qubit) << second_qubit;
-//     int const new_first_bit = ((state & second_bit_mask) >> second_qubit) << first_qubit;
-
-//     int const new_state = (state & !first_bit_mask & !second_bit_mask) | new_first_bit | new_second_bit;
-
-//     amps[new_state] = amplitudes[state];
-// }
-
-
-/**
- * Get a single amplitude
- */
-__kernel void get_single_amplitude(
-    __global cfloat_t *const amplitudes,
-    __global cfloat_t *out,
-    int i)
-{
-    out[0] = amplitudes[i];
-}
-
-/**
- * Calculates The Probabilities Of A State Vector
- */
-__kernel void calculate_probabilities(
-    __global cfloat_t *const amplitudes,
-    __global float *probabilities)
-{
-    int const state = get_global_id(0);
-    cfloat_t amp = amplitudes[state];
-
-    probabilities[state] = cfloat_abs(cfloat_mul(amp, amp));
-}
-
-/**
- * Initializes a register to the value 1|0..100...0>
- *                                          ^ target
- */
-__kernel void initialize_register(
-    __global cfloat_t *amplitudes,
-    int const target)
-{
-    int const state = get_global_id(0);
-    if (state == target)
-    {
-        amplitudes[state] = cfloat_new(1, 0);
-    }
-    else
-    {
-        amplitudes[state] = cfloat_new(0, 0);
-    }
-}

+ 5 - 4
setup.py

@@ -1,16 +1,16 @@
 import setuptools
 
-with open("README.rst", "r") as fh:
+with open("README.md", "r") as fh:
     long_description = fh.read()
 
 setuptools.setup(
     name="qcgpu",
-    version="0.0.1",
+    version="0.0.4",
     author="Adam Kelly",
     author_email="adamkelly2201@gmail.com",
     description="An OpenCL based quantum computer simulator",
     long_description=long_description,
-    long_description_content_type="text/rst",
+    long_description_content_type="text/markdown",
     url="https://github.com/qcgpu/qcgpu",
     packages=setuptools.find_packages(),
     classifiers=[
@@ -18,6 +18,7 @@ setuptools.setup(
         "License :: OSI Approved :: MIT License",
         "Operating System :: OS Independent",
     ],
-    setup_requires=['pytest-runner', 'mako', 'pyopencl', 'pybind11', 'numpy'],
+    setup_requires=['pytest-runner'],
+    install_requires=['mako', 'pyopencl', 'pybind11', 'numpy'],
     tests_require=["pytest"]
 )