NVIDIA / NVIDIA/cuda-quantum

Simplify how target qubits are specified

Open
#3,604 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Required prerequisites
  • Search the issue tracker to check if your feature has already been mentioned or rejected in other issues.
Describe the feature

See below 2 ways in which to input the target qubit, one works but is cumbersome, the other is easier but throws an error:

import cudaq 
import numpy as np

cudaq.register_operation("U2", np.array([[0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1], [1, 1, 1, 0]]))

@cudaq.kernel
def kernel():
    
    a = cudaq.qvector(2)
    b = cudaq.qvector(2)
    
    #this works 
    U2.ctrl(a[0], b[0], b[1]) 
    
    #this throws an error even though we want to access both qubits in the b register of qubits 
    U2.ctrl(a[0], b) 


cudaq.sample(kernel)
print(cudaq.draw(kernel))
---------------------------------------------------------------------------
CompilerError                             Traceback (most recent call last)
Cell In[8], line 18
     13     U2.ctrl(a[0], b[0], b[1]) 
     15     U2.ctrl(a[0], b) 
---> 18 cudaq.sample(kernel)
     19 print(cudaq.draw(kernel))

File /opt/nvidia/cudaq/cudaq/runtime/sample.py:82, in sample(kernel, shots_count, noise_model, explicit_measurements, *args)
     77 if kernel.returnType is not None:
     78     raise RuntimeError(
     79         f"The `sample` API only supports kernels that return None (void). "
     80         f"Kernel '{kernel.name}' has return type '{kernel.returnType}'. "
     81         f"Consider using `run` for kernels that return values.")
---> 82 kernel.compile()
     83 if kernel.module is not None:
     84     for operation in kernel.module.body.operations:

File /opt/nvidia/cudaq/cudaq/kernel/kernel_decorator.py:217, in PyKernelDecorator.compile(self)
    213 self.capturedDataStorage = self.createStorage()
    215 # Caches the module and stores captured data into
    216 # `self.capturedDataStorage`.
--> 217 self.module, self.argTypes, extraMetadata = compile_to_mlir(
    218     self.astModule,
    219     self.capturedDataStorage,
...
    235     hasattr(ast, 'unparse') and astNode is not None else '') + Color.END
--> 236 raise CompilerError(msg)

CompilerError: 792669223.py:15: error: invalid target operand 1, broadcasting is not supported on custom operations.
	 (offending source -> U2.ctrl(a[0], b))
Output is truncated. View as a [scrollable element](command:cellOutput.enableScrolling?dde14a40-5418-49fd-91ae-87b7dac22649) or open in a [text editor](command:workbench.action.openLargeOutput?dde14a40-5418-49fd-91ae-87b7dac22649). Adjust cell output [settings](command:workbench.action.openSettings?%5B%22%40tag%3AnotebookOutputLayout%22%5D)...

The check here should be that the b register is n qubits given the registered gate is 2**n dimensional.

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 with the register_operation/U2.ctrl reproducer and follow the kernel.compile() path shown in the traceback. The completed change should allow a registered 2**n-dimensional operation to accept a target register of n qubits, while preserving the existing explicit-target form.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.