{
"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
}