This is an automated email from the ASF dual-hosted git repository.

400Ping pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/mahout.git


The following commit(s) were added to refs/heads/main by this push:
     new 603dd36bb [Website] Add Community over Code Glasgow 2026 hackathon 
post with Colab notebook and slides (#1513)
603dd36bb is described below

commit 603dd36bb525ba2923823844ea2bd4b73b3d7e01
Author: Jie-Kai Chang <[email protected]>
AuthorDate: Wed Oct 14 13:59:13 2026 +0800

    [Website] Add Community over Code Glasgow 2026 hackathon post with Colab 
notebook and slides (#1513)
    
    * [Website] Add Community over Code Glasgow 2026 hackathon post with Colab 
notebook and slides
    
    Signed-off-by: 400Ping <[email protected]>
    
    * update
    
    Signed-off-by: 400Ping <[email protected]>
    
    * [Website] Format hackathon notebook with ruff
    
    Signed-off-by: 400Ping <[email protected]>
    
    ---------
    
    Signed-off-by: 400Ping <[email protected]>
---
 .../index.md                                       | 122 +++++
 .../slide-01.jpg                                   | Bin 0 -> 75774 bytes
 .../slide-02.jpg                                   | Bin 0 -> 94214 bytes
 .../slide-03.jpg                                   | Bin 0 -> 94548 bytes
 .../slide-04.jpg                                   | Bin 0 -> 96872 bytes
 .../slide-05.jpg                                   | Bin 0 -> 118171 bytes
 .../slide-06.jpg                                   | Bin 0 -> 101718 bytes
 .../slide-07.jpg                                   | Bin 0 -> 95610 bytes
 .../slide-08.jpg                                   | Bin 0 -> 116052 bytes
 .../slide-09.jpg                                   | Bin 0 -> 116024 bytes
 .../slide-10.jpg                                   | Bin 0 -> 110109 bytes
 .../slide-11.jpg                                   | Bin 0 -> 164889 bytes
 .../slide-12.jpg                                   | Bin 0 -> 86393 bytes
 .../slide-13.jpg                                   | Bin 0 -> 70780 bytes
 website/static/hackathon/mahout-hackathon-deck.pdf | Bin 0 -> 781208 bytes
 .../static/hackathon/mahout-hackathon-deck.pptx    | Bin 0 -> 1264326 bytes
 website/static/hackathon/mahout-hackathon-tasks.md | 135 ++++++
 .../static/hackathon/mahout_hackathon_colab.ipynb  | 513 +++++++++++++++++++++
 18 files changed, 770 insertions(+)

diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/index.md 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/index.md
new file mode 100644
index 000000000..3715e48dc
--- /dev/null
+++ b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/index.md
@@ -0,0 +1,122 @@
+---
+title: Apache Mahout Hackathon at Community over Code Glasgow 2026
+date: 2026-10-13
+tags: [news, hackathon, qumat, qdp]
+authors: [mahout-team]
+---
+
+Apache Mahout is running a hands-on hackathon at [Community over Code Glasgow 
2026](https://events.apache.org/events/2026/community-over-code/mahout.html). 
This post collects everything a participant needs in one place: the Google 
Colab notebook, the kickoff slides, and the task list.
+
+- **When:** Tuesday, 13 October 2026, 15:00 to 18:40
+- **Where:** The Wee Dram Room, Community over Code, Glasgow, UK
+- **Mentors:** Andrew Musselman and Krishna Dave, plus Mahout committers in 
the room
+- **Bring:** a laptop with Python 3.10 to 3.12, git and a GitHub account. No 
GPU needed; the GPU part runs in Colab.
+
+<!-- truncate -->
+
+## Downloads
+
+| | |
+|---|---|
+| **Colab notebook** | [![Open In 
Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/apache/mahout/blob/main/website/static/hackathon/mahout_hackathon_colab.ipynb)
 or <a href="pathname:///hackathon/mahout_hackathon_colab.ipynb" 
download>download the .ipynb</a> and upload it with **File > Upload notebook** 
in Colab |
+| **Kickoff slides** | [View as 
PDF](pathname:///hackathon/mahout-hackathon-deck.pdf) or <a 
href="pathname:///hackathon/mahout-hackathon-deck.pptx" download>download the 
.pptx</a>. The slides are also shown below. |
+| **Task sheet** | 
[mahout-hackathon-tasks.md](pathname:///hackathon/mahout-hackathon-tasks.md), 
with reproduction steps and ready-to-file issue text for every task |
+| **Event page** | [events.apache.org: Apache Mahout 
hackathon](https://events.apache.org/events/2026/community-over-code/mahout.html)
 |
+
+## Colab setup: one minute before you run anything
+
+Colab's default runtime is Python 3.13, and Mahout 0.6.0 supports Python 3.10 
to 3.12. Set the runtime first, or the install fails and the QDP part cannot 
run.
+
+1. Menu **Runtime > Change runtime type**.
+2. **Runtime version:** choose **2026.07** (Python 3.12.13), not "Latest".
+3. **Hardware accelerator:** choose **T4 GPU**.
+4. Click **Save**, then **Runtime > Run all**.
+
+The first cell prints the Python version. It should say `3.12`. If it says 
`3.13`, repeat step 2.
+
+The notebook follows the same order as the talk:
+
+- **Parts 0 to 3:** install, a Bell state, the same circuit on Qiskit, Cirq 
and Braket, and the state vector. Spend at most 10 minutes here.
+- **Parts 4 and 5:** optional extras, parameterized circuits and the swap test.
+- **Part 6:** QDP encoding on the GPU. Needs the T4 and the 2026.07 runtime.
+- **Part 7:** the task list, also reproduced below.
+
+## Kickoff slides
+
+*Quantum computing in Python with Qumat and QDP*, presented by Andrew K. 
Musselman and Krishna Dave. 
[PDF](pathname:///hackathon/mahout-hackathon-deck.pdf) · <a 
href="pathname:///hackathon/mahout-hackathon-deck.pptx" download>PPTX</a>
+
+![Slide 1: Apache Mahout, quantum computing in Python with Qumat and 
QDP](./slide-01.jpg)
+
+![Slide 2: What we will do today](./slide-02.jpg)
+
+![Slide 3: Apache Mahout, then and now](./slide-03.jpg)
+
+![Slide 4: Qumat, write once, run on any backend](./slide-04.jpg)
+
+![Slide 5: QDP, GPU-accelerated data encoding](./slide-05.jpg)
+
+![Slide 6: Install in one minute](./slide-06.jpg)
+
+![Slide 7: Hello, Bell state](./slide-07.jpg)
+
+![Slide 8: Same circuit, three backends](./slide-08.jpg)
+
+![Slide 9: Parameterized circuits for optimization](./slide-09.jpg)
+
+![Slide 10: QDP in four lines](./slide-10.jpg)
+
+![Slide 11: Pick a task, one to two hours each, no GPU](./slide-11.jpg)
+
+![Slide 12: From idea to merged pull request](./slide-12.jpg)
+
+![Slide 13: Let's build](./slide-13.jpg)
+
+## Hackathon tasks
+
+Every task is sized for one to two hours, needs no GPU, and ends in a pull 
request with a test. Claim a task by commenting on its issue. Full details, 
including reproduction steps, are in the [task 
sheet](pathname:///hackathon/mahout-hackathon-tasks.md).
+
+**Track A: Qumat (Python only).** All reproduced on `main` and on `qumat` 
0.6.0. Each issue has the reproduction steps.
+
+| # | Issue | Task |
+|---|---|---|
+| A1 | [#1506](https://github.com/apache/mahout/issues/1506) | Clear 
`ValueError` for an unknown backend name (today a `ModuleNotFoundError` leaks) |
+| A2 | [#1507](https://github.com/apache/mahout/issues/1507) | Unsupported 
`simulator_type` should raise instead of `print()` and silently continuing |
+| A3 | [#1508](https://github.com/apache/mahout/issues/1508) | Cirq backend 
ignores the initialized simulator and creates its own `cirq.Simulator()` |
+| A4 | [#1509](https://github.com/apache/mahout/issues/1509) | Bug: reusing a 
parameter name on two gates fails on Qiskit only (`name conflict adding 
parameter 't'`) |
+| A5 | [#1510](https://github.com/apache/mahout/issues/1510) | 
`create_empty_circuit()` without `num_qubits`: Qiskit raises, Cirq and Braket 
allocate on demand |
+| A6 | [#1511](https://github.com/apache/mahout/issues/1511) | Add **one** 
missing gate per person: S, S-dagger, T-dagger, CZ or Phase, on all three 
backends with a test |
+| A7 | [#1512](https://github.com/apache/mahout/issues/1512) | Python 3.13 
support: lift the `<3.13` cap in `pyproject.toml` and add 3.13 to CI |
+
+**Track B: QDP.** B1 to B3 are pure Python. B4 to B6 are Rust: take one only 
if `cargo` is already installed, and start the first `cargo build` right away 
(5 to 10 minutes). No CUDA needed, the build uses stubs like CI does.
+
+| # | Issue | Task |
+|---|---|---|
+| B1 | [#1469](https://github.com/apache/mahout/issues/1469) | `QdpBenchmark` 
does not validate builder argument ranges |
+| B2 | [#1331](https://github.com/apache/mahout/issues/1331) | QDP tests 
should skip, not error, when no GPU is present |
+| B3 | [#1468](https://github.com/apache/mahout/issues/1468) | File loader 
ignores the configured batch limit (one-line wrapper fix plus a test) |
+| B4 | [#1472](https://github.com/apache/mahout/issues/1472) | Read default 
LZ4-compressed Feather files (Rust reader) |
+| B5 | [#787](https://github.com/apache/mahout/issues/787) | NumPy file size 
check to prevent OOM (Rust reader) |
+| B6 | [#1436](https://github.com/apache/mahout/issues/1436) | 
`StreamingProducer`: `VecDeque` for O(1) buffer advance (Rust) |
+
+## From idea to merged pull request
+
+Setup takes about a minute in a terminal (not in Colab):
+
+```bash
+git clone https://github.com/<you>/mahout.git && cd mahout
+pip install uv
+uv sync                      # Qumat and the Python QDP package
+uv run pre-commit install    # ruff + type checks on every commit
+uv run pytest testing/qumat  # smoke test
+```
+
+Then: comment on the issue to claim it, branch, make the change with a test, 
and open a PR that links the issue. One committer approval is required to 
merge, so ping a mentor in the room. Your PR does not have to be finished by 
18:40; mentors will keep reviewing afterwards.
+
+## Getting help
+
+- In the room: ask a mentor.
+- Slack: the `#hackathon` channel on 
[apachecon.slack.com](https://apachecon.slack.com)
+- Mailing list: [[email protected]](mailto:[email protected]) 
(subscribe via [email protected])
+- Code and issues: [github.com/apache/mahout](https://github.com/apache/mahout)
+
+Have fun, and thanks for hacking on Apache Mahout!
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-01.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-01.jpg
new file mode 100644
index 000000000..c7e29beb5
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-01.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-02.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-02.jpg
new file mode 100644
index 000000000..ee3572da8
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-02.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-03.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-03.jpg
new file mode 100644
index 000000000..4d775977d
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-03.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-04.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-04.jpg
new file mode 100644
index 000000000..deb5c87b5
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-04.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-05.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-05.jpg
new file mode 100644
index 000000000..63e413b87
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-05.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-06.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-06.jpg
new file mode 100644
index 000000000..d4d05c2d0
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-06.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-07.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-07.jpg
new file mode 100644
index 000000000..bb4c3918d
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-07.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-08.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-08.jpg
new file mode 100644
index 000000000..df7100005
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-08.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-09.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-09.jpg
new file mode 100644
index 000000000..a98001088
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-09.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-10.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-10.jpg
new file mode 100644
index 000000000..4ba3447aa
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-10.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-11.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-11.jpg
new file mode 100644
index 000000000..3447db839
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-11.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-12.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-12.jpg
new file mode 100644
index 000000000..673e0eb7d
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-12.jpg differ
diff --git a/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-13.jpg 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-13.jpg
new file mode 100644
index 000000000..0fa724ac1
Binary files /dev/null and 
b/docs/blog/2026-10-13-Community-Over-Code-Hackathon/slide-13.jpg differ
diff --git a/website/static/hackathon/mahout-hackathon-deck.pdf 
b/website/static/hackathon/mahout-hackathon-deck.pdf
new file mode 100644
index 000000000..facc9af4c
Binary files /dev/null and b/website/static/hackathon/mahout-hackathon-deck.pdf 
differ
diff --git a/website/static/hackathon/mahout-hackathon-deck.pptx 
b/website/static/hackathon/mahout-hackathon-deck.pptx
new file mode 100644
index 000000000..a98597d6f
Binary files /dev/null and 
b/website/static/hackathon/mahout-hackathon-deck.pptx differ
diff --git a/website/static/hackathon/mahout-hackathon-tasks.md 
b/website/static/hackathon/mahout-hackathon-tasks.md
new file mode 100644
index 000000000..49e9486b9
--- /dev/null
+++ b/website/static/hackathon/mahout-hackathon-tasks.md
@@ -0,0 +1,135 @@
+# Apache Mahout Hackathon Tasks (3-hour format)
+
+**Schedule**
+
+| Time | What |
+|---|---|
+| 0:00 – 0:20 | Intro talk, `pip install qumat`, open the Colab notebook 
(Parts 0 to 3 only, 10 minutes) |
+| 0:20 – 0:30 | Pick a task below, comment on the issue to claim it, fork and 
branch |
+| 0:30 – 2:30 | Hack. Mentors in the room; one has a GPU box for QDP 
verification |
+| 2:30 – 3:00 | Show and tell: open PRs, demo, next steps |
+
+Every task below is sized for **one to two hours** and needs **no GPU**. Each 
one ends in a PR with a test. Anything bigger lives in the appendix for after 
the event.
+
+Setup for every task: `git clone` your fork, `pip install uv`, `uv sync`, `uv 
run pre-commit install`, `uv run pytest testing/qumat` (about a minute).
+
+---
+
+## Track A: Qumat (Python only)
+
+All items reproduced on 2026-10-09 against `main` (commit `bbce3c392`) and 
PyPI `qumat` 0.6.0. Code: `qumat/qumat.py` and 
`qumat/{qiskit,cirq,amazon_braket}_backend.py`. Tests: `testing/qumat/`. Each 
task has a GitHub issue; comment on it to claim the task.
+
+### A1 Clear error for an unknown backend name 
([#1506](https://github.com/apache/mahout/issues/1506))
+
+```python
+QuMat({"backend_name": "pennylane", "backend_options": {}})
+# ModuleNotFoundError: No module named 'qumat.pennylane_backend'
+```
+
+`QuMat.__init__` builds the module path from `backend_name` and lets the 
import error leak. Raise a `ValueError` listing the supported backends 
(`qiskit`, `cirq`, `amazon_braket`) and add a test.
+
+### A2 Unsupported `simulator_type` should raise, not `print()` 
([#1507](https://github.com/apache/mahout/issues/1507))
+
+```python
+QuMat({"backend_name": "cirq", "backend_options": {"simulator_type": 
"density_matrix"}})
+# prints "Simulator type 'density_matrix' is not supported in Cirq. Ignoring 
this argument" and runs anyway
+
+QuMat({"backend_name": "amazon_braket", "backend_options": {"simulator_type": 
"sv1"}})
+# prints "... Using default.", falls back to the AWS SV1 device, then fails 
with NoRegionError
+```
+
+`cirq_backend.py:34` and `amazon_braket_backend.py:51` `print()` and continue. 
Replace with a `ValueError` (or `warnings.warn`), add tests for the error path.
+
+### A3 Cirq backend ignores the initialized simulator 
([#1508](https://github.com/apache/mahout/issues/1508))
+
+`cirq_backend.initialize_backend` returns a simulator, but `execute_circuit` 
and `get_final_state_vector` create a fresh `cirq.Simulator()` and never use 
the `backend` argument. Make the backend object the one that runs the circuit. 
(Density-matrix support is a follow-up, see appendix.)
+
+### A4 Bug: reusing a parameter name on two gates fails on Qiskit only 
([#1509](https://github.com/apache/mahout/issues/1509))
+
+```python
+qc = QuMat(qiskit_config); qc.create_empty_circuit(2)
+qc.apply_rx_gate(0, "t"); qc.apply_rx_gate(1, "t")
+# qiskit:        CircuitError: "name conflict adding parameter 't'"
+# cirq:          ok  [Counter({3: 100})]
+# amazon_braket: ok  Counter({'11': 100})
+```
+
+Cache one `qiskit.circuit.Parameter` per name in the Qiskit backend and add a 
cross-backend test for shared parameters.
+
+### A5 `create_empty_circuit()` without `num_qubits` behaves differently per 
backend ([#1510](https://github.com/apache/mahout/issues/1510))
+
+```python
+qc.create_empty_circuit(); qc.apply_hadamard_gate(0)
+# qiskit:        CircuitError: 'Index 0 out of range for size 0.'
+# cirq / braket: ok, qubit allocated on demand
+```
+
+Pick one behavior (a clear `ValueError` from `QuMat` when `num_qubits` is 
missing is the quick option) and make all three backends match, with tests.
+
+### A6 Add one missing gate (one gate per person) 
([#1511](https://github.com/apache/mahout/issues/1511))
+
+`QuMat` exposes exactly `not, hadamard, cnot, toffoli, swap, cswap, pauli_x, 
pauli_y, pauli_z, t, rx, ry, rz, u`. Pick **one** of: **S**, **S-dagger**, 
**T-dagger**, **CZ**, **Phase P(λ)**. Add `QuMat.apply_<gate>_gate`, implement 
it in all three backends (copy the pattern of `apply_t_gate`), add a row to 
`docs/qumat/basic-gates.md`, and a test in 
`testing/qumat/test_single_qubit_gates.py` or `test_multi_qubit_gates.py` that 
checks the state vector on all backends.
+
+### A7 Python 3.13 support 
([#1512](https://github.com/apache/mahout/issues/1512))
+
+Lift the `<3.13` cap in `pyproject.toml` and add 3.13 to the CI matrix. All 
dependencies already ship 3.13 wheels.
+
+---
+
+## Track B: QDP
+
+### Python only, no Rust toolchain needed
+
+| # | Issue | Task | Where |
+|---|---|---|---|
+| B1 | [#1469](https://github.com/apache/mahout/issues/1469) | `QdpBenchmark` 
does not validate builder argument ranges (zero batches, zero qubits, negative 
warmup are accepted) | `qdp/qdp-python/qumat_qdp/`, pure Python; tests in 
`testing/qdp_python/` run without the extension |
+| B2 | [#1331](https://github.com/apache/mahout/issues/1331) | QDP tests 
instantiate `QdpEngine` or use `device="cuda"` without a GPU check | 
`testing/qdp/`; add `requires_qdp` / `pytest.mark.skipif` so the suite skips 
instead of erroring |
+| B3 | [#1468](https://github.com/apache/mahout/issues/1468) | Rust-backed 
file loader ignores the configured batch limit | one-line fix at 
`qumat_qdp/loader.py:620` (`batch_limit=None`) plus a unit test with a fake 
engine, like `testing/qdp_python/test_fallback.py`; a mentor verifies on the 
GPU box |
+
+### Rust, only if you already have `cargo` installed
+
+The first `cargo build` of `qdp-core` pulls arrow, parquet and friends and 
takes 5 to 10 minutes on a laptop, so start it right after claiming. No CUDA 
needed: without `nvcc` the build uses stubs (`QDP_NO_CUDA=1 cargo test -p 
qdp-core --test <name>`), exactly like CI.
+
+| # | Issue | Task | Where |
+|---|---|---|---|
+| B4 | [#1472](https://github.com/apache/mahout/issues/1472) | QDP cannot read 
default LZ4-compressed Feather files | `qdp-core/src/readers/arrow_ipc.rs`; 
enable Arrow's `ipc_compression` feature in `qdp/Cargo.toml`, add an LZ4 
fixture test to `qdp-core/tests/arrow_ipc_io.rs` |
+| B5 | [#787](https://github.com/apache/mahout/issues/787) | NumPy file size 
check to prevent OOM | `qdp-core/src/readers/numpy.rs`; check the file size 
against the expected shape before reading, test in `qdp-core/tests/numpy.rs` |
+| B6 | [#1436](https://github.com/apache/mahout/issues/1436) | 
`StreamingProducer`: use `VecDeque` for O(1) buffer advance | 
`qdp-core/src/pipeline_runner.rs`; the StreamingProducer inline tests run on 
CPU |
+
+---
+
+## Appendix: follow-ups after the hackathon
+
+Half-day and larger items, kept here so teams that finish early or want to 
continue afterwards can pick them up.
+
+**Qumat**
+
+- Density-matrix simulation on Cirq (`simulator_type="density_matrix"`), 
builds on A3.
+- Controlled rotations CRx, CRy, CRz and RZZ accepting a float or a parameter 
name.
+- Unified result format and bit ordering: today X on qubit 0 gives `{'01': 
10}` on Qiskit, `[Counter({2: 10})]` on Cirq, `Counter({'10': 10})` on Braket.
+- `QuMat.measure(qubits)`; `examples/qumat/quantum_teleportation.py` currently 
calls `qc.circuit.measure` directly, Qiskit only.
+- `QuMat.expectation_value(observable)` for Pauli strings, then 
parameter-shift gradients.
+- OpenQASM export, batch parameter sweeps, ansatz templates, 
`initialize_state(vector)` as the QDP-to-Qumat bridge.
+
+**QDP, fix on a laptop, verify once on a GPU**
+
+- [#1471](https://github.com/apache/mahout/issues/1471) `float32_pipeline` 
keyword mismatch in `qdp-python/src/lib.rs:36`
+- [#1467](https://github.com/apache/mahout/issues/1467) `.pt`/`.pth` loading: 
enable the existing `pytorch` feature in the wheel build (needs libtorch)
+- [#1434](https://github.com/apache/mahout/issues/1434) `Source` enum for 
`PipelineIterator`
+- [#1430](https://github.com/apache/mahout/issues/1430) fail fast when 
`estimate_memory()` exceeds free VRAM
+- [#1431](https://github.com/apache/mahout/issues/1431) PyO3 bindings for 
`Preprocessor`, then [#1432](https://github.com/apache/mahout/issues/1432) docs
+- [#1433](https://github.com/apache/mahout/issues/1433) `KernelElem` trait for 
the f32/f64 FFI stubs
+
+**QDP, needs CUDA kernel work**
+
+- [#1008](https://github.com/apache/mahout/issues/1008) ZZFeatureMap encoding
+- [#1370](https://github.com/apache/mahout/issues/1370) drop mid-stream D2H 
norm validation in batch encoding
+
+**Building QDP from source with a GPU** (your own Linux box or a Colab T4; 
first build 10 to 20 minutes on Colab):
+
+```bash
+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+export QDP_CUDA_ARCH_LIST=75          # T4; omit to build every supported 
architecture
+pip install --no-deps . && pip install ./qdp/qdp-python
+python -m pytest testing/qdp testing/qdp_python -q
+```
diff --git a/website/static/hackathon/mahout_hackathon_colab.ipynb 
b/website/static/hackathon/mahout_hackathon_colab.ipynb
new file mode 100644
index 000000000..fcfec78f8
--- /dev/null
+++ b/website/static/hackathon/mahout_hackathon_colab.ipynb
@@ -0,0 +1,513 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "cell-00",
+   "metadata": {},
+   "source": "# Apache Mahout Hackathon: Qumat and QDP in Google 
Colab\n\nWelcome! This notebook installs Apache Mahout's `qumat` package and 
walks through the examples from the kickoff talk, so you can run everything in 
the browser.\n\n## Before you run anything: set the runtime (1 
minute)\n\nColab's default runtime is **Python 3.13**, and Mahout 0.6.0 
supports **Python 3.10 to 3.12**. Pick the older runtime and a GPU first, 
otherwise the install fails and the QDP part cannot run.\n\n1. [...]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-01",
+   "metadata": {},
+   "source": "## Part 0: Install\n\nApache Mahout ships on PyPI as `qumat`. 
The current release, 0.6.0, declares **Python 3.10 to 3.12**. Run the next cell 
first: it tells you which Python this runtime has and what to do if it is 
newer.\n\n**If it reports Python 3.13 or newer** (the Colab default may have 
moved past 3.12): the clean fix is `Runtime > Change runtime type > Runtime 
version` and pick **2026.07** (Python 3.12.13), then `Runtime > Run all` again. 
Without that, pip silently fa [...]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-02",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import platform\n",
+    "import sys\n",
+    "\n",
+    "PY = sys.version_info[:2]\n",
+    "print(\"Python\", platform.python_version(), \"on\", 
platform.system())\n",
+    "!nvidia-smi -L 2>/dev/null || echo \"No GPU attached (that is fine for 
Parts 0-5)\"\n",
+    "\n",
+    "if PY > (3, 12):\n",
+    "    print(\n",
+    "        \"\\nThis Python is newer than qumat 0.6.0 declares. Recommended: 
Runtime > Change runtime type >\"\n",
+    "        \"\\nRuntime version > 2026.07 (Python 3.12), then Run all again. 
Step 1 will otherwise install\"\n",
+    "        \"\\nqumat with --ignore-requires-python; Step 2 (the QDP wheel) 
will be skipped.\"\n",
+    "    )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-03",
+   "metadata": {},
+   "source": "### Step 1: Qumat (pure Python, works everywhere)"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-04",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "if PY > (3, 12):\n",
+    "    # All of qumat 0.6.0's dependencies ship wheels for 3.13; only 
qumat's own metadata says <3.13.\n",
+    "    %pip install -q --ignore-requires-python \"qumat==0.6.0\"\n",
+    "else:\n",
+    "    %pip install -q qumat"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-05",
+   "metadata": {},
+   "source": "### Step 2: QDP, the GPU extra\n\n`pip install \"qumat[qdp]\"` 
adds the `qumat-qdp` package: a prebuilt Linux wheel for Python 3.10 to 3.12 
that bundles the Rust engine and CUDA kernels. It installs on any Linux 
machine, including a CPU-only Colab runtime, but it needs an NVIDIA GPU to 
actually encode anything (Part 6). There are no macOS, Windows or Python 3.13 
wheels, so the cell skips itself in those cases.\n\nChanging QDP's Rust or CUDA 
code means rebuilding it from sou [...]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-06",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "if platform.system() != \"Linux\":\n",
+    "    print(\"qumat-qdp only ships Linux wheels; skipping on\", 
platform.system())\n",
+    "elif PY > (3, 12):\n",
+    "    print(\n",
+    "        \"qumat-qdp has no wheel for Python\",\n",
+    "        platform.python_version(),\n",
+    "        \"- pin the runtime version to 2026.07 to use Part 6\",\n",
+    "    )\n",
+    "else:\n",
+    "    %pip install -q \"qumat[qdp]\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-07",
+   "metadata": {},
+   "source": "If Colab shows a *Restart runtime* button after the installs, 
click it and continue from the next cell. The packages stay installed."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-08",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from importlib.metadata import PackageNotFoundError, version\n",
+    "\n",
+    "from qumat import QuMat\n",
+    "\n",
+    "print(\"qumat    \", version(\"qumat\"))\n",
+    "try:\n",
+    "    print(\n",
+    "        \"qumat-qdp\",\n",
+    "        version(\"qumat-qdp\"),\n",
+    "        \"(GPU extra installed; needs a GPU at run time)\",\n",
+    "    )\n",
+    "except PackageNotFoundError:\n",
+    "    print(\"qumat-qdp not installed (Parts 1-5 do not need it)\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-09",
+   "metadata": {},
+   "source": "## Part 1: Your first circuit, a Bell state\n\n`QuMat` is the 
one class you need. You give it a backend config (which simulator to use and 
how many shots), then build the circuit gate by gate.\n\nA Bell state is the 
\"hello world\" of quantum computing: a Hadamard puts qubit 0 into 
superposition, and a CNOT entangles qubit 1 with it. Measuring should give only 
`00` and `11`, each about half the time."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-10",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "qiskit_config = {\n",
+    "    \"backend_name\": \"qiskit\",\n",
+    "    \"backend_options\": {\"simulator_type\": \"aer_simulator\", 
\"shots\": 1024},\n",
+    "}\n",
+    "\n",
+    "qc = QuMat(qiskit_config)\n",
+    "qc.create_empty_circuit(num_qubits=2)\n",
+    "qc.apply_hadamard_gate(0)\n",
+    "qc.apply_cnot_gate(0, 1)\n",
+    "\n",
+    "print(qc.draw())\n",
+    "counts = qc.execute_circuit()\n",
+    "print(counts)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-11",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import matplotlib.pyplot as plt\n",
+    "\n",
+    "plt.bar(counts.keys(), counts.values(), color=\"#F28C28\")\n",
+    "plt.title(\"Bell state, 1024 shots\")\n",
+    "plt.xlabel(\"measured bit string\")\n",
+    "plt.ylabel(\"counts\")\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-12",
+   "metadata": {},
+   "source": "**Try it:** add `qc.apply_pauli_x_gate(0)` before executing and 
see how the histogram changes."
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-13",
+   "metadata": {},
+   "source": "## Part 2: Same circuit, three backends\n\nThe backend is just a 
config dictionary. The same gate calls run on Qiskit Aer, Cirq, or the Amazon 
Braket local simulator."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-14",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def bell(backend_name, simulator_type, shots=100):\n",
+    "    qc = QuMat(\n",
+    "        {\n",
+    "            \"backend_name\": backend_name,\n",
+    "            \"backend_options\": {\"simulator_type\": simulator_type, 
\"shots\": shots},\n",
+    "        }\n",
+    "    )\n",
+    "    qc.create_empty_circuit(2)\n",
+    "    qc.apply_hadamard_gate(0)\n",
+    "    qc.apply_cnot_gate(0, 1)\n",
+    "    return qc.execute_circuit()\n",
+    "\n",
+    "\n",
+    "for name, sim in [\n",
+    "    (\"qiskit\", \"aer_simulator\"),\n",
+    "    (\"cirq\", \"default\"),\n",
+    "    (\"amazon_braket\", \"local\"),\n",
+    "]:\n",
+    "    print(f\"{name:14s} -> {bell(name, sim)}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-15",
+   "metadata": {},
+   "source": "Notice the result formats differ slightly: Qiskit and Braket 
return a dict of bit strings, Cirq returns a list with integer basis states 
(`3` is `11`). A small helper that normalizes these would make a nice hackathon 
contribution."
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-16",
+   "metadata": {},
+   "source": "## Part 3: Look at the state vector\n\nCounts are samples. 
`get_final_state_vector()` returns the exact amplitudes, which is handy for 
debugging and for teaching.\n\nFor the Bell state you should see amplitude 
`1/sqrt(2) ~ 0.707` on `|00>` and `|11>` and zero elsewhere."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-17",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "\n",
+    "qc = QuMat(qiskit_config)\n",
+    "qc.create_empty_circuit(2)\n",
+    "qc.apply_hadamard_gate(0)\n",
+    "qc.apply_cnot_gate(0, 1)\n",
+    "\n",
+    "state = np.asarray(qc.get_final_state_vector())\n",
+    "for index, amplitude in enumerate(state):\n",
+    "    print(\n",
+    "        f\"|{index:02b}>  amplitude = {np.round(amplitude, 3)}   
probability = {abs(amplitude) ** 2:.3f}\"\n",
+    "    )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-18",
+   "metadata": {},
+   "source": "## Part 4: Parameterized circuits and a tiny 
optimization\n\nRotation gates accept a **parameter name** instead of a number. 
You bind values when you execute, which is exactly what variational algorithms 
(VQE, QAOA, quantum ML) need.\n\nFirst, sweep `theta` on an `Rx` gate. Theory 
says `P(1) = sin^2(theta / 2)`."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-19",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "qc = QuMat(qiskit_config)\n",
+    "qc.create_empty_circuit(1)\n",
+    "qc.apply_rx_gate(0, \"theta\")  # symbolic parameter\n",
+    "\n",
+    "thetas = np.linspace(0, 2 * np.pi, 13)\n",
+    "measured = []\n",
+    "for theta in thetas:\n",
+    "    counts = qc.execute_circuit(parameter_values={\"theta\": 
float(theta)})\n",
+    "    measured.append(counts.get(\"1\", 0) / 1024)\n",
+    "\n",
+    "plt.plot(\n",
+    "    thetas, np.sin(thetas / 2) ** 2, label=\"theory: sin^2(theta/2)\", 
color=\"#1FA3A3\"\n",
+    ")\n",
+    "plt.plot(thetas, measured, \"o\", label=\"measured (1024 shots)\", 
color=\"#F28C28\")\n",
+    "plt.xlabel(\"theta\")\n",
+    "plt.ylabel(\"P(1)\")\n",
+    "plt.legend()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-20",
+   "metadata": {},
+   "source": "Now let an optimizer drive the parameter. The cost function runs 
the circuit and returns how far `P(1)` is from a target of 0.25. SciPy's COBYLA 
is gradient-free, so shot noise is fine."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-21",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from scipy.optimize import minimize\n",
+    "\n",
+    "TARGET = 0.25\n",
+    "history = []\n",
+    "\n",
+    "\n",
+    "def cost(x):\n",
+    "    counts = qc.execute_circuit(parameter_values={\"theta\": 
float(x[0])})\n",
+    "    p1 = counts.get(\"1\", 0) / 1024\n",
+    "    history.append(p1)\n",
+    "    return (p1 - TARGET) ** 2\n",
+    "\n",
+    "\n",
+    "result = minimize(\n",
+    "    cost, x0=[0.1], method=\"COBYLA\", options={\"maxiter\": 40, 
\"rhobeg\": 0.5}\n",
+    ")\n",
+    "print(f\"best theta = {result.x[0]:.3f}  (theory: {2 * 
np.arcsin(np.sqrt(TARGET)):.3f})\")\n",
+    "print(f\"P(1) at best theta = {history[-1]:.3f}\")\n",
+    "\n",
+    "plt.plot(history, color=\"#F28C28\")\n",
+    "plt.axhline(TARGET, linestyle=\"--\", color=\"#1FA3A3\", 
label=\"target\")\n",
+    "plt.xlabel(\"evaluation\")\n",
+    "plt.ylabel(\"P(1)\")\n",
+    "plt.legend()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-22",
+   "metadata": {},
+   "source": "## Part 5: Swap test, how similar are two states?\n\nQumat has a 
built-in swap test. `measure_overlap(q1, q2, ancilla_qubit)` returns the 
fidelity `|<psi|phi>|^2` between the states on two qubits.\n\n- `|0>` vs `|0>` 
should give about `1.0`\n- `|0>` vs `|+>` (after a Hadamard) should give about 
`0.5`\n- `|0>` vs `|1>` should give about `0.0`"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-23",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def overlap(prepare_second):\n",
+    "    qc = QuMat(\n",
+    "        {\n",
+    "            \"backend_name\": \"qiskit\",\n",
+    "            \"backend_options\": {\"simulator_type\": \"aer_simulator\", 
\"shots\": 4096},\n",
+    "        }\n",
+    "    )\n",
+    "    qc.create_empty_circuit(\n",
+    "        3\n",
+    "    )  # qubit 0 = ancilla, qubit 1 = |0>, qubit 2 = state under test\n",
+    "    prepare_second(qc)\n",
+    "    return qc.measure_overlap(1, 2, ancilla_qubit=0)\n",
+    "\n",
+    "\n",
+    "print(\"|0> vs |0> :\", round(overlap(lambda qc: None), 3))\n",
+    "print(\"|0> vs |+> :\", round(overlap(lambda qc: 
qc.apply_hadamard_gate(2)), 3))\n",
+    "print(\"|0> vs |1> :\", round(overlap(lambda qc: 
qc.apply_pauli_x_gate(2)), 3))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-24",
+   "metadata": {},
+   "source": "## Part 6 (GPU): QDP, encoding classical data on the GPU\n\nQDP 
(Quantum Data Plane) is the second half of Mahout. It is a Rust engine with 
CUDA kernels that turns classical data into quantum state vectors directly on 
the GPU and hands them to PyTorch through DLPack with no host copy.\n\n**This 
part needs a GPU runtime and a Python 3.10 to 3.12 runtime** (the `qumat-qdp` 
wheel has no 3.13 build yet). On the free tier pick `Runtime > Change runtime 
type > T4 GPU` and, if Par [...]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-25",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "try:\n",
+    "    import torch\n",
+    "\n",
+    "    HAS_GPU = torch.cuda.is_available()\n",
+    "except ImportError:  # torch is preinstalled on Colab; this only matters 
elsewhere\n",
+    "    HAS_GPU = False\n",
+    "\n",
+    "try:\n",
+    "    import _qdp  # the native extension inside the qumat-qdp wheel\n",
+    "\n",
+    "    HAS_QDP = True\n",
+    "except ImportError:\n",
+    "    HAS_QDP = False\n",
+    "\n",
+    "QDP_OK = HAS_GPU and HAS_QDP\n",
+    "print(\"CUDA available:\", HAS_GPU, \"| qumat-qdp installed:\", 
HAS_QDP)\n",
+    "if not HAS_GPU:\n",
+    "    print(\n",
+    "        \"Switch to a GPU runtime and re-run from Part 0 to try QDP. The 
cells below skip themselves.\"\n",
+    "    )\n",
+    "elif not HAS_QDP:\n",
+    "    print(\n",
+    "        \"GPU found, but the qumat-qdp wheel is not installed for 
Python\",\n",
+    "        platform.python_version() + \".\"\n",
+    "        \"\\nWheels exist for 3.10 to 3.12 only: Runtime > Change runtime 
type > Runtime version > 2026.07,\"\n",
+    "        \"\\nthen re-run from Part 0. The cells below skip 
themselves.\",\n",
+    "    )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-26",
+   "metadata": {},
+   "source": "QDP itself was installed in Part 0 (`pip install 
\"qumat[qdp]\"`). Encode four numbers into a 2-qubit state and check the 
amplitudes against NumPy."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-27",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "if QDP_OK:\n",
+    "    from qumat.qdp import QdpEngine\n",
+    "\n",
+    "    engine = QdpEngine(device_id=0)  # CUDA backend by default\n",
+    "\n",
+    "    data = [1.0, 2.0, 3.0, 4.0]\n",
+    "    qtensor = engine.encode(data, num_qubits=2, 
encoding_method=\"amplitude\")\n",
+    "\n",
+    "    # DLPack hand-off: single use, so convert once and keep the 
tensor.\n",
+    "    state = torch.from_dlpack(qtensor)\n",
+    "    print(\"shape:\", tuple(state.shape), \"dtype:\", state.dtype, 
\"device:\", state.device)\n",
+    "\n",
+    "    expected = np.array(data) / np.linalg.norm(data)\n",
+    "    print(\"GPU amplitudes :\", state[0].real.cpu().numpy().round(4))\n",
+    "    print(\"numpy reference:\", expected.round(4))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-28",
+   "metadata": {},
+   "source": "Batches are where QDP shines. Encode a few thousand samples at 
once and time it."
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "cell-29",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "if QDP_OK:\n",
+    "    import time\n",
+    "\n",
+    "    NUM_QUBITS = 10  # 1024 amplitudes per sample\n",
+    "    BATCH = 4096\n",
+    "    batch = torch.rand(BATCH, 2**NUM_QUBITS, dtype=torch.float32, 
device=\"cuda\")\n",
+    "\n",
+    "    torch.cuda.synchronize()\n",
+    "    t0 = time.perf_counter()\n",
+    "    qtensor = engine.encode(batch, num_qubits=NUM_QUBITS, 
encoding_method=\"amplitude\")\n",
+    "    states = torch.from_dlpack(qtensor)\n",
+    "    torch.cuda.synchronize()\n",
+    "    elapsed = time.perf_counter() - t0\n",
+    "\n",
+    "    print(\"encoded:\", tuple(states.shape), states.dtype, 
states.device)\n",
+    "    print(\n",
+    "        f\"{BATCH} samples in {elapsed * 1000:.1f} ms  ({BATCH / 
elapsed:,.0f} samples/s)\"\n",
+    "    )\n",
+    "\n",
+    "    # Each row is a normalized quantum state.\n",
+    "    norms = states.abs().pow(2).sum(dim=1)\n",
+    "    print(\"row norms (should all be ~1):\", 
norms[:5].cpu().numpy().round(4))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-30",
+   "metadata": {},
+   "source": "Other encoders use the same call: `encoding_method=\"angle\"` 
(one angle per qubit), `\"basis\"` (an integer index), `\"phase\"`, `\"iqp\"` 
and `\"iqp-z\"`. The encoded tensor can go straight into a PyTorch model; see 
`examples/qdp/simple.ipynb` in the repository for a full training loop."
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cell-31",
+   "metadata": {},
+   "source": [
+    "## Part 7: Hackathon tasks and how to contribute\n",
+    "\n",
+    "Today is a **3-hour** hackathon, so every task below is sized for one to 
two hours, needs no GPU, and ends in a PR with a test. The full sheet with 
reproduction steps and ready-to-file issue text is `tasks.md` in the hackathon 
kit; bigger follow-ups are in its appendix.\n",
+    "\n",
+    "**Track A: Qumat (Python only).** All reproduced on `main` and on `qumat` 
0.6.0.\n",
+    "\n",
+    "| # | Issue | Task |\n",
+    "|---|---|---|\n",
+    "| A1 | [#1506](https://github.com/apache/mahout/issues/1506) | Clear 
`ValueError` for an unknown backend name (today a `ModuleNotFoundError` leaks) 
|\n",
+    "| A2 | [#1507](https://github.com/apache/mahout/issues/1507) | 
Unsupported `simulator_type` should raise instead of `print()` and silently 
continuing |\n",
+    "| A3 | [#1508](https://github.com/apache/mahout/issues/1508) | Cirq 
backend ignores the initialized simulator and creates its own 
`cirq.Simulator()` |\n",
+    "| A4 | [#1509](https://github.com/apache/mahout/issues/1509) | Bug: 
reusing a parameter name on two gates fails on Qiskit only (`name conflict 
adding parameter 't'`) |\n",
+    "| A5 | [#1510](https://github.com/apache/mahout/issues/1510) | 
`create_empty_circuit()` without `num_qubits`: Qiskit raises, Cirq and Braket 
allocate on demand |\n",
+    "| A6 | [#1511](https://github.com/apache/mahout/issues/1511) | Add 
**one** missing gate per person: S, S-dagger, T-dagger, CZ or Phase, on all 
three backends with a test |\n",
+    "| A7 | [#1512](https://github.com/apache/mahout/issues/1512) | Python 
3.13 support: lift the `<3.13` cap in `pyproject.toml` and add 3.13 to CI (all 
dependencies already ship 3.13 wheels; see Part 0) |\n",
+    "\n",
+    "**Track B: QDP.** B1 to B3 are pure Python. B4 to B6 are Rust: take one 
only if `cargo` is already installed, and start the first `cargo build` right 
away (5 to 10 minutes). No CUDA needed, the build uses stubs like CI does.\n",
+    "\n",
+    "| # | Issue | Task |\n",
+    "|---|---|---|\n",
+    "| B1 | [#1469](https://github.com/apache/mahout/issues/1469) | 
`QdpBenchmark` does not validate builder argument ranges |\n",
+    "| B2 | [#1331](https://github.com/apache/mahout/issues/1331) | QDP tests 
should skip, not error, when no GPU is present |\n",
+    "| B3 | [#1468](https://github.com/apache/mahout/issues/1468) | File 
loader ignores the configured batch limit (one-line wrapper fix plus a test) 
|\n",
+    "| B4 | [#1472](https://github.com/apache/mahout/issues/1472) | Read 
default LZ4-compressed Feather files (Rust reader) |\n",
+    "| B5 | [#787](https://github.com/apache/mahout/issues/787) | NumPy file 
size check to prevent OOM (Rust reader) |\n",
+    "| B6 | [#1436](https://github.com/apache/mahout/issues/1436) | 
`StreamingProducer`: `VecDeque` for O(1) buffer advance (Rust) |\n",
+    "\n",
+    "**Setup** (in a terminal, not in Colab; about a minute):\n",
+    "\n",
+    "```bash\n",
+    "git clone https://github.com/<you>/mahout.git && cd mahout\n",
+    "pip install uv\n",
+    "uv sync                      # Qumat and the Python QDP package\n",
+    "uv run pre-commit install    # ruff + type checks on every commit\n",
+    "uv run pytest testing/qumat  # smoke test\n",
+    "```\n",
+    "\n",
+    "**Workflow:** comment on the issue to claim it, branch, make the change 
with a test, open a PR that links the issue. One committer approval is required 
to merge, so ping a mentor in the room. Discussion happens on 
[email protected].\n",
+    "\n",
+    "Have fun, and thanks for hacking on Apache Mahout!"
+   ]
+  }
+ ],
+ "metadata": {
+  "accelerator": "GPU",
+  "colab": {
+   "gpuType": "T4",
+   "name": "mahout_hackathon_colab.ipynb",
+   "provenance": []
+  },
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "name": "python"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}

Reply via email to