NVIDIA / NVIDIA/cuda-quantum

[Python] The lazy evaluation of lambda expressions causes the definition of ElementaryOperator to change unexpectedly

Open
#2,426 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

python-lang stale-notified
Dominant language
C++
Stars
1.1k
Forks
456
Avg merge
1d 22h
Merged PRs (30d)
165

Description

import cudaq
from cudaq import ElementaryOperator
import numpy as np

cudaq.set_target("dynamics")

n = 2
c_op = np.zeros((n, n), dtype=np.complex128)

ElementaryOperator.define(
    "c_op",
    expected_dimensions=[n],
    create= lambda: c_op,
)

c_op = np.array([[0, 1], [0, 0]] , dtype=np.complex128)

result = cudaq.evolve(
    hamiltonian=cudaq.operators.zero(0),
    dimensions={0: n},
    schedule=cudaq.Schedule([0, 1], "time"),
    initial_state=cudaq.State.from_data(np.identity(n, dtype=np.complex128) / n),
    collapse_operators=[ElementaryOperator("c_op", [0])]
)
print(np.array(result.final_state()))

As shown in this example, users can change the definition of an operator after it has been defined. While this behavior is correct according to Python's language specifications, it might lead to unexpected results for users.
In particular, if users use a for loop to call define, users need to be careful because the for loop may inadvertently change the operator definitions. For example,

for c_op in collapse_ops:
    cudaq.ElementaryOperator.define(
        f"c_op_{c_op}",
        expected_dimensions=[n],
        create= lambda: c_op,
    )

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 by running the supplied Python reproduction and tracing ElementaryOperator.define together with the lambda passed as create. Determine the intended behavior for later reassignment and loop-created operators, then add a regression test showing that completed definitions do not change unexpectedly.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
api
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.