cudaq.State.from_data silently misreads non-contiguous NumPy arrays (strides ignored on the host path)

Open Beginner friendly
#5,702 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
numpy, python
Domain
backend, data

Research direction

Read python/runtime/cudaq/algorithms/py_state.cpp, focusing on getNumpyBufferInfo and createStateFromPyBuffer and how the host 1-D and 2-D paths handle strides. Reproduce with the issue's non-contiguous NumPy column view and compare it with np.ascontiguousarray(view). Done means State.from_data honors strides or rejects non-contiguous input instead of silently returning wrong amplitudes.

Written by the indexing model from the issue text.

Description

stale-notified

Describe the bug

cudaq.State.from_data(arr) with a non-contiguous NumPy array (for example a column view A[:, 0], or the ground-state column V[:, 0] returned by np.linalg.eigh for a complex Hermitian matrix) produces a state whose amplitudes are wrong, with no error or warning. The data are read from the underlying buffer as if they were contiguous.

In python/runtime/cudaq/algorithms/py_state.cpp, getNumpyBufferInfo records info.strides, but the host 1-D path in createStateFromPyBuffer then calls state::from_data(std::make_pair(ptr, info.size)), reading info.size consecutive elements from info.ptr. The contiguity helpers (isCContiguous / isFContiguous) are only consulted for CuPy input via shouldCanonicalizeCupyArray; NumPy input is never canonicalized. (The 2-D path only tests strides[1] == itemsize to pick row- vs column-major, so a sliced 2-D array is affected too.) The code is the same on current main.

Steps to reproduce

CUDA-Q 0.15.1 (pip), numpy 2.5.0, Python 3.12, target qpp-cpu:

import numpy as np, cudaq
cudaq.set_target("qpp-cpu")

rng = np.random.default_rng(2)
A = rng.normal(size=(4, 2)) + 1j * rng.normal(size=(4, 2))
A[:, 0] /= np.linalg.norm(A[:, 0])
view = A[:, 0]                      # complex128, view.flags["C_CONTIGUOUS"] is False

@cudaq.kernel
def load(s: cudaq.State):
    q = cudaq.qvector(s)

for arr in (view, np.ascontiguousarray(view)):
    out = np.array(cudaq.get_state(load, cudaq.State.from_data(arr)))
    print(arr.flags["C_CONTIGUOUS"], np.max(np.abs(out - view)))

Output:

False 2.35e+00     <- wrong amplitudes, no error
True  0.00e+00

The common idiom w, V = np.linalg.eigh(H); cudaq.State.from_data(V[:, 0]) with a complex Hermitian H gives a max error of 1.06 in the same way. Real-valued input happens to be safe only because the required dtype cast to complex makes a contiguous copy.

Expected behavior

Either honor the strides (copy to a contiguous buffer, as np.ascontiguousarray does, mirroring what the CuPy path already does) or raise on non-contiguous input.

Impact

Any code that passes an eigenvector column or a slice of a larger array as an initial state gets a silently wrong simulation. Wrappers that use np.asarray(x, dtype=...) do not protect against it, because asarray returns the same strided buffer when the dtype already matches.

Environment

  • CUDA-Q 0.15.1 (pip, aca5853a), numpy 2.5.0, Python 3.12.3, Ubuntu (Linux 6.8), target qpp-cpu
  • Source inspected at main (549d6a0be): python/runtime/cudaq/algorithms/py_state.cpp, getNumpyBufferInfo / createStateFromPyBuffer / isCContiguous / shouldCanonicalizeCupyArray
Dominant language
C++
Stars
1.2k
Forks
490
Avg merge
1d 5h
Merged PRs (30d)
191

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

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.

More from NVIDIA/cuda-quantum

All issues in NVIDIA/cuda-quantum

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.