NVIDIA / NVIDIA/cuQuantum

One-mode MPS NetworkState is rejected despite documented output layout

Open
#227 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Jupyter Notebook
Stars
499
Forks
102
PR merge metrics
No merged PRs in 30d

Description

Summary

NetworkState((2,), dtype="complex128", config=MPSConfig()) rejects a one-mode MPS at construction time. The documented open-boundary MPS layout implies that a one-site output has one physical mode and no left or right bond, so compute_output_state() should return one tensor with shape (2,).

Minimal reproducer
from cuquantum.tensornet.experimental import MPSConfig, NetworkState

with NetworkState((2,), dtype="complex128", config=MPSConfig()) as state:
    output = state.compute_output_state()
    print([tensor.shape for tensor in output])

Actual result:

Traceback (most recent call last):
  File "repro.py", line 3, in <module>
    with NetworkState((2,), dtype="complex128", config=MPSConfig()) as state:
         ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../cuquantum/tensornet/experimental/network_state.py", line 187, in __init__
    raise ValueError(f"For system with one physical dimension, please switch to tensor network simulation method via TNConfig")
ValueError: For system with one physical dimension, please switch to tensor network simulation method via TNConfig

No gate is needed to trigger the issue. Applying a one-qubit gate before requesting the output is currently impossible because construction fails.

Expected behavior

Construction succeeds, and compute_output_state() returns a sequence containing one tensor with shape (2,). This report does not make a claim about numerical output beyond that layout.

The compute_output_state() documentation says MPS tensors use pkn order and that the first tensor omits the left bond p while the last tensor omits the right bond n (source). For a tensor that is both first and last, both bonds are absent. set_initial_mps() documents the same open-boundary convention (source).

Source analysis

Current main and release v26.06.0 are both commit a097bf713ca999886a99b53b474439307956f2fd at the time of testing. The constructor explicitly rejects n == 1 with MPSConfig (lines 186-187). A test helper also expands one-qubit cases to two qubits as a workaround (lines 36-38).

Bypassing only the constructor guard in a source-level harness exposes the next failure in _maybe_set_target_state(): both cumulative-product arrays, and therefore max_extents, are empty for n == 1, but max_extents.max() is called (lines 939-945):

ValueError: zero-size array to reduction operation maximum which has no identity

The harness recorded no backend call before this failure. An otherwise identical two-mode control built target shapes [(2, 2), (2, 2)] and reached state_finalize_mps, so the empty reduction is specific to the one-mode extent construction.

A conceptual fix would be to special-case n == 1, or otherwise make target-extent construction robust to zero bonds, producing (state_mode_extents[0],) without reducing or indexing max_extents. Focused tests could cover one-mode output layout with and without max_extent, plus a simple one-qubit gate if supported by the backend.

Environment and limitation
  • OS: Linux 7.0.0-28-generic x86_64, glibc 2.43
  • Python: 3.13.13
  • GPU: NVIDIA GeForce RTX 4080, compute capability 8.9
  • Driver: 595.71.05
  • Driver-reported CUDA: 13.2
  • cuquantum-python-cu13: 26.6.0
  • cutensornet-cu13: 2.13.0
  • CuPy: 14.1.1
  • NumPy: 2.5.1
  • nvmath-python: 0.9.0
  • cuda-bindings: 13.3.1
  • cuda-core: 0.7.0

The official cutensor-cu13==2.7.0 wheel download repeatedly terminated before completion from both PyPI and NVIDIA's index, so I could not execute a full backend run. The public constructor traceback and the two-mode control above were reproduced with narrowly scoped mocks for pre-construction/backend hooks. The tested 26.6.0 wheel's network_state.py SHA-256 exactly matched the current checkout, and both failures occur in Python before GPU/backend execution.

No external code PR was opened because CONTRIBUTING.md states that code contributions are not accepted at this time.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in python/cuquantum/tensornet/experimental/network_state.py at the constructor guard around lines 186-187 and _maybe_set_target_state() around lines 939-945. Review the documented output layout and the trajectories_noise/network_state_wrap.py helper, then add focused coverage showing that a one-mode state returns one tensor shaped (2,), including max_extent and a simple gate if supported; done means these cases no longer fail during Python-side setup.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.