Przeglądaj źródła

Setup for python3

Adam Kelly 5 lat temu
rodzic
commit
53bbefc8c5

+ 91 - 0
example.py

@@ -0,0 +1,91 @@
+from __future__ import print_function
+import qcgpu
+
+s = qcgpu.State(3)
+h = qcgpu.gate.h()
+
+print(h)
+
+s.apply_gate(h, 0)
+
+print(s)
+
+# from __future__ import absolute_import
+# from __future__ import print_function
+# import pyopencl as cl
+# import pyopencl.array as cl_array
+# import numpy
+# import numpy.linalg as la
+
+# a = numpy.random.rand(8).astype(numpy.complex64)
+
+# ctx = cl.create_some_context()
+# queue = cl.CommandQueue(ctx)
+
+# a_dev = cl_array.to_device(queue, a)
+
+# prg = cl.Program(ctx, """
+#     #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);
+#     }
+
+#     /*
+#     * 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));
+#     }
+
+#     __kernel void sum(__global cfloat_t *a, cfloat_t b)
+#     {
+#       int gid = get_global_id(0);
+#       a[gid] = cfloat_add(a[gid], b);
+#     }
+#     """).build()
+
+# # kernel = prg.sum
+# # kernel.set_scalar_arg_dtypes([
+# #     None,
+# #     None,
+# #     numpy.complex64
+# # ])
+
+# prg.sum(queue, (int(a.shape[0] / 2),), None, a_dev.data, numpy.complex64(3+2j))
+
+# prg.sum(queue, (2, ), None, a_dev.data, numpy.complex64(3+2j))
+
+# print(a_dev)
+
+# print((a.shape[0] / 2,))

+ 0 - 22
examples/bell-state.py

@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-"""
-Bell State / EPR Pair
----------------------
-
-The Bell State, also known as the EPR pair (after Einstein, Podosky and Rosen)
-is the simplest example of entanglement.
-
-The Bell State is defined as the maximally entangled quantum state of two qubits.
-"""
-
-import qcgpu
-
-print("Creating Bell State")
-
-state = qcgpu.state(2)
-
-state.h(0)
-state.cx(0, 1)
-
-print("Measurement Results:")
-print(state.measure())

+ 27 - 0
examples/bell_state.py

@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+
+"""
+Bell State / EPR Pair
+=====================
+
+The Bell State, also known as the EPR pair (after Einstein, Podosky and Rosen)
+is the simplest example of entanglement.
+
+The Bell State is defined as the maximally entangled quantum state of two qubits.
+"""
+
+def bell_state():
+    import qcgpu
+
+    print("Creating Bell State")
+
+    state = qcgpu.state(2)
+
+    state.h(0)
+    state.cx(0, 1)
+
+    print("Measurement Results:")
+    print(state.measure(samples = 1000))
+
+if __name__== "__main__":
+  bell_state()

+ 52 - 0
examples/bernstein_vazirani.py

@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+
+"""
+Bernstein-Vazirani Algorithm
+============================
+
+This algorithm finds a hidden integer :math:`a \in \{ 0, 1\}^n` from
+an oracle :math:`f_a` which returns a bit :math:`a \cdot x \equiv \sum_i a_i x_i \mod 2`
+for an input :math:`x \in \{0,1\}^n`.
+
+A classical oracle returns :math:`f_a(x) = a \dot x \mod 2`, while the quantum oracle
+must be queried with superpositions of input :math:`x`'s.
+
+To solve this problem classically, the hidden integer can be found by checking the
+oracle with the inputs :math:`x = 1,2,\dots,2^i,2^{n-1}`, where each
+query reveals the :math:`i`th bit of :math:`a` (:math:`a_i`).
+This is the optimal classical solution, and is :math:`O(n)`. Using a quantum oracle and the
+Bernstein-Vazirani algorithm, :math:`a` can be found with just one query to the oracle.
+
+The Algorithm
+-------------
+
+1. Initialize :math:`n` qubits in the state :math:`\lvert 0, \dots, 0\rangle`.
+2. Apply the Hadamard gate :math:`H` to each qubit.
+3. Apply the inner product oracle.
+4. Apply the Hadamard gate :math:`H` to each qubit.
+5. Measure the register
+
+From this procedure, we find that the registers measured value is equal to that of
+the original hidden integer.
+"""
+
+def bernstein_vazirani():
+    import qcgpu
+
+    a = 101 # The hidden integer, bitstring is 1100101
+
+    register = qcgpu.State(16) # Create a new quantum register
+
+    register.apply_all(qcgpu.gate.h()) # Apply a hadamard gate to each qubit
+
+    # Apply the inner products oracle
+    for i in range(16):
+        if a & (1 << i) != 0:
+            register.z(i)
+
+    register.apply_all(qcgpu.gate.h()) # Apply a hadamard gate to each qubit
+
+    register.measure(samples=1000) # Measure the register (sample 1000 times)
+
+if __name__== "__main__":
+  bernstein_vazirani()

+ 113 - 31
notebooks/Benchmarking.ipynb

@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 1,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -24,7 +24,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 12,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -59,6 +59,7 @@
     "    start = time.time()\n",
     "\n",
     "    for level in range(depth):\n",
+    "        print(depth-level)\n",
     "        for q in qbits:\n",
     "            ops.H | q\n",
     "            ops.SqrtX | q\n",
@@ -76,7 +77,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 10,
    "metadata": {},
    "outputs": [
     {
@@ -84,27 +85,27 @@
      "output_type": "stream",
      "text": [
       "started\n",
-      "('ended: ', 0.2940499782562256)\n"
+      "('ended: ', 202.95192885398865)\n"
      ]
     },
     {
      "data": {
       "text/plain": [
-       "0.2940499782562256"
+       "202.95192885398865"
       ]
      },
-     "execution_count": 8,
+     "execution_count": 10,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "bench_qcgpu(26,5)"
+    "bench_qcgpu(28,100)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 13,
    "metadata": {},
    "outputs": [
     {
@@ -112,41 +113,122 @@
      "output_type": "stream",
      "text": [
       "started\n",
-      "('ended: ', 12.032409906387329)\n"
+      "100\n",
+      "99\n",
+      "98\n",
+      "97\n",
+      "96\n",
+      "95\n",
+      "94\n",
+      "93\n",
+      "92\n",
+      "91\n",
+      "90\n",
+      "89\n",
+      "88\n",
+      "87\n",
+      "86\n",
+      "85\n",
+      "84\n",
+      "83\n",
+      "82\n",
+      "81\n",
+      "80\n",
+      "79\n",
+      "78\n",
+      "77\n",
+      "76\n",
+      "75\n",
+      "74\n",
+      "73\n",
+      "72\n",
+      "71\n",
+      "70\n",
+      "69\n",
+      "68\n",
+      "67\n",
+      "66\n",
+      "65\n",
+      "64\n",
+      "63\n",
+      "62\n",
+      "61\n",
+      "60\n",
+      "59\n",
+      "58\n",
+      "57\n",
+      "56\n",
+      "55\n",
+      "54\n",
+      "53\n",
+      "52\n",
+      "51\n",
+      "50\n",
+      "49\n",
+      "48\n",
+      "47\n",
+      "46\n",
+      "45\n",
+      "44\n",
+      "43\n",
+      "42\n",
+      "41\n",
+      "40\n",
+      "39\n",
+      "38\n",
+      "37\n",
+      "36\n",
+      "35\n",
+      "34\n",
+      "33\n",
+      "32\n",
+      "31\n",
+      "30\n",
+      "29\n",
+      "28\n",
+      "27\n",
+      "26\n",
+      "25\n",
+      "24\n",
+      "23\n",
+      "22\n",
+      "21\n",
+      "20\n",
+      "19\n",
+      "18\n",
+      "17\n",
+      "16\n",
+      "15\n",
+      "14\n",
+      "13\n",
+      "12\n",
+      "11\n",
+      "10\n",
+      "9\n",
+      "8\n",
+      "7\n",
+      "6\n",
+      "5\n",
+      "4\n",
+      "3\n",
+      "2\n",
+      "1\n",
+      "('ended: ', 971.3228080272675)\n"
      ]
     },
     {
      "data": {
       "text/plain": [
-       "12.032409906387329"
+       "971.3228080272675"
       ]
      },
-     "execution_count": 9,
+     "execution_count": 13,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "bench_projectq(26,5)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "raw_data = {\n",
-    "    'num_qubits': [2,2,2,3,3,3,4,4,4,5,5,5,6,6,6], \n",
-    "    'depth': [10,20,30,10,20,30,10,20,30,10,20,30,10,20,30], \n",
-    "    'time': [0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256, 0.2940499782562256]\n",
-    "}\n",
-    "\n",
-    "df = pd.DataFrame(raw_data, columns = ['num_qubits', 'depth', 'time'])\n",
-    "\n",
-    "df\n",
-    "\n",
-    "df.to_csv('out.csv')"
+    "bench_projectq(28,100)"
    ]
   },
   {

+ 2 - 2
qcgpu/__init__.py

@@ -1,2 +1,2 @@
-import gate
-from state import State
+import qcgpu.gate
+from qcgpu.state import State

+ 12 - 31
qcgpu/backend.py

@@ -45,51 +45,32 @@ class Backend:
     def apply_gate(self, gate, target):
         """Applies a gate to the quantum register"""
 
-        kernel = self.program.apply_gate
-        kernel.set_scalar_arg_dtypes([
-            None,
-            np.int32,
-            self.dtype,
-            self.dtype,
-            self.dtype,
-            self.dtype,
-        ])
-        kernel(
+        self.program.apply_gate(
             self.queue,
-            [self.buffer.shape[0] / 2],
+            [int(self.buffer.shape[0] / 2)],
             None,
             self.buffer.data,
             np.int32(target),
-            gate.a,
-            gate.b,
-            gate.c,
-            gate.d
+            self.dtype(gate.a),
+            self.dtype(gate.b),
+            self.dtype(gate.c),
+            self.dtype(gate.d)
         )
 
     def apply_controlled_gate(self, gate, control, target):
         """Applies a controlled gate to the quantum register"""
 
-        kernel = self.program.apply_controlled_gate
-        kernel.set_scalar_arg_dtypes([
-            None,
-            np.int32,
-            np.int32,
-            self.dtype,
-            self.dtype,
-            self.dtype,
-            self.dtype,
-        ])
-        kernel(
+        self.program.apply_controlled_gate(
             self.queue,
-            [self.buffer.shape[0] / 2],
+            [int(self.buffer.shape[0] / 2)],
             None,
             self.buffer.data,
             np.int32(control),
             np.int32(target),
-            gate.a,
-            gate.b,
-            gate.c,
-            gate.d
+            self.dtype(gate.a),
+            self.dtype(gate.b),
+            self.dtype(gate.c),
+            self.dtype(gate.d)
         )
     
     def qubit_probability(self, target):

+ 35 - 35
qcgpu/kernels/brute-force.cl

@@ -4,10 +4,10 @@
  * Returns the nth number where a given digit
  * is cleared in the binary representation of the number
  */
-static uint nth_cleared(uint n, uint target)
+static int nth_cleared(int n, int target)
 {
-    uint mask = (1 << target) - 1;
-    uint not_mask = ~mask;
+    int mask = (1 << target) - 1;
+    int not_mask = ~mask;
 
     return (n & mask) | ((n & not_mask) << 1);
 }
@@ -25,18 +25,18 @@ static uint nth_cleared(uint n, uint target)
  */
 __kernel void apply_gate(
     __global cfloat_t *amplitudes,
-    uint target,
+    int target,
     cfloat_t A,
     cfloat_t B,
     cfloat_t C,
     cfloat_t D)
 {
-    uint const global_id = get_global_id(0);
+    int const global_id = get_global_id(0);
 
-    uint const zero_state = nth_cleared(global_id, target);
+    int const zero_state = nth_cleared(global_id, target);
 
-    // uint const zero_state = state & (~(1 << target)); // Could just be state
-    uint const one_state = zero_state | (1 << 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];
@@ -50,19 +50,19 @@ __kernel void apply_gate(
  */
 __kernel void apply_controlled_gate(
     __global cfloat_t *amplitudes,
-    uint control,
-    uint target,
+    int control,
+    int target,
     cfloat_t A,
     cfloat_t B,
     cfloat_t C,
     cfloat_t D)
 {
-    uint const global_id = get_global_id(0);
-    uint const zero_state = nth_cleared(global_id, target);
-    uint const one_state = zero_state | (1 << target); // Set the target bit
+    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
 
-    uint const control_val_zero = (((1 << control) & zero_state) > 0) ? 1 : 0;
-    uint const control_val_one = (((1 << control) & one_state) > 0) ? 1 : 0;
+    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];
@@ -87,23 +87,23 @@ __kernel void apply_controlled_gate(
 __kernel void apply_controlled_controlled_gate(
     __global cfloat_t *const amplitudes,
     __global cfloat_t *amps,
-    uint control1,
-    uint control2,
-    uint target,
+    int control1,
+    int control2,
+    int target,
     cfloat_t A,
     cfloat_t B,
     cfloat_t C,
     cfloat_t D)
 {
-    uint const state = get_global_id(0);
+    int const state = get_global_id(0);
     cfloat_t const amp = amplitudes[state];
 
-    uint const zero_state = state & (~(1 << target));
-    uint const one_state = state | (1 << target);
+    int const zero_state = state & (~(1 << target));
+    int const one_state = state | (1 << target);
 
-    uint const bit_val = (((1 << target) & state) > 0) ? 1 : 0;
-    uint const control1_val = (((1 << control1) & state) > 0) ? 1 : 0;
-    uint const control2_val = (((1 << control2) & state) > 0) ? 1 : 0;
+    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)
     {
@@ -132,18 +132,18 @@ __kernel void apply_controlled_controlled_gate(
 // __kernel void swap(
 //     __global cfloat_t *const amplitudes,
 //     __global cfloat_t *amps,
-//     uint first_qubit,
-//     uint second_qubit)
+//     int first_qubit,
+//     int second_qubit)
 // {
-//     uint const state = get_global_id(0);
+//     int const state = get_global_id(0);
 
-//     uint const first_bit_mask = 1 << first_qubit;
-//     uint const second_bit_mask = 1 << second_qubit;
+//     int const first_bit_mask = 1 << first_qubit;
+//     int const second_bit_mask = 1 << second_qubit;
 
-//     uint const new_second_bit = ((state & first_bit_mask) >> first_qubit) << second_qubit;
-//     uint const new_first_bit = ((state & second_bit_mask) >> second_qubit) << first_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;
 
-//     uint const new_state = (state & !first_bit_mask & !second_bit_mask) | new_first_bit | new_second_bit;
+//     int const new_state = (state & !first_bit_mask & !second_bit_mask) | new_first_bit | new_second_bit;
 
 //     amps[new_state] = amplitudes[state];
 // }
@@ -156,7 +156,7 @@ __kernel void calculate_probabilities(
     __global cfloat_t *const amplitudes,
     __global float *probabilities)
 {
-    uint const state = get_global_id(0);
+    int const state = get_global_id(0);
     cfloat_t amp = amplitudes[state];
 
     probabilities[state] = cfloat_abs(cfloat_mul(amp, amp));
@@ -168,9 +168,9 @@ __kernel void calculate_probabilities(
  */
 __kernel void initialize_register(
     __global cfloat_t *amplitudes,
-    uint const target)
+    int const target)
 {
-    uint const state = get_global_id(0);
+    int const state = get_global_id(0);
     if (state == target)
     {
         amplitudes[state] = cfloat_new(1, 0);

+ 1 - 1
qcgpu/state.py

@@ -1,4 +1,4 @@
-from backend import Backend
+from qcgpu.backend import Backend
 import pyopencl as cl
 import numpy as np
 

+ 69 - 0
requirements.txt

@@ -0,0 +1,69 @@
+appdirs==1.4.3
+apturl==0.5.2
+asn1crypto==0.24.0
+Brlapi==0.6.6
+certifi==2018.1.18
+chardet==3.0.4
+chrome-gnome-shell==0.0.0
+colour==0.1.5
+command-not-found==0.3
+cryptography==2.1.4
+cupshelpers==1.0
+decorator==4.3.0
+defer==1.0.6
+distro-info==0.18
+httplib2==0.9.2
+idna==2.6
+keyring==10.6.0
+keyrings.alt==3.0
+language-selector==0.1
+launchpadlib==1.10.6
+lazr.restfulclient==0.13.5
+lazr.uri==1.0.3
+louis==3.5.0
+macaroonbakery==1.1.3
+Mako==1.0.7
+MarkupSafe==1.0
+mpmath==1.0.0
+numpy==1.15.2
+oauth==1.0.1
+olefile==0.45.1
+opencv-python==3.4.2.17
+pexpect==4.2.1
+Pillow==5.2.0
+progressbar==2.5
+protobuf==3.0.0
+pycairo==1.17.1
+pycrypto==2.6.1
+pycups==1.9.73
+pygobject==3.26.1
+pymacaroons==0.13.0
+PyNaCl==1.1.2
+pyopencl==2018.2
+pyRFC3339==1.0
+python-apt==1.6.2
+python-debian==0.1.32
+pytools==2018.5.2
+pytz==2018.3
+pyxdg==0.25
+PyYAML==3.12
+-e git+https://github.com/QCGPU/qcgpu-rust@745ea6d5c1f23d08a20d300a68e5a40d03e3b063#egg=qcgpu
+reportlab==3.4.0
+requests==2.18.4
+requests-unixsocket==0.1.5
+scipy==1.1.0
+screen-resolution-extra==0.0.0
+SecretStorage==2.3.1
+simplejson==3.13.2
+six==1.11.0
+system-service==0.3
+systemd-python==234
+tqdm==4.24.0
+ubuntu-drivers-common==0.0.0
+ufw==0.35
+unattended-upgrades==0.1
+urllib3==1.22
+usb-creator==0.3.3
+wadllib==1.3.2
+xkit==0.0.0
+zope.interface==4.3.2

+ 2 - 2
setup.py

@@ -1,6 +1,6 @@
 import setuptools
 
-with open("README.md", "r") as fh:
+with open("README.rst", "r") as fh:
     long_description = fh.read()
 
 setuptools.setup(
@@ -10,7 +10,7 @@ setuptools.setup(
     author_email="adamkelly2201@gmail.com",
     description="An OpenCL based quantum computer simulator",
     long_description=long_description,
-    long_description_content_type="text/markdown",
+    long_description_content_type="text/rst",
     url="https://github.com/qcgpu/qcgpu",
     packages=setuptools.find_packages(),
     classifiers=[