vidmag 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vidmag-0.2.0/.claude/rules/development-practices.md +87 -0
- vidmag-0.2.0/.editorconfig +30 -0
- vidmag-0.2.0/.gitattributes +35 -0
- vidmag-0.2.0/.github/ISSUE_TEMPLATE/bug.md +33 -0
- vidmag-0.2.0/.github/ISSUE_TEMPLATE/hardware-result.md +32 -0
- vidmag-0.2.0/.github/PULL_REQUEST_TEMPLATE.md +32 -0
- vidmag-0.2.0/.github/actionlint.yaml +10 -0
- vidmag-0.2.0/.github/dependabot.yml +31 -0
- vidmag-0.2.0/.github/workflows/ci.yml +397 -0
- vidmag-0.2.0/.github/workflows/deploy-pages.yml +44 -0
- vidmag-0.2.0/.github/workflows/gpu.yml +201 -0
- vidmag-0.2.0/.github/workflows/lint.yml +63 -0
- vidmag-0.2.0/.github/workflows/release.yml +78 -0
- vidmag-0.2.0/.gitignore +52 -0
- vidmag-0.2.0/.pre-commit-config.yaml +48 -0
- vidmag-0.2.0/.readthedocs.yaml +39 -0
- vidmag-0.2.0/CHANGELOG.md +137 -0
- vidmag-0.2.0/CITATION.cff +50 -0
- vidmag-0.2.0/CLAUDE.md +297 -0
- vidmag-0.2.0/CONTRIBUTING.md +109 -0
- vidmag-0.2.0/LICENSE +58 -0
- vidmag-0.2.0/Makefile +138 -0
- vidmag-0.2.0/PKG-INFO +336 -0
- vidmag-0.2.0/README.md +283 -0
- vidmag-0.2.0/SECURITY.md +33 -0
- vidmag-0.2.0/benches/apple_m2_max_opencl_2026-08-10.md +93 -0
- vidmag-0.2.0/benches/baseline_tests_2026-08-09_macos.txt +3 -0
- vidmag-0.2.0/benches/baseline_tests_2026-08-09_osiris_rtx3090.txt +26 -0
- vidmag-0.2.0/benches/bench_a100.json +261 -0
- vidmag-0.2.0/benches/bench_h100.json +252 -0
- vidmag-0.2.0/benches/bench_p100.json +190 -0
- vidmag-0.2.0/benches/bench_rtx3090.json +251 -0
- vidmag-0.2.0/benches/bench_t4.json +94 -0
- vidmag-0.2.0/benches/kaggle_runs/README.md +27 -0
- vidmag-0.2.0/benches/kaggle_runs/evm-cuda-baseline.log +356 -0
- vidmag-0.2.0/benches/kaggle_runs/evm-cuda-fp16-profile.log +253 -0
- vidmag-0.2.0/benches/kaggle_runs/evm-cuda-gpu-comparison.log +462 -0
- vidmag-0.2.0/benches/kaggle_runs/evm-cuda-gpu-comparison_2026-08-22_p100.log +105 -0
- vidmag-0.2.0/benches/kaggle_runs/evm-cuda-tests.log +393 -0
- vidmag-0.2.0/data/.gitkeep +0 -0
- vidmag-0.2.0/docs/changelog.md +3 -0
- vidmag-0.2.0/docs/comparison.md +48 -0
- vidmag-0.2.0/docs/concepts/backends.md +158 -0
- vidmag-0.2.0/docs/concepts/how-it-works.md +61 -0
- vidmag-0.2.0/docs/concepts/parameters.md +63 -0
- vidmag-0.2.0/docs/concepts/phase-based.md +92 -0
- vidmag-0.2.0/docs/concepts/pitfalls.md +63 -0
- vidmag-0.2.0/docs/contributing.md +3 -0
- vidmag-0.2.0/docs/dev/PLAN.md +564 -0
- vidmag-0.2.0/docs/dev/archive/README.md +51 -0
- vidmag-0.2.0/docs/dev/archive/blog_bandwidth_limit.md +227 -0
- vidmag-0.2.0/docs/dev/archive/blog_further_optimizations.md +915 -0
- vidmag-0.2.0/docs/dev/archive/blog_speedup.md +685 -0
- vidmag-0.2.0/docs/dev/gpu-runner.md +218 -0
- vidmag-0.2.0/docs/dev/packaging-notes.md +208 -0
- vidmag-0.2.0/docs/dev/release-checklist.md +84 -0
- vidmag-0.2.0/docs/dev/torch-backend-notes.md +124 -0
- vidmag-0.2.0/docs/getting-started/first-result.md +66 -0
- vidmag-0.2.0/docs/getting-started/install.md +88 -0
- vidmag-0.2.0/docs/img/baby_demo.gif +0 -0
- vidmag-0.2.0/docs/img/face_demo.gif +0 -0
- vidmag-0.2.0/docs/img/og_preview.png +0 -0
- vidmag-0.2.0/docs/index.md +74 -0
- vidmag-0.2.0/docs/internals/design.md +21 -0
- vidmag-0.2.0/docs/internals/making-it-fast.md +354 -0
- vidmag-0.2.0/docs/licence.md +41 -0
- vidmag-0.2.0/docs/performance.md +204 -0
- vidmag-0.2.0/docs/recipes/building-blocks.md +103 -0
- vidmag-0.2.0/docs/recipes/motion.md +77 -0
- vidmag-0.2.0/docs/recipes/pulse.md +67 -0
- vidmag-0.2.0/docs/recipes/streaming.md +95 -0
- vidmag-0.2.0/docs/recipes/vibration.md +59 -0
- vidmag-0.2.0/docs/reference/api.md +22 -0
- vidmag-0.2.0/docs/reference/cli.md +63 -0
- vidmag-0.2.0/docs/reference/ops.md +33 -0
- vidmag-0.2.0/docs/robots.txt +4 -0
- vidmag-0.2.0/docs/stability.md +55 -0
- vidmag-0.2.0/docs/video/baby_input.mp4 +0 -0
- vidmag-0.2.0/docs/video/baby_motion.mp4 +0 -0
- vidmag-0.2.0/docs/video/face_input.mp4 +0 -0
- vidmag-0.2.0/docs/video/face_pulse.mp4 +0 -0
- vidmag-0.2.0/mkdocs.yml +113 -0
- vidmag-0.2.0/pyproject.toml +436 -0
- vidmag-0.2.0/scripts/cloud/colab_benchmark.ipynb +295 -0
- vidmag-0.2.0/scripts/cloud/kaggle/README.md +66 -0
- vidmag-0.2.0/scripts/cloud/kaggle/kernel-metadata.json +13 -0
- vidmag-0.2.0/scripts/cloud/kaggle/run_gpu_comparison.py +242 -0
- vidmag-0.2.0/scripts/dev/make_golden_fixtures.py +139 -0
- vidmag-0.2.0/scripts/dev/record_backend_bench.py +158 -0
- vidmag-0.2.0/scripts/dev/record_gpu_bench.py +228 -0
- vidmag-0.2.0/scripts/dev/verify_install.sh +114 -0
- vidmag-0.2.0/scripts/download_samples.py +119 -0
- vidmag-0.2.0/scripts/experiments/README.md +19 -0
- vidmag-0.2.0/scripts/experiments/bound_microbench.py +245 -0
- vidmag-0.2.0/scripts/experiments/measure_fp16_experiments.py +164 -0
- vidmag-0.2.0/scripts/experiments/prove_fp16_cost.py +209 -0
- vidmag-0.2.0/scripts/profile_full_comparison.py +342 -0
- vidmag-0.2.0/scripts/render_cuda_videos.py +101 -0
- vidmag-0.2.0/scripts/run_evm.py +36 -0
- vidmag-0.2.0/src/vidmag/__init__.py +131 -0
- vidmag-0.2.0/src/vidmag/_cli.py +619 -0
- vidmag-0.2.0/src/vidmag/api.py +414 -0
- vidmag-0.2.0/src/vidmag/backend/__init__.py +58 -0
- vidmag-0.2.0/src/vidmag/backend/generic.py +267 -0
- vidmag-0.2.0/src/vidmag/backend/ops.py +226 -0
- vidmag-0.2.0/src/vidmag/backend/pipelines.py +169 -0
- vidmag-0.2.0/src/vidmag/backend/registry.py +265 -0
- vidmag-0.2.0/src/vidmag/cpu/__init__.py +70 -0
- vidmag-0.2.0/src/vidmag/cpu/backend.py +148 -0
- vidmag-0.2.0/src/vidmag/cpu/csp.py +254 -0
- vidmag-0.2.0/src/vidmag/cpu/filters.py +143 -0
- vidmag-0.2.0/src/vidmag/cpu/magnify.py +648 -0
- vidmag-0.2.0/src/vidmag/cpu/ops.py +128 -0
- vidmag-0.2.0/src/vidmag/cpu/phase_magnify.py +209 -0
- vidmag-0.2.0/src/vidmag/cpu/pyramids.py +256 -0
- vidmag-0.2.0/src/vidmag/cuda/CMakeLists.txt +170 -0
- vidmag-0.2.0/src/vidmag/cuda/DESIGN.md +400 -0
- vidmag-0.2.0/src/vidmag/cuda/__init__.py +128 -0
- vidmag-0.2.0/src/vidmag/cuda/_common.py +59 -0
- vidmag-0.2.0/src/vidmag/cuda/array.py +215 -0
- vidmag-0.2.0/src/vidmag/cuda/batched.py +723 -0
- vidmag-0.2.0/src/vidmag/cuda/benchmark.py +342 -0
- vidmag-0.2.0/src/vidmag/cuda/bindings.cpp +2120 -0
- vidmag-0.2.0/src/vidmag/cuda/include/evm_check.cuh +40 -0
- vidmag-0.2.0/src/vidmag/cuda/include/evm_common.cuh +118 -0
- vidmag-0.2.0/src/vidmag/cuda/include/evm_dlpack.cuh +66 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/amplify_render.cu +430 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/blur_dn.cu +70 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/butter_bandpass.cu +67 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/color_cvt.cu +123 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/fp16_cvt.cu +52 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/ideal_bandpass.cu +109 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/iir_bandpass.cu +297 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/lpyr.cu +287 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/spatial.cu +956 -0
- vidmag-0.2.0/src/vidmag/cuda/kernels/transpose.cu +220 -0
- vidmag-0.2.0/src/vidmag/cuda/ops.py +299 -0
- vidmag-0.2.0/src/vidmag/cuda/pipelines.py +429 -0
- vidmag-0.2.0/src/vidmag/cuda/runtime.py +56 -0
- vidmag-0.2.0/src/vidmag/io/__init__.py +30 -0
- vidmag-0.2.0/src/vidmag/io/capture.py +102 -0
- vidmag-0.2.0/src/vidmag/io/h264.py +60 -0
- vidmag-0.2.0/src/vidmag/io/video.py +142 -0
- vidmag-0.2.0/src/vidmag/metal/__init__.py +25 -0
- vidmag-0.2.0/src/vidmag/metal/array.py +107 -0
- vidmag-0.2.0/src/vidmag/metal/kernels.metal +346 -0
- vidmag-0.2.0/src/vidmag/metal/ops.py +342 -0
- vidmag-0.2.0/src/vidmag/metal/runtime.py +139 -0
- vidmag-0.2.0/src/vidmag/notebook.py +34 -0
- vidmag-0.2.0/src/vidmag/opencl/__init__.py +29 -0
- vidmag-0.2.0/src/vidmag/opencl/array.py +109 -0
- vidmag-0.2.0/src/vidmag/opencl/kernels.cl +368 -0
- vidmag-0.2.0/src/vidmag/opencl/ops.py +373 -0
- vidmag-0.2.0/src/vidmag/opencl/runtime.py +149 -0
- vidmag-0.2.0/src/vidmag/presets.py +171 -0
- vidmag-0.2.0/src/vidmag/stream.py +297 -0
- vidmag-0.2.0/src/vidmag/torch_backend/__init__.py +40 -0
- vidmag-0.2.0/src/vidmag/torch_backend/ops.py +319 -0
- vidmag-0.2.0/src/vidmag/torch_backend/runtime.py +70 -0
- vidmag-0.2.0/src/vidmag/vulkan/__init__.py +28 -0
- vidmag-0.2.0/src/vidmag/vulkan/array.py +112 -0
- vidmag-0.2.0/src/vidmag/vulkan/ops.py +370 -0
- vidmag-0.2.0/src/vidmag/vulkan/runtime.py +351 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/_common.glsl +16 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/add_and_quantize.comp +32 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/add_and_quantize.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/add_into.comp +11 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/add_into.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/apply_gain.comp +12 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/apply_gain.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/band_project.comp +16 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/band_project.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/bgr_u8_to_ntsc.comp +25 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/bgr_u8_to_ntsc.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/build.py +82 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/butter_bandpass.comp +22 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/butter_bandpass.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/corr_dn_cols.comp +39 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/corr_dn_cols.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/corr_dn_rows.comp +39 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/corr_dn_rows.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/iir_bandpass.comp +19 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/iir_bandpass.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/iir_step.comp +16 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/iir_step.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/resize_bilinear.comp +40 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/resize_bilinear.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/subtract.comp +12 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/subtract.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/up_conv_cols.comp +43 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/up_conv_cols.spv +0 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/up_conv_rows.comp +43 -0
- vidmag-0.2.0/src/vidmag/vulkan/shaders/up_conv_rows.spv +0 -0
- vidmag-0.2.0/tests/__init__.py +39 -0
- vidmag-0.2.0/tests/cuda/conftest.py +73 -0
- vidmag-0.2.0/tests/cuda/test_api_cuda.py +197 -0
- vidmag-0.2.0/tests/cuda/test_batched_kernels.py +393 -0
- vidmag-0.2.0/tests/cuda/test_benchmark.py +97 -0
- vidmag-0.2.0/tests/cuda/test_color_cvt.py +73 -0
- vidmag-0.2.0/tests/cuda/test_device_array.py +164 -0
- vidmag-0.2.0/tests/cuda/test_device_buffer.py +48 -0
- vidmag-0.2.0/tests/cuda/test_device_resident_bandpass.py +159 -0
- vidmag-0.2.0/tests/cuda/test_lpyr.py +66 -0
- vidmag-0.2.0/tests/cuda/test_ops.py +199 -0
- vidmag-0.2.0/tests/cuda/test_pipelines.py +236 -0
- vidmag-0.2.0/tests/cuda/test_spatial.py +58 -0
- vidmag-0.2.0/tests/cuda/test_temporal.py +75 -0
- vidmag-0.2.0/tests/cuda/test_upsample.py +64 -0
- vidmag-0.2.0/tests/fixtures/golden_color_gdown_ideal.npz +0 -0
- vidmag-0.2.0/tests/fixtures/golden_input.npz +0 -0
- vidmag-0.2.0/tests/fixtures/golden_motion_lpyr_butter.npz +0 -0
- vidmag-0.2.0/tests/fixtures/golden_motion_lpyr_ideal.npz +0 -0
- vidmag-0.2.0/tests/fixtures/golden_motion_lpyr_iir.npz +0 -0
- vidmag-0.2.0/tests/test_against_mit_reference.py +74 -0
- vidmag-0.2.0/tests/test_api.py +553 -0
- vidmag-0.2.0/tests/test_backend_registry.py +215 -0
- vidmag-0.2.0/tests/test_cli.py +278 -0
- vidmag-0.2.0/tests/test_documentation.py +139 -0
- vidmag-0.2.0/tests/test_filters.py +101 -0
- vidmag-0.2.0/tests/test_generic_pipelines.py +140 -0
- vidmag-0.2.0/tests/test_golden.py +190 -0
- vidmag-0.2.0/tests/test_phase_based.py +226 -0
- vidmag-0.2.0/tests/test_pipeline.py +136 -0
- vidmag-0.2.0/tests/test_portable_backends.py +417 -0
- vidmag-0.2.0/tests/test_public_api.py +157 -0
- vidmag-0.2.0/tests/test_pyramids.py +82 -0
- vidmag-0.2.0/tests/test_reference_lock.py +123 -0
- vidmag-0.2.0/tests/test_streaming.py +155 -0
- vidmag-0.2.0/tests/test_video_encode.py +80 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Development Practices (binding)
|
|
2
|
+
|
|
3
|
+
These rules govern **how** every step of `docs/dev/PLAN.md` is implemented. They are
|
|
4
|
+
section 3d of that plan, committed here so every session loads them. They are not advice.
|
|
5
|
+
|
|
6
|
+
## 1. Test-driven — the check comes before the thing it checks
|
|
7
|
+
|
|
8
|
+
- Start each plan step by writing, or pointing at, the failing check named in that phase's
|
|
9
|
+
success criteria. No implementation file is created before that check exists.
|
|
10
|
+
- The check is a real command, not a claim. Examples in this repo:
|
|
11
|
+
`.venv/bin/python -m pytest tests/ -q -p no:randomly` (300 passed, 102 skipped on 2026-08-18),
|
|
12
|
+
`pytest tests/cuda/ -q` on a GPU host, `scripts/dev/verify_install.sh` for packaging work.
|
|
13
|
+
- Non-Python work gets a check too: a `src/vidmag/cuda/CMakeLists.txt` change is tested by a scripted
|
|
14
|
+
fresh-venv install, a docs change by `mkdocs build --strict` plus running its snippets.
|
|
15
|
+
- Phase 0 exists to build this net (golden fixtures, `tests/test_reference_lock.py`, recorded
|
|
16
|
+
baselines in `benches/`). Later red-green cycles run inside it.
|
|
17
|
+
|
|
18
|
+
## 2. KISS — two sanctioned abstraction layers, no third
|
|
19
|
+
|
|
20
|
+
- The only abstractions this restructure may introduce are `vidmag.backend.Ops` and
|
|
21
|
+
`vidmag.backend.Pipelines` (plan section 3c) plus the backend registry. Base classes, config
|
|
22
|
+
objects, plugin hooks or dispatch layers beyond those need the operator's approval first.
|
|
23
|
+
- Prefer a plain function to a class, a frozen dict to a config system, a copy-pasteable
|
|
24
|
+
example to a helper framework. `vidmag/` is written that way — match it.
|
|
25
|
+
|
|
26
|
+
## 3. YAGNI — build exactly the current step
|
|
27
|
+
|
|
28
|
+
- No speculative parameters, no "while I'm here" generality, no Phase 4 code smuggled into
|
|
29
|
+
Phase 1. If the plan looks wrong or incomplete, stop and surface the gap to the operator
|
|
30
|
+
instead of quietly building extra.
|
|
31
|
+
- Touch only the files your step names. No reformatting or refactoring of neighbouring code.
|
|
32
|
+
|
|
33
|
+
## 4. DRY — one source of truth, one named exception
|
|
34
|
+
|
|
35
|
+
- Single-sourced by design: the version string, the preset table, `tests/cuda/conftest.py:TOL`,
|
|
36
|
+
the conformance suite, the backend registry, and the reference constants
|
|
37
|
+
(`DROP_LAST`, `EXAGGERATION_FACTOR`, `BINOM5`, `BINOM5_SUM1`). Import them; never retype a
|
|
38
|
+
literal that can be imported. New duplication needs a stated reason in the commit message.
|
|
39
|
+
- **The named exception:** the FP32/FP16 pipeline bodies in `src/vidmag/cuda/batched.py` and the
|
|
40
|
+
templated kernels may stay duplicated where merging them risks numeric drift — the README's
|
|
41
|
+
accuracy claims (motion FP16 vs FP32 RMSE 0.00140) are load-bearing. Correctness outranks
|
|
42
|
+
DRY. Comment the exception at the site.
|
|
43
|
+
|
|
44
|
+
## 5. Fail loud
|
|
45
|
+
|
|
46
|
+
- No silent fallbacks and no silently skipped work. Backend selection is always printed; a
|
|
47
|
+
missing backend reports *why* (missing extra, no driver, no device). A ~700x CPU/GPU cliff
|
|
48
|
+
must never be reached by accident.
|
|
49
|
+
- No bare `except`. Every CUDA runtime call is wrapped in `CUDA_CHECK`
|
|
50
|
+
(`src/vidmag/cuda/include/evm_check.cuh`), which throws `std::runtime_error` so pybind11 surfaces it as
|
|
51
|
+
a catchable Python exception — "a silent error can never propagate into a tolerance
|
|
52
|
+
failure". Keep that posture in Python: raise, don't degrade.
|
|
53
|
+
- Report skip counts, never just passes. On this Mac the honest line is
|
|
54
|
+
"300 passed, 102 skipped" — those skips include the whole NVIDIA suite and prove
|
|
55
|
+
nothing about it. No single machine runs every backend.
|
|
56
|
+
- `tests/cuda/conftest.py:TOL` and `tests/test_against_mit_reference.py` are append-only.
|
|
57
|
+
Loosening a tolerance is its own separately reviewed commit carrying the measurement.
|
|
58
|
+
|
|
59
|
+
## 6. Verify, then claim; land one plan step per commit
|
|
60
|
+
|
|
61
|
+
- A step is done only when its named command has actually run and its output is recorded in
|
|
62
|
+
the report. "Should work" and "looks right" are not results.
|
|
63
|
+
- One plan step = one commit, full suite green, the step named in the message
|
|
64
|
+
(e.g. `Phase 1 step 1.6: make CUDA optional in CMake`), so history maps one-to-one onto
|
|
65
|
+
`docs/dev/PLAN.md`. Unrelated changes in that commit are not permitted.
|
|
66
|
+
- Do not commit unless the operator asked for it; the orchestrating session commits.
|
|
67
|
+
|
|
68
|
+
## 7. The NVIDIA GPU code leads; the other backends follow it
|
|
69
|
+
|
|
70
|
+
- Performance work starts in the NVIDIA GPU code — `src/vidmag/cuda/kernels/*.cu` and `src/vidmag/cuda/bindings.cpp`.
|
|
71
|
+
That is what this project exists to make fast, and it is where a measurement is worth taking.
|
|
72
|
+
- **A change to the NVIDIA code is not finished when it lands.** Once it is accepted, check
|
|
73
|
+
whether the same change applies to every other backend, and apply it where it does:
|
|
74
|
+
|
|
75
|
+
| Backend | Where its kernels live |
|
|
76
|
+
|---|---|
|
|
77
|
+
| OpenCL | `src/vidmag/opencl/kernels.cl` |
|
|
78
|
+
| Apple Metal | `src/vidmag/metal/kernels.metal` |
|
|
79
|
+
| Vulkan | `src/vidmag/vulkan/shaders/*.comp` |
|
|
80
|
+
| PyTorch | `src/vidmag/torch_backend/ops.py` (tensor operations, no kernels) |
|
|
81
|
+
| Processor (Python) | `src/vidmag/cpu/pyramids.py`, `src/vidmag/cpu/filters.py` |
|
|
82
|
+
|
|
83
|
+
- State which backends the change was carried to and which it does not apply to, with the
|
|
84
|
+
reason. "Does not apply, because that backend has no separate upsample kernel" is a complete
|
|
85
|
+
answer; saying nothing is not.
|
|
86
|
+
- Carry it in its own commit, separate from the NVIDIA change, so a numeric regression on one
|
|
87
|
+
backend cannot be mistaken for a fault in the original.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Editor defaults, matching the formatter this project already runs so that
|
|
2
|
+
# saving a file in any editor produces what `ruff format` would produce.
|
|
3
|
+
# Settings live in pyproject.toml under [tool.ruff]; these mirror them.
|
|
4
|
+
root = true
|
|
5
|
+
|
|
6
|
+
[*]
|
|
7
|
+
charset = utf-8
|
|
8
|
+
end_of_line = lf
|
|
9
|
+
insert_final_newline = true
|
|
10
|
+
trim_trailing_whitespace = true
|
|
11
|
+
indent_style = space
|
|
12
|
+
indent_size = 4
|
|
13
|
+
|
|
14
|
+
[*.{py,pyi}]
|
|
15
|
+
max_line_length = 88
|
|
16
|
+
|
|
17
|
+
# CUDA, C++ and the shader languages follow the same four-space style as the
|
|
18
|
+
# Python, which is what the existing kernel sources use.
|
|
19
|
+
[*.{cu,cuh,cpp,h,hpp,cl,metal,comp,glsl}]
|
|
20
|
+
indent_size = 4
|
|
21
|
+
|
|
22
|
+
[*.{yml,yaml,json,toml}]
|
|
23
|
+
indent_size = 2
|
|
24
|
+
|
|
25
|
+
[*.md]
|
|
26
|
+
# Two trailing spaces are a hard line break in Markdown; do not eat them.
|
|
27
|
+
trim_trailing_whitespace = false
|
|
28
|
+
|
|
29
|
+
[Makefile]
|
|
30
|
+
indent_style = tab
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Line endings and binary detection, declared rather than guessed.
|
|
2
|
+
#
|
|
3
|
+
# Git infers "binary" from content, and gets it right most of the time. The
|
|
4
|
+
# cost of the rare miss is high here: a compiled Vulkan shader or a test
|
|
5
|
+
# fixture that had line endings rewritten on checkout is silently corrupt, and
|
|
6
|
+
# the failure surfaces far from the cause. So the file types are stated.
|
|
7
|
+
|
|
8
|
+
# Text files: normalise to LF in the repository, whatever the editor wrote.
|
|
9
|
+
* text=auto eol=lf
|
|
10
|
+
|
|
11
|
+
# Shell scripts and Makefiles break outright with CRLF, so pin them.
|
|
12
|
+
*.sh text eol=lf
|
|
13
|
+
Makefile text eol=lf
|
|
14
|
+
|
|
15
|
+
# GPU kernel sources are text and read by a compiler at build or run time.
|
|
16
|
+
*.cu text eol=lf
|
|
17
|
+
*.cuh text eol=lf
|
|
18
|
+
*.cl text eol=lf
|
|
19
|
+
*.metal text eol=lf
|
|
20
|
+
*.comp text eol=lf
|
|
21
|
+
*.glsl text eol=lf
|
|
22
|
+
|
|
23
|
+
# Binary. Never converted, never diffed as text.
|
|
24
|
+
*.spv binary
|
|
25
|
+
*.npz binary
|
|
26
|
+
*.mp4 binary
|
|
27
|
+
*.gif binary
|
|
28
|
+
*.png binary
|
|
29
|
+
*.jpg binary
|
|
30
|
+
*.ipynb binary linguist-language=Python
|
|
31
|
+
|
|
32
|
+
# Keep the language statistics on the shelf honest: generated, vendored and
|
|
33
|
+
# non-source material should not count as the project's implementation.
|
|
34
|
+
docs/** linguist-documentation
|
|
35
|
+
benches/** linguist-generated
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Something is wrong
|
|
3
|
+
about: Report incorrect behaviour
|
|
4
|
+
title: ""
|
|
5
|
+
labels: bug
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**What happened, and what you expected instead**
|
|
9
|
+
|
|
10
|
+
**How to reproduce it**
|
|
11
|
+
|
|
12
|
+
The smallest script that shows the problem. If it needs a video, say which one
|
|
13
|
+
and where to get it.
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**What it printed**
|
|
19
|
+
|
|
20
|
+
Errors in full, please, not just the last line.
|
|
21
|
+
|
|
22
|
+
**Your setup**
|
|
23
|
+
|
|
24
|
+
- Version (`python -c "import vidmag; print(vidmag.__version__)"`):
|
|
25
|
+
- Backend (`python -c "from vidmag import backend; print(backend.select('auto')[0])"`):
|
|
26
|
+
- Operating system and Python version:
|
|
27
|
+
|
|
28
|
+
**Before you file: is the output identical to the input?**
|
|
29
|
+
|
|
30
|
+
That is usually the frequency band rather than a defect — a band narrower than
|
|
31
|
+
your clip can resolve selects nothing. The library warns when this happens.
|
|
32
|
+
[What can go wrong](../../docs/concepts/pitfalls.md) covers it and several
|
|
33
|
+
similar cases.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Result from hardware we cannot test
|
|
3
|
+
about: Report running the suite on an AMD, Intel or other device
|
|
4
|
+
title: "Hardware result: "
|
|
5
|
+
labels: hardware-report
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This project has an NVIDIA card and an Apple machine to test on, and nothing
|
|
9
|
+
else. Support for other hardware is described as expected rather than verified
|
|
10
|
+
because nobody has run it. A report here changes that.
|
|
11
|
+
|
|
12
|
+
**The device**
|
|
13
|
+
|
|
14
|
+
- Name as reported (`python -c "from vidmag.opencl import runtime; print(runtime.device_name())"`):
|
|
15
|
+
- Operating system and version:
|
|
16
|
+
- Driver version:
|
|
17
|
+
|
|
18
|
+
**Test suite**
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
python -m pytest tests/ -q
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Paste the output, including the skip count.
|
|
25
|
+
|
|
26
|
+
**Anything that failed**
|
|
27
|
+
|
|
28
|
+
Paste the failure in full.
|
|
29
|
+
|
|
30
|
+
**Speed, if you measured it**
|
|
31
|
+
|
|
32
|
+
The steps are in `benches/apple_m2_max_opencl_2026-08-10.md`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## What this changes, and why
|
|
2
|
+
|
|
3
|
+
<!-- What the change does, and the problem it solves. If it fixes an issue, link it. -->
|
|
4
|
+
|
|
5
|
+
## How it was verified
|
|
6
|
+
|
|
7
|
+
<!-- The commands you actually ran, with their output. Not "tests pass" — the
|
|
8
|
+
numbers. This project reports skip counts alongside pass counts, because no
|
|
9
|
+
single machine can run every backend: a machine without an NVIDIA card
|
|
10
|
+
skips that whole suite, and a machine with one has no Apple or OpenCL
|
|
11
|
+
driver. Say which machine you ran on. -->
|
|
12
|
+
|
|
13
|
+
- [ ] `python -m pytest tests/ -q -p no:randomly` — passed / skipped:
|
|
14
|
+
- [ ] `ruff check .` and `ruff format --check .`
|
|
15
|
+
- [ ] `mypy`
|
|
16
|
+
- [ ] Ran on (operating system, and graphics hardware if relevant):
|
|
17
|
+
|
|
18
|
+
## For performance changes
|
|
19
|
+
|
|
20
|
+
<!-- Delete if not applicable. -->
|
|
21
|
+
|
|
22
|
+
- [ ] Measured, with the before and after numbers and how they were taken
|
|
23
|
+
- [ ] Said which backends the change reached, and which it does not apply to
|
|
24
|
+
and why (see rule 7 in `.claude/rules/development-practices.md`)
|
|
25
|
+
|
|
26
|
+
## For changes that alter numerical output
|
|
27
|
+
|
|
28
|
+
<!-- Delete if not applicable. -->
|
|
29
|
+
|
|
30
|
+
- [ ] Compared against the NumPy baseline, which is the correctness oracle
|
|
31
|
+
- [ ] No tolerance in `tests/cuda/conftest.py` was loosened. Loosening one is a
|
|
32
|
+
separate pull request carrying the measurement that justifies it.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Config for actionlint (https://github.com/rhysd/actionlint).
|
|
2
|
+
#
|
|
3
|
+
# Without this, actionlint rejects `runs-on: [self-hosted, linux, x64, cuda]` in
|
|
4
|
+
# gpu.yml with "label \"cuda\" is unknown" — it has no way to know which custom
|
|
5
|
+
# labels this project's self-hosted runners carry. Declaring the label here is
|
|
6
|
+
# also the one place that says a runner must be registered with it; see
|
|
7
|
+
# docs/dev/gpu-runner.md.
|
|
8
|
+
self-hosted-runner:
|
|
9
|
+
labels:
|
|
10
|
+
- cuda
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Keeps the two things this project pins from going stale.
|
|
2
|
+
#
|
|
3
|
+
# The workflow actions are pinned to commit hashes, which is what stops a moved
|
|
4
|
+
# tag from running unreviewed code with this repository's credentials. The cost
|
|
5
|
+
# of that is that nothing updates them; this is what updates them, as a pull
|
|
6
|
+
# request that can be read before it is merged.
|
|
7
|
+
version: 2
|
|
8
|
+
updates:
|
|
9
|
+
- package-ecosystem: github-actions
|
|
10
|
+
directory: "/"
|
|
11
|
+
schedule:
|
|
12
|
+
interval: monthly
|
|
13
|
+
commit-message:
|
|
14
|
+
prefix: "ci"
|
|
15
|
+
labels: ["dependencies"]
|
|
16
|
+
|
|
17
|
+
- package-ecosystem: pip
|
|
18
|
+
directory: "/"
|
|
19
|
+
schedule:
|
|
20
|
+
interval: monthly
|
|
21
|
+
commit-message:
|
|
22
|
+
prefix: "deps"
|
|
23
|
+
labels: ["dependencies"]
|
|
24
|
+
# ruff and mypy are pinned exactly on purpose (see pyproject.toml): a new
|
|
25
|
+
# release adds rules, and a lint gate that turns red without anybody
|
|
26
|
+
# editing code is one people learn to ignore. Let Dependabot propose those
|
|
27
|
+
# bumps, but as their own pull request so the rule churn is reviewed alone.
|
|
28
|
+
groups:
|
|
29
|
+
runtime:
|
|
30
|
+
patterns: ["*"]
|
|
31
|
+
exclude-patterns: ["ruff", "mypy"]
|