Skip to content

Commit

Permalink
Move Cirq-FT infrastructure to Qualtran
Browse files Browse the repository at this point in the history
  • Loading branch information
tanujkhattar committed Oct 12, 2023
1 parent bb4af36 commit 8842c4d
Show file tree
Hide file tree
Showing 18 changed files with 2,454 additions and 155 deletions.
2 changes: 2 additions & 0 deletions qualtran/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@
Soquet,
)

from ._infra.gate_with_registers import GateWithRegisters

# --------------------------------------------------------------------------------------------------
244 changes: 244 additions & 0 deletions qualtran/_infra/gate_with_registers.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "3b990f88",
"metadata": {},
"outputs": [],
"source": [
"# Copyright 2023 The Cirq Developers\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"id": "bf9c80ce",
"metadata": {},
"source": [
"# Gate with Registers\n",
"\n",
"This package includes a subclass of `cirq.Gate` called `GateWithRegisters`. Instead of operating on a flat list of `cirq.Qid`, this lets the developer define gates in terms of named registers of given widths."
]
},
{
"cell_type": "markdown",
"id": "c0833444",
"metadata": {},
"source": [
"## `Signature`\n",
"\n",
"`Register` objects have a name, a bitsize and a shape. `Signature` is an ordered collection of `Register` with some helpful methods."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c75414f2",
"metadata": {},
"outputs": [],
"source": [
"from qualtran import Register, Signature\n",
"\n",
"control_reg = Register(name='control', bitsize=2)\n",
"target_reg = Register(name='target', bitsize=3)\n",
"control_reg, target_reg"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b38d210c",
"metadata": {},
"outputs": [],
"source": [
"r = Signature([control_reg, target_reg])\n",
"r"
]
},
{
"cell_type": "markdown",
"id": "2b32274b",
"metadata": {},
"source": [
"You can also use the `build` factory method to quickly define a set of registers"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4f10e66e",
"metadata": {},
"outputs": [],
"source": [
"r == Signature.build(\n",
" control=2,\n",
" target=3,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "a5955208",
"metadata": {},
"source": [
"### `GateWithRegisters`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b3957db4",
"metadata": {},
"outputs": [],
"source": [
"import cirq\n",
"from qualtran import GateWithRegisters\n",
"\n",
"class MyGate(GateWithRegisters):\n",
" \n",
" @property\n",
" def signature(self):\n",
" return Signature.build(\n",
" control=2,\n",
" target=3,\n",
" )\n",
" \n",
" def decompose_from_registers(self, context, control, target):\n",
" assert len(control) == 2\n",
" assert len(target) == 3\n",
" \n",
" for c in control:\n",
" for t in target:\n",
" yield cirq.CNOT(c, t)\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2de931eb",
"metadata": {},
"outputs": [],
"source": [
"gate = MyGate()\n",
"gate"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef98f3a2",
"metadata": {},
"outputs": [],
"source": [
"# Number of qubits is derived from registers\n",
"cirq.num_qubits(gate)"
]
},
{
"cell_type": "markdown",
"id": "2d725646",
"metadata": {},
"source": [
"The `Signature` object can allocate a dictionary of `cirq.NamedQubit` that we can use to turn our `Gate` into an `Operation`. `GateWithRegisters` exposes an `on_registers` method to compliment Cirq's `on` method where we can use names to make sure each qubit is used appropriately."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "057148da",
"metadata": {},
"outputs": [],
"source": [
"from qualtran._infra.gate_with_registers import get_named_qubits\n",
"\n",
"r = gate.signature\n",
"quregs = get_named_qubits(r)\n",
"quregs"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0257d8f1",
"metadata": {},
"outputs": [],
"source": [
"operation = gate.on_registers(**quregs)\n",
"operation"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "541f2e91",
"metadata": {},
"outputs": [],
"source": [
"from cirq.contrib.svg import SVGCircuit\n",
"SVGCircuit(cirq.Circuit(operation))"
]
},
{
"cell_type": "markdown",
"id": "6686f7f8",
"metadata": {},
"source": [
"## `GateHelper`\n",
"\n",
"Since `GateWithRegisters` contains enough metadata to derive qubits, an operation, and a circuit we provide a helper class to provide easy access to these quantities."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "93a6c8f2",
"metadata": {},
"outputs": [],
"source": [
"import qualtran.cirq_interop.testing as cq_testing\n",
"\n",
"g = cq_testing.GateHelper(gate)\n",
"\n",
"print('r:', g.r)\n",
"print('quregs:', g.quregs)\n",
"print('operation:', g.operation)\n",
"print('\\ncircuit:\\n', g.circuit)\n",
"print('\\n\\ndecomposed circuit:\\n', cirq.Circuit(cirq.decompose_once(g.operation)))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.8.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading

0 comments on commit 8842c4d

Please sign in to comment.