Skip to content
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

cannot use @cudaq.kernel in the interpreter: OSError: could not get source code #2593

Open
3 of 4 tasks
jeffhammond opened this issue Feb 6, 2025 · 1 comment
Open
3 of 4 tasks

Comments

@jeffhammond
Copy link

Required prerequisites

  • Consult the security policy. If reporting a security vulnerability, do not report the bug using this form. Use the process described in the policy to report the issue.
  • Make sure you've read the documentation. Your issue may be addressed there.
  • Search the issue tracker to verify that this hasn't already been reported. +1 or comment there if it has.
  • If possible, make a PR with a failing test to give us a starting point to work on!

Describe the bug

I tried to run the demo on https://nvidia.github.io/cuda-quantum/latest/applications/python/vqe_advanced.html directly in the interpreter. It fails with the following:

>>> import cudaq
>>> @cudaq.kernel
... def kernel(qubit_num: int, electron_num: int, thetas: list[float]):
...     qubits = cudaq.qvector(qubit_num)
...
OSError: could not get source code

Steps to reproduce the bug

Type this into the interpreter and press return:

>>> import cudaq
>>> @cudaq.kernel
... def kernel(qubit_num: int, electron_num: int, thetas: list[float]):
...     qubits = cudaq.qvector(qubit_num)
...
OSError: could not get source code

Expected behavior

What the documentation describes on the aforementioned page.

Is this a regression? If it is, put the last known working version (or commit) here.

Not a regression

Environment

  • CUDA-Q version: latest. I ran pip install --upgrade cudaq today.
  • Python version: 3.10.12
  • C++ compiler: GCC 11.4
  • Operating system: Ubuntu 22.04.5 LTS

Suggestions

No response

@bebora
Copy link
Contributor

bebora commented Feb 11, 2025

Possible solution

The problem highlighted from @jeffhammond can be solved by using Python 3.13. Unfortunately, CUDA-Q does not support Python 3.13 at the moment (#2228).

inspect module related problems

There are two other situations that results in the same error. In these two cases, simply updating Python is not enough. The inspect module might have some limitations in these scenarios.

Interpreting from stdin

Assuming to have a valid CUDA-Q Python program, run:
cat program.py | python3
instead of the usual:
python3 program.py
The OSError will be raised.

Using dask from a Jupyter Notebook

Create a fresh venv and pip install dask distributed cudaq ipykernel jupyterlab.
Open three terminals:

  1. Load the venv and run dask scheduler
  2. Load the venv and run dask worker tcp://localhost:8786
  3. Load the venv and run jupyter lab

Open the url provided by the last command to open Jupyter in the browser.
Create a new Python 3 ipykernel file.
Add a cell with the following content:

from dask.distributed import Client
import dask

client = Client("tcp://localhost:8786")

qubit_count = 16

@dask.delayed
def function(qbits):
    import cudaq
    
    @cudaq.kernel
    def kernel(qubit_count: int):
        qubits = cudaq.qvector(qubit_count)
        h(qubits[0])
        for i in range(0, qubit_count-1):
            x.ctrl(qubits[i], qubits[i+1])
        mz(qubits)

    result = str(cudaq.sample(kernel, qbits, shots_count=100))
    return result

result = function(qubit_count).compute()
print(result)

Run the cell and the following error is shown (here are the last lines):

File ~/coding/cq_bugs/venv/lib/python3.10/site-packages/cudaq/kernel/kernel_decorator.py:69, in __init__()
     66     self.kernelFunction = function
     67     self.name = kernelName if kernelName != None else self.kernelFunction.__name__
     68     self.location = (inspect.getfile(self.kernelFunction),
---> 69                      inspect.getsourcelines(self.kernelFunction)[1]
     70                     ) if self.kernelFunction is not None else ('', 0)
     72 self.capturedDataStorage = None
     74 self.module = module

File /usr/lib/python3.10/inspect.py:1121, in getsourcelines()
   1113 """Return a list of source lines and starting line number for an object.
   1114 
   1115 The argument may be a module, class, method, function, traceback, frame,
   (...)
   1118 original source file the first line of code was found.  An OSError is
   1119 raised if the source code cannot be retrieved."""
   1120 object = unwrap(object)
-> 1121 lines, lnum = findsource(object)
   1123 if istraceback(object):
   1124     object = object.tb_frame

File /usr/lib/python3.10/inspect.py:950, in findsource()
    946     # Allow filenames in form of "<something>" to pass through.
    947     # `doctest` monkeypatches `linecache` module to enable
    948     # inspection, so let `linecache.getlines` to be called.
    949     if not (file.startswith('<') and file.endswith('>')):
--> 950         raise OSError('source code not available')
    952 module = getmodule(object, file)
    953 if module:

OSError: source code not available

Toggle the "Enable debugger" icon and run the cell again. The code will crash the first time but not the next times.
A similar behavior is exhibited when running the notebook inside VS Code. From my experiments, it will always crash when running and it will always work when debugging.

Minimal problematic code examples

The previous paragraphs showed CUDA-Q examples. Here are two ways to cause the usual error without importing cudaq, while keeping the problematic code inspection logic.

Standalone Python file (to be passed through stdin)

import inspect

def my_func():
    return 0xE4

print(inspect.getsourcelines(my_func))

Dask + Jupyter cell

from dask.distributed import Client
import dask

client = Client("tcp://localhost:8786")

@dask.delayed
def function():
    import inspect

    def my_func():
        return 0xE4
    
    return inspect.getsourcelines(my_func)

result = function().compute()
print(result)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants