-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Infra: Combine manual and examples build #339
Changes from 62 commits
ab8fdb8
3e6d7e1
64e9f8e
706209c
6262306
19b25f6
395903e
89005ec
376c32d
254379b
5b1dc32
890dfc1
0113fd8
f217f47
b3b95f6
baa75a7
098e19d
f87c73b
645621d
a688a93
bee3d85
db94684
c3efce3
90e297b
65c105f
3c88171
9547785
bea0a70
f5489fa
137493c
65038c8
87084cd
3cdaa66
f654414
ede0492
0f6d5e7
d3b421a
031a684
1479596
0bba024
2962f8d
30a77c7
95ca70b
d3d224b
4bcf70d
70337bd
33e898f
dc3d84d
7d943ea
c6aff9f
383f475
bc85f1e
37c912f
d3d2d94
716c653
cf6d705
5678ddc
be15f3c
1faa830
9e59a43
a510eee
0ca986d
e40cc4e
d053f9a
73f38a3
cabf99b
31953ef
2e9ce32
8dd5008
0540dbe
189c4f8
abcfe33
8b69648
4579038
141c4ae
9f2fb02
b141e14
1d9c807
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: check manual | ||
name: check docs build | ||
|
||
on: | ||
pull_request: | ||
|
@@ -28,35 +28,28 @@ jobs: | |
- '.github/**' | ||
|
||
check: | ||
name: check manual | ||
name: check docs build | ||
needs: changes | ||
if: github.event_name == 'schedule' || needs.changes.outputs.manual == 'true' | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
submodules: true | ||
fetch-depth: '0' | ||
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* +refs/heads/*:refs/remotes/origin/* | ||
- name: Set up Python 3.11 | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: 3.11 | ||
- name: install python requirements for manual | ||
- name: install python requirements for docs | ||
run: | | ||
python -m pip install --upgrade pip | ||
python -m pip install wheel | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The removed packages are now all in poetry? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, with the exception of the The furo theme is used instead. |
||
python -m pip install -c manual_constraints.txt sphinx sphinx-book-theme jupyter-sphinx quimb | ||
python -m pip install -r manual_requirements.txt | ||
python -m pip install kahypar | ||
python -m pip install sphinx-copybutton | ||
python -m pip install ipyparallel | ||
python -m pip install qiskit-algorithms | ||
python -m pip install poetry | ||
poetry install | ||
- name: install graphviz | ||
run: | | ||
sudo apt-get update | ||
sudo apt-get install graphviz | ||
- name: build manual | ||
sudo apt-get update | ||
sudo apt-get install graphviz | ||
- name: build manual and examples | ||
run: | | ||
cd manual/ | ||
sed "s/REQUIREMENTS/$(sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' ../manual_requirements.txt | tr -d '\n')/" index-rst-template > index.rst | ||
sphinx-build -b html . build -W | ||
poetry run ./build-docs.sh |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[submodule "docs/quantinuum-sphinx"] | ||
path = docs/quantinuum-sphinx | ||
url = https://github.com/CQCL/quantinuum-sphinx.git | ||
branch = dist | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a protected branch? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure Is it protected @aidanCQ ? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/sh | ||
|
||
cd docs/ | ||
|
||
rm -rf build/ | ||
sphinx-build -b html . build -W | ||
|
This file was deleted.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this used for? Do we still need it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this file is needed. |
cqc-melf marked this conversation as resolved.
Show resolved
Hide resolved
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
const navConfig = { | ||
|
||
"navTextLinks": [ | ||
{ | ||
"title": "API Docs", | ||
"href": "../api-docs", | ||
"pathMatch": "somewhere", | ||
}, | ||
{ | ||
"title": "Blog", | ||
"href": "../blog/", | ||
"pathMatch": "somewhere", | ||
}, | ||
{ | ||
"title": "User Guide", | ||
"href": "../user-guide", | ||
"pathMatch": "somewhere", | ||
}, | ||
], | ||
"navProductName": "TKET", | ||
"navIconLinks": [ | ||
{ | ||
"title": "TKET Github", | ||
"href": "https://github.com/CQCL/tket", | ||
"pathMatch": "somewhere", | ||
"iconImageURL": "_static/assets/github.svg", | ||
}, | ||
{ | ||
"title": "TKET Slack Channel", | ||
"href": "https://tketusers.slack.com/", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a valid invite link? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked this and it seems to go to the correct page for people not in the workspace. |
||
"pathMatch": "somewhere", | ||
"iconImageURL": "_static/assets/slack.svg", | ||
}, | ||
{ | ||
"title": "TKET Stack Exchange", | ||
"href": "https://quantumcomputing.stackexchange.com/questions/tagged/pytket", | ||
"pathMatch": "somewhere", | ||
"iconImageURL": "_static/assets/stack.svg", | ||
}, | ||
], | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Configuration file for the Sphinx documentation builder. | ||
# See https://www.sphinx-doc.org/en/master/usage/configuration.html | ||
|
||
copyright = "2020-2024, Quantinuum" | ||
author = "Quantinuum" | ||
|
||
|
||
html_title = "pytket user guide" | ||
|
||
extensions = [ | ||
"sphinx.ext.intersphinx", | ||
"sphinx.ext.mathjax", | ||
"jupyter_sphinx", | ||
"sphinx_copybutton", | ||
"sphinx.ext.autosectionlabel", | ||
"myst_nb", | ||
] | ||
|
||
myst_enable_extensions = ["dollarmath", "html_image", "attrs_inline"] | ||
|
||
html_theme = "furo" | ||
templates_path = ["./quantinuum-sphinx/_templates/"] | ||
html_static_path = ["./quantinuum-sphinx/_static/", "_static/"] | ||
|
||
pytketdoc_base = "https://tket.quantinuum.com/api-docs/" | ||
|
||
intersphinx_mapping = { | ||
"python": ("https://docs.python.org/3/", None), | ||
"pytket": (pytketdoc_base, None), | ||
"qiskit": ("https://docs.quantum.ibm.com/api/qiskit", None), | ||
"pytket-qiskit": ("https://tket.quantinuum.com/extensions/pytket-qiskit/", None), | ||
cqc-melf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"pytket-quantinuum": ( | ||
"https://tket.quantinuum.com/extensions/pytket-quantinuum/", | ||
None, | ||
), | ||
"sympy": ("https://docs.sympy.org/latest/", None), | ||
} | ||
|
||
|
||
nb_execution_mode = "cache" | ||
|
||
nb_execution_excludepatterns = [ | ||
"examples/backends/Forest_portability_example.ipynb", | ||
"examples/backends/backends_example.ipynb", | ||
"examples/backends/qiskit_integration.ipynb", | ||
"examples/backends/comparing_simulators.ipynb", | ||
"examples/algorithms_and_protocols/expectation_value_example.ipynb", | ||
"examples/algorithms_and_protocols/pytket-qujax_heisenberg_vqe.ipynb", | ||
"examples/algorithms_and_protocols/spam_example.ipynb", | ||
"examples/algorithms_and_protocols/entanglement_swapping.ipynb", | ||
] | ||
|
||
exclude_patterns = ["jupyter_execute/*", ".jupyter_cache", "manual/README.md"] |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should I review the notebooks, or are they just moved? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry diff is misleading. I have just moved the files. I haven't changed the content |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"cells":[{"cell_type":"markdown","metadata":{},"source":["# Ansatz sequencing\n","\n","**Download this notebook - {nb-download}`ansatz_sequence_example.ipynb`**"]},{"cell_type":"markdown","metadata":{},"source":["When performing variational algorithms like VQE, one common approach to generating circuit ansätze is to take an operator $U$ representing excitations and use this to act on a reference state $\\lvert \\phi_0 \\rangle$. One such ansatz is the Unitary Coupled Cluster ansatz. Each excitation, indexed by $j$, within $U$ is given a real coefficient $a_j$ and a parameter $t_j$, such that $U = e^{i \\sum_j \\sum_k a_j t_j P_{jk}}$, where $P_{jk} \\in \\{I, X, Y, Z \\}^{\\otimes n}$. The exact form is dependent on the chosen qubit encoding. This excitation gives us a variational state $\\lvert \\psi (t) \\rangle = U(t) \\lvert \\phi_0 \\rangle$. The operator $U$ must be Trotterised, to give a product of Pauli exponentials, and converted into native quantum gates to create the ansatz circuit.<br>\n","<br>\n","This notebook will describe how to use an advanced feature of `pytket` to enable automated circuit synthesis for $U$ and reduce circuit depth dramatically.<br>\n","<br>\n","We must create a `pytket` `QubitPauliOperator`, which represents such an operator $U$, and contains a dictionary from Pauli string $P_{jk}$ to symbolic expression. Here, we make a mock operator ourselves, which resembles the UCCSD excitation operator for the $\\mathrm{H}_2$ molecule using the Jordan-Wigner qubit encoding.<br>\n","<br>\n","First, we create a series of `QubitPauliString` objects, which represent each $P_{jk}$."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["from pytket.pauli import Pauli, QubitPauliString\n","from pytket.circuit import Qubit"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["q = [Qubit(i) for i in range(4)]\n","qps0 = QubitPauliString([q[0], q[1], q[2]], [Pauli.Y, Pauli.Z, Pauli.X])\n","qps1 = QubitPauliString([q[0], q[1], q[2]], [Pauli.X, Pauli.Z, Pauli.Y])\n","qps2 = QubitPauliString(q, [Pauli.X, Pauli.X, Pauli.X, Pauli.Y])\n","qps3 = QubitPauliString(q, [Pauli.X, Pauli.X, Pauli.Y, Pauli.X])\n","qps4 = QubitPauliString(q, [Pauli.X, Pauli.Y, Pauli.X, Pauli.X])\n","qps5 = QubitPauliString(q, [Pauli.Y, Pauli.X, Pauli.X, Pauli.X])"]},{"cell_type":"markdown","metadata":{},"source":["Now, create some symbolic expressions for the $a_j t_j$ terms."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["from pytket.circuit import fresh_symbol"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["symbol1 = fresh_symbol(\"s0\")\n","expr1 = 1.2 * symbol1\n","symbol2 = fresh_symbol(\"s1\")\n","expr2 = -0.3 * symbol2"]},{"cell_type":"markdown","metadata":{},"source":["We can now create our `QubitPauliOperator`."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["from pytket.utils import QubitPauliOperator"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["dict1 = dict((string, expr1) for string in (qps0, qps1))\n","dict2 = dict((string, expr2) for string in (qps2, qps3, qps4, qps5))\n","operator = QubitPauliOperator({**dict1, **dict2})\n","print(operator)"]},{"cell_type":"markdown","metadata":{},"source":["Now we can let `pytket` sequence the terms in this operator for us, using a selection of strategies. First, we will create a `Circuit` to generate an example reference state, and then use the `gen_term_sequence_circuit` method to append the Pauli exponentials."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["from pytket.circuit import Circuit\n","from pytket.utils import gen_term_sequence_circuit\n","from pytket.partition import PauliPartitionStrat, GraphColourMethod"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["reference_circ = Circuit(4).X(1).X(3)\n","ansatz_circuit = gen_term_sequence_circuit(\n"," operator, reference_circ, PauliPartitionStrat.CommutingSets, GraphColourMethod.Lazy\n",")"]},{"cell_type":"markdown","metadata":{},"source":["This method works by generating a graph of Pauli exponentials and performing graph colouring. Here we have chosen to partition the terms so that exponentials which commute are gathered together, and we have done so using a lazy, greedy graph colouring method.<br>\n","<br>\n","Alternatively, we could have used the `PauliPartitionStrat.NonConflictingSets`, which puts Pauli exponentials together so that they only require single-qubit gates to be converted into the form $e^{i \\alpha Z \\otimes Z \\otimes ... \\otimes Z}$. This strategy is primarily useful for measurement reduction, a different problem.<br>\n","<br>\n","We could also have used the `GraphColourMethod.LargestFirst`, which still uses a greedy method, but builds the full graph and iterates through the vertices in descending order of arity. We recommend playing around with the options, but we typically find that the combination of `CommutingSets` and `Lazy` allows the best optimisation.<br>\n","<br>\n","In general, not all of our exponentials will commute, so the semantics of our circuit depend on the order of our sequencing. As a result, it is important for us to be able to inspect the order we have produced. `pytket` provides functionality to enable this. Each set of commuting exponentials is put into a `CircBox`, which lets us inspect the partitoning."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["from pytket.circuit import OpType"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["for command in ansatz_circuit:\n"," if command.op.type == OpType.CircBox:\n"," print(\"New CircBox:\")\n"," for pauli_exp in command.op.get_circuit():\n"," print(\n"," \" {} {} {}\".format(\n"," pauli_exp, pauli_exp.op.get_paulis(), pauli_exp.op.get_phase()\n"," )\n"," )\n"," else:\n"," print(\"Native gate: {}\".format(command))"]},{"cell_type":"markdown","metadata":{},"source":["We can convert this circuit into basic gates using a `pytket` `Transform`. This acts in place on the circuit to do rewriting, for gate translation and optimisation. We will start off with a naive decomposition."]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["from pytket.transform import Transform"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["naive_circuit = ansatz_circuit.copy()\n","Transform.DecomposeBoxes().apply(naive_circuit)\n","print(naive_circuit.get_commands())"]},{"cell_type":"markdown","metadata":{},"source":["This is a jumble of one- and two-qubit gates. We can get some relevant circuit metrics out:"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["print(\"Naive CX Depth: {}\".format(naive_circuit.depth_by_type(OpType.CX)))\n","print(\"Naive CX Count: {}\".format(naive_circuit.n_gates_of_type(OpType.CX)))"]},{"cell_type":"markdown","metadata":{},"source":["These metrics can be improved upon significantly by smart compilation. A `Transform` exists precisely for this purpose:"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["from pytket.transform import PauliSynthStrat, CXConfigType"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["smart_circuit = ansatz_circuit.copy()\n","Transform.UCCSynthesis(PauliSynthStrat.Sets, CXConfigType.Tree).apply(smart_circuit)\n","print(\"Smart CX Depth: {}\".format(smart_circuit.depth_by_type(OpType.CX)))\n","print(\"Smart CX Count: {}\".format(smart_circuit.n_gates_of_type(OpType.CX)))"]},{"cell_type":"markdown","metadata":{},"source":["This `Transform` takes in a `Circuit` with the structure specified above: some arbitrary gates for the reference state, along with several `CircBox` gates containing `PauliExpBox` gates.<br>\n","<br>\n","We have chosen `PauliSynthStrat.Sets` and `CXConfigType.Tree`. The `PauliSynthStrat` dictates the method for decomposing multiple adjacent Pauli exponentials into basic gates, while the `CXConfigType` dictates the structure of adjacent CX gates.<br>\n","<br>\n","If we choose a different combination of strategies, we can produce a different output circuit:"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["last_circuit = ansatz_circuit.copy()\n","Transform.UCCSynthesis(PauliSynthStrat.Individual, CXConfigType.Snake).apply(\n"," last_circuit\n",")\n","print(last_circuit.get_commands())"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["print(\"Last CX Depth: {}\".format(last_circuit.depth_by_type(OpType.CX)))\n","print(\"Last CX Count: {}\".format(last_circuit.n_gates_of_type(OpType.CX)))"]},{"cell_type":"markdown","metadata":{},"source":["Other than some single-qubit Cliffords we acquired via synthesis, you can check that this gives us the same circuit structure as our `Transform.DecomposeBoxes` method! It is a suboptimal synthesis method.<br>\n","<br>\n","As with the `gen_term_sequence` method, we recommend playing around with the arguments and seeing what circuits come out. Typically we find that `PauliSynthStrat.Sets` and `CXConfigType.Tree` work the best, although routing can affect this somewhat."]}],"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.6.4"}},"nbformat":4,"nbformat_minor":2} |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know if there is a reason why we are not using
ubuntu-latest
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. I can use the latest if you'd prefer?