{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Translating from Qubiter to Xanadu PennyLane\n", "\n", "The purpose of this notebook is to illustrate how to translate a Qubiter English file for\n", "a quantum circuit, into a Xanadu Pennylane \"qnode\"\n", "\n", "Next, we will create 2 Qubiter English files and then translate them to Pennylanese " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First change your working directory to the qubiter directory in your computer, and add its path to the path environment variable." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/home/rrtucci/PycharmProjects/qubiter/qubiter/jupyter_notebooks\n", "/home/rrtucci/PycharmProjects/qubiter\n" ] } ], "source": [ "import os\n", "import sys\n", "print(os.getcwd())\n", "os.chdir('../../')\n", "print(os.getcwd())\n", "sys.path.insert(0,os.getcwd())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we create a Qubiter English file and its corresponding Picture file." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "loaded OneQubitGate, WITHOUT autograd.numpy\n" ] } ], "source": [ "from qubiter.device_specific.Qubiter_to_PennyLane import *" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "file_prefix = \"qbtr2penny_test1\"\n", "num_qbits = 3\n", "emb = CktEmbedder(num_qbits, num_qbits)\n", "wr = SEO_writer(file_prefix, emb)\n", "wr.write_H(0)\n", "wr.write_X(1)\n", "wr.write_Y(1)\n", "wr.write_Z(1)\n", "wr.write_cnot(0, 1)\n", "wr.write_cz(0, 1)\n", "wr.write_qbit_swap(1, 0)\n", "wr.write_Rx(2, rads=np.pi)\n", "wr.write_Ry(2, rads=np.pi)\n", "wr.write_Rz(2, rads=np.pi)\n", "wr.write_one_qbit_gate(1, OneQubitGate.P_1_phase_fac, [np.pi])\n", "wr.write_Rn(0, rads_list=[np.pi, np.pi, np.pi])\n", "wr.close_files()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
1
HAD2\tAT\t0
2
SIGX\tAT\t1
3
SIGY\tAT\t1
4
SIGZ\tAT\t1
5
SIGX\tAT\t1\tIF\t0T
6
SIGZ\tAT\t1\tIF\t0T
7
SWAP\t1\t0
8
ROTX\t180.000000\tAT\t2
9
ROTY\t180.000000\tAT\t2
10
ROTZ\t180.000000\tAT\t2
11
P1PH\t180.000000\tAT\t1
12
ROTN\t180.000000\t180.000000\t180.000000\tAT\t0
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "wr.print_eng_file(jup=True)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
1
|   |   H
2
|   X   |
3
|   Y   |
4
|   Z   |
5
|   X---@
6
|   Z---@
7
|   <--->
8
Rx  |   |
9
Ry  |   |
10
Rz  |   |
11
|   @P  |
12
|   |   R
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "wr.print_pic_file(jup=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we translate this to a single PennyLane qnode called Turing" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "aqasm_name = 'PennyL'\n", "qnode_name = 'Turing'\n", "Qubiter_to_PennyLane(file_prefix, num_qbits,\n", " qnode_name,\n", " aqasm_name=aqasm_name,\n", " write_qubiter_files=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following 3 files were generated by the constructor just called:\n", "\n", "1. ../io_folder/qbtr2penny_test1_X1_3_eng.txt\n", "2. ../io_folder/qbtr2penny_test1_X1_3_ZLpic.txt\n", "3. ../io_folder/qbtr2penny_test1_PennyL.py\n", "\n", "Files 1 and 2 are Qubiter style English and Picture files (they differ from the input English file principally in that they include more NOTA lines).\n", "\n", "File 3 is the PennyLane file that we wanted. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " This first example\n", "has no placeholder variables. It just shows that most PennyLane gates are supported." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we create another Qubiter English file and its corresponding Picture file." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "file_prefix = \"qbtr2penny_test2\"\n", "num_qbits = 4\n", "emb = CktEmbedder(num_qbits, num_qbits)\n", "wr = SEO_writer(file_prefix, emb)\n", "wr.write_Rx(2, rads=np.pi/7)\n", "wr.write_Rx(1, rads='#2*.5')\n", "wr.write_Rn(3, rads_list=['#1', '-#1*3', '#2'])\n", "wr.write_Rx(1, rads='-my_fun#2#1')\n", "wr.write_cnot(2, 3)\n", "wr.close_files()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
1
ROTX\t25.714286\tAT\t2
2
ROTX\t#2*.5\tAT\t1
3
ROTN\t#1\t-#1*3\t#2\tAT\t3
4
ROTX\t-my_fun#2#1\tAT\t1
5
SIGX\tAT\t3\tIF\t2T
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "wr.print_eng_file(jup=True)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
1
|   Rx  |   |
2
|   |   Rx  |
3
R   |   |   |
4
|   |   Rx  |
5
X---@   |   |
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "wr.print_pic_file(jup=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we translate this to a single PennyLane qnode called Feynman.\n", "This time, the English file uses a placeholder function called `my_fun`.\n", "All placeholder functions must be\n", "defined beforehand in a file and the\n", "path to that file must be specified via the variable `fun_defs_path`.\n", "In this example, `my_fun` is defined in the following file\n", "\n", "../io_folder/qbtr2penny_test2_fun_defs.py\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "aqasm_name = 'PennyL'\n", "fun_defs_path = 'qbtr2penny_test2_fun_defs.py'\n", "qnode_name = 'Feynman'\n", "Qubiter_to_PennyLane(file_prefix, num_qbits,\n", " qnode_name,\n", " fun_defs_path,\n", " aqasm_name=aqasm_name,\n", " write_qubiter_files=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following 3 files were generated by the constructor just called:\n", "\n", "1. ../io_folder/qbtr2penny_test2_X1_4_eng.txt\n", "2. ../io_folder/qbtr2penny_test2_X1_4_ZLpic.txt\n", "3. ../io_folder/qbtr2penny_test2_PennyL.py\n", "\n", "Files 1 and 2 are Qubiter style English and Picture files (they differ from the input English file principally in that they include more NOTA lines).\n", "\n", "File 3 is the PennyLane file that we wanted. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that\n", "* the argument of gate QubitUnitary() calls the function rot(). This function is\n", "defined internally in the qnode. The translating software automatically copies the def of rot() from\n", "the file `OneQubitGate.py` where it is defined.\n", "* the argument of one of the RX() rotations calls the function my_fun(). This function is defined\n", "internally in the qnode too. The translating software automatically copies the def of my_fun() from\n", "the file at `fun_defs_path`\n", "* We haven't specified what type of object the Hamiltonian hamil is. Ideally, I would like the constructor `Hermitian` to accept a hamil which is an object of the class QubitOperator from the open-source library OpenFermion.\n", "\n", "I haven't tested yet whether this qnode works\n", "in PennyLane, with Rigetti's hardware and with Tensorflow or PyTorch \n", "\n", "This is a particularly demanding test of PennyLane, but I\n", "will consider PennyLane **incomplete** until and unless it can handle this qnode,\n", "or some alternative that accomplishes the same goals.\n", "Incomplete because I feel this qnode uses features that are possible to code and that most users \n", "of Pennylane will want to have them. Tensorflow's back-propagation should be able to\n", "reach inside the user supplied functions my_fun() and rot(),\n", "although the code defining those functions might need some superficial modifications like replacing the `np.` by something else" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" }, "toc": { "colors": { "hover_highlight": "#DAA520", "running_highlight": "#FF0000", "selected_highlight": "#FFD700" }, "moveMenuLeft": true, "nav_menu": { "height": "51px", "width": "252px" }, "navigate_menu": true, "number_sections": true, "sideBar": true, "threshold": 4, "toc_cell": false, "toc_section_display": "block", "toc_window_display": false, "widenNotebook": false } }, "nbformat": 4, "nbformat_minor": 4 }