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

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

Vector Slicing

Tags: tutorial

Tutorial 02 introduced how to build parameterized qkernels and how to broadcast single-qubit gates over a whole register. This chapter introduces slicing, a Qamomile feature that helps you write more complex qkernels.

Basic slice syntax

Indexing a Vector[Qubit] with a Python slice (start:stop:step) returns a VectorView — a handle that refers to a sub-range of the parent vector. In most situations you can use it just like an ordinary Vector[Qubit].

<Figure size 600x496 with 1 Axes>

A few things to notice in demo:

  • evens = q[0::2] creates a VectorView covering the even-indexed qubits of q. Similarly, odds = q[1::2] covers the odd-indexed qubits.

  • The evens[i] = qmc.h(evens[i]) inside the loop follows the same affine pattern you saw in Tutorial 02 — each element is consumed and a new element handle replaces it.

  • VectorView can be used in much the same way as Vector[Qubit].

Inline shorthand

When the body is a single broadcastable operation, you don’t need to name the VectorView. Borrow, transform, and return in one statement.

<Figure size 600x496 with 1 Axes>

Nested slices

A VectorView can itself be sliced again to produce another VectorView. The result covers a sub-range of the parent VectorView. Each level borrows from the one above, and each level must be returned to its immediate parent before its grandparent can be touched.

Concretely: if outer = q[0::2] and inner = outer[1:3], the return order is inner → outer → root. Return inner to outer first, then outer to q.

<Figure size 600x496 with 1 Axes>

Passing a VectorView to a helper kernel

When a VectorView is passed to an external qkernel, it is treated the same as a Vector[Qubit].

<Figure size 850.5x828 with 1 Axes>

The same convention extends to the built-in helpers in qamomile.circuit.stdlib. qmc.qft, qmc.iqft, and qmc.qpe all take a Vector[Qubit] and work equally well on a VectorView.

<Figure size 631.5x496 with 1 Axes>

Splitting a qubit array via slicing

In Qamomile, you cannot directly split or merge the qubit array Vector[Qubit] itself. Slicing, however, lets you extract several VectorViews from one large qubit array, so you can write an algorithm as if you had multiple registers. Below, we apply QFT to the whole register and then apply QFT again to just a portion. Qamomile’s QFT (qmc.qft) takes a Vector[Qubit] as input, so without slicing you would have to write QFT from scratch inside your qkernel. With slicing, you can pull out a portion of the qubit array and skip that work.

<Figure size 774.5x496 with 1 Axes>

Error patterns with VectorView

A VectorView is created by borrowing the qubits specified by the slice from its parent qubit array Vector[Qubit]. From the parent’s perspective, those qubits are lent out; until they are returned, the parent Vector[Qubit] cannot access them directly. For the same reason, operations that consume the parent Vector[Qubit] as a whole are not allowed either. To return the lent qubits, you must perform a slice assignment.

Below we walk through error patterns where the lent qubits are accessed without first being returned.

Error type: QubitBorrowConflictError
Error message: Parent slot 'q[1]' is currently held by a VectorView slice.
Access it through the view, or let the view finish before touching the parent directly.
Error type: UnreturnedBorrowError
Error message: Array 'q' has unreturned slice-view borrows from q[slice].
Borrowed slots: q[0] (held by slice view), q[2] (held by slice view), q[4] (held by slice view)

Fix: Return every active view via slice assignment before consuming the parent:
  view = q[a:b:c]
  # ... use view ...
  q[a:b:c] = view  # explicit return
Error type: QubitBorrowConflictError
Error message: Parent slot 'q[2]' is already owned by another slice view 'q[slice]' and cannot be re-sliced while that view is live.  Consume / release the existing view before slicing the same range again.
Error type: AffineTypeError
Error message: Slice assignment RHS view 'q[slice]' no longer owns 'q[2]'; the parent's borrow record points at an unrelated view / element.  This view was likely drained by a later overlapping slice; reconstruct the view before assigning it back.

Next: Controlled Gates — qmc.control for built-in gates and sub-kernels, concrete vs symbolic control counts, and the catalogue of patterns that do not compose.