Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions python/pecos/slr/gen_codes/gen_qasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from __future__ import annotations

from pecos import __version__
from pecos.slr.vars import QReg


class QASMGenerator:
Expand Down Expand Up @@ -291,14 +292,22 @@ def qgate_qasm(self, op, repr_str: str | None = None):
op.qargs = (op.qargs,)

for q in op.qargs:
if isinstance(q, tuple):
if isinstance(q, QReg):
# Broadcasting across a qubit register is inconsistent with the current Permute
# strategy, so "unroll" broadcast operations to make them act on individual qubits.
# See, for example, https://github.com/PECOS-packages/PECOS/issues/95.
lines = [f"{repr_str} {qubit};" for qubit in q]
str_list.extend(lines)

elif isinstance(q, tuple):
if len(q) != op.qsize:
msg = f"Expected size {op.qsize} got size {len(q)}"
raise Exception(msg)
qs = ",".join([str(qi) for qi in q])
str_list.append(f"{repr_str} {qs};")

str_list.append(f"{repr_str} {str(q)};")
else:
str_list.append(f"{repr_str} {q};")
Copy link
Contributor Author

@perlinm perlinm Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me like that the unconditional final str_list.append(...) was a bug, and should have been inside an else statement. Otherwise this method first acts the gate on every qs in q and then again appends a gate on (the tuple) q.

Copy link
Member

@ciaranra ciaranra Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, SWAP is a unitary gate that could possibly be converted to a physical permute if a compiler is smart enough. There is a need to distinguish the two operations as you may what fine control and choose one over the other and do not want to rely on a compiler.

As far as rewriting QASM, the user should no longer be responsible with debugging that. This is the job of the language (e.g., SLR)/compiler. If the underlying base language had support for Permute, then that would make things cleaner; however, SLR needs to metaprogram features that are not supported by the base language which is essentially what higher languages have to do when converting to lower languages. They provide more facilities then the simpler underlying language provides.

That being said. I want to rewrite the Permute object to be a little more friendly to code generation and just stores the info in a nice manner to be handed off to the code generator function.

Copy link
Contributor Author

@perlinm perlinm Dec 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgrading SWAP to a "native gate" of the hardware is perfectly compatible with thinking of it as a unitary gate. Relabeling qubits does implement the desired unitary operation, and it is an advantage of trapped ion platform that it can perform SWAP gates perfectly 🙂! Not all platforms can do this. This is also a capability that can be leveraged by circuit-level compilers (search this paper for "swap mirroring", for example), but doing so requires that the hardware recognize SWAP as a native gate. This essentially "exposes" the virtual SWAP capability to compilers that work on the level of (say) pytket, cirq, or qiskit.

There is also precedent here: having a virtual native SWAP gate is directly analogous to virtual Rz gates on IBM devices. IBM devices accept Rz instructions, but do not actually apply any physical operations any qubits when asked to "apply" an Rz gate (they instead make a software-level update of a rotating frame).

From the perspective of compiler development, the way to get "fine control" and execute a specific sequence of physical operations is to build the circuit you want, and run it in "verbatim" mode to bypass/disable any compiler. Another option is to have compilation flags that toggle various compiler features. There is no control or choice removed by upgrading the SWAP gate to a native virtual operation (and in fact, at the moment you already "rely on a compiler" to convert a SWAP instruction into 3 MS gates).

Final point:

As far as rewriting QASM, the user should no longer be responsible with debugging that.

As a matter of practice, we have definitely resorted to examining QASM to debug PECOS and would appreciate the option to continue doing so 🙂

In any case, what are your thoughts of unrolling broadcast operations in this PR? Some fix for #95 is necessary to use both Permute and (say) Steane.sz in the same SLR (and Permute is used for Steane.t_tel).


return "\n".join(str_list)

Expand Down
Loading