Skip to content

Add Warp tutorial notebooks#185

Open
nv-snidhan wants to merge 13 commits into
NVIDIA:mainfrom
nv-snidhan:snidhan/reorg-warp-notebooks
Open

Add Warp tutorial notebooks#185
nv-snidhan wants to merge 13 commits into
NVIDIA:mainfrom
nv-snidhan:snidhan/reorg-warp-notebooks

Conversation

@nv-snidhan

Copy link
Copy Markdown
Contributor

Summary

This PR moves the Warp material out of the Accelerated Python guide into a dedicated tutorials/warp tutorial and expands it from two chapter notebooks into a four-notebook sequence.

Changes

  • Move the existing Warp intro and Ising notebooks to tutorials/warp/notebooks/01_intro_to_warp.ipynb and tutorials/warp/notebooks/02_ising_model.ipynb, remove the old Accelerated Python README entries, and add tutorials/warp/README.md with notebook descriptions and Colab links.
  • Rework notebook 01 from the old Chapter 12 material into a broader introduction to Warp. The notebook now walks through kernels, typed arguments, kernel cache behavior, array creation and transfer, language restrictions, Python-scope versus kernel-scope APIs, user functions, structs, and automatic differentiation.
  • Replace the old introductory particle walkthrough in notebook 01 with a galaxy simulation capstone. The capstone ties together NumPy initialization, wp.array data movement, wp.launch, wp.vec3 particle state, fused versus non-fused kernel structure, and result visualization.
  • Add notebook 03, a 2-D Navier-Stokes solver that teaches finite-difference vorticity updates, fused stencil kernels, Warp tile FFTs, a Fourier-space Poisson solve, full solver assembly, and CUDA graph capture.
  • Add notebook 04, a differentiable simulation tutorial using the Navier-Stokes solver for target matching and optimal perturbation examples. It covers the practical changes needed for Warp autodiff, including avoiding in-place updates, recording with wp.Tape(), using warp.optim, and interoperability with PyTorch.
  • Add helper packages and image assets for the intro, Ising, Navier-Stokes, and differentiable Navier-Stokes notebooks.

@copy-pr-bot

copy-pr-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown
Contributor

👋 Thank you for your contribution!

This pull request is from a forked repository so GitHub Actions will not be able to run CI. A maintainer will review your changes shortly and manually trigger the CI.

@maintainers Please review this PR when you have a chance and follow the instructions in the CONTRIBUTING.md file to trigger the CI.

@nv-snidhan

Copy link
Copy Markdown
Contributor Author

@jnbntz @tscudiero can you please add one of the people from your team and @shi-eric as the reviewers for this PR?

@nv-snidhan nv-snidhan force-pushed the snidhan/reorg-warp-notebooks branch 2 times, most recently from 0482240 to 92834aa Compare June 11, 2026 21:29
@jnbntz jnbntz requested a review from shi-eric June 12, 2026 13:07
@brycelelbach

Copy link
Copy Markdown
Collaborator

ok to test

@brycelelbach

Copy link
Copy Markdown
Collaborator

/ok to test 92834aa

Just to confirm, are you adding the images with Git LFS? That's required to keep the repo size from getting very large.

This looks nice at a glance - can you add the docker compose definitions for this tutorial? You should be able to take the config for the accelerated Python tutorial as a starting point.

@brycelelbach brycelelbach force-pushed the snidhan/reorg-warp-notebooks branch from 92834aa to 98687ca Compare June 18, 2026 22:55
@brycelelbach

Copy link
Copy Markdown
Collaborator

/ok to test 92834aa

@copy-pr-bot

copy-pr-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown

/ok to test 92834aa

@brycelelbach, there was an error processing your request: E2

See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/2/

@brycelelbach

Copy link
Copy Markdown
Collaborator

/ok to test 98687ca

@brycelelbach

Copy link
Copy Markdown
Collaborator

@nv-snidhan can you please sign your commits?

@github-actions

Copy link
Copy Markdown
Contributor

❌ Git Signature Check Failed

🔗 View workflow run logs

Found 10 unsigned commit(s):

Unsigned commits
  • 98687ca: Tutorials/Warp: Use media URLs and fix review issues. (unsigned)
  • ca8ac26: Keep Advanced Warp topics heading (unsigned)
  • 483354a: Consolidate Warp notebook cleanup (unsigned)
  • 386c3fc: Add Warp notebook copyright headers (unsigned)
  • 2137960: Update Warp install guidance (unsigned)
  • b7fb9ac: Organize Warp notebook helpers (unsigned)
  • 1c5bc23: Add Warp Navier-Stokes tutorials (unsigned)
  • be06efe: Move Warp notebooks to tutorials (unsigned)
  • 3cf4bae: Refine Warp intro notebook (unsigned)
  • 2e6be7f: Tutorials/Accelerated Python: Reconcile Warp intro with GTC DLI notebook. (unsigned)

How to fix:

  1. Configure commit signing (if not already done):

    # For GPG signing
    git config --global commit.gpgsign true
    
    # Or for SSH signing (Git 2.34+)
    git config --global gpg.format ssh
    git config --global user.signingkey ~/.ssh/id_ed25519.pub
  2. Re-sign your commits:

    git rebase -i origin/main --exec "git commit --amend --no-edit -S"
    git push --force-with-lease

📚 GitHub documentation on signing commits

@nv-snidhan nv-snidhan force-pushed the snidhan/reorg-warp-notebooks branch from 98687ca to fa6854e Compare June 26, 2026 20:32
@nv-snidhan

Copy link
Copy Markdown
Contributor Author

@brycelelbach

Just to confirm, are you adding the images with Git LFS? That's required to keep the repo size from getting very large.

Yes, we are using Git LFS for images

This looks nice at a glance - can you add the docker compose definitions for this tutorial? You should be able to take the config for the accelerated Python tutorial as a starting point.

Done

can you please sign your commits?

Done

@nv-snidhan nv-snidhan force-pushed the snidhan/reorg-warp-notebooks branch 5 times, most recently from 1d65fe5 to f2ff889 Compare June 26, 2026 23:36
nv-snidhan and others added 8 commits July 7, 2026 09:28
…ook.

Signed-off-by: snidhan <snidhan@nvidia.com>
The notebook previously opened with a particle simulation before
introducing kernels and arrays, which made the chapter feel more
like a reference pass than a guided introduction. It also aliased
Warp float64 as double and included a large scalar type table in
the array section.

Reframe the overview around the core programming model, add the
galaxy teaser, remove the redundant particle walkthrough, and start
the kernel section with a Celsius-to-Fahrenheit elementwise example.
The deeper topics are now grouped after the core model, and
explicit double precision examples use wp.float64 directly.

Signed-off-by: snidhan <snidhan@nvidia.com>
The Warp notebooks no longer fit the Accelerated Python User Guide
chapter layout. Keeping them under that path also forced chapter-based
file names and image directories that are awkward for future tutorial
notebooks.

Move the Warp notebooks into tutorials/warp with numbered notebook
names and notebook-specific image directories. Add a tutorial README
with local and Colab links, and remove the old Chapter 12 entries from
the Accelerated Python notebook index.

Signed-off-by: snidhan <snidhan@nvidia.com>
The Warp tutorial area previously contained only the introductory and
Ising notebooks. The Navier-Stokes classroom materials lived outside
this repository, so the tutorial README could not point readers to the
next solver-focused lessons.

Add the Navier-Stokes and differentiable Navier-Stokes notebooks under
tutorials/warp, along with their helper modules and image assets. Update
local asset imports and documentation links so the notebooks work from
their new home, and track copied binary assets through Git LFS.

Signed-off-by: snidhan <snidhan@nvidia.com>
The Warp notebook directory had helper modules mixed directly with the
notebooks. That made the tutorial area harder to scan and left little
room for more notebook-specific support code.

Move the helpers into importable subpackages under notebooks/helpers,
split by notebook family. Update notebook imports and prose references
to the new package paths while preserving the existing helper
implementations.

Signed-off-by: snidhan <snidhan@nvidia.com>
The intro notebook still showed CUDA-version-specific conda selector
examples for Warp. Those examples age quickly and can make the setup
section look stale even when the generic package install is enough.

Replace the conda examples with the current generic conda-forge install
form and keep PyPI as the primary installation path. Also simplify the
nightly package wording while preserving the warning that nightlies are
less tested than release packages.

Signed-off-by: snidhan <snidhan@nvidia.com>
The Navier-Stokes Warp notebooks still carried course-specific header markup from the original GTC material, and they did not include the copyright block used by the other tutorial notebooks.

They now start with the 2026 NVIDIA copyright and license header and use plain markdown titles that match the intro notebook style.

Signed-off-by: snidhan <snidhan@nvidia.com>
Recent Warp notebook edits were split across several small cleanup commits. Keeping them separate made the branch history noisy without adding useful review boundaries.

Combine the documentation wording, setup-cell consistency, and notebook polish into one commit while preserving the final notebook contents exactly. Earlier commits that add and organize the tutorials remain separate.

Signed-off-by: snidhan <snidhan@nvidia.com>
Signed-off-by: snidhan <snidhan@nvidia.com>
Signed-off-by: snidhan <snidhan@nvidia.com>
@nv-snidhan nv-snidhan force-pushed the snidhan/reorg-warp-notebooks branch from aacdde6 to 4bf5c75 Compare July 7, 2026 16:41
@shi-eric

shi-eric commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

np.meshgrid(x, y) defaults to indexing="xy", so x varies along array axis 1 and y along axis 0. The Warp kernel uses its first index as x and its second as y, so the validation passes fields to the kernel with the axes reversed.

This affects the numerical validation, not just the plot. With the default test parameters, the numerical and analytical results have a correlation of approximately -1 and a maximum error of about 11.998. Using np.meshgrid(x, y, indexing="ij") changes the correlation to approximately 1 and reduces the maximum error to about 0.001958.

Please preserve the kernel's axis convention here with indexing="ij". The arrays can be transposed separately when passed to imshow if needed for conventional plot orientation.

@shi-eric

shi-eric commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Running logo_solver.py directly from the directory containing it fails with the default arguments:

cd tutorials/warp/notebooks/helpers/differentiable_navier_stokes
python logo_solver.py

The command raises:

FileNotFoundError: Target image not found:
images/differentiable-navier-stokes/gtc_logo.png

The default target is first resolved relative to the current directory. The fallback then joins the same relative target beneath the script directory, but the bundled image is located beneath tutorials/warp/notebooks/images. As a result, the default CLI only works when launched from the undocumented tutorials/warp/notebooks working directory.

Could the bundled default be constructed relative to the notebooks directory instead?

notebooks_dir = Path(__file__).resolve().parents[2]
default_target = (
    notebooks_dir
    / "images"
    / "differentiable-navier-stokes"
    / "gtc_logo.png"
)

This would make the default invocation independent of the working directory while allowing user-provided relative --target paths to retain normal current-directory semantics. The unused warp.examples import in the existing fallback can also be removed.

@shi-eric

shi-eric commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

The constructor documents use_cuda_graph=None as automatic device detection, but the current assignment does not implement that behavior:

self.use_cuda_graph = use_cuda_graph and wp.get_device().is_cuda

On a CUDA device, passing None leaves self.use_cuda_graph as None. The later truthiness checks therefore skip graph capture and use the standard execution path. Callers selecting the documented automatic mode silently lose CUDA-graph acceleration.

Could None be handled explicitly?

device_is_cuda = wp.get_device().is_cuda
self.use_cuda_graph = (
    device_is_cuda
    if use_cuda_graph is None
    else use_cuda_graph and device_is_cuda
)

If automatic detection is not intended, the alternative would be to remove None from the type annotation and documentation.

@nv-snidhan nv-snidhan force-pushed the snidhan/reorg-warp-notebooks branch from 4bf5c75 to 25567bb Compare July 7, 2026 19:24
@nv-snidhan

Copy link
Copy Markdown
Contributor Author

@shi-eric

  • Changed to X, Y = np.meshgrid(x, y, indexing="ij")
  • gtc_logo.png is now detected relative to the notebook folder as
notebooks_dir = Path(__file__).resolve().parents[2]
  default_target = (
      notebooks_dir
      / "images"
      / "differentiable-navier-stokes"
      / "gtc_logo.png"
  )
  • Updated the CUDA graph usage as mentioned above.

@brycelelbach

Copy link
Copy Markdown
Collaborator

/ok to test 25567bb

@robobryce robobryce left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I focused this review on consistency with ACH's documented tutorial contract, then exercised the notebooks on a B200 with warp-lang 1.14.0.

The main consistency items should be addressed before merge:

  1. Please align the new tutorial with docs/brev_launchable_architecture.md:

    • Rename the notebooks to the documented NN__descriptive_name.ipynb form and update the README, Compose URL, and cross-links. Notebook 04 should also drop 01. / 03. from displayed link text, since ACH explicitly keeps sequence numbers out of notebook bodies.
    • Notebook 03 is an exercise notebook with four TODO cells, but it has no executable __SOLUTION counterpart.
    • Add the standard tutorials/warp/brev/test.bash plus a meaningful notebook/helper smoke test. The tutorial is auto-discovered and its image build is green, but the standard test path currently has no Warp test entrypoint, so none of this content is exercised.
  2. Commits 92e00c2 and ffa658d are missing Signed-off-by trailers. CONTRIBUTING.md requires both DCO sign-off and a cryptographic signature on every commit; the green signature check only covers the latter.

There are also several runtime/content issues to fix:

  • Notebook 01 has seven uncaught expected-error cells, so normal automated execution cannot finish it. Please catch/assert the expected exceptions or render invalid examples as non-executable snippets. In particular, the device-access example sets the process-global wp.config.launch_array_access_mode to CHECKED and never restores the default, so subsequent launches and the fusion benchmark run under altered global state.
  • The in-place transpose lesson in notebook 03 is nondeterministic. On B200/Warp 1.14 its validator printed PASSED: all 65536 elements match expected transpose, immediately before prose claiming the result is incorrect. The kernel is genuinely racy, but a value comparison can pass by accident; explain that explicitly and do not rely on a failed plot. More broadly, the diffusion/advection validators compute and discard max_error, FFT error is never checked, and transpose failures only print. The solution test should enforce tolerances.
  • Both notebook 04 snapshot loops mix states across optimizer steps: train_step() updates the optimized input before returning, while the saved trajectory/loss still corresponds to the pre-update input. Capture the input before the update, or re-run the forward pass after it, so each GIF frame depicts one consistent state.
  • Keep notebook-local media paths relative. Anonymous Colab testing confirmed that relative raster and SVG paths resolve against the exact source commit. The new hardcoded NVIDIA/.../main URLs are broken in the PR/forks until assets exist upstream and make old tags/event branches display media from a different revision; relative paths also match the sibling tutorials.

Lower-priority consistency follow-ups:

  • Notebook 04 calls itself a differentiable continuation of notebook 03, but silently changes Forward Euler/512²/DT=0.0005 to hidden SSP-RK3 helpers with different grid sizes and DT=0.001. Please introduce and justify those changes, or isolate autodiff changes on the solver that was just taught.
  • In notebook 02, the Python baseline and checkerboard run both write images/ising-model/256x256_2.269.gif, so the latter overwrites the former. Use method-specific names under an outputs/ directory, as notebook 04 does.
  • Leave a relocation link in the old Accelerated Python index rather than deleting the Chapter 12 rows without a pointer.

What passed: canonical notebook formatting, Git LFS checks, Compose parsing, helper imports/compilation, notebook 02, both notebook 04 optimizations, and notebook 03 end-to-end after applying its documented answers. The Warp image build also completed successfully.

Add the per-tutorial brev/ config (dockerfile, docker-compose.yml,
requirements.txt) so the Warp tutorial builds and serves on Brev,
matching the self-registering pattern the other tutorials use. Link
the compose file from the root README table and add a Brev/Colab
deploy section to the tutorial README.

Trim the dependency set to what the notebooks and helpers actually
import: warp-lang, numpy, scipy, matplotlib, ipympl, Pillow, plus the
Jupyter stack. Drop RAPIDS, cupy, cuda-python, and MPI versus
accelerated-python; none are used here. Omit the nsys/ncu profiling
services since the notebooks embed pre-captured Nsight images rather
than running profilers live.

Do not install PyTorch. Notebook 04 references the Warp <-> PyTorch
autograd bridge only in prose; no notebook or helper imports torch in
executable code. Verified notebook 04 runs error-free without it. This
keeps the shipped image about 5 GB smaller (9.85 GB vs 14.7 GB).

Signed-off-by: snidhan <snidhan@nvidia.com>
Colab's markdown math renderer does not support the calligraphic
\mathcal font, so every equation using \mathcal{F} or \mathcal{L}
displayed as raw LaTeX text. Replace \mathcal{F} -> \mathbf{F} and
\mathcal{L} -> \mathbf{L} (\mathbf renders in Colab and keeps the
operator's visual weight). Also single-line the two display-math
blocks whose opening $$ sat alone on a line, and drop \! / \bigl in
the optimal-perturbation objective, for broader renderer
compatibility. No change to the mathematics.

Set OPTIMIZER_STEPS to 100 in Example 1 to match Example 2.

Signed-off-by: snidhan <snidhan@nvidia.com>
Make the GPU check in 02_ising_model raise RuntimeError when no
CUDA device is present, matching notebooks 01, 03, and 04. The old
code only printed a warning and continued, so a CPU-only Colab
runtime would crash mid-kernel instead of failing fast with a clear
message.

Point the three SVG diagrams in 01_intro_to_warp at absolute
raw.githubusercontent.com/.../main/ URLs instead of relative paths.
That notebook has no Colab clone cell, so the relative paths did not
resolve on Colab; SVGs are not LFS-tracked, so the raw host (not the
media LFS host) is correct.

Signed-off-by: snidhan <snidhan@nvidia.com>
@nv-snidhan nv-snidhan force-pushed the snidhan/reorg-warp-notebooks branch from 25567bb to 8f6d3e3 Compare July 8, 2026 00:34
@nv-snidhan

Copy link
Copy Markdown
Contributor Author

@brycelelbach @robobryce

Rename the notebooks to the documented NN__descriptive_name.ipynb form and update the README, Compose URL, and cross-links. Notebook 04 should also drop 01. / 03. from displayed link text, since ACH explicitly keeps sequence numbers out of notebook bodies.

I renamed all four notebooks, updated the README, Colab URLs, Compose launch path, and notebook cross-links, and removed sequence numbers from notebook 04's displayed link text. A repository check confirms that no old filename remains.

Notebook 03 is an exercise notebook with four TODO cells, but it has no executable __SOLUTION counterpart.

Notebook 03 is a self-contained guided tutorial with four inline collapsible solutions, not a separate exercise and answer pair. Creating a __SOLUTION copy would duplicate 73 cells and create maintenance drift for four checkpoints.

Add the standard tutorials/warp/brev/test.bash plus a meaningful notebook/helper smoke test. The tutorial is auto-discovered and its image build is green, but the standard test path currently has no Warp test entrypoint, so none of this content is exercised.

I added brev/test.bash following the lightweight default used by nvmath-python, which validates GPU availability with nvidia-smi. I did not add a Warp-specific pytest suite because these teaching notebooks contain intentional failures and long workloads.

Commits 92e00c2 and ffa658d are missing Signed-off-by trailers. CONTRIBUTING.md requires both DCO sign-off and a cryptographic signature on every commit; the green signature check only covers the latter.

I rewrote those commits as f0ec2d0 and e164f4a. Both now contain Signed-off-by: snidhan <snidhan@nvidia.com> and retain SSH signatures.

Notebook 01 has seven uncaught expected-error cells, so normal automated execution cannot finish it. Please catch/assert the expected exceptions or render invalid examples as non-executable snippets. In particular, the device-access example sets the process-global wp.config.launch_array_access_mode to CHECKED and never restores the default, so subsequent launches and the fusion benchmark run under altered global state.

The error cells intentionally expose Warp's native diagnostics, so catching them or converting them to snippets would weaken the lesson. I retained those intentional errors and restored launch_array_access_mode with try/finally, so CHECKED cannot affect later launches.

The in-place transpose lesson in notebook 03 is nondeterministic. On B200/Warp 1.14 its validator printed PASSED: all 65536 elements match expected transpose, immediately before prose claiming the result is incorrect. The kernel is genuinely racy, but a value comparison can pass by accident; explain that explicitly and do not rely on a failed plot. More broadly, the diffusion/advection validators compute and discard max_error, FFT error is never checked, and transpose failures only print. The solution test should enforce tolerances.

The prose now states that the racy in-place kernel may pass or fail and asks learners to rerun it. The fixed out-of-place transpose raises on any mismatch; the other validators remain instructional diagnostics rather than a generalized test suite.

Both notebook 04 snapshot loops mix states across optimizer steps: train_step() updates the optimized input before returning, while the saved trajectory/loss still corresponds to the pre-update input. Capture the input before the update, or re-run the forward pass after it, so each GIF frame depicts one consistent state.

Both loops now copy the optimized input on snapshot iterations before train_step(). Each saved input, trajectory, and loss therefore describes the same optimizer state without an extra forward solve.

Keep notebook-local media paths relative. Anonymous Colab testing confirmed that relative raster and SVG paths resolve against the exact source commit. The new hardcoded NVIDIA/.../main URLs are broken in the PR/forks until assets exist upstream and make old tags/event branches display media from a different revision; relative paths also match the sibling tutorials.

I converted notebook 01's three ordinary-Git SVG references to relative ./images/... paths, matching notebooks 03 and 04. I retained absolute URLs for Git LFS-backed PNG and GIF assets, pinned them to asset commit 4cabbfd, and verified that every referenced URL returns content.

Notebook 04 calls itself a differentiable continuation of notebook 03, but silently changes Forward Euler/512²/DT=0.0005 to hidden SSP-RK3 helpers with different grid sizes and DT=0.001. Please introduce and justify those changes, or isolate autodiff changes on the solver that was just taught.

Notebook 04 is a conceptual continuation, not a line-for-line differentiation of notebook 03. Its SSP-RK3, DT=0.001, and grid choices are intentional for optimization stability and Warp tape memory; forcing Forward Euler at 512 x 512 would increase memory without correcting a defect.

In notebook 02, the Python baseline and checkerboard run both write images/ising-model/256x256_2.269.gif, so the latter overwrites the former. Use method-specific names under an outputs/ directory, as notebook 04 does.

The three animation cells now use method-specific python_, warp_naive_, and warp_checkerboard_ filenames, so equal lattice sizes and temperatures no longer overwrite one another. I kept the existing output directory to limit the change.

Leave a relocation link in the old Accelerated Python index rather than deleting the Chapter 12 rows without a pointer.

The repository has no internal links to this legacy index, and other relocated tutorial folders do not leave relocation notes. The canonical root index already links the Warp tutorial; a note here would not repair bookmarks or Colab URLs that target the deleted notebook paths, so I have not added one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants