From fee97b8c24ca0b420c32577e5c261bd7a377cce8 Mon Sep 17 00:00:00 2001 From: Matthew Harrigan Date: Tue, 7 Dec 2021 15:26:49 -0800 Subject: [PATCH 1/3] Add dev_tools/check_notebooks.py Change-Id: I578c7a45d1946d89b8de1ca15d3353ccc8578f76 --- dev_tools/.gitignore | 1 + dev_tools/check_notebooks.py | 103 ++++++++++++++++++++++++++ docs/qaoa/optimization_analysis.ipynb | 21 ++++++ 3 files changed, 125 insertions(+) create mode 100644 dev_tools/.gitignore create mode 100644 dev_tools/check_notebooks.py diff --git a/dev_tools/.gitignore b/dev_tools/.gitignore new file mode 100644 index 00000000..fd02abca --- /dev/null +++ b/dev_tools/.gitignore @@ -0,0 +1 @@ +notebook_envs \ No newline at end of file diff --git a/dev_tools/check_notebooks.py b/dev_tools/check_notebooks.py new file mode 100644 index 00000000..ea49971a --- /dev/null +++ b/dev_tools/check_notebooks.py @@ -0,0 +1,103 @@ +import os +import shutil +import time +from multiprocessing import Pool +from subprocess import run as _run, CalledProcessError + +BASE_PACKAGES = [ + # for running the notebooks + "jupyter", + # assumed to be part of colab + "seaborn~=0.11.1", +] + + +def _check_notebook(notebook_fn, notebook_id, stdout, stderr): + """Helper function to actually do the work in `check_notebook`. + + `check_notebook` has all the context managers and exception handling, + which would otherwise result in highly indented code. + """ + print(f'Starting {notebook_id}') + + def run(*args, **kwargs): + return _run(*args, check=True, stdout=stdout, stderr=stderr, **kwargs) + + # 1. create venv + venv_dir = os.path.abspath(f'./notebook_envs/{notebook_id}') + run(['python', '-m', 'venv', '--clear', venv_dir]) + + # 2. basic colab-like environment + pip = f'{venv_dir}/bin/pip' + run([pip, 'install'] + BASE_PACKAGES) + + # 3. execute + jupyter = f'{venv_dir}/bin/jupyter' + env = os.environ.copy() + env['PATH'] = f'{venv_dir}/bin:{env["PATH"]}' + run([jupyter, 'nbconvert', '--to', 'html', '--execute', notebook_fn], cwd='../', env=env) + + # 4. clean up + shutil.rmtree(venv_dir) + + +def check_notebook(notebook_fn): + """Check a notebook. + + 1. Create a venv just for that notebook + 2. Verify the notebook executes without error (and that it installs its own dependencies!) + 3. Clean up venv dir + + A scratch directory dev_tools/notebook_envs will be created containing tvenv as well as + stdout and stderr logs for each notebook. Each of these files and directories will be + named according to the "notebook_id", which is `notebook_fn.replace('/', '-')`. + + The executed notebook will be rendered to html alongside its original .ipynb file for + spot-checking. + + Args: + notebook_fn: The filename of the notebook relative to the repo root. + """ + notebook_id = notebook_fn.replace('/', '-') + start = time.perf_counter() + with open(f'./notebook_envs/{notebook_id}.stdout', 'w') as stdout, \ + open(f'./notebook_envs/{notebook_id}.stderr', 'w') as stderr: + try: + _check_notebook(notebook_fn, notebook_id, stdout, stderr) + except CalledProcessError: + print('ERROR!', notebook_id) + end = time.perf_counter() + print(f'{notebook_id} {end - start:.1f}s') + + +NOTEBOOKS = [ + 'docs/otoc/otoc_example.ipynb', + 'docs/guide/data_analysis.ipynb', + 'docs/guide/data_collection.ipynb', + 'docs/qaoa/example_problems.ipynb', + 'docs/qaoa/precomputed_analysis.ipynb', + 'docs/qaoa/hardware_grid_circuits.ipynb', + 'docs/qaoa/optimization_analysis.ipynb', + 'docs/qaoa/tasks.ipynb', + 'docs/qaoa/landscape_analysis.ipynb', + 'docs/qaoa/routing_with_tket.ipynb', + 'docs/quantum_chess/concepts.ipynb', + # 'docs/quantum_chess/quantum_chess_rest_api.ipynb', # runs a server, never finishes. + # 'docs/quantum_chess/quantum_chess_client.ipynb', # uses the server, requires modification. + 'docs/hfvqe/molecular_data.ipynb', + 'docs/hfvqe/quickstart.ipynb', + 'docs/fermi_hubbard/publication_results.ipynb', + 'docs/fermi_hubbard/experiment_example.ipynb', +] + + +def main(): + os.chdir(os.path.dirname(__file__)) + os.makedirs('./notebook_envs', exist_ok=True) + with Pool(4) as pool: + results = pool.map(check_notebook, NOTEBOOKS) + print(results) + + +if __name__ == '__main__': + main() diff --git a/docs/qaoa/optimization_analysis.ipynb b/docs/qaoa/optimization_analysis.ipynb index 6fb6e173..f875e30a 100644 --- a/docs/qaoa/optimization_analysis.ipynb +++ b/docs/qaoa/optimization_analysis.ipynb @@ -62,6 +62,27 @@ "" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "\n", + "Install the ReCirq package:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " import recirq\n", + "except ImportError:\n", + " !pip install -q git+https://github.com/quantumlib/ReCirq sympy~=1.6" + ] + }, { "cell_type": "markdown", "metadata": { From bfe32d0fa4ec287ed41220b1ceb916fd42022210 Mon Sep 17 00:00:00 2001 From: Matthew Harrigan Date: Wed, 8 Dec 2021 10:51:59 -0800 Subject: [PATCH 2/3] docs Change-Id: I07c189f27b2c7c2adcf184e56437abab2e8eafe8 --- dev_tools/check_notebooks.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dev_tools/check_notebooks.py b/dev_tools/check_notebooks.py index ea49971a..04f15c18 100644 --- a/dev_tools/check_notebooks.py +++ b/dev_tools/check_notebooks.py @@ -12,11 +12,17 @@ ] -def _check_notebook(notebook_fn, notebook_id, stdout, stderr): +def _check_notebook(notebook_fn: str, notebook_id: str, stdout, stderr): """Helper function to actually do the work in `check_notebook`. `check_notebook` has all the context managers and exception handling, which would otherwise result in highly indented code. + + Args: + notebook_fn: The notebook filename + notebook_id: A unique string id for the notebook that does not include `/` + stdout: A file-like object to redirect stdout + stderr: A file-like object to redirect stderr """ print(f'Starting {notebook_id}') @@ -41,7 +47,7 @@ def run(*args, **kwargs): shutil.rmtree(venv_dir) -def check_notebook(notebook_fn): +def check_notebook(notebook_fn: str): """Check a notebook. 1. Create a venv just for that notebook From 13d042935e61ddbaee974c85fad0baa594e1bef2 Mon Sep 17 00:00:00 2001 From: Matthew Harrigan Date: Wed, 8 Dec 2021 11:50:48 -0800 Subject: [PATCH 3/3] nbfmt Change-Id: I4308d149b9f088f565c68aad304ad6ee420e976b --- docs/qaoa/optimization_analysis.ipynb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/qaoa/optimization_analysis.ipynb b/docs/qaoa/optimization_analysis.ipynb index f875e30a..1241317c 100644 --- a/docs/qaoa/optimization_analysis.ipynb +++ b/docs/qaoa/optimization_analysis.ipynb @@ -64,7 +64,9 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "id": "314b4703b85b" + }, "source": [ "## Setup\n", "\n", @@ -74,7 +76,9 @@ { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "id": "ca9285a3a162" + }, "outputs": [], "source": [ "try:\n",