## 10 Comparison to Other Implementations  
We compare the execution time and the number of gates our implementation generates against Qubiter and UQC. To obtain the total gate count, we use the number of lines in the output quantum assembly, which also includes rotation gates and not just CNOTs. The results for OpenQL, Qubiter and UQC are plotted in Figure 15. All of the implementations use an exact  
Figure 14: Additional memory allocated per line, for different sizes of unitary matrices \begin{table}
\begin{tabular}{c c c c c c c c c c} \hline \hline
**Line** & **1-Qubit** & **2-Qubit** & **3-Qubit** & **4-Qubit** & **5-Qubit** & **6-Qubit** & **7-Qubit** & **8-Qubit** & **9-Qubit** & **10-Qubit** \\ \hline Initial & 43.078 & 43.117 & 42.973 & 43.172 & 43.102 & 42.914 & 42.906 & 43.180 & 43.063 & 43.082 \\ \hline matrix = & & & & & & & & & & \\ np.load(...) & 0 & 0 & 0 & 0 & 0 & 0 & 0.734 & 1.375 & 4.570 \\ \hline u1 = ql.Unitary(...) & 0 & 0 & 0 & 0 & 0 & 0.766 & 1.855 & 3.258 & 12.160 & 48.141 \\ \hline u1.decompose() & 0 & 0 & 0 & 0 & 0.820 & 0.867 & 1.945 & 5.750 & 12.156 & 46.184 \\ \hline k.gate(...) & 0 & 0 & 0 & 1.230 & 0.660 & 1.711 & 6.441 & 27.582 & 120.65 & 483.65 \\ \hline p.add\_kernel(k) & 0 & 0 & 0 & 0 & 0 & 0 & 0.316 & 1.344 & 4.441 & 18.105 \\ \hline compiler.compile(p) & 0 & 0 & 0 & 0 & 0.313 & 0.328 & 1.535 & 6.039 & 24.141 & 16.137 \\ \hline \hline \end{tabular}
\end{table} 
Table 3: Additional memory allocated at each line of Listing 1 for the decomposition of unitary matrices of different sizes, in MiB. decomposition algorithm and therefore generate a constant number of gates for each size of the (non-sparse) input matrix. It is clear that OpenQL always generates fewer gates than Qubiter, and almost all of the difference is in the number of CNOTs. This is because we use QSD in our implementation of unitary decomposition in OpenQL. For a 10-qubit gate, unitary decomposition with OpenQL generates half as many CNOTs as Qubiter, and produces a total circuit that is almost 3 times as short. When compared to UQC, our OpenQL implementation generates about 50% more of any type of gate. This difference is because UQC uses an optimal circuit at the two-qubit gate level, where OpenQL uses another iteration of QSD and then ZYZ-decomposition, which results in more gates. The implementations are also compared on the time used to compute the unitary decompositions. The total wall-clock execution time for the decomposition and circuit generation of 2 to 10-qubit unitary gates can be found in Figure 16. The total execution time of all decompositions scales approximately linearly with the input matrix size (\(4^{n}\) for an \(n\)-qubit gate) for the decomposition of small matrices due to matrix loading and circuit generation operations and then becomes \(8^{n}\) when the decomposition of bigger matrices begins to take more time than the other steps. This is around the decomposition of seven-qubit unitary gates. Figure 16: Execution time of the decomposition and circuit generation for OpenQL, Qubiter and UQC for different sizes of unitary matrices. Figure 15: Number of generated CNOTs and total gates for OpenQL, UQC and Qubiter from the decomposition of different sizes of unitary matrices. As can be seen in the figure, OpenQL is considerably faster than Qubiter and UQC. When comparing the total execution times, it becomes clear that the OpenQL implementation takes more time per input matrix element (\(8^{n}\)) due to the use of CSD. Qubiter does not have that issue, but using unitary decomposition in OpenQL is about 10 to 100 times faster for the decomposition of 1 to 10-qubit unitary gates. This can most likely be attributed to the languages the compilers are programmed in and how well the implementation takes advantage of the programming language. Qubiter is written in Python and the UQC is written in Mathematica, both of which are considerably slower than C++, used for OpenQL [28].