Skip to content

Internal issue with DataView iterator increment operator when size along at least one axis is zero #1621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
joeycarter opened this issue Apr 7, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@joeycarter
Copy link
Contributor

We discovered this issue with the DataView iterator increment operator when putting together #1598:

iterator &operator++()
{
int64_t next_axis = -1;
int64_t idx;
for (int64_t i = R; i > 0; --i) {
idx = i - 1;
if (indices[idx]++ < view.sizes[idx] - 1) {
next_axis = idx;
break;
}
indices[idx] = 0;
loc -= (view.sizes[idx] - 1) * view.strides[idx];
}
loc = next_axis == -1 ? -1 : loc + view.strides[next_axis];
return *this;
}

See the comment here for more details.

In short, when the size along at least one axis of the data view is zero, there's an issue with the multidimensional indexing computation that results in the loc variable increasing indefinitely until the program segfaults. Specifically, the issue is that view.sizes[idx] == 0 with idx == 1 on the first iteration, resulting in an underflow error when subtracting 1 from it (since view.sizes is of type size_t). We added an assert in #1598 to ensure that the iteration terminates before an underflow error occurs, but the original issue with the multidimensional indexing should be fixed properly.


As far as we are aware, there are no user-facing or internal functions that will trigger this error. To reproduce it, you can modify the NullQubit::Sample() function to the following

void Sample(DataView<double, 2> &samples, size_t)
{
    std::fill(samples.begin(), samples.end(), 0.0);
}

and execute the following workload:

import pennylane as qml

@qml.qjit
@qml.qnode(qml.device("null.qubit", wires=0, shots=10))
def circuit():
    return qml.sample()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant