A High-Level Quantum Templating Language

Marcus Edwards
13 min readNov 27, 2024

--

Here I propose a universal high-level cloud-native programming language for quantum computing, called High Level Quantum or HLQ. The language is universal in the sense that it supports compilation to each of the assembly languages that correspond with the quantum information processing paradigms that exist in the emerging quantum computing industry. The language is easily extensible to include future paradigms as well.

A truly universal programming language for quantum computing needs to support a growing variety of quantum information processing paradigms. In order to keep up with the growth of the quantum computing industry, it needs to be easily extensible and scalable. On the other hand, it must consist of well-defined unadulterated representations of the laws of quantum physics to be accepted by the science community. This balance suggests that a fast-moving, but strongly typed language that allows for specificity could be a good choice for the underlying language implementation.

I believe that this language could one day become a notable step in the development of the hybrid quantum cloud since it is a (the first?) language that attempts to bring the different quantum computing paradigms of the several industry companies together into one open-source and community-managed technology. However, I stand on the shoulders of giants in this work. Without the underlying technology developed by IBM [3] and Xanadu [4] this technology could never exist.

The types of quantum information processors we see in the emerging quantum computing industry include ion trap [6], superconducting [3, 7, 8], photonic [4] and topological [5] quantum computers. D-Wave has also produced superconducting qubit based quantum annealers. These can be categorized as instances of a few computing paradigms: gate model qubit quantum computing, continuous variable quantum computing, and quantum annealing. Each of these has its corresponding low-level programming language. These include IBM’s OpenQASM [11] for qubit computing, Xanadu’s BlackBird [12] for CV computing and Scott Pakin’s QMASM [13] out of Los Alamos National Laboratory for quantum annealing.

The need for a universal quantum programming language, and for smart quantum software has been acknowledged in several spheres. On July 26th, 2019 an article was published online called ”Towards a Universal Quantum Programming Language” [14] which outlined the necessity of developing such a language, and its current relevance, saying in conclusion:

“If we are going to get a universal quantum language, most likely it
has yet to be invented. Now is a great time for language designers
and implementers to try new ideas.”

The need for such a technology has also been acknowledged in academia. An article by Rigetti published in Nature International Journal of Science entitled “First Quantum Computers need Smart Software” [15] says explicitly:

“Easy programming interfaces are crucial to making quantum computers widely usable; examples include Quil and OpenQASM from IBM. More sophisticated options still need to be added, such as optimizations for specific types of processors. Higher-level languages for writing and compiling quantum programs also need to be developed.”

This paper also describes important considerations for a high-level quantum programming language’s development. These can be taken as guiding principles for this work. One such principle which HLQ takes to heart is described succinctly in this paper: “Researchers must resist pressure to standardize tools prematurely or keep the high-level, exploratory parts of the programming stack proprietary” [15]. HLQ also does not impose a limiting standardization on high-level descriptors of quantum systems since is it is so extensible.

This philosophy is similarly what has driven me to become a contributor to
Xanadu’s core StrawberryFields codebase on a voluntary basis, and a co-author of the 0.10 release [17].

The article in Nature “First Quantum Computers need Smart Software” [15]
concludes with a final point, saying:

“Finally, the quantum-computing community must prioritize engagement with experts in areas such as simulation and machine learning.”

This statement in a way describes the fundamental motivation for HLQ’s
existence. Having been deeply involved in both, I desire to bring the knowledge and community of quantum and classical computing together. HLQ is fundamentally a language in which classical and quantum ideas can be efficiently expressed together. A programming language well-suited to its application is as fundamental a descriptor of information systems as the language of mathematics itself. Hence, the structure and design of HLQ takes inspiration from prior work in each of classical computing, quantum computing and quantum physics in order to be well-suited to its purpose:

• The fastest-growing web programming framework Vue.js
• The foundational hardware description language VHDL
• Low-level quantum assembly languages
• The gate model of unitary quantum transformations
• The Hamiltonian description of quantum systems

The hope is that there will be familiar elements in the language to developers, engineers and physicists from each layer of the tech and information science stack.

HLQ brings together OpenQASM, BlackBird and QMASM to create a unified quantum programming language. HLQ effectively transforms these assembly languages into tools for defining language primitives. A primitive in HLQ can be described in any one, or multiple, of these languages. HLQ is then capable of composing these primitives in such a way that they can work together to solve a problem. HLQ then prepares the elements of the composed hybrid code for execution in the appropriate environment.

Possible Implementation

In one possible implementation of the language, HLQ would be possible to compile and execute due to the existence of a complex, distributed cloud backend. Once HLQ has determined what sort of execution is appropriate for each element of the hybrid code, and the measurement interfaces that will be necessary for the elements to communicate between one another, it would make calls to the Quantum Experiment Engine (QEE) [16]. The Quantum Experiment Engine then determines exactly how to best execute the given elements of the hybrid algorithm. The QEE is capable of orchestrating the execution of hybrid code via various simulation techniques with a quantum co-processor.

Via HLQ’s syntax and typing system, each element of a hybrid algorithm can be explicitly or inferentially parameterized for a specific execution methodology. A developer may have different priorities when it comes to the purpose of each of their algorithm’s hybrid elements. So, the QEE is capable of bypassing its default algorithm execution optimization to prioritize the verbosity, readout format, and backend preferences of the developer.

The QEE backend would intelligently distribute the processing and aggregate the results of a hybrid algorithm’s elements such that a developer makes use of results from various types of quantum and classical execution backends between each line of HLQ code without needing to be concerned about how / where the underlying primitives of each line were executed.

Language

HLQ defines a composition based abstracted functional programming methodology for writing cloud-native hybrid quantum algorithms. HLQ is a system that allows a developer to compose quantum operations using a straightforward syntax. When composing the core of a hybrid algorithm, a developer is fundamentally describing a set of input/output transfer functions analogous to the transfer functions which are used to describe linear and non-linear transformations of signals in memoryless analog signal processing. This is because realizable hybrid algorithms do not involve quantum memories.

Rather, a hybrid algorithm should compose input / output functions whilst making use of quantum co-processing. Then, once results from a functional hybrid algorithm are accumulated, classical memories can be used transactionally in the typical fashion. Hence, an HLQ program will contain two distinct sorts of code blocks: functional and procedural blocks. All uses of quantum co-processing are restricted to the functional blocks. Classical transfer functions can be used with quantum operators of different types throughout a block of functional programming. However, only classical programming can be included in procedural blocks of code.

A runnable HLQ script uses a different file format than an importable Component script. Attempting to import a runnable script or attempting to run an importable script will raise an error.

Functional Programming

Template System

Inspired by the spread of XML-derived templating systems like React’s JSX and Vue’s component markup, HLQ makes use of XML-like templates to describe its Components as well. These tags come built-in:

• TransferFunction (encapsulates a transfer function’s definition)
• Params (contains declarations of any parameters for its parent Transfer-
Function)
• Interface (describes a possible output format for its parents TransferFunction)
• QASM (contains parameterized or static QASM assembly code)
• BlackBird (contains parameterized or static BlackBird assembly code)
• QMASM (contains parameterized or static QMASM assembly code)

A TransferFunction should contain functional code which may make use
of other imported Components. Imported Components may be composed via bracketed nesting. A TransferFunction does not need to contain a Params tag, but must include at least one Interface.

<TransferFunction>
<Params>

</Params>

<Interface>

</Interface>
</TransferFunction>

Type System

The type system is what HLQ uses to validate and understand the composition of the various types of quantum and classical transfer functions. The available types for quantum data at the time of release include:

• Transmon (superconducting qubits)
• Gaussian (photonic qumode Gaussian states)
• Ising (parameterized Ising Hamiltonians)

The type of an element in a functional code block is denoted with the element’s tag like so:

<tag:type>
</tag>

Any element can be explicitly typed. In Component definitions, every element must be typed. However, when a multi-type Component is imported and used by a higher-order Component, the type can be omitted in the higher-order TransferFunction’s definition in order to denote that the type of the imported Component should be automatically chosen via type inference.
Elements which must have types include TransferFunctions and Interfaces. Only one TransferFunction per type can be described per HLQ file. When a file is imported, its filename can be used to reference its Component in the importing script.

Import System

HLQ uses a single page component idea similar to Vue’s. Each HLQ file represents a Component. Any HLQ file automatically exports the TransferFunctions found in it. Each importable file should fundamentally describe one functional TransferFunction, which may be defined in several different quantum computing paradigms via the types system. This is so that the file structure mirrors the functional nature of the Components themselves.

Primitive Components

The lowest order Components should be defined not in terms of other imported Components, but in an assembly language. Assembly language code can be included in a TransferFunction definition using an appropriate built-in tag. The assembly code should make up the tag’s body. This code can be parameterized using a format similar to JavaScript’s string templating. Any variables referenced as parameters should be included in the Params block of the QASM tag’s parent TransferFunction.

<QASM>
h ${register}[${q}]
</QASM>

Procedural Proramming

A runnable HLQ script represents an entry point to an HLQ program. Such a script may import any Components required for its definition. These runnable files use a fluid functional programming syntax for their functional code blocks. Imported Components may simply be composed via bracketed nesting. The outputs of functional blocks of code may be assigned to classical memory locations, and then HLQ’s simple classical programming language features may be used to complete any local processing of these outputs.

Procedural programming may also be used to define classical TransferFunctions. However, unlike a runnable HLQ script, classical TransferFunction definitions still require at least one Interface and follow all other requirements for functional Components described in the previous section as well.

The procedural code blocks may make use of the following language features. The variable types supported in HLQ are the following: array, float, complex, int, str, bool and map. Mathematical expressions may be used which involve the following elements: sqrt, sin, cos, tan, arcsin, arccos, arctan, sinh, cosh, tanh, arcsinh, arccosh, arctanh, exp, log, pi, +, -, *, /, **, =. These are designed to mimic the types and expressions available in Xanadu’s BlackBird language so that a developer does not need to learn more than one set of classical variable types and mathematical expression formats. HLQ also supports other important language features such as for and while loops.

Example

Below is an example of how one might use HLQ to run a simple quantum
algorithm on IBM’s Melbourne quantum computer.

# An HLQ script for running an error-safe Deutsch Jozsa algorithm on the IBM Melbourne quantum computer
use types.qubit.Transmon;
use types.classical.Binary;
use types.classical.Integer;
use types.quantum.TransferFunction;
use components.algorithms.errorCorrection.shorCode;
use components.algorithms.deutschJozsa;
use components.operators.qubit.cnot;
use components.utils.correctDim;
use components.utils.generate;

# Pre-processing can be written using ordinary classical programming
n:Integer = 13;
# Create a quantum TransferFunction, specify the qubit type and the return type
result:Binary =
# Wrap the TransferFunction with Shor’s bit and phase flip error protection code
shorCode:Transmon {
# Specify the algorithm to run
deutschJozsa {
### Begin oracle definition ###
# Resize the enclosed components’ unitary via Kronecker products with the identity to operate on the entire state
correctDim(qubits=n) {
# Generate the gates that make up a TransferFunction (in this case a balanced oracle function)
generate(i=0; i<n; i+=2) {
# Specify the individual operators
cnot(source=i, target=n)
}
}
### End oracle definition ###
}
}(n);

# The assignment causes the functional experiment code to be evaluated, running the experiment!
print(result:Binary);

Component Composition

HLQ allows a developer to create a runnable TransferFunction object, using composable Components. These Components can be pre-defined algorithms or operators. For example, the shorCode error correction algorithm is used in our Deutsch Jozsa example. Below is an example, the Deutsch Jozsa algorithm Component.

# Duetsch Jozsa algorithm component code
use types.classical.Binary;
use types.qubit.Transmon;
use components.operators.qubit.hadamard;
use components.operators.qubit.pauliX;
use components.operators.qubit.measure;
use components.utils.generate;

# Define the component’s TransferFunction, and identify compatible types
<TransferFunction:Transmon>
# Declare component parameters and default values
<Params>
n:Integer = 3;
</Params>

generate(i=0; i<n; i+=1) {
hadamard(qubit=i)
}
pauliX(qubit=n)
hadamard(qubit=n)

# Specify where this component’s children’s TransferFunctions will be rendered
<slot/>

generate(i=0; i<n; i+=1) {
hadamard(qubit=i)
}

# Define an interface that yields a value when the TransferFunction is executed
<interface:Transmon->Binary>
generate(i=0; i<n; i+=1) {
measure(qubit=i)
}
</interface>
</TransferFunction>

This is a “high order” Component, meaning that it uses other Components in its definition. One of the lower order Components that it uses is shown here.

# Hadamard operator component code
use types.classical.Binary;
use types.classical.String;
use types.qubit.Transmon;
use components.implementations.qasm;

# The operator is defined in a type-compatible low level language
<TransferFunction:Transmon>
<Params>
q:Integer = 0;
register:String = ’q’;
</Params>

<QASM>
h ${register}[${q}]
</QASM>

# An interface is only executed if called upon by a higher order component
<interface:Binary>
measure(qubit=q)
</interface>
</TransferFunction>

The TypeSpace

The way HLQ knows how to execute a TransferFunction is by its type. There are many theorized types of quantum computers, and a few of them are now accessible through the quantum cloud. A popular type of superconductor based quantum computer uses Transmon qubits.

A concept that all developers will be familiar with is the namespace. A
namespace is a segment of code in which each declared variable is maintained by a unique name. Same-named variables in different namespaces will not conflict with one another, but within each namespace only one variable can be assigned to each unique name.

HLQ uses a concept called the typespace. For example, the this line
defines a type for the TransferFunction in our Deutsch Jozsa experiment. The type is Transmon.

TransferFunction:Transmon -> Binary { ... }

The closure denoted by the curly braces { … } represents the scope of this
type binding. Within this typed scope, only type-compatible Components may be composed. This means each Component that appears within these braces must either have a TransferFunction with an Implementation that is Transmon compatible, or have a compatible Interface.

Each Component of a TransferFunction must have at least one possible
Implementation. Implementations are Components that accept raw low level code. When an HLQ program is run, the entire Component tree is compiled to a set of low level scripts that can together achieve the entire program’s functional procedure.

When a Component has several possible Implementations, it is a “mixed
type” Component. Such a Component can be included in a higher order Component’s TransferFunction without its type being explicitly specified, and the compatible Implementation type will be determined automatically by the typespace.

Below is an example of a mixed type Component.

# Teleportation algorithm component code
use types.classical.BinaryVector;
use types.classical.Complex;
use types.qubit.Transmon;
use types.cv.Gaussian;
use components.operators.qubit.hadamard;
use components.operators.qubit.cnot;
use components.operators.qubit.pauliX;
use components.operators.cv.beamSplitter;
use components.operators.cv.squeezed;
use components.operators.cv.coherent;
use components.operators.cv.measureX;
use components.operators.cv.measureP;
use components.operators.cv.positionGate;
use components.operators.cv.phaseGate;
use components.operators.measure;
use components.utils.cv.scale;
use components.utils.generate;
use components.utils.correctDim;

<TransferFunction:Transmon>
<Params>
n:Integer = 3; # number of qubits to teleport
</Params>

correctDim(qubits=n*3) {
generate(i=0; i<n; i+=1) {
cnot(source=i, target=i+n)
hadamard(qubit=i)
}
measure(i+n) {
pauliX(qubit=i+2*n) # element conditional on measurement result
}
measure(i) {
pauliZ(qubit=i+2*n)
}
}

# Define an interface that yields a different (not Transmon) typed value
<interface:Binary>
generate(j=0; j<n; j+=1) {
measure(j+2*n)
}
</interface>

# The default interface corresponding to the TransferFunction type is implicitly defined
</TransferFunction>

# Can define alternative typed TransferFunction
<TransferFunction:Gaussian>
generate(i=0; i<n; i+=1) {
coherent(alpha=1+0.5j, qumode=i)
squeezed(r=-2, qumode=i+n)
squeezed(r=2, qumod=i+2*n)

beamSplitter(qumodes=[i+n, i+2*n])
beamSplitter(qumodes=[i, i+n])

measureX(qumode=i)
measureP(qumode=1+n)

positionGate(pos=scale(qumode=i, sqrt(2)), qumode=i+2*n)
phaseGate(phase=scale(qumode=i+n, sqrt(2), qumode=i+2*n)
}
<interface:Binary>
generate(j=0; j<n; j+=1) {
measure(j+2*n)
}
</interface>
</TransferFunction>

References

1.TypeScript Language Specification. (n.d.). Retrieved from https://github.-
com/microsoft/TypeScript/blob/master/doc/TypeScript%20Language%2-
0Specification.pdf
2. Edwards, Marcus. ”TypeScript Implementations of OpenQASM and BlackBird to Enable Web-Accessible Hybrid Quantum Cloud Computing.” [ref]
3. “Cramming More Power Into a Quantum Device.” IBM Research Blog,
15 Mar. 2019, www.ibm.com/blogs/research/2019/03/power-quantum-
device/.

4. “Xanadu Raises $32M Series A to Bring Photonic Quantum Computing
to the Cloud.” Canada NewsWire, 2019, pp. Canada NewsWire, Jun 24,
2019.
5. Gibney, E. (2016). Inside Microsoft’s quest for a topological quantum
computer. Nature. doi:10.1038/nature.2016.20774.
6. “Ion-Based Commercial Quantum Computer Is a First.” Physics World, 20
Dec. 2018, physicsworld.com/a/ion-based-commercial-quantum-computer-
is-a-first/.
7. “Rigetti.” Rigetti, www.rigetti.com/.
8. “Quantum.” Google AI, ai.google/research/teams/applied-science/quantum-ai/.
9. Will Zeng, et al. “First Quantum Computers Need Smart Software.”
Nature, vol. 549, no. 7671, 2017, pp. 149–151.
10. “Towards a Universal Quantum Programming Language.” SIGPLAN Blog, 29 July 2019, blog.sigplan.org/2019/07/26/towards-a-universal-quantum-programming-language/.
11. Andrew W. Cross, Lev S. Bishop, John A. Smolin, Jay M. Gambetta
”Open Quantum Assembly Language” arXiv:1707.03429
12. Nathan Killoran, Josh Izaac, Nicol´as Quesada, Ville Bergholm, Matthew Amy, and Christian Weedbrook. Strawberry Fields: A Software Platform for Photonic Quantum Computing 2018. arXiv:1804.03159
13. Pakin, S. (2019). Targeting Classical Code to a Quantum Annealer. Pro-
ceedings of the Twenty-Fourth International Conference on Architectural
Support for Programming Languages and Operating Systems — ASPLOS
19. doi:10.1145/3297858.3304071
14. “Towards a Universal Quantum Programming Language.” SIGPLAN Blog, 29 July 2019, blog.sigplan.org/2019/07/26/towards-a-universal-quantum-programming-language/.
15. Zeng, Will, et al. “First Quantum Computers Need Smart Software.”
Nature, vol. 549, no. 7671, 2017, pp. 149–151., doi:10.1038/549149a.
16. Edwards, Marcus. “Developing a Hybrid Methodology for Solving Quan-
tum Problems.” Canadian Association of Physics CAM Conference. Lau-
rentian University, Sudbury, ON, Canada. 25 July 2019.
17. S. Ahmed, T. Bromley, I. Dhand, M. Edwards, C. Gogolin, J. Izaac, N. Kil-
loran, F. Miatto, N. Quesada. “StrawberryFields Release 1.10.” GitHub,
22 Apr. 2019, github.com/XanaduAI/strawberryfields/releases/tag/v0.10.0.

--

--

No responses yet