Skip to content

Conversation

mpharrigan
Copy link
Collaborator

@mpharrigan mpharrigan commented Mar 10, 2025

This pull request is the second in a series for supporting open system (classical data & measurement), roadmap item #445.

This branch is based on #1584

Bloq.basis_state_phase

This new method can be overridden for phased-classical gates. In this PR, I show how CZ can support this new method. This leaves the basis states alone but applies a phase when 11 is encountered.

PhasedClassicalSimState(ClassicalSimState)

I refactored the classical simulator into a (mutable) class with initialization .from_cbloq(...), binst-by-binst stepping .step(), and finalization .finalize(). These can be combined with .simulate(), which is the new backend for the familiar entry points Bloq.call_classically(...) and friends.

Doing ordinary classical simulation will raise an error if it encounters a bloq with a non-trivial phase. The phased classical simulator will raise an error if it encounters a bloq without classical action; otherwise it will propagate phase. If a bloq does not specifically annotate a phase (but does indeed have classical action), the trivial +1 phase is assumed.

Non-changes (yet)

This PR does not directly support any "open systems" things. The ultimate goal is to support fuzz-testing measurement-based uncomputation. Since MBUC involves tracking phases, this PR is a necessary but not sufficient pre-requisite.

Related

@mpharrigan mpharrigan changed the title [open systems] Phased classical simulation [open-systems] Phased classical simulation Mar 11, 2025
@mpharrigan mpharrigan marked this pull request as ready for review April 9, 2025 22:39
@mpharrigan mpharrigan requested a review from tanujkhattar April 9, 2025 22:39
@mpharrigan mpharrigan merged commit 7b5c8d5 into quantumlib:main May 13, 2025
8 checks passed
wjhuggins pushed a commit to wjhuggins/Qualtran that referenced this pull request May 31, 2025
This pull request is the second in a series for supporting open system
(classical data & measurement), roadmap item
quantumlib#445.

~~This branch is based on quantumlib#1584~~

## `Bloq.basis_state_phase`

This new method can be overridden for phased-classical gates. In this
PR, I show how `CZ` can support this new method. This leaves the basis
states alone but applies a phase when `11` is encountered.

## `PhasedClassicalSimState(ClassicalSimState)`

I refactored the classical simulator into a (mutable) class with
initialization `.from_cbloq(...)`, binst-by-binst stepping `.step()`,
and finalization `.finalize()`. These can be combined with
`.simulate()`, which is the new backend for the familiar entry points
`Bloq.call_classically(...)` and friends.

Doing ordinary classical simulation will raise an error if it encounters
a bloq with a non-trivial phase. The phased classical simulator will
raise an error if it encounters a bloq without classical action;
otherwise it will propagate phase. If a bloq does not specifically
annotate a phase (but does indeed have classical action), the trivial +1
phase is assumed.

## Non-changes (yet)

This PR does not directly support any "open systems" things. The
ultimate goal is to support fuzz-testing measurement-based
uncomputation. Since MBUC involves tracking phases, this PR is a
necessary but not sufficient pre-requisite.

## Related

 - This PR unblocks quantumlib#1527 
 - quantumlib#1499 easier to test
- https://arxiv.org/abs/2105.13410 has a ton of cool circuit
constructions that can be tested with this
@mpharrigan mpharrigan deleted the 2025-03/classical-sim-1 branch June 11, 2025 17:39
mpharrigan added a commit that referenced this pull request Jul 14, 2025
This pull request is the third in a series for supporting open system
(classical data & measurement), roadmap item
#445.

~~This branch is based on #1590 (for my convenience; it doesn't use any
of that functionality)~~

## `Bloq.tensor_contract(superoperator=True)`

This is the new interface. It will return a 0-, 2-, or 4-dimensional
tensor for constants, density matrices, and superoperators (resp) to
support simulating programs with measurements and non-unitary maps. Read
the docs for the indexing convention for the superoperator; but if
you're really doing something with the superoperators you may want to
operate on the quimb tensor network with friendly indices itself.

## `cbloq_to_superquimb`

The workhorse of the new functionality is this function that converts a
composite bloq to a tensor network that represents the density matrix
and/or superoperator of the program. Some operations like measurement or
discarding qubits cannot be represented in a pure-state statevector /
unitary picture.

`cbloq_to_superquimb` still uses `Bloq.my_tensors` to construct the
network. It adds each tensor twice: once in the "forward" direction and
again in the "backward" (adjoint) direction.

## `DiscardInd`

The `Bloq.my_tensors` method can now return a `DiscardInd` object, which
signifies that that tensor index should be discarded by tracing it out.

It turns out that this simple extension lets you represent any CPTP map
using the "system+environment" modeling approach.


## `MeasZ`, `Discard`

This PR includes two non-unitary maps: measuring in the Z basis and
discarding a qubit or classical bit.


## Manipulating quimb tensor networks

This PR makes some changes to the way we handle outer indices in the
quimb tensor network. This should only be of interest to folks who use
the "hands on" approach of directly manipulating the tensor networks.
The changes make sense and clean up some of the docs.

The outer indices are now re-mapped to tuples of qualtran objects that
actually make sense rather than keeping them as `Connection`s to
`DanglingT` objects. There is a new flag `friendly_indices=True` which
will make the outer indices friendly strings.

**breaking change** I renamed and made-private the
`get_left_and_right_inds` function. The original idea was to use this as
a public way of getting a handle on the outer indices, but it was always
tricky to use; and needed to be changed to support the new variety of
outer indices present in the superoperator networks. No one should need
a replacement for this function since the `qtn.TensorNetwork` object
outer indices now just intrinsically make sense.

## Non-changes

This includes the minimal set of non-unitary CPTP bloqs to support the
docs notebooks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants