Skip to content

Commit

Permalink
Get CI green for guides migration (Qiskit#1520)
Browse files Browse the repository at this point in the history
Part of Qiskit#1462

This PR prepares our checks for the guides migration to get green CI
when we make the change. Changes:

- Added API docs links to `ignore.ts`. Those links need to be updated
from the other repos and from the Box artifacts for historical versions.
Once the migration is done we'll have redirects set up for those links
as explained
[here](Qiskit#1461).
- Added some words to the cspell dictionary and fixed other complaints
from the checker
- Added a script to fix the Qiskit bot files by changing the paths to
`guides/`. The PR also changes the ignores we had to `guides/`, leaving
the old ones that should be removed once the migration is done.
- Fixed the `update_internal_links.py` script to switch over more links
and consider the migration guides.
- Added entries for the notebooks with their names on the `guides/`
folder. Once the migration is done, we need to remove the old ones.
  • Loading branch information
arnaucasau authored Jun 14, 2024
1 parent f68dc7c commit c7e2a8b
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/notebook-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ jobs:
with:
# Add your notebook to this list if it needs latex or graphviz to run
files: |
docs/guides/visualize-circuits.ipynb
docs/guides/custom-backend.ipynb
docs/guides/transpiler-stages.ipynb
docs/guides/represent-quantum-computers.ipynb
docs/guides/common-parameters.ipynb
docs/build/circuit-visualization.ipynb
docs/build-new/circuit-visualization.ipynb
docs/transpile/common-parameters.ipynb
Expand Down
3 changes: 3 additions & 0 deletions cspell/dictionaries/qiskit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,7 @@ simulable
resynthesizes
sdist"
transpiling
mthree
Algorithmiq
unphysical

34 changes: 29 additions & 5 deletions scripts/commands/checkQiskitBotFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ import { load } from "js-yaml";
import { globby } from "globby";

const ALLOWED_OWNERLESS_FILES = new Set([
"docs/guides/_toc",
"docs/guides/bit-ordering",
"docs/guides/operators-overview",
"docs/guides/save-circuits",
"docs/guides/create-a-transpiler-plugin",
"docs/guides/custom-backend",
"docs/guides/transpiler-plugins",
"docs/guides/local-testing-mode",
"docs/guides/plot-quantum-states",
"docs/guides/using-ibm-quantum-simulators",
"docs/guides/circuit-execution",
"docs/guides/configure-runtime-compilation",
"docs/guides/execution-modes-faq",
"docs/guides/execution-modes",
"docs/guides/native-gates",
"docs/guides/save-jobs",
"docs/guides/visualize-results",
"docs/guides/create-transpiler-plugin",
"docs/guides/intro-to-patterns",
"docs/guides/optimize-for-hardware",
"docs/guides/postprocess-results",
// Todo: remove the following old paths
"docs/start/_toc",
"docs/build/_toc",
"docs/build/bit-ordering",
Expand All @@ -40,25 +62,27 @@ const ALLOWED_OWNERLESS_FILES = new Set([
]);

const ALLOWED_NONEXISTENT_FILES = new Set([
"docs/build/qubit-order",
"docs/build/operators_overview",
"docs/run/reserve-system-time",
"docs/migration-guides/index",
"docs/migration-guides/qiskit-runtime",
"docs/migration-guides/qiskit-runtime-examples",
"docs/migration-guides/qiskit-quantum-instance",
"docs/migration-guides/qiskit-algorithms-module",
"docs/migration-guides/qiskit-opflow-module",
// Todo: remove or rename the following old paths
"docs/build/qubit-order",
"docs/build/operators_overview",
"docs/run/reserve-system-time",
]);

const GLOBS = [
"docs/migration-guides/*",
"docs/guides/*",
// Todo: remove the following old globs
"docs/start/*",
"docs/build/*",
"docs/transpile/*",
"docs/verify/*",
"docs/run/*",
"docs/migration-guides/*",
"docs/guides/*",
];

async function main() {
Expand Down
18 changes: 18 additions & 0 deletions scripts/lib/links/ignores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ const _QISKIT_UTILS = [
"https://github.com/python-constraint/python-constraint%3E__",
];

const _PATTERNS_REORG_IGNORES = [
"/run/primitives-examples",
"/run/sessions",
"/build/circuit-construction",
"/start/configure-qiskit-local#environment-variables",
"/build/pulse",
"/run",
"/transpile",
"/run/max-execution-time",
"/run/configure-runtime-compilation",
"/run/configure-error-mitigation",
"/start/install#qiskit-versioning",
"/start/configure-qiskit-local",
"/run/primitives-get-started#3-initialize-the-qiskit-runtime-sampler",
"/run/primitives-get-started#3-initialize-qiskit-runtime-estimator",
];

const ALWAYS_IGNORED_URLS__EXPECTED = [
"https://auth.quantum-computing.ibm.com/api",
"https://www.cs.tau.ac.il/~nogaa/PDFS/r.pdf",
Expand All @@ -49,6 +66,7 @@ const ALWAYS_IGNORED_URLS__SHOULD_FIX = [
// Bad anchor in qiskit_ibm_runtime.options.Options.md for 0.14 - 0.16.
"/run/max-execution-time#maximum-execution-time",
..._QISKIT_UTILS,
..._PATTERNS_REORG_IGNORES,
];

export const ALWAYS_IGNORED_URLS = new Set([
Expand Down
35 changes: 33 additions & 2 deletions scripts/nb-tester/notebooks.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
# For notebooks to be tested "normally" (no mocking)
notebooks_normal_test = [
"docs/guides/construct-circuits.ipynb",
"docs/guides/circuit-library.ipynb",
"docs/guides/visualize-circuits.ipynb",
"docs/guides/classical-feedforward-and-control-flow.ipynb",
"docs/guides/operators-overview.ipynb",
"docs/guides/pulse.ipynb",
"docs/guides/save-circuits.ipynb",
"docs/guides/dynamic-circuits-considerations.ipynb",
"docs/guides/error-mitigation-explanation.ipynb",
"docs/guides/get-backend-information.ipynb",
"docs/guides/save-jobs.ipynb",
"docs/guides/visualize-results.ipynb",
"docs/guides/common-parameters.ipynb",
"docs/guides/create-transpiler-plugin.ipynb",
"docs/guides/custom-backend.ipynb",
"docs/guides/custom-transpiler-pass.ipynb",
"docs/guides/defaults-and-configuration-options.ipynb",
"docs/guides/dynamical-decoupling-pass-manager.ipynb",
"docs/guides/represent-quantum-computers.ipynb",
"docs/guides/set-optimization.ipynb",
"docs/guides/transpile-with-pass-managers.ipynb",
"docs/guides/transpiler-plugins.ipynb",
"docs/guides/transpiler-stages.ipynb",
"docs/guides/build-noise-models.ipynb",
"docs/guides/local-testing-mode.ipynb",
"docs/guides/plot-quantum-states.ipynb",
"docs/guides/simulate-with-qiskit-aer.ipynb",
"docs/guides/simulate-stabilizer-circuits.ipynb",
"tutorials/explore-composer/explore-composer.ipynb",
# Todo: remove old notebooks
"docs/build/circuit-construction.ipynb",
"docs/build/circuit-library.ipynb",
"docs/build/circuit-visualization.ipynb",
Expand Down Expand Up @@ -28,7 +58,6 @@ notebooks_normal_test = [
"docs/verify/plot-quantum-states.ipynb",
"docs/verify/simulate-with-qiskit-aer.ipynb",
"docs/verify/stabilizer-circuit-simulation.ipynb",
"tutorials/explore-composer/explore-composer.ipynb",
]

# Don't test the following notebooks (this section can include glob patterns)
Expand All @@ -51,8 +80,10 @@ notebooks_that_submit_jobs = [
# A job is "too big" if a cell can't run in under 5 mins, or we run out of
# memory on a reasonable device.
notebooks_no_mock = [
"docs/start/hello-world.ipynb",
"docs/guides/hello-world.ipynb",
"tutorials/combine-error-mitigation-options-with-the-estimator-primitive/combine-error-mitigation-options-with-the-estimator-primitive.ipynb",
"tutorials/repeat-until-success/repeat-until-success.ipynb",
"tutorials/build-repetition-codes/build-repetition-codes.ipynb",
# Todo: remove old notebook
"docs/start/hello-world.ipynb",
]
6 changes: 3 additions & 3 deletions scripts/patterns-reorg/page_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def postprocess_index_content(index: str) -> str:
This final "post-process results" step of a Qiskit pattern involves stitching the outputs from
the prior step back together to obtain the desired result. This can involve a range of classical
data processing steps such as visualising results, readout error mitigation techniques, marginalizing
data processing steps such as visualizing results, readout error mitigation techniques, marginalizing
quasi-probability distributions to ascertain results on smaller sets of qubits or post-selection on inherent
properties of the problem, such as total spin, parity, or particle conservation by removing
unphysical observables.
Expand Down Expand Up @@ -159,7 +159,7 @@ def patterns_index_content() -> str:
## Optimize for target hardware
In this step you take the abstract circuits (or operators) produced from the map step and perform a series of optimizations on them. This may include mapping the route and layout of the circuit to physical qubit hardware, converting to basis gates of the hardware, and reducing the number of operations, all designed to optimize the likelihood of success in the later execute step. At this point you may also wish to test out your circuits with a simulator before executiong on real hardware in the next step
In this step you take the abstract circuits (or operators) produced from the map step and perform a series of optimizations on them. This may include mapping the route and layout of the circuit to physical qubit hardware, converting to basis gates of the hardware, and reducing the number of operations, all designed to optimize the likelihood of success in the later execute step. At this point you may also wish to test out your circuits with a simulator before executing on real hardware in the next step
During this step abstract circuits must be transpiled to Instruction Set Architecture (ISA) circuits. An ISA circuit is one that only consists of gates understood by the target hardware (basis gates), and any multi-qubit gates needed to obey any connectivity constraints (coupling map). Only ISA circuits can be run on IBM hardware using IBM Qiskit Runtime.
Expand All @@ -174,7 +174,7 @@ def patterns_index_content() -> str:
## Post-process results
This final step involves stitching the outputs from the prior step back together to obtain the desired result. This can involve a range of classical data processing steps such as visualising results, readout error mitigation techniques, marginalizing quasi-probability distributions to ascertain results on smaller sets of qubits or post-selection on inherent properties of the problem, such as total spin, parity, or particle conservation by removing unphysical observables.
This final step involves stitching the outputs from the prior step back together to obtain the desired result. This can involve a range of classical data processing steps such as visualizing results, readout error mitigation techniques, marginalizing quasi-probability distributions to ascertain results on smaller sets of qubits or post-selection on inherent properties of the problem, such as total spin, parity, or particle conservation by removing unphysical observables.
---
Expand Down
26 changes: 20 additions & 6 deletions scripts/patterns-reorg/update_internal_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from main import OLD_FOLDERS, REDIRECTS


def update_link(markdown: str, folder: str, link: str) -> str:
def update_link(markdown: str, folder: str, link: str, prefix: str) -> str:
anchor_index = link.find("#")

if link.startswith("http") or anchor_index == 0:
Expand All @@ -35,9 +35,22 @@ def update_link(markdown: str, folder: str, link: str) -> str:

link_split = link_without_anchor.split("/")
if link.startswith("/") or link.startswith("../"):
search_key = f"{link_split[-2]}/{link_split[-1]}"
if link_split[-2] == "..":
# Match links to a folder like '../../transpile'
search_key = link_split[-1]
else:
if link_split[-1] == "":
# Match links like '../transpile/'
search_key = link_split[-2]
else:
# Match links like '../transpile/index'
search_key = f"{link_split[-2]}/{link_split[-1]}"
else:
search_key = f"{folder}/{link_split[-1]}"
if link_without_anchor == "./":
# Match links with anchors to the index page, e.g. './#example-1'
search_key = f"{folder}"
else:
search_key = f"{folder}/{link_split[-1]}"

if search_key not in REDIRECTS:
return markdown
Expand All @@ -51,19 +64,20 @@ def update_link(markdown: str, folder: str, link: str) -> str:
if link == redirect_to:
return markdown

return markdown.replace(link, f"./{redirect_to}")
return markdown.replace(link, f"{prefix}{redirect_to}")


def main() -> None:
inline_link_re = re.compile(r"\[([^\]]+)\]\(([^)]+)\)")

for folder in OLD_FOLDERS:
for folder in [*OLD_FOLDERS, "api/migration-guides"]:
prefix = "/guides/" if folder == "api/migration-guides" else "./"
for file_path in glob.glob(f"docs/{folder}/*"):
file = Path(file_path)
markdown = file.read_text()
markdown = re.sub(
inline_link_re,
lambda m: update_link(m[0], folder, m[2]),
lambda m: update_link(m[0], folder, m[2], prefix),
markdown,
)
file.write_text(markdown)
Expand Down
86 changes: 86 additions & 0 deletions scripts/patterns-reorg/update_qiskit_bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env python3.11

# This code is a Qiskit project.
#
# (C) Copyright IBM 2024.
#
# This code is licensed under the Apache License, Version 2.0. You may obtain a
# copy of this license in the LICENSE file in the root directory of this source
# tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this copyright
# notice, and modified files need to carry a notice indicating that they have
# been altered from the originals.

import yaml
from textwrap import dedent
from pathlib import Path
from main import OLD_FOLDERS, REDIRECTS


def get_new_qiskit_bot_notifications(qiskit_bot_file_path: str) -> None:
with open(qiskit_bot_file_path, "r") as file:
data = yaml.load(file, Loader=yaml.SafeLoader)

new_entries = {}
for file_path in data["notifications"]:
file_path_split = file_path.split("/")
search_key = f"{file_path_split[-2]}/{file_path_split[-1]}"

if search_key in REDIRECTS:
new_file = REDIRECTS[search_key]
if new_file == "":
new_file = "index"
new_entries[f"docs/guides/{new_file}"] = data["notifications"][file_path]
elif file_path_split[-2] not in OLD_FOLDERS:
# We don't want to modify the migration guides
new_entries[file_path] = data["notifications"][file_path]

return new_entries


def replace_indentation_placeholder(qiskit_bot_file_path: str) -> None:
file = Path(qiskit_bot_file_path)
data = file.read_text()
data = data.replace('"INDENTATION":', "notifications:")
file.write_text(data)


def generate_new_qiskit_bot_file(
qiskit_bot_file_path: str, notifications: dict[str, str]
) -> None:
with open(qiskit_bot_file_path, "w") as file:
file.write(
dedent(
"""\
---
always_notify: true
notification_prelude: |
Thanks for contributing to Qiskit documentation!
Before your PR can be merged, it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. Thanks! 🙌
# We use backticks around users who don`t want a GitHub notification, but whom
# we still want their name in the Qiskit Bot message so people know they are
# relevant.
"""
)
)
# Use a placeholder to have the correct indentation for the notifications
yaml.dump(
{"INDENTATION": notifications},
file,
default_flow_style=False,
default_style='"',
)
replace_indentation_placeholder(qiskit_bot_file_path)


def main() -> None:
qiskit_bot_file_path = "qiskit_bot.yaml"
notifications = get_new_qiskit_bot_notifications(qiskit_bot_file_path)
generate_new_qiskit_bot_file(qiskit_bot_file_path, notifications)


if __name__ == "__main__":
main()

0 comments on commit c7e2a8b

Please sign in to comment.