Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Local setup

This repository uses uv for the Python environment and focused Julia projects under notebooks_jl/environments/.

Install Julia

If you do not have a Julia installation yet, consider using juliaup, which installs Julia and keeps several versions side by side. The Julia notebook projects carry locks for Julia 1.10.11 and Julia 1.12.6.

Instantiate the notebook project once from the repository root:

julia --project=notebooks_jl -e 'using Pkg; Pkg.instantiate()'

Each Julia notebook activates that project when it runs locally. In Colab the bootstrap selects the focused project under notebooks_jl/environments/<notebook-key> instead, so no manual installation step is needed there.

To report the version you are actually running, start Julia and call versioninfo(). Instantiating against an incompatible release fails at the notebook’s setup cell, so this is a diagnostic rather than a required step.

Build the book

From the repository root, install the locked documentation environment and build the static site:

uv sync --locked --group docs
make build-book

Jupyter Book 2 also uses Node.js; confirm that node and npm are available if the build reports a missing frontend tool. The generated site is written to _build/html/. Serve it instead of opening index.html directly:

python -m http.server --directory _build/html

Open the URL printed by the server. make build-book targets a site root by default; CI sets BASE_URL=/QUBONotebooks for the GitHub Pages project path.

Execute notebooks

Portable and credential-free execution targets write refreshed copies to .nbverify/:

make verify-python-portable
make verify-dwave-python-local
make verify-qci-julia-local
make verify-five-starter-problems-julia-local

Additional targets and environment details are listed in the repository README. In particular, Julia notebooks activate their own focused projects, and the Python QCI notebook uses a separate dependency environment from the D-Wave notebooks because their NetworkX constraints conflict.

All Python notebook verification targets use PYTHONWARNINGS=error as a shared runner contract. This includes the portable QUBO/GAMA notebooks, the local D-Wave notebook, and optional CUDA-Q execution, so the inexpensive portable CI lane catches dependency deprecations on every PR. Notebook-specific exceptions must filter only an exact, documented upstream notice.

On Linux and macOS, the runner uses IPC sockets in a private temporary directory. It checks the encoded path, including a channel suffix, against ZeroMQ’s platform limit. Windows and an overly long TMPDIR use TCP instead; Jupyter may then log its unencrypted-TCP notice. Python warnings still fail verification. The launcher initializes the event loop after shell setup and provides an awaitable shutdown callback to avoid Jupyter’s startup and shutdown deprecations. Revisit those workarounds when updating ipykernel or Tornado; #152 tracks their removal.

MathProg Python local execution

The complete MathProg notebook requires GLPK, CBC, IPOPT, BONMIN, and Couenne. On Ubuntu 22.04, install GLPK and the runtime libraries once:

sudo apt-get install glpk-utils libgfortran5 libgomp1 liblapack3 libblas3

Then install the locked Python groups and the versioned IDAES solver bundle:

uv sync --locked --group docs --group mathprog
uv run --locked --group docs --group mathprog idaes get-extensions --release 3.4.2 --distro ubuntu2204 --to .nbverify/mathprog-solvers
export PATH="$PWD/.nbverify/mathprog-solvers:$PATH"
make verify-mathprog-python-local

IDAES verifies the downloaded bundle’s checksums. Other platforms need the corresponding IDAES build (consult idaes get-extensions --info) or compatible local solver executables on PATH; the CI recipe above is tested on Ubuntu 22.04. The Python packages use the existing mathprog group and uv.lock.

Verification runs every lesson cell, checks solver termination and feasibility, and compares the LP, ILP, convex MINLP, and global nonconvex MINLP objectives with their known optima. BONMIN’s nonconvex example checks feasibility without claiming global optimality. Missing executables and failed solves are errors; there is no silent solver fallback. No account or commercial license is used. CI gives installation and execution a separate 10-minute job. Fresh outputs go to .nbverify/; the published figures are preserved.

D-Wave Python local execution

make verify-dwave-python-local uses the existing locked docs and qubo groups on Python 3.10–3.12. It checks seeded local samples against exhaustive enumeration and executes the notebook without importing the Ocean cloud client, reading saved QPU configuration, or contacting Leap. The target forces QUBONOTEBOOKS_DWAVE_ENABLE_QPU=0 even if the caller enabled it. CI runs this path in a separate job with a 10-minute budget.

Hardware demonstrations require a separately managed Ocean environment and QUBONOTEBOOKS_DWAVE_ENABLE_QPU=1 before opening or executing the notebook. Use DWAVE_API_TOKEN, Colab Secrets, or your existing Ocean local configuration. Opted-in connectivity and submission errors stop execution. The Ocean cloud client remains outside the lock because it brings in diskcache, which the repository dependency policy excludes. Published QPU outputs are retained historical examples; local verification writes its own results to .nbverify/.

Optional CUDA-Q

CUDA-Q is an optional dependency group for CPU quantum simulation. On Python 3.11 or 3.12, install and verify it from the repository root with:

make verify-cudaq-python

The target installs docs, qubo, and cudaq and runs Lecture 4’s D-Wave notebook on qpp-cpu, with QPU access forced off. Its optional quantum sections follow the classical QUBO and augmentation lectures, in this order:

These are CPU demonstrations of quantum algorithms and make no speedup claim. Allow about two minutes after installation: the combined target measured 96 seconds on Linux x86_64 (WSL2), using Python 3.12, CUDA-Q 0.16, and two CPU threads. Runtime varies with the machine; the CI budget remains 10 minutes including installation.

Verification fails if either optimization section is missing or skipped, or if a Python warning is raised. The notebook filters only CUDA-Q 0.16’s exact import notice about a future API change; other warnings remain actionable under the shared Python runner contract above.

Ordinary Lecture 4 execution without CUDA-Q prints one skip notice for both quantum sections and continues. Lecture 2 has no CUDA-Q code or dependency. The published Lecture 4 retains its enabled annealing example and adds QAOA results from an enabled CPU run. The verification target writes fresh results for both methods to .nbverify/4-DWAVE_python.ipynb. Missing-package tests and the D-Wave local target verify the skip path; the CUDA-Q target requires each method to finish its own numerical checks. Run make test-cudaq-python for the focused kernel and import-guard tests in the same CPU environment. The shared Hamiltonian-mapping checks run with make test-python.

To install without running verification:

uv sync --locked --group docs --group qubo --group cudaq

The group pins the CUDA-Q distribution line cuda-quantum-cu13>=0.16.0,<0.17 and requires Python 3.11+. Python 3.10 remains supported by the portable groups; requesting cudaq on 3.10 fails explicitly. The default and portable groups exclude CUDA-Q. Running a portable target afterwards synchronizes back to its smaller environment; use UV_PROJECT_ENVIRONMENT=/path/to/separate/venv to keep an optional environment separately.

Published wheels cover Linux x86_64/aarch64 (glibc 2.28+) and macOS Apple Silicon (macOS 13+). Native Windows and Intel macOS have no wheels for this release. Linux x86_64 on Ubuntu 22.04 and WSL2 was tested; the other wheel platforms were not executed. Hosted Colab installation remains unmeasured. The CPU target needs no GPU or CUDA driver, but the distribution still downloads GPU libraries.

The #138 measurements on two fresh Ubuntu 22.04 runners found a 2.91 GB complete environment, 2.33 GB more than docs + qubo, about 1.48 GB of additional wheel payload, and a 2.91 GB uv cache (decimal GB). Cold synchronization took 9.7–41.0 seconds. Allow space for both the environment and cache; filesystem sharing can affect actual disk use. These are measured release/platform figures, not cross-platform guarantees.

A separate CPU workflow runs on changes to the dependency files, Makefile, verification scripts, D-Wave notebook, focused tests, or workflow itself, or by manual dispatch. It has a 10-minute limit and no persistent CUDA-Q cache. Existing CI jobs retain their original targets and installed groups. No GPU execution target is provided.

QCi Python local execution

From the repository root, run make verify-qci-python-local. This creates the isolated environment locked under notebooks_py/environments/qci, executes the complete notebook in a fresh kernel, and writes results to .nbverify/. It uses HiGHS for both classical references and checks the QCi polynomial, quadratic, and constrained models by local evaluation and exact enumeration. No separately downloaded solver binaries or cloud credentials are needed. make test-qci-python runs the focused numerical and cloud-boundary tests. CI runs both commands on Python 3.12 with a 10-minute job budget.

This project supports Python 3.11–3.12. Its eqc-models==0.20.2 dependency requires NetworkX 2, so it cannot share the root project’s NetworkX 3 environment. To open the notebook interactively, run:

uv run --locked --project notebooks_py/environments/qci jupyter lab

The local Make targets remove QCI_TOKEN and force cloud access off, including when the caller supplies a conflicting Make variable. For a deliberate cloud run, set QUBONOTEBOOKS_QCI_ENABLE_CLOUD=1 before starting Jupyter and supply QCI_TOKEN in the environment or Colab Secrets. A token alone never enables submission; opted-in credential or service failures stop execution. Published cloud outputs remain historical examples and were not regenerated by the credential-free check.

The notebook temporarily filters only the exact upstream import log that the optional eqc-direct client is unavailable on Python 3.11+. That direct-device client is not used by these examples; cloud and local APIs are available. Other logging notices and Python warnings remain visible.

Commercial solvers

No notebook in this collection calls a commercial solver, and neither solver below is a dependency of any notebook project. They are documented here because the notebooks are a starting point for your own models, where an LP/MIP or MINLP licence is often worth having. The mathematical-programming notebook, the one where a commercial solver would otherwise be expected, solves its examples with GLPK, Cbc, Ipopt, Bonmin, and Couenne, all open source.

Gurobi is one of the most powerful LP and MIP solvers available today, and free academic licences are offered. Visit the Gurobi website, create an account, preferably with an academic email address, and obtain a licence. You can then download and use the software.

BARON is one of the most powerful MINLP solvers available today. Students from the University System of Georgia and CMU and UIUC affiliates are eligible for a free licence. Visit the BARON website, create an account with an academic email address, and obtain a licence. You can then download and use the software.

Credentials

Cloud execution is always explicit. Provide credentials only through the process environment or an approved secret store. QCI submission requires QUBONOTEBOOKS_QCI_ENABLE_CLOUD=1 and QCI_TOKEN; D-Wave QPU submission requires the corresponding QPU opt-in and DWAVE_API_TOKEN. Do not rerun or replace committed D-Wave QPU outputs unless new QPU access and credits have been deliberately approved.

The book build itself never executes notebooks or contacts a cloud solver.