Skip to content

One-mode MPS NetworkState is rejected despite documented output layout #227

Description

@khlaifiabilel

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions