Browse Source

Adding More Benchmarking Tools

Adam Kelly 6 years ago
parent
commit
71c786c3f9
7 changed files with 353 additions and 160 deletions
  1. 56 0
      benchmark.py
  2. 58 59
      notebooks/Testing.ipynb
  3. 134 0
      notebooks/Verification.ipynb
  4. 16 0
      notebooks/out.csv
  5. 89 0
      notebooks/settings.json
  6. 0 40
      other_testing.py
  7. 0 61
      testing.py

+ 56 - 0
benchmark.py

@@ -0,0 +1,56 @@
+# This script is to run the benchmarks.
+import numpy as np
+import sys
+import csv
+import time
+import qcgpu
+import os.path
+
+results_file = 'benchmark_results.csv'
+
+def bench_qcgpu(n, depth):
+    state = qcgpu.State(n)
+
+    h = qcgpu.gate.h()
+    x = qcgpu.gate.x()
+    sqrt_x = qcgpu.gate.sqrt_x()
+
+    start = time.time()
+
+    for level in range(depth):
+        for q in range(n):
+    
+            state.apply_gate(h, q)
+            state.apply_gate(sqrt_x, q)
+
+            if q != 0:
+                state.apply_controlled_gate(x, q, 0)
+        
+    runtime = time.time() - start
+    return {'name': 'qcgpu', 'num_qubits': n, 'depth': depth, 'time': runtime}
+
+def create_csv(filename):
+    file_exists = os.path.isfile(filename)
+    csvfile = open(filename, 'a')
+   
+    headers = ['name', 'num_qubits', 'depth', 'time']
+    writer = csv.DictWriter(csvfile, delimiter=',', lineterminator='\n',fieldnames=headers)
+
+    if not file_exists:
+        writer.writeheader()  # file doesn't exist yet, write a header
+
+    # writer.writerow({'TimeStamp': dic['ts'], 'light': dic['light'], 'Proximity': dic['prox']}
+
+    return writer
+
+def write_csv(writer, data):
+    print("Qubits: " + str(data['num_qubits']) + ", Depth: " + str(data['depth']) + ", Time: " + str(data['depth']))
+    writer.writerow(data)
+
+writer = create_csv(results_file)
+for i in range(2, 25):
+    for d in [5,10,15,20]:
+        data = bench_qcgpu(i, d)
+        write_csv(writer, data)
+
+

+ 58 - 59
notebooks/Testing.ipynb

@@ -2,53 +2,29 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [],
    "source": [
-    "%load_ext line_profiler\n",
-    "%matplotlib inline\n",
-    "\n",
-    "import matplotlib.pyplot as plt\n",
-    "from IPython.display import set_matplotlib_formats\n",
+    "import sys\n",
+    "import time\n",
+    "import pandas as pd\n",
     "import numpy as np\n",
+    "\n",
+    "# QCGPU Imports\n",
     "import qcgpu\n",
+    "\n",
+    "# ProjectQ Imports\n",
     "from projectq import MainEngine\n",
     "import projectq.ops as ops\n",
     "from projectq.backends import Simulator\n",
-    "import sys\n",
-    "import time\n",
-    "\n",
-    "set_matplotlib_formats('png', 'pdf')\n",
-    "plt.style.use('ggplot')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 27,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "def plot_qcgpu_state(state):\n",
-    "    labels = map(\n",
-    "        lambda i: np.binary_repr(i, state.num_qubits), \n",
-    "        range(0, 2**state.num_qubits)\n",
-    "    )\n",
-    "\n",
-    "    y_pos = np.arange(len(labels))\n",
-    "    performance = list(state.probabilities())\n",
-    " \n",
-    "    plt.bar(y_pos, performance, align='center')\n",
-    "    plt.xticks(y_pos, labels)\n",
-    "    plt.ylabel('Amplitude')\n",
-    "    plt.title('Probability Amplitudes')\n",
-    "\n",
-    "    plt.show()"
+    "from projectq.types import Qureg\n",
+    "\n"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -100,32 +76,35 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 8,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "started\n",
+      "('ended: ', 0.2940499782562256)\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "0.2940499782562256"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
-    "# h = qcgpu.gate.h()\n",
-    "# x = qcgpu.gate.x()\n",
-    "# s = qcgpu.gate.s()\n",
-    "# t = qcgpu.gate.t()\n",
-    "# y = qcgpu.gate.y()\n",
-    "# z = qcgpu.gate.z()\n",
-    "\n",
-    "# # Random Circuit\n",
-    "# state = qcgpu.State(5)\n",
-    "\n",
-    "# state.apply_gate(h, 0)\n",
-    "# state.apply_gate(t, 0)\n",
-    "# state.apply_gate(y, 0)\n",
-    "# state.apply_gate(z, 0)\n",
-    "# state.apply_gate(h, 0)\n",
-    "\n",
-    "# state.num_qubits"
+    "bench_qcgpu(26,5)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "execution_count": 9,
    "metadata": {},
    "outputs": [
     {
@@ -133,21 +112,41 @@
      "output_type": "stream",
      "text": [
       "started\n",
-      "('ended: ', 0.2988259792327881)\n"
+      "('ended: ', 12.032409906387329)\n"
      ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "12.032409906387329"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
     }
    ],
    "source": [
-    "%lprun -f bench_qcgpu bench_qcgpu(26,5)"
+    "bench_projectq(26,5)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": 13,
    "metadata": {},
    "outputs": [],
    "source": [
-    "# bench_projectq(26,5)"
+    "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')"
    ]
   },
   {

+ 134 - 0
notebooks/Verification.ipynb

@@ -0,0 +1,134 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Verification\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "import qcgpu\n",
+    "from projectq import MainEngine\n",
+    "import projectq.ops as ops\n",
+    "from projectq.backends import Simulator, CircuitDrawer"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def qcgpu_amplitudes(n, depth):\n",
+    "    state = qcgpu.State(n)\n",
+    "\n",
+    "    h = qcgpu.gate.h()\n",
+    "    x = qcgpu.gate.x()\n",
+    "    t = qcgpu.gate.t()\n",
+    "\n",
+    "    for level in range(depth):\n",
+    "        for q in range(n):\n",
+    "    \n",
+    "            state.apply_gate(h, q)\n",
+    "            state.apply_gate(t, q)\n",
+    "\n",
+    "            if q != 0:\n",
+    "                state.apply_controlled_gate(x, q, 0)\n",
+    "        \n",
+    "    return state.amplitudes()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def projectq_amplitudes(n, depth):\n",
+    "#     drawing_engine = CircuitDrawer()\n",
+    "#     eng = MainEngine(drawing_engine)\n",
+    "    sim = Simulator(gate_fusion=True)\n",
+    "    eng = MainEngine(backend=sim, engine_list=[])\n",
+    "    qbits = eng.allocate_qureg(n)\n",
+    "\n",
+    "    for level in range(depth):\n",
+    "        for q in qbits:\n",
+    "            ops.H | q\n",
+    "            ops.T | q\n",
+    "            if q != qbits[0]:\n",
+    "                ops.CNOT | (q, qbits[0])\n",
+    "\n",
+    "\n",
+    "    eng.flush()\n",
+    "    amplitudes = sim.cheat()[1]\n",
+    "    for q in qbits:\n",
+    "        ops.Measure | q\n",
+    "   \n",
+    "    return amplitudes\n",
+    "#     return drawing_engine.get_latex()\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 70,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 70,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "def verify(n, depth):\n",
+    "    amps_qcgpu = qcgpu_amplitudes(n,depth)\n",
+    "    amps_projectq = np.transpose(np.array([projectq_amplitudes(n,depth)]))\n",
+    "#     print(amps_qcgpu)\n",
+    "#     print(amps_projectq)\n",
+    "    return np.allclose(amps_qcgpu, amps_projectq, rtol=1e-04)\n",
+    "                        \n",
+    "verify(25,15)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 2",
+   "language": "python",
+   "name": "python2"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.15rc1"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}

+ 16 - 0
notebooks/out.csv

@@ -0,0 +1,16 @@
+,num_qubits,depth,time
+0,2,10,0.2940499782562256
+1,2,20,0.2940499782562256
+2,2,30,0.2940499782562256
+3,3,10,0.2940499782562256
+4,3,20,0.2940499782562256
+5,3,30,0.2940499782562256
+6,4,10,0.2940499782562256
+7,4,20,0.2940499782562256
+8,4,30,0.2940499782562256
+9,5,10,0.2940499782562256
+10,5,20,0.2940499782562256
+11,5,30,0.2940499782562256
+12,6,10,0.2940499782562256
+13,6,20,0.2940499782562256
+14,6,30,0.2940499782562256

+ 89 - 0
notebooks/settings.json

@@ -0,0 +1,89 @@
+{
+    "control": {
+        "shadow": false, 
+        "size": 0.1
+    }, 
+    "gate_shadow": true, 
+    "gates": {
+        "AllocateQubitGate": {
+            "allocate_at_zero": false, 
+            "draw_id": false, 
+            "height": 0.15, 
+            "offset": 0.1, 
+            "pre_offset": 0.1, 
+            "width": 0.2
+        }, 
+        "DeallocateQubitGate": {
+            "height": 0.15, 
+            "offset": 0.2, 
+            "pre_offset": 0.1, 
+            "width": 0.2
+        }, 
+        "EntangleGate": {
+            "offset": 0.2, 
+            "pre_offset": 0.2, 
+            "width": 1.8
+        }, 
+        "HGate": {
+            "offset": 0.3, 
+            "pre_offset": 0.1, 
+            "width": 0.5
+        }, 
+        "MeasureGate": {
+            "height": 0.5, 
+            "offset": 0.2, 
+            "pre_offset": 0.2, 
+            "width": 0.75
+        }, 
+        "Ph": {
+            "height": 0.8, 
+            "offset": 0.3, 
+            "pre_offset": 0.2, 
+            "width": 1.0
+        }, 
+        "Rx": {
+            "height": 0.8, 
+            "offset": 0.3, 
+            "pre_offset": 0.2, 
+            "width": 1.0
+        }, 
+        "Ry": {
+            "height": 0.8, 
+            "offset": 0.3, 
+            "pre_offset": 0.2, 
+            "width": 1.0
+        }, 
+        "Rz": {
+            "height": 0.8, 
+            "offset": 0.3, 
+            "pre_offset": 0.2, 
+            "width": 1.0
+        }, 
+        "SqrtSwapGate": {
+            "height": 0.35, 
+            "offset": 0.1, 
+            "width": 0.35
+        }, 
+        "SqrtXGate": {
+            "offset": 0.3, 
+            "pre_offset": 0.1, 
+            "width": 0.7
+        }, 
+        "SwapGate": {
+            "height": 0.35, 
+            "offset": 0.1, 
+            "width": 0.35
+        }, 
+        "XGate": {
+            "height": 0.35, 
+            "offset": 0.1, 
+            "width": 0.35
+        }
+    }, 
+    "lines": {
+        "double_classical": true, 
+        "double_lines_sep": 0.04, 
+        "init_quantum": true, 
+        "style": "very thin"
+    }
+}

+ 0 - 40
other_testing.py

@@ -1,40 +0,0 @@
-from projectq import MainEngine
-import projectq.ops as ops
-from projectq.backends import Simulator
-import sys
-import time
-
-if len(sys.argv) > 1:
-    n = int(sys.argv[1])
-else:
-    n = 16
-
-if len(sys.argv) > 1:
-    depth = int(sys.argv[2])
-else:
-    depth = 10
-
-print('Qubits: %d, Depth %d' % (n, depth))
-
-
-eng = MainEngine(backend=Simulator(gate_fusion=True), engine_list=[])
-qbits = eng.allocate_qureg(n)
-
-start = time.time()
-
-for level in range(depth):
-    for q in qbits:
-        ops.H | q
-        ops.SqrtX | q
-        if q != qbits[0]:
-            ops.CNOT | (q, qbits[0])
-
-
-
-runtime = time.time() - start
-
-for q in qbits:
-    ops.Measure | q
-    
-print(runtime)
-

+ 0 - 61
testing.py

@@ -1,61 +0,0 @@
-# import qcgpu
-# import perf
-
-# def run(num_qubits, depth):
-#     state = qcgpu.State(num_qubits)
-#     h = qcgpu.gate.h()
-
-#     for i in range(num_qubits * depth):
-#         state.apply_gate(h, i % num_qubits)
-
-import qcgpu
-import sys
-import time
-
-# ------------------------------------------
-# number of qubits and depth
-# ------------------------------------------
-if len(sys.argv) > 1:
-    n = int(sys.argv[1])
-else:
-    n = 16
-
-if len(sys.argv) > 1:
-    depth = int(sys.argv[2])
-else:
-    depth = 10
-
-print('Qubits: %d, Depth %d' % (n, depth))
-
-
-# ------------------------------------------
-# qubit register
-# ------------------------------------------
-
-state = qcgpu.State(n)
-
-# ------------------------------------------
-# circuit
-# ------------------------------------------
-
-h = qcgpu.gate.h()
-x = qcgpu.gate.x()
-sqrt_x = qcgpu.gate.sqrt_x()
-
-# timing -- get the start time
-start = time.time()
-
-# random circuit
-for level in range(depth):
-    for q in range(n):
-        state.apply_gate(h, q)
-        state.apply_gate(sqrt_x, q)
-
-        if q != 0:
-            state.apply_controlled_gate(x, q, 0)
-
-# timing -- get the end time
-runtime = time.time() - start
-
-# print out the runtime
-print(runtime)