From 57780670d6832133207ca2dca49b2e8e7e1f8f62 Mon Sep 17 00:00:00 2001 From: Helena Zhang Date: Mon, 6 Nov 2023 13:07:45 -0500 Subject: [PATCH] Update docstring options parser and add docs cron job (#1312) Qiskit 0.45 introduces singleton gates, which have dynamically generated type objects, so their associated module have to be accessed from the `base_class` attribute. This PR update the docstring options parser to work correctly with these objects. It also specifies the `iqp` style when drawing circuits to avoid deprecation warnings during the build, and adds the docs build to the daily cron job so this kind of issue can be caught more quickly in the future. Because Aer 0.13.0 is causing a slowdown in docs builds, this PR also temporarily pins the version to 0.12.2 until the next patch release. (cherry picked from commit f16be3b6d54c395d5846f4869c12fc817883d9b7) # Conflicts: # .github/workflows/cron-staging.yml # docs/tutorials/calibrations.rst # requirements-extras.txt # tox.ini --- .github/workflows/cron-staging.yml | 38 ++++++++++++++++++- docs/_ext/custom_styles/option_parser.py | 7 +++- docs/manuals/characterization/tphi.rst | 6 +-- .../verification/randomized_benchmarking.rst | 6 +-- docs/tutorials/calibrations.rst | 13 +++++-- docs/tutorials/custom_experiment.rst | 6 +-- docs/tutorials/getting_started.rst | 12 +++--- requirements-dev.txt | 1 + requirements-extras.txt | 5 +++ tox.ini | 22 +++++++++++ 10 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 requirements-extras.txt diff --git a/.github/workflows/cron-staging.yml b/.github/workflows/cron-staging.yml index 587439bd7e..9621788167 100644 --- a/.github/workflows/cron-staging.yml +++ b/.github/workflows/cron-staging.yml @@ -43,4 +43,40 @@ jobs: run: tox -e terra-main if: runner.os == 'macOS' env: - OMP_NUM_THREADS: 1 \ No newline at end of file +<<<<<<< HEAD + OMP_NUM_THREADS: 1 +======= + TEST_TIMEOUT: 120 + OMP_NUM_THREADS: 1 + docs: + name: docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: 3.11 + - name: Pip cache + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-docs-${{ hashFiles('setup.py','requirements.txt','requirements-extras.txt','requirements-dev.txt','constraints.txt') }} + - name: Install Deps + run: | + python -m pip install -U tox + sudo apt-get install -y pandoc graphviz + - name: Build Docs + run: tox -edocs-terra-main + - name: Compress Artifacts + run: | + mkdir artifacts + tar -Jcvf html_docs.tar.xz docs/_build/html + mv html_docs.tar.xz artifacts/. + - uses: actions/upload-artifact@v3 + with: + name: html_docs + path: artifacts +>>>>>>> f16be3b (Update docstring options parser and add docs cron job (#1312)) diff --git a/docs/_ext/custom_styles/option_parser.py b/docs/_ext/custom_styles/option_parser.py index bb11b5645b..da9b1e4c70 100644 --- a/docs/_ext/custom_styles/option_parser.py +++ b/docs/_ext/custom_styles/option_parser.py @@ -26,7 +26,7 @@ from sphinx.ext.napoleon import GoogleDocstring -_parameter_doc_regex = re.compile(r'(.+?)\(\s*(.*[^\s]+)\s*\):(.*[^\s]+)') +_parameter_doc_regex = re.compile(r"(.+?)\(\s*(.*[^\s]+)\s*\):(.*[^\s]+)") class QiskitExperimentsOptionsDocstring(GoogleDocstring): @@ -201,8 +201,11 @@ def _value_repr(value: Any) -> str: return f"{{{dict_repr}}}" if value.__class__.__module__ == "builtins": return f":obj:`{value}`" - if value.__class__.__module__.startswith("qiskit"): + if value.__class__.__module__ and value.__class__.__module__.startswith("qiskit"): return f"Instance of :class:`.{value.__class__.__name__}`" + # for singleton gates that don't have directly accessible module names + if hasattr(value, "base_class") and value.base_class.__module__.startswith("qiskit"): + return f"Instance of :class:`.{value.base_class.__name__}`" if callable(value): return f"Callable :func:`{value.__name__}`" if isinstance(value, np.ndarray): diff --git a/docs/manuals/characterization/tphi.rst b/docs/manuals/characterization/tphi.rst index a4748ff749..e59ba0c1a3 100644 --- a/docs/manuals/characterization/tphi.rst +++ b/docs/manuals/characterization/tphi.rst @@ -54,11 +54,11 @@ relaxation time estimate. We can see that the component experiments of the batch .. jupyter-execute:: exp = Tphi(physical_qubits=(0,), delays_t1=delays_t1, delays_t2=delays_t2, num_echoes=1) - exp.component_experiment(0).circuits()[-1].draw("mpl") + exp.component_experiment(0).circuits()[-1].draw(output="mpl", style="iqp") .. jupyter-execute:: - exp.component_experiment(1).circuits()[-1].draw("mpl") + exp.component_experiment(1).circuits()[-1].draw(output="mpl", style="iqp") Run the experiment and print results: @@ -94,7 +94,7 @@ experiment: t2type="ramsey", osc_freq=1e5) - exp.component_experiment(1).circuits()[-1].draw("mpl") + exp.component_experiment(1).circuits()[-1].draw(output="mpl", style="iqp") Run and display results: diff --git a/docs/manuals/verification/randomized_benchmarking.rst b/docs/manuals/verification/randomized_benchmarking.rst index 12381826e7..067d518046 100644 --- a/docs/manuals/verification/randomized_benchmarking.rst +++ b/docs/manuals/verification/randomized_benchmarking.rst @@ -215,20 +215,20 @@ The default RB circuit output shows Clifford blocks: # Run an RB experiment on qubit 0 exp = StandardRB(physical_qubits=(0,), lengths=[2], num_samples=1, seed=seed) c = exp.circuits()[0] - c.draw("mpl") + c.draw(output="mpl", style="iqp") You can decompose the circuit into underlying gates: .. jupyter-execute:: - c.decompose().draw("mpl") + c.decompose().draw(output="mpl", style="iqp") And see the transpiled circuit using the basis gate set of the backend: .. jupyter-execute:: from qiskit import transpile - transpile(c, backend, **vars(exp.transpile_options)).draw("mpl", idle_wires=False) + transpile(c, backend, **vars(exp.transpile_options)).draw(output="mpl", style="iqp", idle_wires=False) .. note:: In 0.5.0, the default value of ``optimization_level`` in ``transpile_options`` changed diff --git a/docs/tutorials/calibrations.rst b/docs/tutorials/calibrations.rst index 63b35f68b6..a0bc6d0303 100644 --- a/docs/tutorials/calibrations.rst +++ b/docs/tutorials/calibrations.rst @@ -168,7 +168,7 @@ Instantiate the experiment and draw the first circuit in the sweep: .. jupyter-execute:: circuit = spec.circuits()[0] - circuit.draw(output="mpl") + circuit.draw(output="mpl", style="iqp") We can also visualize the pulse schedule for the circuit: @@ -221,7 +221,7 @@ with different amplitudes. .. jupyter-execute:: - rabi.circuits()[0].draw("mpl") + rabi.circuits()[0].draw(output="mpl", style="iqp") After the experiment completes the value of the amplitudes in the calibrations will automatically be updated. This behaviour can be controlled using the ``auto_update`` @@ -312,7 +312,7 @@ negative amplitude. from qiskit_experiments.library import RoughDragCal cal_drag = RoughDragCal([qubit], cals, backend=backend, betas=np.linspace(-20, 20, 25)) cal_drag.set_experiment_options(reps=[3, 5, 7]) - cal_drag.circuits()[5].draw(output='mpl') + cal_drag.circuits()[5].draw(output="mpl", style="iqp") .. jupyter-execute:: @@ -389,7 +389,7 @@ over/under rotations is the highest. overamp_exp = FineXAmplitude(qubit, backend=backend) overamp_exp.set_transpile_options(inst_map=inst_map) - overamp_exp.circuits()[4].draw(output='mpl') + overamp_exp.circuits()[4].draw(output="mpl", style="iqp") .. jupyter-execute:: @@ -455,8 +455,13 @@ error which we want to correct. from qiskit_experiments.library import FineSXAmplitudeCal +<<<<<<< HEAD amp_cal = FineSXAmplitudeCal([qubit], cals, backend=backend, schedule_name="sx") amp_cal.circuits()[4].draw(output="mpl") +======= + amp_cal = FineSXAmplitudeCal((qubit,), cals, backend=backend, schedule_name="sx") + amp_cal.circuits()[4].draw(output="mpl", style="iqp") +>>>>>>> f16be3b (Update docstring options parser and add docs cron job (#1312)) Let's run the calibration experiment: diff --git a/docs/tutorials/custom_experiment.rst b/docs/tutorials/custom_experiment.rst index 1fe7f848d8..4f6d97323b 100644 --- a/docs/tutorials/custom_experiment.rst +++ b/docs/tutorials/custom_experiment.rst @@ -547,7 +547,7 @@ Let's use a GHZ circuit as the input: for i in range(1, nq): qc.cx(i-1, i) - qc.draw("mpl") + qc.draw(output="mpl", style="iqp") Check that the experiment is appending a random Pauli and measurements as expected: @@ -560,7 +560,7 @@ Check that the experiment is appending a random Pauli and measurements as expect # Run ideal randomized meas experiment exp = RandomizedMeasurement(qc, num_samples=num_samples) - exp.circuits()[0].draw("mpl") + exp.circuits()[0].draw(output="mpl", style="iqp") We now run the experiment with a GHZ circuit on an ideal backend, whic produces nearly perfect symmetrical results between :math:`|0000\rangle` and :math:`|1111\rangle`: @@ -614,4 +614,4 @@ unaffected by the added randomized measurements, which use its own classical reg qc.cx(i-1, i) exp = RandomizedMeasurement(qc, num_samples=num_samples) - exp.circuits()[0].draw("mpl") \ No newline at end of file + exp.circuits()[0].draw(output="mpl", style="iqp") \ No newline at end of file diff --git a/docs/tutorials/getting_started.rst b/docs/tutorials/getting_started.rst index e0ddfaa48b..eeb90982bf 100644 --- a/docs/tutorials/getting_started.rst +++ b/docs/tutorials/getting_started.rst @@ -94,11 +94,11 @@ first and last circuits for our :math:`T_1` experiment: .. jupyter-execute:: print(delays) - exp.circuits()[0].draw(output='mpl') + exp.circuits()[0].draw(output="mpl", style="iqp") .. jupyter-execute:: - exp.circuits()[-1].draw(output='mpl') + exp.circuits()[-1].draw(output="mpl", style="iqp") As expected, the delay block spans the full range of time values that we specified. @@ -320,11 +320,11 @@ child experiments can be accessed via the .. jupyter-execute:: - parallel_exp.component_experiment(0).circuits()[0].draw(output='mpl') + parallel_exp.component_experiment(0).circuits()[0].draw(output="mpl", style="iqp") .. jupyter-execute:: - parallel_exp.component_experiment(1).circuits()[0].draw(output='mpl') + parallel_exp.component_experiment(1).circuits()[0].draw(output="mpl", style="iqp") The circuits of all experiments assume they're acting on virtual qubits starting from index 0. In the case of a parallel experiment, the child experiment @@ -332,7 +332,7 @@ circuits are composed together and then reassigned virtual qubit indices: .. jupyter-execute:: - parallel_exp.circuits()[0].draw(output='mpl') + parallel_exp.circuits()[0].draw(output="mpl", style="iqp") During experiment transpilation, a mapping is performed to place these circuits on the physical layout. We can see its effects by looking at the transpiled @@ -342,7 +342,7 @@ and the :class:`.StandardRB` experiment's gates are on physical qubits 3 and 1. .. jupyter-execute:: - parallel_exp._transpiled_circuits()[0].draw(output='mpl') + parallel_exp._transpiled_circuits()[0].draw(output="mpl", style="iqp") :class:`.ParallelExperiment` and :class:`.BatchExperiment` classes can also be nested arbitrarily to make complex composite experiments. diff --git a/requirements-dev.txt b/requirements-dev.txt index 4ac3de7dd2..2bd51d2ec9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,4 @@ +qiskit-terra>=0.45.0 black~=22.0 stestr pylint~=2.16.2 diff --git a/requirements-extras.txt b/requirements-extras.txt new file mode 100644 index 0000000000..25689a0858 --- /dev/null +++ b/requirements-extras.txt @@ -0,0 +1,5 @@ +qiskit-ibm-provider>=0.6.1 # for submitting experiments to backends through the IBM provider +cvxpy>=1.3.2 # for tomography +scikit-learn # for discriminators +qiskit-aer>=0.11.0,<=0.12.2 # temporary version pin until 0.13.1 release +qiskit_dynamics>=0.4.0 # for the PulseBackend diff --git a/tox.ini b/tox.ini index 96ce53e543..5455e6b1bd 100644 --- a/tox.ini +++ b/tox.ini @@ -75,7 +75,29 @@ setenv = commands = sphinx-build -T -W --keep-going -b html {posargs} docs/ docs/_build/html +<<<<<<< HEAD [pycodestyle] max-line-length = 100 +======= +[testenv:docs-terra-main] +usedevelop = True +passenv = + EXPERIMENTS_DEV_DOCS + PROD_BUILD + RELEASE_STRING + VERSION_STRING +deps = + git+https://github.com/Qiskit/qiskit-terra + -r{toxinidir}/requirements-dev.txt + -r{toxinidir}/requirements-extras.txt +commands = + sphinx-build -j auto -T -W --keep-going -b html {posargs} docs/ docs/_build/html + +[testenv:docs-clean] +skip_install = true +deps = +allowlist_externals = rm +commands = rm -rf {toxinidir}/docs/stubs/ {toxinidir}/docs/_build +>>>>>>> f16be3b (Update docstring options parser and add docs cron job (#1312))