eclipse-qrisp / Qrisp

Qrisp - a framework for high-level programming of Quantum computers
https://www.qrisp.eu/
Eclipse Public License 2.0
83 stars 23 forks source link

ConjugationEnvironment error #46

Open diehoq opened 4 months ago

diehoq commented 4 months ago

The following code raises Exception: Tried to perform operation cswap on unallocated qubit qbl_392.0, which seems to be a bug

def to_be_debugged(x, p, m):
    n = p.bit_length()
    u = qrisp.QuantumFloat(n)
    u[:] = p
    v = qrisp.QuantumFloat(n)
    v[:] = x
    r = qrisp.QuantumModulus(2 * p)
    r[:] = 0
    s = qrisp.QuantumModulus(2 * p)
    s[:] = 1

    f = qrisp.QuantumBool()
    f[:] = True
    for i in range(2 * n):
        a = qrisp.QuantumBool()

        with qrisp.control(a):
            qrisp.swap(u, v)
            qrisp.swap(r, s)
        # uncompute a
        qrisp.mcx([s[0]], a, ctrl_state="0")
        a.delete()

    r = p - r
    res = qrisp.QuantumModulus(p)
    for i in range(res.size):
        qrisp.swap(res[i], r[i])

    # Uncompute u,v,s,f
    f.flip()
    f.delete()
    qrisp.x(u)
    u.delete()
    v.delete()
    r.delete()
    s -= p
    s.delete()
    return res
p=7
t1 = qrisp.QuantumModulus(p)
t1[:] = 6
t2 = qrisp.QuantumModulus(p)
t2[:] = 2
m = qrisp.QuantumArray(qtype=qrisp.QuantumBool(), shape=(2*p.bit_length(),))
with qrisp.conjugate(to_be_debugged)(t1,p,m) as q:
    s = q*t2
for a in m:
    a.delete(verify=True)

ERROR:

{--------------------------------------------------------------------------- Exception Traceback (most recent call last) Cell In[29], [line 7](vscode-notebook-cell:?execution_count=29&line=7) [5](vscode-notebook-cell:?execution_count=29&line=5) t2[:] = 2 [6](vscode-notebook-cell:?execution_count=29&line=6) m = qrisp.QuantumArray(qtype=qrisp.QuantumBool(), shape=(2*p.bit_length(),)) ----> [7](vscode-notebook-cell:?execution_count=29&line=7) with qrisp.conjugate(to_be_debugged)(t1,p,m) as q: [8](vscode-notebook-cell:?execution_count=29&line=8) s = q*t2 [9](vscode-notebook-cell:?execution_count=29&line=9) for a in m: File [~\Documents\GitHub\Qrisp\src\qrisp\environments\conjugation_environment.py:163](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/conjugation_environment.py:163), in ConjugationEnvironment.__enter__(self) [161](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/conjugation_environment.py:161) instr = temp_data.pop(i) [162](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/conjugation_environment.py:162) if isinstance(instr, QuantumEnvironment): --> [163](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/conjugation_environment.py:163) instr.compile() [164](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/conjugation_environment.py:164) else: [165](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/conjugation_environment.py:165) self.env_qs.data.append(instr) File [~\Documents\GitHub\Qrisp\src\qrisp\environments\control_environment.py:336](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:336), in ControlEnvironment.compile(self) [332](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:332) instruction.qubits = [self.condition_truth_value] + list( [333](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:333) instruction.qubits [334](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:334) ) [335](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:335) # Append instruction --> [336](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:336) self.env_qs.append(instruction) [338](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:338) perm_unlock(ctrl_qubits) [340](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/environments/control_environment.py:340) if inversion_tracker == -1: File [~\Documents\GitHub\Qrisp\src\qrisp\core\quantum_session.py:446](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:446), in QuantumSession.append(self, operation_or_instruction, qubits, clbits) [444](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:444) if issubclass(operation_or_instruction.__class__, Instruction): [445](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:445) instruction = operation_or_instruction --> [446](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:446) self.append(instruction.op, instruction.qubits, instruction.clbits) [447](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:447) return [450](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:450) elif issubclass(operation_or_instruction.__class__, Operation): File [~\Documents\GitHub\Qrisp\src\qrisp\core\quantum_session.py:496](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:496), in QuantumSession.append(self, operation_or_instruction, qubits, clbits) [490](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:490) raise Exception( [491](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:491) f"Tried to perform operation {operation.name} on " [492](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:492) f"unallocated qubit {input}" [493](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:493) ) [495](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:495) if operation.name not in ["qb_alloc", "barrier"]: --> [496](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:496) check_alloc(qubits) [499](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:499) # We now need to merge the sessions and treat their differing environment [500](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:500) # levels. The idea here is that if a quantum session A is not identical to the [501](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:501) # environment session B, there have been no gates applied within that [502](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:502) # environment so far (otherwise merging would have occured). Thus, all data of A [503](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:503) # belongs into the original_data attribute of the environment with the highest [504](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:504) # level environment, where the environment quantum session isn't identical to A. [505](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:505) flattened_qubits = [] File [~\Documents\GitHub\Qrisp\src\qrisp\core\quantum_session.py:486](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:486), in QuantumSession.append..check_alloc(input, res) [484](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:484) if isinstance(input, list): [485](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:485) for item in input: --> [486](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:486) check_alloc(item) [487](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:487) else: [488](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:488) if not input.allocated: [489](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:489) # pass File [~\Documents\GitHub\Qrisp\src\qrisp\core\quantum_session.py:490](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:490), in QuantumSession.append..check_alloc(input, res) [487](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:487) else: [488](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:488) if not input.allocated: [489](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:489) # pass --> [490](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:490) raise Exception( [491](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:491) f"Tried to perform operation {operation.name} on " [492](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:492) f"unallocated qubit {input}" [493](https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/dpolimen/Documents/GitHub/Framework-Benchmarking/~/Documents/GitHub/Qrisp/src/qrisp/core/quantum_session.py:493) ) Exception: Tried to perform operation cswap on unallocated qubit qbl_400.0 }
positr0nium commented 4 months ago

Hi Diego, I fixed the issue within https://github.com/eclipse-qrisp/Qrisp/commit/46bdb971c3dc720ed0d24eacca00d10d11ca34f0 . Your code unfortunately has more problems. The QuantumVariables res and r are allocated within the function and are not being uncomputed. This should however be managable by allocating res and r prior to the conjugation and replacing the line r = p - r with an in-place function.

positr0nium commented 4 months ago

The following in-place function should do :)

from qrisp import *

# Performs a modular inplace right subtraction, ie.
# r = p - r
def inpl_rsub(r, p):
    x(r)
    r.inpl_adder(r.modulus+1, r)
    r += p

# Test function for a variety of inputs
for n in [5, 7, 13, 17, 19]:
    for p in range(n):

        r = QuantumModulus(n)

        h(r)
        init_r = r.duplicate(init = True)

        inpl_rsub(r, p)

        mes_res = multi_measurement([init_r, r])

        for init_r, r in mes_res.keys():
            if init_r is np.nan:
                continue
            if (p - init_r)%n != r:
                print(f"Adder failed for input constellation r = {init_r}, p = {p}")
                raise
diehoq commented 4 months ago

Thank you for the fix. I get what you mean for the QuantumVariable res, but r is indeed uncomputed within the algorithm. Do you mean something else?

positr0nium commented 4 months ago

With the line r = r - p You create a new QuantumVariable and call it r. The reference to the previous r is lost. The new r is uncomputed, while the old r stays alive. You can fix it by using the in-place function that I gave, because it doesn't create a new QuantumVariable

diehoq commented 4 months ago

Ah yes, indeed, and in this case you won't need to allocate it prior the conjugation