NVIDIA/cuda-quantum

Enable emitting circuit diagrams for unitary quantum kernels in LaTeX

bettinaheim opened this issue · 3 comments

Description

The CUDA-Q platform allows users to build and execute hybrid quantum-classical kernels. While learning CUDA-Q and also while developing with CUDA-Q, it is helpful to visualize quantum circuits and states to gain intuition, to spot check code, and to communicate with others. We need to expand the visualization functionality into CUDA-Q. CUDA-Q currently contains the ability to visualize unitary quantum kernels as circuit diagrams. These diagrams are emitted in ASCII. To facilitate incorporating such diagrams in papers and other materials, we would like to add support for emitting them in LaTeX instead.

Details

The documentation of the current draw function can be found here (Python) and here (C++).
The API is defined in draw.h, with the corresponding implementation of this functionality is in draw.cpp. This implementation should be extended to take an optional argument format , i.e. an additional overload

template<typename QuantumKernel, typename ...Args>
std::string cudaq::draw(std::string format, QuantumKernel &&kernel, Args&&... args)

should be created, where valid values for format are "ascii" or "latex", and a new Python binding should be created for that overload in py_draw.cpp.

Possible options for LaTeX package to generate circuit diagrams are qcircuit and yquant.

Hi, I have started working on this for unitary hack!
I would lean towards quantikz for the LaTeX output; I believe it is the most commonly used package. Is there a specific reason why you would prefer the other packages?

Hi, thanks for working on this!

I would lean towards quantikz for the LaTeX output; I believe it is the most commonly used package. Is there a specific reason why you would prefer the other packages?

I'm unsure which of the various packages is the most commonly used. I have tried most of them. The main disadvantage of quantikz is its syntax: the readability of the latex degrades rapidly as circuits become bigger.

Compare the code to generate:

image

(Image taken from yquant docs)

The following are the code taken from the documentation of each package:

  • quantikz:
\begin{quantikz}
& \gate{H} & \ctrl{1} & \gate{H}\gategroup[2,steps=3,style={innersep=6pt}]{reversed c-{\sc not}} & \ctrl{1} & \gate{H} & \ctrl{1} & & \\
& & \targ{} & \gate{H} & \targ{} & \gate{H} & \targ{} & \gate{H} &
\end{quantikz}
  • yquant:
\begin{tikzpicture}
   \begin{yquant*}
      h a;
      cnot b | a;
      [name=left]
      h -;
      cnot b | a;
      [name=right]
      h -;
      cnot b|a;
      h b;
  \end{yquant*}
  \node[fit=(left-0) (left-1) (right-0) (right-1),draw, inner sep=6pt, "reversed c\textsc{not}"] {}; 
\end{tikzpicture}

If there a need to analyze the output latex in order to solve a bug, quantikz syntax will make this debugging process much more difficult.

Hm, I am not sure if I would agree:

as soon as we reach 8 quantum gates, h will be highly overloaded in yquant ;)

Also an experience from just having implemented it:
If there is debugging to be done, it can be easier fixed in the existing draw function; The quantikz output takes all its layering code from the draw function.
The logic to produce quantikz then becomes rather simple:
https://github.com/freifrauvonbleifrei/cuda-quantum/blob/cf0cdd31bcae1c2b11aa980a8fb82cbe7976ce6f/runtime/cudaq/algorithms/draw.cpp#L598-L642
Conversely, for a given LaTeX statement you can easily find in which column of your diagram it is supposed to appear (try latex-formatting in your editor such that the tabs align, and it already looks similar to the diagram output).

But if you wanted to produce simplified yquant code like the above documentation example, there would need to be more logic (like checking if every gate gets a h in the respective layer, so you can write h -). And debugging for really large circuits, you would need to figure which exact LaTeX line introduces the error you see in a diagram.

I would argue that C++ readability in this case is more important than the readability of intermediate output.
Of course, the decision ultimately has to be made by the maintainers!